Biblioteka Timers v.16.4.0 – Program sterowany czasem
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. Badum-tsss.
Właściwie tutaj mógłbym skończyć swoje filozofowanie i wrócić do pisania kolejnej mrugającej diody. Jednak do dzwonka jeszcze daleko i nie chcę zostawić cię szanowny czytelniku z niczym.
Bo wkurza mnie, że na Arduino tak trudno napisać coś bardziej skomplikowanego. Wielu już próbowało. Wielu się nawet udało. Jednak ich kod wyglądał po tej operacji jak koń po westernie.
Jedną z większych bolączek jest funkcja „delay(czas)”. Użyjesz takiej, to ci zablokuje cały program. Więc program może robić tylko jedną rzecz. Jak chcesz zrobić inną w tym samym czasie – dokup drugie Arduino! Prawie jak tablety.
Moim remedium na te problemy jest…
Biblioteka Timers
Jej idea jest prosta. Rodzice podróżują z dziećmi samochodem. Dzieci co jakiś czas pytają „kieeedy dojedziemyyyy?”. Rodzice wymyślają jakąś odpowiedź i mamy spokój na kolejne 15 minut, w czasie których każdy może robić swoje.
Gdyby taką wycieczkę organizowało Arduino. Po zapytaniu, wszyscy zamarliby w bezruchu aż jakimś cudem samochód dotoczy się na miejsce przeznaczenia – czyli do rowu.
Postanowiłem napisać bibliotekę, która działa wg naturalnego scenariusza.
Ustawiasz timer na jakiś czas. Program robi swoje i co jakiś czas sprawdza specjalną funkcję, która odpowiada, że czas już minął, albo nie minął. To tyle. Jak minął to dzieją się rzeczy które miały się dziać po tym czasie. Jak nie minął to dzieją się inne.
W końcu człowiek jak spojrzy na zegarek to nie zatrzymuje się aż będzie godzina na którą czekał. Tylko robi coś innego i co jakiś czas sprawdza czas.
Moje rozwiązanie jest nawet lepsze, bo pozwala stworzyć dużo timerów i sprawdzać na każdym inny odliczany czas.
Oznacza to, że Arduino może teraz robić wiele rzeczy na raz. To tak jakbyś miał stertę budzików i w zależności od tego który zadzwoni, robiłbyś coś innego. Genialne!
Jak działa biblioteka Timers
Najpierw trzeba wytworzyć timer. Robi się go jak zmienną. Wystarczy napisać.
Timer mojTimer;
Teraz pod nazwą „mojTimer” masz swój timer do odliczania czasu.
Możesz zrobić więcej takich timerów pod różnymi nazwami, albo ich tablicę.
Potem ustalasz ile czasu timer ma odliczać.
mojTimer.begin(3000);
W tym przypadku kazałem mu odliczać 3000 milisekund czyli 3 sekundy.
Oczywiście to nie blokuje programu. Program wykonuje dalsze rozkazy. Skąd wiadomo, że czas upłynął?
if (mojTimer.available()) {
// Tu wpisujesz co ma się dziać kiedy czas timera upłynie
}
Funkcja o nazwie „available” należąca do „mójTimer” to takie „spojrzenie na zegarek”, czy już?
Program się nie blokuje tylko odpowiada, że czas już minął, albo nie minął. Jeśli tak to wykona się kawałek programu w nawiasach klamrowych po „if”.
Jeśli chcesz by timer zaczął liczyć od nowa, wystarczy użyć:
mojTimer.restart();
To są podstawy użycia biblioteki Timers. W tej prostocie tkwi siła niczym w Minecraft ;-) Tylko zamiast klocków są timery.
Działanie biblioteki Timers w praktyce
No i doigrałem się. Pierwszy praktyczny przykład mojej biblioteki to te oklepane mruganie diodą. Ale co poradzić. Na jego przykładzie przekonasz się o zaletach tego rozwiązania.
#include <Timers.h> Timer ledBlinkTimer; void setup() { pinMode(LED_BUILTIN, OUTPUT); ledBlinkTimer.begin(SECS(2)); } void loop() { if (ledBlinkTimer.available()) { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); ledBlinkTimer.restart(); } }
Na początku za pomocą „include” informujesz, że będzie używana biblioteka Timers.
Potem tworzysz timer o nazwie „ledBlinkTimer”.
W funkcji „setup” ustawiasz timer na 2 sekundy za pomocą „begin” i „SECS”.
W funkcji „loop” program sprawdza czy upłynął już czas timera.
Jeśli tak to zamieniane jest świecenie diody z nieświeceniem i następuje reset timera za pomocą funkcji „restart”. Potem wszystko dzieje się od nowa.
Do funkcji „loop” możesz dopisać kolejne elementy programu. Nic nie będzie blokowane i wiele niezależnych elementów programu może współpracować razem. W ten sposób Arduino może robić więcej niż jedną rzecz na raz. W końcu można pisać rozbudowane programy bez zbędnych zmartwień.
Jeśli spodobała Ci się ta biblioteka, przejdź na stronę projektu, pobierz ją i zapoznaj się z dodatkowymi funkcjami oraz przykładami.
Biblioteka współpracuje z płytkami TinyBrd, Arduino, Teensy, ESP8266 i innymi.
Jeśli skorzystam z instrukcji mojTimer.time(STOP) to zatrzymuje timer i wpisuje wartosc tak? Jak w takim razie mozna wznowić prace timera?
Bartosz: By wznowić pracę timera, powinieneś od nowa wpisać wartość czasu interwału, różną od 0 :-)
Hey potrzebuję zliczać czas jak długo na czujnik oświetlenia pada światło :) i po upływie np 10 minut zaświecić LED czy tą biblioteką mogę to wykonać?
Pozdrawiam
Oczywiście może, ale trochę nie rozumiem. Możesz napisać jaśniej? :-)
Witam.
Przepraszam ,że umieszczam mój problem w komentarzu ale nie znalazłem lepszego miejsca niż właśnie ten artykuł (normalny język autora SUUPER a nie muchy w nosie i podejście jeśli się nie znasz to spadaj;-) a jeśli dobrze kombinuje to funkcja timer mogła by rozwiązać mój problem.
Problemem jest sterowanie silnikami DC za pomocą pilota IR.(projekt mieszalnika bez świecidełek typu LCD, itp)
Niestety jestem zielony jeśli chodzi o pisanie programów więc wykorzystuję tzw. gotowce.
Takt tez uczyniłem w tym przypadku ->skopiowałem kod z książki „Arduino 65 praktycznych proje..”nr projektu 51 (Sterowanie robotem za pomocą pilota IR) no i klops, głowa pękła, teraz trzeba wezwać FACHOWCÓW!!! bo nie wiem jak przekształcić kod by wykonywał następujące polecenia:
->wciskam przycisk „1” na pilocie uruchamiam 1 program (zadany kierunki, czas np 45 min i prędkość )
->potrzebuję teraz zatrzymać ten program w dowolnym momencie jego pracy np klawiszem „#” i włączyć kolejny program przypisany do innego przycisku .
skrót ideowy:-
>przycisk „1” =START programu1
->przycisk”#”=STOP
->przycisk „2”=START programu 2
->itd.
Podsumowując pilotem chce zmieniać programy w każdym momencie ich trwania a nie sterować parametrami (delay i pwm) tak jak jest to w przypadku projektu 51.
Jeśli dobrze kombinuje funkcja timer mogła by zadziałać ale nie wiem jak ją użyć w moim kodzie.
Proszę o jakąkolwiek pomoc, mogę przesłać mój zmodyfikowany kod.
pozdrawiam i dziękuje.
Karol
gibon843@wp.pl
Pokaż jak teraz wygląda twój program, a my pomożemy ci go przerobić na lepszy :-)
Możesz go wkleić na jakiś serwis typu ideone, pastebin i podać link do niego.
Cześć Łukasz dziękuje za odpowiedz w moim temacie.
Nie wiem jak przekazać moją myśl najprościej :)
Włączam arduino z podłączonym czujnikiem np światła.
Gdy zaświecimy na czujnik jakimś mocnym źródłem światła to czujnik to wyłapie i podniesie swój odczyt np z 30 jednostek na 100 jednostek.
I w tym momencie chcę liczyć czas jak długo trwało przekroczenie odczytu czujnika np powyżej 50 jednostek.
Po przekroczeniu 50 odpala stoper i liczy np 10 sekund
Czy jest taka możliwość w tej bibliotece ?
Pozdrawiam
Witam przesyłam kod do mieszalnika/czyszczarki
https://pastebin.com/12xfWpyJ
tak to wygląda na dzień dzisiejszy.
Pozdrawiam i dziękuję.
Karol
gibon843@wp.pl
Witam.
Mam problem z programem opartym na czasie z zegara rtc .
Pytanie czy podczas wyświetlania na LCD czasu (godziny: minuty: sekundy ta biblioteka nie będzie zawieszać wyświetlania czasu podczas wykonywania np. odliczania czasu do wygaśnięcia podświetlania monitora )
Maciej: Ta biblioteka nie blokuje programu. Dlatego jest taka fajna :-). To program pyta bibliotekę czy zadeklarowany czas już minął przez metodę „available()”.
bardzo fajna biblioteka, uprasza standardową funkcję millis() :)
mam jednak pytanie, w jaki sposób zresetować licznik w funkcji loop?
potrzebuję, aby w dowolnym czasie trwania programu, po spełnieniu danego warunku timer zaczął odliczać czas od początku, coś w rodzaju:
#include
Timer ledBlinkTimer;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (warunkek =true){
ledBlinkTimer.begin(SECS(2));
if (ledBlinkTimer.available())
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
ledBlinkTimer.restart();
}
}
}
niestety przeniesienie funkcji start z setup do loop powoduje że timer nie działa:(
Pozdrawiam
uzupełniając poprzedni wpis, tworzę sterownik świateł mijania i świateł do jazdy dziennej, ogólnie od uruchomienia programu warunki działają ok, problem się jednak pojawia gdy program działa już jakiś czas, wtedy zmiana natężenia światła od razu wpływa na stan przekaźnika co jest niestety nieporządane, dodałem histerezę, która resetuje timery, jednak jeżeli zmiana ośwetlenia jest zbyt intensywna program tego nie wyłapie i przeskoczy funkcję resetującą timery co powoduje że zmiana stanu na wyjściu Atmegi jest natychmiastowa:(
Poniżej wycinek faktycznego programu
if ((lux setlux) && (luxsetlux+50) && DRL == false) {
if (DRLTimer.available()) {
digitalWrite(12, LOW); //wyłączenie świateł mijania
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
DRL = true;
hst = false;
DRLTimer.restart();
}
}
else {
}
Cześć! Mam pytanie dotyczące biblioteki Timers. Muszę wygenerować sygnał high/low o wysokiej częstotliwości z Arduino – czy mogę ustawić wartość mniejszą od 1 ms w timer.begin()?
Czy któryś z kolegów pomógł by mi w stworzeniu programu do takiego rozwiązania https://www.swiatelka.pl/viewtopic.php?t=21855 ? Bardzo proszę! Pozdrawiam!
Już nieaktualne…
Witam!
Czy istnieje możliwość podawania czasu dla timera poprzez zmienną? Chodzi mi o sytuację, w której nie chcę na sztywno w programie umieszczać zadanego czasu a używać do tego celu czasu, który został odmierzony poprzez inną funkcję. W moim przypadku chodzi m.in. o czas zamykania otwierania rolet (chcę wykorzystać arduino m.in. do sterowania roletami okiennymi jako wielokanałowy sterownik, ale okna są różnej wysokości więc i czas zamykania i otwierania jest różny. Do tego dochodzi dodatkowo też problem, że jedne rolety pracują lżej, drugie ciężej i też są nieznaczne rozbieżności przez to). Potrzebuję więc mieć możliwość kalibracji czasu i zapisywania go w pamięci nieulotnej procesora a następnie odczyt ich i wykorzystanie do sterowania timerami. Stąd właśnie moje pytanie, czy jest możliwość przekazywania czasu poprzez zmienną.
Pozdrawiam
„Czy istnieje możliwość podawania czasu dla timera poprzez zmienną?”
Oczywiście, nawet podczas działania timera.
Mam pewien problem przy kompilacji dla nano, jedyny co używam, wiec nie wiem jak jest w innych.
Chodzi o błąd w parametrze timera begin jesli ta wartosc bedzie wieksza niz 32, zawsze jest źle i nawet wyglada na to ze timer nie liczy.
Wgrałem Arduino do innego komputera i przy kompilacji mam ostrzezenie:
WARNING: Category 'time,timeout’ in library Timers is not valid. Setting to 'Uncategorized’
Tak biblioteka traci ważność w 2022 r.
jak powiedział Ryszard :
i jeśli wartość ta jest większa niż 32 SECS, blokuje Arduino
Szkoda
Szkoda, że nie bangla z DigiSpark :(
witam może to właściwy tema bo chciał bym zmienić mój programik w millis ponieważ w z delay nie można wstawić przerwania w trakcie działania programu tylko nie wiem jak do końca ugryźć
Program ma działać tak(ten działa ale na delay)
posiadam dwa przyciski
jedno wyjście(po testach na Ledzie będzie zamontowany tranzystor)
po przyciśnięciu przycisku1 muszę go przytrzymać 3 sekundy by program się uruchomił
na wyjsciu sygnał wysoki(15s) niski(3s) wysoki niski wysoki niski do kolejnego przyciśnięcia
jak przycisnę przycisk2 też muszę przytrzymać 3 sekundy by uruchomić
wyjście wysoki(15s) niski ciągle do kolejnego uruchomienia
i tu zaczynają sie moje schody bo chciał bym mieć możliwość przerwania(resetu) przez kolejny przycisk
https://pastebin.com/ZVrL0YSJ
w sumie na timer by bylo jeszce lepiej
Witam,
Szukałem możliwości zrobienia przekaźnika o dwóch czasach, inny czas przerwy i inny pracy. Mam taki przy piecu i nawala. Chciałem skorzystać z microArduino i przekaźnika.
Trafiłem na bibliotekę timers.h i wg opisu wszystko pięknie i ładnie ale poległem.
Skleciłem taki kod:
#include
Timer czas1;
Timer czas2;
void setup()
{
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
czas1.begin(1000);
czas2.begin(5000);
}
void loop()
{
if (czas1.available())
{
digitalWrite(2, LOW);
czas1.restart();
}
if (czas2.available())
{
digitalWrite(2, HIGH);
czas1.restart();
}
}
Niestety odlicza tylko pierwszy czas i dalej stop.
Kombinowałem różne warianty, niestety bez efektów.
Pomoże ktoś z tak chyba banalnym problemem?
Z góry dzięki!
Na szybko – w drugim ifie celowo używasz czas1.restart() ?
Sorki – pomyłka.
Wkleiłem jakąś wersję po eksperymentach. W pierwszym Ifie wg mnie powinien być czas2.restart();
No ale … nadal tylko odlicza pierwszy czas.
Hej :) Czy jest możliwość zmiany nazwy Biblioteki? Gryzie mi się z innym „Timers”
Dziękuję z góry + dobra robota! :)
Witam wszystkich,
bardzo dobrze opisana biblioteka :) Chciałbym sie dowiedzieć, czy do mojego projektu będzie ona idealnym rozwiązaniem.
Chcę stworzyć przepływomierz, który nadzorowałby przepływ wody. Jeśli przepływ wody przekroczy np. 30 litrów (ciągłego pobierania z powodu uszkodzenia rury) to program miałby odłączyć dopływ wody. Po naprawieniu usterki chciałbym aby woda ponownie leciała to chciałbym przepływ wody uruchomić przyciskiem. i moje pytanie brzmi:
czego użyć aby po osiągnięciu 30l. wody program „wyłączył się”, zawiesił swoje działanie do czasu przyciśnięcia?
Nie oczekuję, że ktoś mi napisze kod, tylko potrzebowałbym kawałek kodu takiego rozwiązania z opisem co do czego służy. Będę wdzięczny za każda odpowiedź i podpowiedź :)
Witam wszystkich. Mam dokładnie taki sam problem jak Ryszard. Powyżej 32 sec biblioteka nie reaguje na upływ czasu. Ma ktoś na to rozwiązanie?
Tak biblioteka traci ważność w 2022 r.
jak powiedział Ryszard :
i jeśli wartość ta jest większa niż 32 SECS, blokuje Arduino
Szkoda