Arduino Delay [Tutorial]

i denne tutorial lærer du, hvordan du korrekt bruger funktionen delay() til at tilføje en vis forsinkelse mellem 2 handlinger i dine Arduino-programmer. Derefter vil du opdage, hvorfor brug af delay() ofte ikke er en god ide, når du vil gøre dine programmer skala, og hvordan du løser det.

Okay, lad os komme i gang!

Indholdsfortegnelse

Hvorfor har du brug for forsinkelser i dine Arduino-programmer?

nå, et Arduino-program er meget afhængig af eksterne input/output for at arbejde.

Tag et simpelt eksempel: du vil måske overvåge tilstanden af en trykknap 100 gange i sekundet eller få en LED til at blinke hvert 0,5 sekund.

nu, hvordan kan du opnå det? Et Arduino-program fungerer sådan:

  • for det første udføres funktionen setup() en gang.
  • derefter udføres loop() – funktionen igen og igen, indtil du slukker for din Arduino.

ethvert program, du skriver, udføres med fuld hastighed. Så hvis du laver en LED-blink i din kode, hvad der vil ske, er, at LED ‘ en blinker med en meget høj hastighed (mindst flere tusinde gange i sekundet).

du lærer at bruge Arduino til at bygge dine egne projekter?

Tjek Arduino for begyndere og Lær trin for trin.

hvis du vil kontrollere tiden – det vil sige, skal du sørge for, at LED ‘ en kun blinker hvert 0,5 sekund og ikke i fuld hastighed – skal du tilføje en vis forsinkelse i din kode.

implementering af Arduino delay i din kode

funktionen Arduino delay ()

her er en kode til at få en LED til at blinke (her vælger vi den indbyggede LED, ingen grund til at tilføje nogen ekstern LED) hvert 0,5 sekund-dette er et af de mest almindelige eksempler, du vil se, hvis du begynder 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å hvordan fungerer denne kode?

først bruger du en” Definer”, så du ikke behøver at kode nummeret” 13 ” flere gange i din kode, og det gør dit program mere læsbart.

du opsætter pin-tilstanden til OUTPUT med funktionen pinMode().

derefter, i loop() funktion, du:

  1. Tænd for LED ‘en
  2. brug delay(500) for at få programmet til at sove i 500 millisekunder, eller 0,5 sekunder
  3. Sluk for LED’ en
  4. brug delay(500) for at få programmet til at sove igen i 0,5 sekunder
  5. og gå tilbage til trin 1, fordi loop() funktionen fortsætter med at blive udført igen og igen.

funktionen delay() forventer, at du giver et antal millisekunder – ikke sekunder – til at sove. Så hvis du tænker på få sekunder, skal du multiplicere tallet med 1000, og du har den værdi, du har brug for.

lav en Arduino-forsinkelse i 1 minut

hvis du vil få din Arduino til at sove i 1 minut eller i flere minutter, så er det ret nemt.

Tag antallet af minutter, multiplicer det med 60 for at få antallet af sekunder, og multiplicer det derefter med 1000 for at få antallet af millisekunder.

eks: delay(3 * 60 * 1000); får programmet til at sove i 3 minutter.

funktionen Arduino delayMicroseconds ()

hvis du har brug for at være mere præcis, skal du muligvis bruge funktionen delayMicroseconds(). Med delayMicroseconds() kan du give et antal mikrosekunder til at sove. Minimumsvarigheden for delay() er 1 millisekund, så hvis du har brug for at sove i kun 400 mikrosekunder, har du her en ny løsning.

denne funktion kan være meget nyttig, når du kommunikerer med nogle komponenter. For eksempel skal Arduino sende nogle data til komponenten og derefter læse noget svar. Lad os sige, at komponenten har brug for 6 mikrosekunder for at behandle anmodningen og levere nøjagtige data.

så i dit program kan du have noget som dette:

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

ikke blokerende forsinkelse – hvorfor du bør undgå at bruge forsinkelse()

