Arduino Delay [Tutorial]

i den här handledningen lär du dig hur du använder funktionen delay() för att lägga till lite fördröjning mellan 2 åtgärder i dina Arduino-program. Då kommer du att upptäcka varför använda delay() är ofta inte en bra ide när du vill göra dina program skala, och hur man rättar till det.

Okej, låt oss komma igång!

Innehållsförteckning

Varför behöver du förseningar i dina Arduino-program?

Tja, ett Arduino-program bygger mycket på externa ingångar/utgångar för att fungera.

ta ett enkelt exempel: Du kanske vill övervaka tillståndet för en tryckknapp 100 gånger per sekund, eller få en LED att blinka var 0,5 sekund.

nu, hur kan du uppnå det? En Arduino program fungerar så här:

  • först utförs funktionen setup() en gång.
  • sedan körs funktionen loop() om och om igen tills du stänger av din Arduino.

alla program som du skriver kommer att köras med full hastighet. Så om du gör en LED blinkar i din kod, vad som kommer att hända är att lysdioden blinkar med en mycket hög hastighet (flera tusen gånger per sekund åtminstone).

du lär dig hur du använder Arduino för att bygga dina egna projekt?

kolla in Arduino för nybörjare och lär dig steg för steg.

om du vill styra tiden – det vill säga, Se till att lysdioden blinkar bara var 0,5 sekund och inte i full hastighet-måste du lägga till en viss fördröjning i din kod.

implementera Arduino delay i din kod

funktionen Arduino delay ()

här är en kod för att få en LED att blinka (här väljer vi den inbyggda lysdioden, du behöver inte lägga till någon extern LED) var 0,5: e sekund-detta är ett av de vanligaste exemplen du ser om du börjar med Arduino.

#define LED_PIN 13void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500);}

så, hur fungerar den här koden?

först använder du en” definiera ”så att du inte behöver hårdkoda numret” 13 ” flera gånger i din kod och det gör ditt program mer läsbart.

du ställer in pin-läget för att mata ut med funktionen pinMode().

sedan, i funktionen loop(), du:

  1. slå på lysdioden
  2. använd delay(500) för att få programmet att sova i 500 millisekunder, eller 0,5 sekunder
  3. Stäng av lysdioden
  4. använd delay(500) för att få programmet att sova igen i 0,5 sekunder
  5. och gå tillbaka till steg 1, eftersom funktionen loop() fortsätter att köras om och om igen.

funktionen delay() förväntar dig att du ger ett antal millisekunder – inte sekunder – att sova. Så, om du tänker på några sekunder, multiplicera sedan numret med 1000 och du har det värde du behöver.

gör en Arduino-fördröjning i 1 minut

om du vill få din Arduino att sova i 1 minut eller i flera minuter är det ganska enkelt.

ta antalet minuter, multiplicera det med 60 för att få antalet sekunder och multiplicera det sedan med 1000 för att få antalet millisekunder.

Ex: delay(3 * 60 * 1000); får programmet att sova i 3 minuter.

funktionen Arduino delayMicroseconds ()

om du behöver vara mer exakt kan du behöva använda funktionen delayMicroseconds(). Med delayMicroseconds() kan du ge ett antal mikrosekunder att sova. Minsta varaktighet för delay() är 1 millisekund, så om du behöver sova i bara 400 mikrosekunder, här har du en ny lösning.

denna funktion kan vara mycket användbar när du kommunicerar med vissa hårdvarukomponenter. Till exempel måste Arduino skicka några data till komponenten och sedan läsa lite svar. Låt oss säga att komponenten behöver 6 mikrosekunder för att behandla begäran och leverera exakta data.

då kan du i ditt program ha något liknande:

