2023-01-08

Biblioteka Timers.h


 W przykładach omawianych we wcześniejszych postach ciągle pojawia się biblioteka timers.h autorstwa kolegi Wojtka.

Dla ułatwienia dziś kilka słów o niej.




Najpierw link do pliku timers.h

I krótki opis działania biblioteki w programie

1.Obsługa cykliczna zdarzeń. Najbardziej oczywiste zastosowanie.

#include <Timers.h>
Timers <2> akcja; 
void setup(){
   akcja.attach(0, 1000, zrob_cos_co1sek);  // inicjalizacja procesu
}
 void loop(){
 akcja.process();  //pooling - cyklicznie wywołanie by sprawdzić czy już czas działać
}
void zrob_cos_co1sek() {
//wlasny podprogram do wykonania co 1 sek
}

Wywołanie podprogramu zrob_cos następuje co 1 sek - np będzie to zmiana stanu leda na przeciwny, wyświetlenie wartości odczytanej z czujnika itd itd  Uzyskuję w ten sposób obsługę zdarzeń o częstotliwości dostosowanej do rzeczywistych potrzeb. Umieszczenie programu zrob_coś w pętli głównej  programu spowoduje, że wykonywał się on będzie  (niepotrzebnie) setki lub tysiące razy na sekundę.  Możemy go spowolnić  dodając nieśmiertelne delay(), ale zablokuje to możliwość wykonania innych pożytecznych rzeczy przez procesor. Timers.h rozwiąże ten problem za mnie - odczeka w tle 1  sek nie wstrzymując działania innych fragmentów kodu po czym w odpowiednim momencie uruchomi program zrob_coś.

2.Obsługa cykliczna zdarzeń z dynamiczną zmianą częstotliwości obsługi. To odmiana pkt. 1 pozwalająca na zmianę częstości wywołania programu zrob_cos w trakcie działania programy np. zwiększenia szybkości migania led jako sygnalizacja nowego stanu w procesorze.


.

#include <Timers.h>
Timers <2> akcja; 
void setup(){
   akcja.attach(0, 1000, zrob_cos);  // inicjalizacja procesu
}
 void loop(){
 akcja.process();  //pooling - cyklicznie wywołanie by sprawdzić czy już czas działać
if (zmiana stanu przycisku)  {
      if (zmiana z 0>1) akcja.updateInterval(0,500); else akcja.updateInterval(0, 1000); 
  }
}
void zrob_cos() {
//wlasny podprogram do wykonania cyklicznie
}

 Świetnie nadaje się np. jako wskaźnik stanu w działaniu programu z wykorzystaniem tylko jednego LEDa. 

3. Zatrzymanie/ start cyklicznej obsługi zdarzeń. To w zasadzie pkt.2 z z ustawionym czasem obsługi = 0.

.

#include <Timers.h>
Timers <2> akcja; 
void setup(){
   akcja.attach(0, 1000, zrob_cos);  // inicjalizacja procesu
}
 void loop(){
 akcja.process();  //pooling - cyklicznie wywołanie by sprawdzić czy już czas działać
if (zmiana stanu przycisku)  {
      if (zmiana z 0>1) akcja.updateInterval(0,0); else akcja.updateInterval(0, 1000); 
  }
}
void zrob_cos(){
//wlasny podprogram do wykonania cyklicznie
}
.


 To świetna sprawa - np. uruchamiam wykonywanie większości procedur głównego programu dopiero po nawiązaniu połączenia z serwerem ale pozostała część odpowiedzialna realizację funkcji  działa nadal nieprzerwanie.

4 Praca monostabilna - jednokrotne odmierzanie zadanego odcinka czasu. To moim zdaniem jedno z ciekawszych możliwości zastosowań tej do bólu prostej biblioteki

.

#include <Timers.h>
Timers <2> akcja; 
int i=1;

void setup(){
   akcja.attach(0, 0, zrob_cos);  // inicjalizacja procesu
}
 void loop(){
akcja.process();  //pooling - cyklicznie wywołanie by sprawdzić czy już czas działać
if (i) akcja.setInterval(0,5000); // zrob cos za 5 sek
}
void zrob_cos()  {
akcja.updateInterval(0,0); //wyłącz timer 
i=0;
//wlasny podprogram do wykonania jednokrotnie 
}

W momencie PZ następuje jakieś zdarzenie i uruchamiany jest timer na zadany odcinek czasu (koniecznie wywołaniem funkcji setInterval  bo wtedy mamy pewność, że timer odliczy dokładnie zadany odcinek czasu). Po jego upływie timer wywołuje procedurę zrob_cos, która wstrzymuje dalsze odliczanie timera i wykonuje zadany nasz program. Znakomicie nadaje się to do uruchamiania np. pompy obiegowej CO.

Co ważne odcinek czasu na jaki uruchamiany  jest timer może być dowolnie zmieniamy podczas każdorazowego uruchamiania timera a także w trakcie odliczania .
W programie możemy zadecydować  o tym czy kolejny sygnał sterujący w czasie pracy timera  będzie uwzględniony czy nie w procesie odliczania odcinka czasu. Możemy także  sterować zachowaniem timera w zależności od tego czy do zmiany czasu w trakcie odliczania użyjemy funkcji  setInterval   czy też updateInterval . Tym samy dostajemy arcyciekawe możliwości zastosowania biblioteki Timers.h w pracy monostabilnej: 

    1. Praca monostabilna ze stałym czasem - gdy kolejny sygnał wzbudzający timer pojawiający się w trakcie odliczania nie przedłuża odcinku czasu
    2. Praca monostabilna z odświeżaniem czasu - gdy kolejny sygnał wzbudzający timer pojawiający się w trakcie odliczania  przedłuża odcinku czasu o kolejną tą samą wartość.
    3. Praca monostabilna ze zminą czasu - gdy kolejny sygnał wzbudzający timer pojawiający się w trakcie odliczania  przedłuża odliczany okres  nową wartość.
    4. Praca monostabilna ze zminą czasu 2 - gdy kolejny sygnał wzbudzający timer pojawiający się w trakcie odliczania  zmienia odliczany okres. Jeśli timer odliczył już czas nowo ustawianej wartości następuje natychmiastowe wywołanie funkcji zrob_co. Gdy odliczany odcinek czasu jest krótszy niż  nowa wartość, timer "dolicza czas do nowej wartości i wywołuje funkcję zrob_cos.
    5. Praca monostabilna z możliwością zatrzymania timera w trakcie odliczania 
    6. Itd .............


    Jak na tak prostą bibliotekę ilość możliwych do wykorzystania opcji rozrasta się imponująco.

    Biblioteka ta przypomina mi nieśmiertelny timer NE555 królujący od lat w rożnych aplikacjach częstotliwościowo/czasowych i dla którego wciąż pojawiają  się nowe ciekawe zastosowania.

    Z pobieżnego tylko oglądu tej biblioteki widać już jak bardzo potrafi ona ułatwić i uprzyjemnić obsługę wszelkiej maści zdarzeń w tworzonych programach.

    T to tyle na dziś













    Brak komentarzy:

    Prześlij komentarz