Arduino Polska Forum

Pełna wersja: Biblioteka timers
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2
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.
Po co Ci ta biblioteka?

Kod:
unsigned long timer;
bool flag = false;

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(2) == LOW) && !flag){
    flag = true;
    timer = millis();
  }

  if(digitalRead(2) == HIGH) flag = false;

  if(millis() - timer == 500){
    Serial.println("brawo, minelo 500 ms od pojawienia się obiektu");
  }
}
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ł.
Stron: 1 2