så nu hvor du forstår, hvad der er en forsinkelse i Arduino, og hvordan du implementerer den med delay() og delayMicroseconds(), lad os se, hvordan du bruger forsinkelsesfunktionaliteten – men uden disse funktioner.

hvorfor?

når du bruger delay(), stopper udførelsen af dit program og genoptages først, når forsinkelsen er afsluttet.

dette er OK, hvis du kun har en handling at gøre – eksempel: blink en enkelt LED – men hvad nu hvis du har brug for at tage sig af flere udstyrskomponenter eller kommunikere med andre enheder såsom Arduino-kort eller din egen computer?

hvordan kunne du få en LED til at blinke hvert 0,5 sekund og en anden til at blinke hvert 0,8 sekund?

i så fald vil du sidde fast ganske hurtigt. Hvis du stadig vil bruge delay(), kan du finde en løsning, hvor du bruger kortere forsinkelser mellem flere handlinger, men dette vil gøre dit program mere kompliceret, hver gang du tilføjer en ny handling.

løsningen på det er simpelthen at overvåge tiden uden at bruge funktionen delay(), dybest set for at finde en måde at gengive opførslen på delay() uden at bruge den.

kodeeksempel – Arduino delay uden forsinkelse ()

lad os omskrive vores blink LED-eksempel uden at bruge 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; }}

lad os analysere denne kode linje for linje.

initialisering

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

først initialiserer du 3 variabler i det globale omfang:

  • lastTimeLedBlinked: denne variabel vil blive brugt til at gemme sidste gang LED blinkede. Dybest set, hver gang vi får LED ‘ en til at blinke, opdaterer vi denne variabel med den aktuelle tid – ved hjælp af millis () – funktionen.
  • forsinkelse mellem blink: dette er den tid, du vil vente mellem 2 handlinger – her er handlingen at blinke LED ‘ en.
  • ledState: vi bliver nødt til at gemme den aktuelle LED ‘ s tilstand (høj eller lav), så vi kan vide, hvad der var den tidligere tilstand, og handle i overensstemmelse hermed.

hvorfor i det globale omfang? Nå, hvad vi planlægger at gøre er at opdatere disse variabler i loop() funktionen og få adgang til dem igen næste gang vi går ind i loop(). Hvis vi opretter variablerne inde i loop(), vil variablerne være lokale variabler og vil således blive ødelagt, når du afslutter loop() – funktionen. Således næste gang loop() kaldes igen, vil alle værdier gå tabt, og du vil oprette variabler igen uden tidligere værdi inde. Her ved at oprette variablerne uden for funktionen kan vi få dem til at “overleve” og beholde deres værdi hver gang vi indtaster loop().

implementering af Arduino delay-funktionaliteten i loop-funktionen

lad os nu se, hvad der sker i funktionen loop().

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

først læser du den aktuelle tid med funktionen millis().

 if (timeNow - lastTimeLedBlinked > delayBetweenBlink) {

og nu sammenligner du den aktuelle tid, du lige har læst, med den forrige gang LED ‘ en blinkede. Hvis der er gået nok tid (mere end den værdi, der er gemt i forsinkelsemellem blink), betyder det, at du kan indtaste if().

denne kodestruktur-læsning af tiden og sammenligning af den med forrige gang du har udført en handling – er, hvordan du erstatter funktionen delay(). Dybest set beregner du bare en varighed her. Og som du kan se betyder det, at dit program indeholder flere linjer til en simpel applikation, men det giver dig meget mere kontrol, og det er meget mere skalerbart.

så hvad vil der ske? Nå, loop() vil fortsætte med at blive udført i fuld hastighed. Hver gang vil dit program kontrollere, om der er gået nok tid. Hvis ikke, slutter loop() her, fordi den ikke kommer ind i If-strukturen.

og når lige nok tid er gået, indtaster vi if().

udførelse af handlingen

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

OK, du har lige indtastet if(), og dette hvor du vil gøre, hvad du skal gøre.

her får vi LED ‘ en til at blinke. Og fordi vi ikke kan vide direkte, hvad der var den tidligere tilstand for LED ‘ en (da vi har indtastet loop() mange gange og mistet alle lokale variabler oprettet inde), får vi den tilstand fra en global variabel.

hvad vi gør med denne globale variabel er enkel: hvis den var lav, satte vi den til høj, og hvis den var høj, satte vi den til lav. Og så opdaterer vi selvfølgelig den fysiske LED-tilstand i overensstemmelse hermed med digitalWrite().

 lastTimeLedBlinked = timeNow; }}