...void loop() { // send data to component delayMicroseconds(6); // reach out to component again to read data}

non blocking delay – varför du bör undvika att använda delay()

så nu när du förstår vad som är en fördröjning i Arduino och hur man implementerar den med delay() och delayMicroseconds(), låt oss se hur du använder fördröjningsfunktionen – men utan dessa funktioner.

varför?

när du använder delay() stoppas körningen av ditt program och återupptas först efter att förseningen är klar.

detta är OK om du bara har en åtgärd att göra-exempel: blinka en enda LED – men vad händer om du behöver ta hand om flera hårdvarukomponenter eller kommunicera med andra enheter som Arduino-kort eller din egen dator?

med föregående exempel, hur kan du få en LED att blinka var 0,5: e sekund och en annan att blinka var 0,8: e sekund?

i så fall kommer du att fastna ganska snabbt. Om du fortfarande vill använda delay() kan du hitta en lösning där du använder kortare förseningar mellan flera åtgärder, men det gör ditt program mer komplicerat varje gång du lägger till en ny åtgärd.

lösningen på det är helt enkelt att övervaka tiden utan att använda funktionen delay(), i princip för att hitta ett sätt att reproducera beteendet hos delay() utan att använda den.

kodexempel-Arduino delay without delay()

låt oss skriva om vårt blink LED-exempel utan att använda delay().

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;void setup() { pinMode(LED_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); if (timeNow - lastTimeLedBlinked > delayBetweenBlink) { if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState); lastTimeLedBlinked = timeNow; }}

låt oss analysera denna kod rad för rad.

initialisering

#define LED_PIN 13unsigned int lastTimeLedBlinked = millis();unsigned int delayBetweenBlink = 500;byte ledState = LOW;

först initierar du 3 variabler i det globala omfånget:

  • lastTimeLedBlinked: denna variabel kommer att användas för att lagra den sista gången lysdioden blinkade. I grund och botten, varje gång vi får lysdioden att blinka, uppdaterar vi den här variabeln med den aktuella tiden – med millis () – funktionen.
  • delayBetweenBlink: det här är den tid du vill vänta mellan 2 åtgärder – här är åtgärden att blinka lysdioden.
  • ledState: vi kommer att behöva lagra den aktuella lysdiodens tillstånd (hög eller låg) så att vi kan veta vad som var det tidigare tillståndet och vidta åtgärder i enlighet därmed.

varför i den globala omfattningen? Tja, vad vi planerar att göra är att uppdatera dessa variabler i funktionen loop()och komma åt dem igen nästa gång vi går in i loop(). Om vi skapar variablerna inuti loop() kommer variablerna att vara lokala variabler och kommer därmed att förstöras när du avslutar funktionen loop(). Således, nästa gång loop() kallas igen, kommer alla värden att gå vilse och du skapar variabler igen utan föregående värde inuti. Här, genom att skapa variablerna utanför funktionen kan vi få dem att ”överleva” och behålla sitt värde varje gång vi anger loop().

implementera Arduino delay-funktionen i loop-funktionen

låt oss nu se vad som händer i funktionen loop().

void loop() { unsigned int timeNow = millis();

först läser du aktuell tid med funktionen millis().

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

och nu jämför du den aktuella tiden du just har läst, med föregående gång lysdioden blinkade. Om tillräckligt med tid har gått (mer än värdet lagrat i delayBetweenBlink) betyder det att du kan ange if().

denna kodstruktur-läser tiden och jämför den med föregående gång du har gjort en åtgärd – är hur du ersätter funktionen delay(). I grund och botten beräknar du bara en varaktighet här. Och som du kan se betyder det att ditt program innehåller fler rader för en enkel applikation, men det ger dig mycket mer kontroll och det är mycket mer skalbart.

så, vad kommer att hända? Jo, loop() kommer att fortsätta att köras i full fart. Varje gång kommer ditt program att kontrollera om tillräckligt med tid har gått. Om inte, slutar loop() här, eftersom det inte kommer in i if-strukturen.

och när bara tillräckligt med tid har gått, går vi in i if().

utför åtgärden

 if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(LED_PIN, ledState);

OK, du har just angett if(), och det här gör du vilken åtgärd du behöver göra.

här får vi LED-lampan att blinka. Och eftersom vi inte kan veta direkt vad som var det tidigare tillståndet för lysdioden (eftersom vi har angett loop() många gånger och förlorat alla lokala variabler skapade inuti), får vi det tillståndet från en global variabel.

vad vi gör med den här globala variabeln är enkel: om den var låg, satte vi den till hög, och om den var hög, satte vi den till låg. Och så uppdaterar vi naturligtvis det fysiska LED-tillståndet i enlighet därmed med digitalWrite().

 lastTimeLedBlinked = timeNow; }}

slutligen, och det här är super viktigt, sparar vi den aktuella tiden som sista gången vi blinkade lysdioden. Om vi inte gör det kommer programmet att blinka lysdioden i full hastighet eftersom villkoret inuti if() alltid kommer att vara sant.

