delay() Arduino-funktion: Arduino-funktion: Tight Loops and Blocking Code
Har du nogensinde lavet et Arudino-projekt, og du vil have noget til at ske med et tidsbestemt interval? Måske vil du have, at en servo skal bevæge sig hvert 3. sekund, eller måske vil du hvert 1. minut sende en statusopdatering til en webserver.
Hvordan gør du det? Er der en funktion, der er enkel og ligetil, der hjælper os med dette? Ja, det er der! Vi vil diskutere delay-funktionen samt millis()-funktionen i videoen nedenfor:
Dette er del 2 af vores miniserie om millis()-funktionen. Del 1 hjælper os med at forstå, hvad millis() funktionen gør, del 2 diskuterer stramme loops og blokerende kode, og del 3 diskuterer, hvornår millis() funktionen overgår delay() funktionen.
Temaer i denne lektion
- Tætte loops
- Blokeringskode
- Ancient opskrift på inspirerende musik
Millis() versus Delay()
Så du vil have noget til at ske med et bestemt interval, og du leder efter en løsning. Hvis dit svar er at bruge delay-funktionen, ja, så har du på en måde ret. Men der er en anden måde.
Den mere cool og smarte løsning er Arduino millis()-funktionen. Og jo mere fortrolig du er med at bruge millis-funktionen til at hjælpe dig med at tidsbestemme begivenheder i din Arduino-kode, jo nemmere vil det være at indarbejde andre dele i dit program senere hen.
Når du begynder at bruge millis()-funktionen, bliver du gladere og mere munter, og for pokker da, folk vil kunne lide dig.
![Arduino Millis()-funktion](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/people_like_you.png)
Tight Loops
Først vil vi diskutere begrebet “tight loop”. Og når vi siger en stram løkke, hvad betyder det så?
Lad os tage et kig på en Arduino-skitse til en demonstration af en stram løkke. Hvis vi starter med den mest grundlæggende skitse, har vi kun to funktioner: void setup og void loop. Og som du måske ved, kører void setup kun én gang, hvorefter den overlader showet til void loop.
![Arduino void setup loop](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/void_setup_loop_2.png)
Void loop gennemgår derefter hver eneste kodelinje, der måtte være inde i loopet (inden for disse krøllede parenteser).
Den udfører den første linje, derefter udfører den den anden og derefter den tredje og så videre osv. osv. indtil den når til bunden. Og så går den tilbage til toppen.
Hvor hurtigt udfører den sløjfen? Det afhænger af, hvilket Arduino-kort du bruger, men en Arduino Uno har en clockhastighed på 16 megahertz. Det betyder altså, at der sker 16 millioner instruktioner hvert sekund på Arduino’en!
![Arduino clock speed](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/16-Mhz.png)
Hver linje af kode er ikke nødvendigvis en instruktion. Faktisk er det mest sandsynligt, at det er flere instruktioner. Men det er stadigvæk relativt hurtigt (din computerprocessor kører sandsynligvis med gigahertz-hastigheder… det er milliarder).
Så ville du betragte den tomme skitse som en stram løkke? Helt sikkert, det er så hurtigt og så stramt som du kan lave en løkke. Da der ikke er noget inde i loopet, der skal udføres, er den tid, det tager at gå igennem skitsen, praktisk talt nul. Sagt på en anden måde er intervallet fra loopens start til slut kort (derfor er den hurtig, eller “stram”).
Lad os tilføje nogle linjer kode. Vi starter den serielle kommunikation og udskriver derefter noget til det serielle monitorvindue.
![Arduino tight loop seriel kommunikation](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/03/tight_loop.png)
Er dette en tight loop? Det vil sige, fra starten af loopet til slutningen af loopet, tager det meget lang tid? Det tager meget lidt tid, så det er et hurtigt, stramt loop.
Det er dog værd at bemærke, at dette loop ikke er så stramt som det foregående eksempel. I det foregående eksempel havde vi ingen kode. Så den kørte bare hurtigt gennem løkken. Nu hvor vi har en funktion her, serial print, vil det tage (en lillebitte) smule tid at udskrive “Ice Ice Baby” til serial monitor.
Men dette er stadig en ret hurtig løkke. Så lad os tilføje en lille smule mere kode. Vi får programmet til at kontrollere, om der er trykket på en knap, og hvis det er tilfældet, får vi sendt noget nyt til den serielle monitor
![Arduino tight loop serial monitor with button push](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_2.png)
Så vi har erklæret en knap og brugt en if-anvisning til at kontrollere og se, om der er blevet trykket på knappen. Er spændingen på pin fem høj? Hvis ja, så udskriver vi noget andet til det serielle monitorvindue.
Er dette en stram sløjfe? Så fra starten af løkken til slutningen af løkken, er det ret hurtigt?
Ja, det er stadig ret hurtigt. Det er en ret stram sløjfe. Vi har fire linjer kode. Vi udskriver til den serielle skærm, og så laver vi en hurtig kontrol for at se, om der bliver trykket på en knap. Og hvis det er tilfældet, udskriver vi noget. Stadig stramt, stadig hurtigt.
Næste lad os tilføje en forsinkelse til dette program ved hjælp af Arduino delay()-funktionen. Du kan se nedenfor, at vi har tilføjet en forsinkelse på tusind millisekunder (1 sekund) til løkken.
![Arduino tight loop with delay](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_3.png)
Er dette stadig en tight loop? Er tiden, fra starten af loopet til slutningen af loopet, meget lang tid? Nej, dette er bestemt ikke en stram løkke. Koden starter hurtigt, vi laver serial print, men så bliver vi stoppet lige der ved delay-funktionen.
Hele programmet går i stå, mens vi venter på, at denne delay-kode bliver færdig.
Når Arduino’en kommer til denne kodelinje, er det lidt som at gå i købmandsbutikken. Du kommer ind i køen med 12 varer eller mindre, men så trækker fyren foran dig sit checkhæfte frem og begynder at skrive en check. Du ved, at du vil være der i et minut. Det er det samme her.
![Når nogen trækker en check ud i ekspreskøen](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/checkout.png)
Det er altså ikke et snævert loop. Tiden fra starten af løkken til slutningen af løkken er ret betydelig. Især sammenlignet med de sidste par programmer. Størrelsesordenen af tiden er enorm.
Nu har vi forsøgt at demonstrere her, at hele denne idé om stramme sløjfer er relativ. Det hele afhænger af din applikation. Hvis du har brug for at kontrollere status for en sensor hver 10 milliontedel af et sekund, så er et program med tre linjer kode måske ikke stramt nok, det afhænger bare af det.
En anden pointe er, at ikke alle linjer kode tager lige lang tid at udføre. Hvis du kalder en funktion, der gør en masse ting, som f.eks. serial print, så kan denne ene kodelinje tage en hel del længere tid end 10 andre kodelinjer.
Så tætheden af en løkke er en relativ idé.
![Tætheden af en Arduino-loop er relativ - Einstein](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/The-tightness-of-a-loop-is-relative.png)
Blokeringskode
Når et program stopper på et tidspunkt, og tager noget tid til at udføre noget kode, kan denne kode kaldes blokeringskode. Dette er et generelt udtryk.
I vores program har vi delay-funktionen, der fungerer som blokeringskode. Ingen af koden efter delay kan køre, før delay er overstået, så den bliver blokeret.
Blokeringskode er dog ikke kun, når vi bruger funktionen delay().
Lad os tage vores program og slippe af med delay, men vi tilføjer en for-loop. Vores for-loop vil udskrive tal og tekst til den serielle port.
![Arduino stramt for loop](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/tight_loop_4.png)
Så hvor længe kører dette loop i? Den kommer til at køre i et stykke tid, fordi den skal igennem 100 iterationer, før den stopper.
Og hvad med koden efter denne for-loop? Er den i stand til at køre? Nej, den er nødt til at vente, fordi den bliver blokeret af for-løjpen.
Denne for-løjpe er indlejret i hovedløkken. Er for-sløjfen en “stram” sløjfe? Før du svarer, skal vi igen understrege, hvordan du skal tænke på det: Tager det meget tid at gennemgå denne for-loop, fra toppen til bunden?
Det gør det egentlig ikke. Den har kun to linjer kode. Så det er en ret stram løkke.
Men det er en stram løkke, der skal igennem en masse iterationer, før programmet kan komme til koden under den. Så selv en stram løkke kan blokere vores kode, hvis den tvinges til at køre gennem flere iterationer.
Mere om delay()-funktionen
Lad os tale lidt mere om denne delay-funktion. Hvad har vi konstateret indtil videre?
For det første har vi sagt, at forsinkelsesfunktionen mindsker tætheden i en løkke. Hvis du har en stram løkke, og du tilføjer forsinkelsesfunktionen, vil det tage mere tid og gøre den mindre stram. Det vil sige, at den tid, det tager at komme fra starten af løkken til bunden, vil stige med forsinkelsesfunktionen.
Vi ved også, at forsinkelsesfunktionen blokerer kode. Dette går hånd i hånd med det, vi lige har sagt. Når delay-funktionen kører, blokerer den anden kode for at køre, mens den forsinker.
Du tror måske, at denne delay-funktion er en total slacker! Den kommer aldrig til at betyde noget i vores projekter. Men for en masse simple programmer, som vi skriver, fungerer delay-funktionen fantastisk godt. Den er enkel at bruge, den er virkelig nem at stave, og den gør præcis, hvad den siger.
![Arduino delay-funktionen er en sofakartoffel](https://i0.wp.com/www.programmingelectronics.com/wp-content/uploads/2019/04/Is-the-delay-function-a-total-slacker__.png)
Så vi bør ikke nødvendigvis udelukke delay() funktionen fra vores programmeringsværktøjskasse. Vi skal bare erkende, at det er en simpel programmeringsfunktion, der kan fungere i mange tilfælde.
Der er dog et tidspunkt, hvor man begynder at løbe ind i problemer. Det har at gøre med den blokeringseffekt, som delay-funktionen har i vores program.
I den næste lektion i serien, del 3, skal vi identificere, hvor dette virkelig bliver et problem. Du lærer, hvornår det giver mening at bruge delay()-funktionen i et program, og hvornår det er på tide at skifte til at bruge millis()-funktionen.
Review
Først talte vi om tætheden i en løkke. Vi sagde, at tætheden af en løkke er relativ. Det afhænger af, hvad din applikation er.
For det andet talte vi om blokeringskode, eller kode, der blokerer. I bund og grund er det et generisk udtryk, som vi kan give til kode, der vil tage noget tid at udføre, og som vil stoppe andre dele af vores program fra at køre, mens den udføres.
Vi håber, at du nød denne lektion! I den næste del af denne serie fortsætter vi vores rejse for at lære at bruge millis-funktionen til at skabe tidsbestemte, gentagne hændelser i vores Arduino-kode. Vi ses næste gang!
![Arduino gammel opskrift på inspirerende musik](https://programmingelectronics.com/wp-content/uploads/2019/04/ancient-recipe-gif.gif)