Arduino handledning: använda millis () istället för fördröjning()

en välkänd Arduino-funktion är delay() som pausar programmet för en mängd millisekunder som anges som parameter.

millis(), å andra sidan är en funktion som returnerar mängden millisekunder som har gått sedan programstart.

vid första anblicken kan du tvivla på användbarheten av denna funktion. Faktum är att det är extremt användbart i många scenarier, ofta ”ersätter” delay() helt. Låt oss först titta på hur vi kan använda millis() nästan exakt som delay().

tidsfrågor är ofta närvarande i programmeringen.

använda millis () som fördröjning()

int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {time_now = millis(); Serial.println("Hello"); while(millis() < time_now + period){//wait approx. ms}}

om du vill att din kod bara ska pausa i 1000 ms i slutet av varje loop-iteration är koden ovan lite dum. Du kan bara använda delay(1000) istället. Den enda skillnaden mellan koden ovan och en kod med delay(1000) i slutet är att slingan i ovanstående kod kommer att köras ganska exakt en gång varje sekund. Slingan i en kod med delay(1000) kommer att köras lite mindre frekvent eftersom det också tar lite tid att köra Serial.println("Hello").

Varför använda millis() istället för delay ()?

vi kommer nu att titta på två fördelar med millis() jämfört med delay().

exakt Timing

den första fördelen vi diskuterar är exakt timing. Kodvis, vi täckte detta i det sista kapitlet. Med millis() kan vi se till att slingan går så ofta som vi vill, oavsett exekveringstid (uppenbarligen så länge exekveringstiden är mindre tid den önskade perioden). Med delay() är detta inte möjligt eftersom vi inte vet hur länge loopkörningstiden är.

exakt timing som denna är mycket användbar vid sampling vid en viss frekvens eller körning av filter, bland annat.

icke-blockerande

den andra fördelen med millis() är att det inte kommer att hindra oss från att köra kod medan ”väntar”.

låt oss säga att vi vill skriva ut ”Hej” över seriell en gång varje sekund medan vi gör andra saker under tiden. Detta är inte möjligt med delay() eftersom det pausar hela koden. Här är ett sätt vi kan göra detta:

int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_now + period){time_now += period;Serial.println("Hello");} //Run other code}

denna bit kod är ganska lik den första biten, förutom att den inte blockerar resten av programmet när den inte skrivs ut över seriell.

exempel: en enkel schemaläggare

låt oss skriva ett enkelt exempel där vi skapar en schemaläggare som skriver ut vissa bitar av text med olika intervall.

#define INTERVAL_MESSAGE1 5000#define INTERVAL_MESSAGE2 7000#define INTERVAL_MESSAGE3 11000#define INTERVAL_MESSAGE4 13000unsigned long time_1 = 0;unsigned long time_2 = 0;unsigned long time_3 = 0;unsigned long time_4 = 0;void print_time(unsigned long time_millis);void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_1 + INTERVAL_MESSAGE1){time_1 +=INTERVAL_MESSAGE1;print_time(time_1);Serial.println("I'm message number one!");} if(millis() >= time_2 + INTERVAL_MESSAGE2){time_2 +=INTERVAL_MESSAGE2;print_time(time_2);Serial.println("Hello, I'm the second message.");} if(millis() >= time_3 + INTERVAL_MESSAGE3){time_3 +=INTERVAL_MESSAGE3;print_time(time_3);Serial.println("My name is Message the third.");} if(millis() >= time_4 + INTERVAL_MESSAGE4){time_4 += INTERVAL_MESSAGE4;print_time(time_4);Serial.println("Message four is in the house!");}}void print_time(unsigned long time_millis){Serial.print("Time: ");Serial.print(time_millis/1000);Serial.print("s - ");}

så här ser de första 60 sekunderna i seriemonitorn ut:

detta är ett trevligt och enkelt sätt att synkronisera avrättningar i din kod. Du kan också köra annan kod samtidigt.

micros () och överflödig

precis som delay() har en mikrosekundversion som heter delayMicroseconds(), millis() har micros(). Om du behöver bättre upplösning kan micros() vara vägen att gå.

var dock medveten om att micros()kommer att flyta över efter cirka 70 minuter, jämfört med millis() 50 dagar. Detta innebär att funktionernas returvärden börjar om från noll.

ännu viktigare: för att lära dig hur du kan undvika överflödesproblemet alltogether, läs det här blogginlägget.

sammanfattning

millis() och micros() är verkligen praktiska funktioner att använda när man arbetar med tidsuppgifter. Om du inte är medveten om dessa kan du sluta använda delay() istället, vilket inte alltid fungerar så bra (om alls).

för mer Arduino tips & tricks, kolla in vår Arduino Tutorials blogg kategori. Håll ögonen öppna för mer Arduino-relaterat innehåll i framtiden också!

Lämna ett svar

Din e-postadress kommer inte publiceras.