Arduino, programera fördröjning.

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
pinch
Inlägg: 182
Blev medlem: 7 december 2014, 19:42:10
Ort: Stockholm

Arduino, programera fördröjning.

Inlägg av pinch »

Hur programerar man enklast en fördröjning på en Arduino ?
Ska styra en relämodul från digitala insignaler och vill ha en fördröjning så att det krävs obruten insignal i visst antal sek innan styrsignal till relä skickas ut.
Som ett relä med tillslagsfördröjning, om insignalen bryts innan inställd tid så ska tiden starta om.
Hoppas jag gör mig förstådd :)
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Arduino, programera fördröjning.

Inlägg av Icecap »

För mig är det följande:
1: Skapa en timer-interrupt på en lämplig hastighet.
2: I Timer-ISR'n kollas insignalen och är det Aktivt räknas en variabel upp, dock inte högre än aktiveringsvärdet.
3: Om insignalen är Inaktivt nollas räknaren.
Detta görs parallellt för alla insignaler som ska fördröjas, då med var sin räknare och evt. var sitt aktiveringsvärde.

Main-loop läser variabeln (en eller fler) och är den/de uppe på aktiveringsvärdet slås reläet på, i motsatt fall slås det av.

Ganska enkelt egentligen, det svåra kan vara att komma igång med timer-interrupt om man inte är van.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Arduino, programera fördröjning.

Inlägg av Magnus_K »

Enklast blir nog att använda dig av delay-funktionen.
Skapa en if-sats som blir sann om inputten är aktiv och i if-satsen använder du först delay() och sen aktivera utgången.

Skulle vilja skriva ett kodexempel men sitter vid luren och det tar sån hiskelig tid. Gillar inte att ge svaret att du ska söka på det men i det här fallet är det tyvärr det enda jag kan skriva. Sök på arduino if och arduino delay.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46974
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Arduino, programera fördröjning.

Inlägg av TomasL »

Ingen bra ide, om man vill göra någonting annat.

Använd någon av processorns timers, initiera den till lämpligt värde.
Sedan kan du antingen använda interrupt eller polla timern med jämna mellanrum.
nifelheim
Den första
Inlägg: 2489
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Arduino, programera fördröjning.

Inlägg av nifelheim »

finns en funktion som heter millis()
, som helt oväntat räknar millisekunder hela tiden.

https://www.arduino.cc/en/Reference/Millis



om ingången är låg sätt time = millis();
om millis() är större än ( time + 5000 ) sätt utgången hög ; // 5000 millisekunder = 5 sekunder
börja om;
pinch
Inlägg: 182
Blev medlem: 7 december 2014, 19:42:10
Ort: Stockholm

Re: Arduino, programera fördröjning.

Inlägg av pinch »

Otroligt vad många kunniga svar jag fick på så kort tid.
Jag tackar och bugar och har lite att exprimentera med nu :)
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Arduino, programera fördröjning.

Inlägg av mri »

nifelheims förslag skulle jag också rekommendera, enkel metod och passar väl in i arduino loop() "tänket". men fixa den så den fungerar korrekt även när millis() räknaren slår runt till noll.
Mr Andersson
Inlägg: 1409
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Arduino, programera fördröjning.

Inlägg av Mr Andersson »

Nu kanske jag missförstår svaren i tråden, men jag tycker det verkar som att inget av alternativen garanterar en oavbruten insignal som var ett av kraven.
Jag har väldigt lite erfarenhet av arduino/AVR men det borde väl finnas interrupts för när pinnar ändrar state?

Mitt förslag:
- Skapa en ISR för "pinne ändrad" som kollar om pinnen är hög eller låg. Om hög, starta en timer. Om låg, stoppa timern och sätt utgången låg.
- Vid timer-interrupt sätt utgången till hög.
nifelheim
Den första
Inlägg: 2489
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Arduino, programera fördröjning.

Inlägg av nifelheim »

Det var två kanske viktiga synpunkter, ( svårt att veta utan att ha mer information om ditt projekt ) :-)


millis() retunerar en "unsigned integer", 32 bitar, ungefär 4 miljarder millisekunder sedan slår den runt och börjar på noll,
finns det risk att du ska köra din arduino i mer än 49 dagar i sträck måste du ta hänsyn till det.


Om du gör en loop enligt mitt förslag kommer den att kolla status på ingången några tusen gånger i sekunden,
finns det risk för avbrott i signalen som är väldigt korta , och dessutom hamnar mitt emellan två avläsningar av ingången,
(alltså mindre än en tusendels sekund) så kommer det inte att upptäckas,
då måste du sätta upp avbrotts hantering, ISR, "Interupt Service Routine"

https://www.arduino.cc/en/Reference/AttachInterrupt
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Arduino, programera fördröjning.

Inlägg av mri »

nifelheim: personligen tycker jag inte det finns orsak att medvetat koda in en potentiell bug. :-)

Kod: Markera allt

// Ungefär såhär:

unsigned long start_time;

void loop()
{
...
    if ( signal låg )
    {
       start_time = millis();
    }
    if ((millis() - start_time) >= 5000)
    {
       // aktivera relä
    }
...
}
En viktig sak i denna lösning är att uttrycket (millis() - start_time) evalueras som samma datatyp som returvärdet från millis() och variabeln start_time, annars fungerar det inte korrekt. Vill man vara riktigt pedantisk sätter man in en (unsigned long) typkonvertering framför uttrycket, dvs: "if ((unsigned long)(millis() - start_time) >= 5000)"

Vad gäller att detektera korta glitchar måste TS ta ställning om det kan lösas på ovanstående sätt.
nifelheim
Den första
Inlägg: 2489
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Arduino, programera fördröjning.

Inlägg av nifelheim »

du har givetvis helt rätt :-)
Användarvisningsbild
Jan Almqvist
Inlägg: 1655
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Arduino, programera fördröjning.

Inlägg av Jan Almqvist »

mri skrev:nifelheim: personligen tycker jag inte det finns orsak att medvetat koda in en potentiell bug. :-)

Kod: Markera allt

// Ungefär såhär:

unsigned long start_time;

void loop()
{
...
    if ( signal låg )
    {
       start_time = millis();
    }
    if ((millis() - start_time) >= 5000)
    {
       // aktivera relä
    }
...
}
En viktig sak i denna lösning är att uttrycket (millis() - start_time) evalueras som samma datatyp som returvärdet från millis() och variabeln start_time, annars fungerar det inte korrekt. Vill man vara riktigt pedantisk sätter man in en (unsigned long) typkonvertering framför uttrycket, dvs: "if ((unsigned long)(millis() - start_time) >= 5000)"

Vad gäller att detektera korta glitchar måste TS ta ställning om det kan lösas på ovanstående sätt.
Det finns nog flera brister i exemplet ovan t.ex. att om signalen är hög redan från början kommer start_time inte att initieras...
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Arduino, programera fördröjning.

Inlägg av mri »

javisst, men avsikten var inte att lösa hela uppgiften och presentera ett komplett program utan att visa hur man kan göra fördröjningen, som även fungerar när millis() slår runt till noll.
Användarvisningsbild
Jan Almqvist
Inlägg: 1655
Blev medlem: 1 oktober 2013, 20:48:26
Ort: Orust

Re: Arduino, programera fördröjning.

Inlägg av Jan Almqvist »

Är du säker på att den fungerar när millis() slår runt till noll?
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Arduino, programera fördröjning.

Inlägg av mri »

Ifall jag nu inte skrivit nåt omedvetet fel där så, ja, tämligen säker. :)
Skriv svar