Biblioteki odliczania odcinków czasu
Doświadczenie nas uczy, że najwięcej czasu procesor przeznacza na nierobienie niczego (podwójne przeczenie w programowaniu daje prawdę w życiu różnie). A dokładniej - na sprawdzanie lub czekanie na sygnał informujący, że jest coś do zrobienia.Są trzy źródła tych sygnałów, które mogą przerwać procesorowi stan błogiej bezczynności.
- Wewnętrzne sygnały generowane w zadanych interwałach czasu zmuszające do wykonania określonych procedur.
- Sygnały zewnętrzne (cyfrowe, analogowe) , pojawiające się na wejściach procesora, które mają być obsłużone określoną procedurą
- przerwania - to też rodzaj wewnętrznych lub zewnętrznych sygnałów ale obsługiwanych w sposób szczególny
Obecnie poszukam bibliotek ułatwiających generowanie wewnętrznych sygnałów potrzebnych do wykonania zdefiniowanych zadań w określonych odcinkach czasu.
Poprzednie i obecne biblioteki mają jeden wspólny mianownik - ich prawidłowe działanie wymaga możliwie jak najczęstszej obsługi tych bibliotek (tzw. polling). A to po to by program nie przegapił lub znacząco nie opóźnił obsługi tego sygnału. W pętli głównej umieszczane są procedury typu ObsługaZdarzen(), sama zaś programy w pętli głównej winny być obiegana cyklicznie z maksymalną możliwą prędkością (stąd kategoryczny zakaz używania funkcji delay()).
Dziś do analizy idą biblioteki związane z czasem, które NIE używają dodatkowych wewnętrznych liczników procesora poza T0 przywiązanym do funkcji milis() .
Znalezione biblioteki czasu
- SimpleTimer
- Timer
- TimerOne
- TimerTree
- Timers
SimpleTimer
Opis tuBiblioteka używana w programach BLYNK więc wydaje się być dobrą. Ale lektura kodu wykazuje że może i dobra ale na pewno nie simple.
Użycie
#include <SimpleTimer.h> SimpleTimer zegar;Ustawienie w setup() - ustawia pierwszą z liczników dla funkcji "zegar" - może być ich 8
co 1 sek będzie wywoływana procedura repeatMe
zegar.setInterval(1000, repeatMe);Procedura obsługi w loop()
timer.run();
Inne ustawienia - wywołanie pojedyncze procedury. timerId to nr licznika obsługującego tę procedurę
timerId = timer.setTimeout(1000, callMeLater);wywołanie określoną ilość razy
timerId = timer.setTimer(1000, repeatMeFiveTimes, 5);sprawdzenie czy dany zegar jest otwarty
f(timer.isEnabled(timerId)otwarcie zamknięcie przełączenie - danego nr zegara
timer.enable(timerId);
timer.disable(timerId);
timer.toggle(timerId);
restart odliczania danego zegara i kasowanie zegara
timer.restartTimer(wd_timer_id); timer.deleteTimer(timerId);zwraca ile zadeklarowaliśmy zegarów
n = timer.getNumTimers();
Biblioteka wygląda profesjonalne i działa jak obiecuje autor - zobaczymy co dalej
Timer
Biblioteka o trochę inne filozofii - bardziej zbliżona do generatora sygnałów elektrycznych.Deklaracja
#include "Timer.h" Timer t;Ustawienie w setup()
t.pulse(pin, 10 * 60 * 1000, HIGH); // wygenerowanie pulsu 10 min na pinieProcedura obsługi w loop()
t.update();
Pozostałe ustawienia
generator o zadanym czasie 2*100 ms zaczynający od stalu LOW , 10 - potwórzenie oscylacji 10 x
t.oscillate(pin, 100, LOW); t.oscillate(pin, 100, LOW, 10);
wywołanie procedury co 1 sek , wywołanie 10 razy
t.every(1000, takeReading); t.every(1000, takeReading, 10);
za jakiś czas zrob coś - Event to nr zadania
int afterEvent = t.after(10000, doAfter);
każda z tych funkcji zwraca Id procesu
zatrzymanie procesu
int stop(int id)
Biblioteka taka sobie - na razie nie widzę zastosowania
TimerOne
Używa wewnętrznych timerów - odpadaTimerTree
jw - odpadaTimers
Hm to ciekawa biblioteka autorstwa wojtekizkOpisana tu>>>> . I jak pisze autor dobra bo prosta......Zobaczmy
Z lenistwa przekopiuję jej opis
1) Konstruktor - inicjalizacja obiektu klasy Timers.
Przykład:
Timers <8> akcja; - Powołujemy do życia obiekt klasy Timers o przykładowej nazwie akcja, który może obsłużyć 8 niezależnych wątków (zdarzeń)
2) Funkcja attach(nr wątku, interfał wywołania, funkcja obsługi), gdzie:
- numer wątku, to numer jednego z 8 wcześniej zdefiniowanych w konstruktorze wątków;
- interfał - odstęp czasu w ms. W tych odsępach będzie wywoływana funkcja obsługi
- funkcja obsługi - nazwa funkcji, jak ma być wykonywana.
W tym zakresie funkcja attach jest łudząco podobna do funkcji attachInterrupt.
Przykłady:
akcja.attach(2,5000,pokazTemp); - co 5 sekund wątek 3 (liczymy od 0) wywołuje funkcję pokazTemp()
akcja.attach(0, 1000, pokazCzas); - co 1 sekundę wątek pierwszy wywołuje funkcję pokazCzas()
akcja.attach(1,0,flopKierunek); - definiujemy wątek nr 2, ale nie mamy na razie zamiaru z niego korzystać - interfał =0
UWAGA!!!
Funkca attach musi być zainicjowana w funkcji setup() dla każdego z wątków. Jeśli nie mamy zamiaru od razu korzystać z danego wątku, to w funkcji attach ustawiamy interfał na 0.
3) Funkcja updateInterval(nr wątku, akt interfał), gdzie:
- nr wątku, to numer jednego z 8 wcześniej zdefiniowanych w konstruktorze wątków;
- akt interfał - dynamiczna zmiana czasu wywoływania funkcji, w szczególnym przypadku dla interfał=0 wyłączamy obsługę wątku.
Przykłady:
akcja.updateInterval(2,0); - zatrzymanie obsługi wątku nr 3
akcja.updateInterval(4,189); - zmiana lub ustawienie dla wątku nr 5 czasu wywoływania funkcji obsługi na 189 ms.
4) funkcja process() - wywoływana w pętli loop, uruchamia globalną obsługę wszystkich zadeklarowanych w konstruktorze wątków
Przykład:
akcja.process();
I to wszystko
No nie powiem jestem pod wrażeniem - krótko jasno oczywiście. Jestem za
Pozostaje jeszcze tylko pobrać tę bibliotekę - jest na końcu posta widoczna po zalogowaniu
albo tutaj :)
Wniosek
na razie pobawimy się biblioteką Timers.h. Jeśli będzie trzeba coś więcej wrócimy do SimpleTimer.
cdn
Brak komentarzy:
Prześlij komentarz