Witam,
staram się nauczyć zastępować delay czasem.
Niestety utknąłem na wykorzystaniu gotowej biblioteki timers polskiego autorstwa
https://starter-kit.nettigo.pl/2016/04/b...rs-16-4-0/
Chcę zacząć odliczanie czasu, ale dopiero po spełnieniu warunku. Niestety to nie działa.
Kod:
#include <Timers.h>
Timer mojTimer;
void setup() {
Serial.begin(9600); // testowe uruchomienie logów
pinMode(2, INPUT); // czujnik optyczny (1 - brak przedmiotu, 0 - jest przedmiot w polu widzenia)
}
void loop() {
if (!digitalRead) {
mojTimer.begin(3000);
v1= 1;
}
if (v1 && mojTimer.available()) {
Serial.println("brawo, minelo 500 ms od pojawienia się obiektu");
v1 = 0;
}
}
Mój stary umysł już chyba nie pojmuje zasad działania języka C. W tutorialach ustawienie startu czasu ma miejsce w funkcji setup, ale mi zależy nam tym, aby stoper odmierzał czas od pojawienia się przedmiotu przed czujnikiem.
Próbowałem podobnie robić z funkcją milis, ale efekt podobny.
Skoro się uczy niech się nauczy rejestrów timera a życie stanie się proste.... Bo nie ruzumiem po co się uczyć czegoś co i tak ma wady i nie jest po naszych myślach..
No tak, tylko do prostego odliczania czasu nie potrzeba ani żadnej niestandardowej biblioteki, ani konfigurować timerów. Zwykła funkcja millis() wywołana w odpowiednim miejscu.
Ok, dzięki za pomoc.
Działa, ale drukuje info podwójnie (nie wiem czemu), tak jakby funkcja przeleciała aż 2 razy w ciągu 1 ms.
Jeśli bym chciał np. w czasie trwania sygnału z czujnika wykonywać naprzemiennie czynności, w tym przypadku drukowanie komunikatu to zrobiłem tak:
Kod:
void loop(){
if(digitalRead(2) == LOW) && !flag){
flag = true;
timer = millis();
}
if(digitalRead(2) == HIGH) flag = false;
if(millis() - timer == 500){
Serial.println("minelo 500 ms od pojawienia się obiektu");
}
if (millis() - timer == 1000){
Serial.println("Minelo 1000 ms od pojawienia się obiektu");
timer = 0;
flag = false;
}
Ale niestety wartość timer cały czas leci na 0 a komunikatów nie drukuje. Zeruję timer i flagę, aby leciało na nowo, ale bez skutku.
nigdy nie dawaj "==" rób program tak by przewidzieć odchyłki bo trafić millis == 1 to jak trafić w totka
Tego się domyśliłem i robiłem nawet np. tak:
if((millis() - timer >= 500) && (millis() - timer <= 1000) )
to efekt był ten sam.
Właśnie dlatego przerzuciłem się na bibliotekę timers bo nie umiałem sobie poradzić z millis();.
Pisałem to na kolanie, nie oczekuj, że będzie pozbawione wad.
Pokombinuj z tą flagą. Może dodaj jeszcze jedną, zobaczysz co z tego wyjdzie.
tak się nie robi
if (mills - czas1 >= 500){
czas1 =mills;
}
if(mills - czas2 >= 1000){
czas2 = millis;
}
Nie odmierzaj dwóch czasów jedną zmienną tak się nie da.. Po wykonaniu warunku resetuj czasy inaczej warunek bedzie spełniany aż nie zresetujesz... W twoim przypadku wystarczą też flagi
Kod:
void loop(){
if(digitalRead(2) == LOW) && ( !flag1 || !flag2) ){
flag1 = true;
flag2 = true;
timer = millis();
}
if(millis() - timer >= 500 && flag1 ){
flag1 = false;
Serial.println("minelo 500 ms od pojawienia się obiektu");
}
if (millis() - timer >= 1000 && flag2){
flag2 = false;
Serial.println("Minelo 1000 ms od pojawienia się obiektu");
}
Kombinowałem na różne sposoby i to sobie działa jak chce.
Mam elektrozawór i 2 siłowniki. Chciałem więc zobaczyć jak to zadziała w praktyce i mimo że te odstępy są równe (po 500 ms) to tak jakby za każdym cyklem jest jakieś zaburzenie i absolutnie nie działa to równo. Z delay(); jest idealnie bo ustawiam np. po 500 ms opóźnienia i siłownik pracuje cały czas równo - wysuwa się i chowa w odstępach po 500 ms.
Nie chcę jednak blokować arduino delayem, stąd próba zastosowania czy biblioteki czy za Waszą namową - funkcji millis.
Do testów dałem taki kod:
Kod:
if ((mills - czas1 >= 500)){
czas1 = millis();
digitalWrite(z1, LOW);
Serial.println("cykl");
}
if (czas1 - czas2 >= 500) {
czas2 = millis();
digitalWrite(z1, HIGH);
Serial.println("cyk2");
}
Wydaje mi się że problemem jest to, że elektrozawór nie wyrabia się przy tak szybkim działaniu. Jak tylko wrzucam delay nawet na np. 60 ms w pierwszy czy drugi warunek to działa dobrze. Ale to znów jest delay.
Z delay działa taki kod (z1 to elektrozawór sterowany arduino):
Kod:
if (digitalRead(2)) {
digitalWrite(z1, HIGH);
delay(500);
digitalWrite(z1, LOW);
delay(500);
}
else {
digitalWrite(z1, LOW);
}
Efektem jest to że siłownik wysywa sie i chowa w cyklach po 500 ms. Jak nie ma sygnału z czujnika (pin 2) to ustawia stan niski i siłownik się chowa w oczekiwaniu na sygnał.