genom att ställa in föregående tid till aktuell tid ”återställer vi timern”.

så i det exemplet kommer if() bara att anges var 500 millisekunder eller 0,5 sekunder.

och nu är det bra eftersom ditt program inte slutar, så du kan fortsätta att utföra olika oberoende åtgärder medan du fortfarande ”väntar” på att blinka lysdioden.

2 åtgärder” samtidigt ”

till exempel, låt oss säga att du vill blinka en LED varje 0.5 sekunder och en annan var 0,8 sekund.

#define LED_1_PIN 13#define LED_2_PIN 10unsigned int lastTimeLed1Blinked = millis();unsigned int delayBetweenBlink1 = 500;byte led1State = LOW;unsigned int lastTimeLed2Blinked = millis();unsigned int delayBetweenBlink2 = 800;byte led2State = LOW;void setup() { pinMode(LED_1_PIN, OUTPUT); pinMode(LED_2_PIN, OUTPUT);}void loop() { unsigned int timeNow = millis(); // Action 1 - Blink LED 1 if (timeNow - lastTimeLed1Blinked > delayBetweenBlink1) { if (led1State == LOW) { led1State = HIGH; } else { led1State = LOW; } digitalWrite(LED_1_PIN, led1State); lastTimeLed1Blinked = timeNow; } // Action 2 - Blink LED 2 if (timeNow - lastTimeLed2Blinked > delayBetweenBlink2) { if (led2State == LOW) { led2State = HIGH; } else { led2State = LOW; } digitalWrite(LED_2_PIN, led2State); lastTimeLed2Blinked = timeNow; }}

som du kan se upprepar vi kodstrukturen för den andra åtgärden vi har lagt till. Och båda åtgärderna kommer inte att störa varandra!

Recap

om du vill göra en Arduino fördröjning utan att använda delay():

  1. skapa en global variabel för att lagra den senaste gången du gjorde en specifik åtgärd.
  2. skapa en annan global variabel för att lagra den varaktighet du vill ha mellan 2 åtgärder.
  3. i funktionen loop()läser du aktuell tid med millis().
  4. strax efter det, använd en if-struktur och använd villkoret (timeNow - lastTimeActionWasExecuted > delayBetweenActions).
  5. när du har angett if(), gör åtgärden.
  6. och fortfarande i if(), lagra den aktuella tiden som föregående gång.

du kan upprepa dessa steg för varje åtgärd som du behöver en Arduino fördröjning.

när det är ok att använda delay () och delayMicroseconds ()

det finns särskilda tillfällen när du använder delay() i din kod är fortfarande OK.

här är 2 av dem:

  • du måste initiera en komponent under installationen av ditt program, och den här komponenten behöver lite tid för att initieras – till exempel 1,5 sekunder. I det här fallet är det helt bra att använda delay(1500) i din setup() – funktion. I grund och botten kommer alla delay() i funktionen setup() i ditt Arduino-program inte att vara ett problem.
  • som förklaras i delayMicroseconds() – delen måste du vänta några mikrosekunder (inte millisekunder!) vid kommunikation med en extern komponent. Om du upptäcker att användning av delayMicroseconds() med ett litet antal (till exempel 10) inte stör resten av ditt program, kan du fortfarande använda det utan att behöva oroa dig för mycket. Men betrakta det som ett undantag, inte den gemensamma regeln.

slutsats-använd Arduino delay () med försiktighet

på grund av arten av Arduino-program måste du ofta lägga till förseningar i din kod, så du kan välja när du ska utföra vissa åtgärder och hur ofta du vill utföra dem.

funktionerna delay() och delayMicroseconds() är mycket enkla funktioner att använda och lades till Arduino-språket så att fullständiga nybörjare kunde börja med något enkelt.

men som du såg i den här handledningen kan du använda delay() för att få dig att fastna riktigt snabbt. Så det är bäst att först förstå varför du behöver det, hur man använder det och sedan hur man får samma beteende utan att använda Arduino delay() – funktionen direkt.

när du har förstått kodstrukturen för att bli av med delay() kommer du att kunna förbättra dina Arduino-program mycket, och multitasking blir ganska enkelt.

Lämna ett svar

Din e-postadress kommer inte publiceras.