Arduino Millis() vs Delay()

Arduino Millis() vs Delay()

Od początku…

Do obsługi czasu w Arduinio standardowo mamy do wyboru tylko 4 funkcje…

  • delay() zatrzymuje program, na określony (w milisekundach ) czas – delayMicroseconds() również zatrzymuje program na określony (w mikrosekundach) czas.
  • millis() zwraca czas jaki upłynął od uruchomienia programu do obecnej chwili (czas wyrażony w milisekundach). Funkcje resetują się po upływie 50 dni.
  • micros() również zwraca czas jaki upłynął od momentu uruchomienia programu do obecnej chwili (czas wyrażony w mikrosekundach). Funkcja resetuje się po upływie 70 minut.

„Z powyzszego najczęściej korzystamy z funkcji dealy(), co niestety jest błędem…”

No, może nie do końca błędem, ale raczej nie powinniśmy z tego korzystać. Istnieją określone przypadki kiedy warto użyć tej funkcji w swoim kodzie, o ile jednak jest to możliwe, warto zastanowić się nad innym rozwiązaniem.

Dlaczego unikamy delay() i temu podobnych?

„Funkcja zatrzymuje program na określony czas…” I rzeczywiście tak się dzieje; procesor przez ten krótki dla nas czas nie wykonuje żadnej czynności, w rzeczywistości mógłby jednak nadal wykonywać jakieś działanie, np. zbierać dane odmierzając jednocześnie potrzebny czas. (To tak, jakbyśmy przez cały dzień siedzieli w miejscu i tylko co godzinę zaświecali lub gasili światło.)

Przykład wraz z rozwiązaniem.

{

pinMode(7, OUTPUT);

}

void loop()

digitalWrite(7, HIGH);

delay(1000);

digitalWrite(7, LOW);

delay(1000);

}

Schemat połączenia – nie ma tutaj nic trudnego, 

Opis problemu, jak już wcześniej wspominałem powinniśmy unikać zatrzymywania programu na jakiś czas. Spróbujemy zatem napisać program który będzie cały czas działał jednocześnie odmierzając czas i w odpowiednim czasie wykonywał określone operacje – w tym wypadku podawał stan wysoki na pin siódmy.

 

Rozwiązanie – praktyczne wykorzystani millis().

 

 

  unsigned long actual = millis(), t1 = millis(); // pobieramy aktualny czas oraz czas naszej diody

bool s1 = 0; // stan naszej diody

unsigned long  difference (unsigned long one, unsigned long two) // po prostu różnica czasów

{

return one – two; // zwracamy wynik

}

 

void setup()

{

pinMode(7, OUTPUT);  // ustawiamy pin 7 jako wyjście

}

 

void loop()

{

if (difference(actual, t1) > 1000) // obliczmy różnice czasu aktualnego od czas ostatniego użycia diody i sprawdzamy czy większy czy 1 sekunda (1000 milisekund)

{

s1 = !s1; // zmieniamy stan naszej diody

t1 = millis(); // czas użycia diody

}

 

digitalWrite(7, s1); // podajemy stan wysoki 1 lub niski 0

 

actual = millis(); // aktualizujemy czas

}

 

Tym razem kod jest jednak nieco dłuższy, wszystko zostało opisane komentarzami tak, że nikt nie powinien mieć problemu z jego analizą. Początkowo czas aktualny i czas  diody wynosi 0. W czasie działania programu pobierany jest czas aktualny (10, 20, 30 milisekund…), od którego potem odejmowany jest czas użycia diody. Jeżeli różnica czasu, czyli wynik funkcji, będzie większy niż czas podany, zostanie wykonany warunek – w tym wypadku zmiana stanu diody.

Uproszczona wersja kodu wraz z przykładem na 3 diodach

unsigned long actual = millis();

unsignedlong t1 = millis(), t2 = millis(), t3 = millis();

bools1 = 0, s2 = 0, s3 = 0;

unsignedlong ofset (unsigned long one, unsigned long two)

{

return one – two;

}

voidsetup()

{

begin(9600);

pinMode(7, OUTPUT);

pinMode(8, OUTPUT);

pinMode(9, OUTPUT);

}

voidloop()

{

if (ofset(actual, t1) > 1000)

{

s1 = !s1;

t1 = millis();

}

 

if (ofset(actual, t2) > 500)

{

s2 = !s2;

t2 = millis();

}

if (ofset(actual, t3) > 250)

{

s3 = !s3;

t3 = millis();

}

 

digitalWrite(7, s1);

digitalWrite(8, s2);

digitalWrite(9, s3);

 

actual = millis();

}

Na koniec mam dla was złą wiadomość – w przypadku millis() nie wystarczy po prostu skopiować kod, delikatnie poprawić i dodać do swojego projektu. Każdy program jest inny – my jedynie przedstawiliśmy sposób wykorzystania tej funkcji, tak aby ułatwić wam zrozumienie tego tematu.

Maciek Szostak dla Learnduino.pl

Ryszard Marcin

Create Account



Log In Your Account