endelig, og det er super vigtigt, sparer vi den aktuelle tid som sidste gang vi blinkede LED ‘ en. Hvis vi ikke gør det, blinker programmet LED ‘ en i fuld hastighed, fordi tilstanden inde i if() altid vil være sand.

ved at indstille den forrige tid til den aktuelle tid “nulstiller vi timeren”.

så i dette eksempel indtastes if() kun hvert 500 millisekunder eller 0,5 sekunder.

og nu er det godt, fordi dit program ikke stopper, så du kan fortsætte med at udføre forskellige uafhængige handlinger, mens du stadig “venter” for at blinke LED ‘ en.

2 handlinger “på samme tid”

lad os for eksempel sige, at du vil blinke en LED hver 0.5 sekunder og en anden hvert 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, gentager vi kodestrukturen for den anden handling, vi har tilføjet. Og begge handlinger vil ikke forstyrre hinanden!

Recap

hvis du vil lave en Arduino forsinkelse uden at bruge delay():

  1. Opret en global variabel, der skal gemmes, sidste gang du udførte en bestemt handling.
  2. Opret en anden global variabel for at gemme den ønskede varighed mellem 2 handlinger.
  3. i funktionen loop()skal du læse den aktuelle tid med millis().
  4. lige efter det skal du bruge en if-struktur og bruge tilstanden (timeNow - lastTimeActionWasExecuted > delayBetweenActions).
  5. når du har indtastet if(), skal du gøre handlingen.
  6. og stadig i if() skal du gemme det aktuelle klokkeslæt som forrige gang.

du kan gentage disse trin for hver handling, som du har brug for en Arduino-forsinkelse.

når det er ok at bruge delay () og delayMicroseconds ()

der er særlige lejligheder, når du bruger delay() i din kode er stadig OK.

her er 2 af dem:

  • du skal initialisere en komponent under opsætningen af dit program, og denne komponent har brug for lidt tid til at blive initialiseret – for eksempel 1,5 sekunder. I dette tilfælde er det helt fint at bruge delay(1500) i din setup() funktion. Dybest set vil enhver delay() i funktionen setup() i dit Arduino-program ikke være et problem.
  • som forklaret i delayMicroseconds() delen, skal du vente et par mikrosekunder (ikke millisekunder!) ved kommunikation med en ekstern komponent. Hvis du finder ud af, at brug af delayMicroseconds() med et lille antal (for eksempel 10) ikke forstyrrer resten af dit program, kan du stadig bruge det uden at skulle bekymre dig for meget. Men overvej det som en undtagelse, ikke den fælles regel.

konklusion – Brug Arduino delay() med omhu

på grund af arten af Arduino-programmer skal du ofte tilføje forsinkelser i din kode, så du kan vælge, hvornår du skal udføre nogle handlinger, og hvor ofte du vil udføre dem.

funktionerne delay() og delayMicroseconds() er meget enkle funktioner at bruge og blev føjet til Arduino-sproget, så komplette begyndere kunne starte med noget simpelt.

men som du så i denne vejledning, kan du ved hjælp af delay() – funktionen direkte.

når du har forstået kodestrukturen for at slippe af med delay(), vil du være i stand til at forbedre dine Arduino-programmer meget, og multitasking bliver ganske let.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.