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:
- Praca monostabilna ze stałym czasem - gdy kolejny sygnał wzbudzający timer pojawiający się w trakcie odliczania nie przedłuża odcinku czasu
- 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ść.
- Praca monostabilna ze zminą czasu - gdy kolejny sygnał wzbudzający timer pojawiający się w trakcie odliczania przedłuża odliczany okres nową wartość.
- 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.
- Praca monostabilna z możliwością zatrzymania timera w trakcie odliczania
- 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