niedziela, 21 sierpnia 2016

Arduino biblioteki - cd ..... obsługa Timer

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.
  1.  Wewnętrzne sygnały generowane w zadanych interwałach czasu  zmuszające do wykonania określonych procedur.
  2.  Sygnały zewnętrzne (cyfrowe, analogowe) , pojawiające się na wejściach procesora, które mają być obsłużone określoną procedurą
  3. przerwania - to też rodzaj wewnętrznych lub zewnętrznych sygnałów ale obsługiwanych w sposób szczególny
W poprzednim poście analizowałem biblioteki mające pobudzać mikroprocesor do wykonania zaprogramowanych zadań, których źródłem były cyfrowe 0/1 sygnały zewnętrzne.

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
  1. SimpleTimer
  2. Timer
  3. TimerOne
  4. TimerTree 
  5. Timers

SimpleTimer

Opis tu
Biblioteka 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 pinie  
Procedura 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 - odpada

 TimerTree 

jw - odpada

Timers

Hm to ciekawa biblioteka autorstwa wojtekizk
Opisana 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