Arduino Polska Forum

Pełna wersja: Komparator na wejściu Arduino i problem z czasem
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Witam serdecznie,

Mam problem z komparatorem i arduino, mianowicie do do pinu 2 arduino, skonfigurowane jako INPUT_PULLUP mam podłączony komparator który sprawdza napięcie wiec ciągle na pinie 2 jest sygnał LOW lub HIGH.

Docelowo chciałbym aby program sprawdzał stan wejścia 2 czy jest LOW czy HIGH i wykonywał inne polecenie dla LOW i inne dla HIGH ale dopiero gdy stan LOW/HIGH utrzymuje się dłużej nić 5 sekund, jeżeli stan na pinie 2 jest krótszy niż 5 sekund to brak jakiejkolwiek reakcji. Ma to zabezpieczyć układ przed krótkimi wahaniami napięcia na wejściu komparatora.

Nie bardzo wiem jak temat ugryźć dlatego proszę o pomoc jak do tego tematu podejść. 
Z góry dziękuję za wszelką pomoc.
Wykorzystaj funkcję zliczającą czas w Arduino - millis(), to licznik ms. Jak zauważysz w programie zmianę to przepisujesz jego wartość - start liczenia, jeśli utrzyma się przez 5000 to masz swój stan. Zapisujesz go w osobnej zmiennej by następnym razem szukać przeciwnego. Zastanów się też czy na przeciwny zmieniać też po 5s czy wystarczy krótszy okres. Analogicznie jest robione omijanie drgań styków przy przyciskach, tylko czasy są po 30-100ms.
Przykładów jest mnóstwo, również tu na forum.
Kod:
boolean flaga = 0;
unsigned long czas = millis();

void setup() {
 pinMode(13, OUTPUT);
 pinMode(2, INPUT_PULLUP);
 digitalWrite(13, LOW);
}

void loop()
{
 if(digitalRead(2)==LOW && flaga == 0)
 {
   delay(50);
 flaga = 1;
   czas = millis();
 }
 
 if(digitalRead(2)==HIGH)
 {
   delay(50);
   flaga = 0;
 }
 
 if(flaga == 1 && millis() - czas > 4000)
 {
   digitalWrite(13, HIGH);
   while (digitalRead(2)==LOW){
     
   }
 }
 else digitalWrite(13, LOW);

}

Jest progres, prawie OK, ale gdy trzymam stan niski na 2 to jest reakcja dopiero po 4 sekunda i jest ok, ale jak mienię stan na HIGH, od razu wyłącza diodę w arduino a zależy mi na tym aby jak szybko zmienię stan to nadal dioda była zapalona, a gdy stan HIGH będzie utrzymywał się dłużej tj. 4 sekundy dopiero wyłączył diodę.
else digitalWrite(13, LOW);

to ci wyłącza
Nie do końca bo w/w kodzie działa tylko opóźnienie na stanie LOW a na HIGH brak opóźnienia. Walczę dalej i doszedłem do tego:

Kod:
boolean flaga = 0;
unsigned long czas = millis();
unsigned long czas2 = millis();
void setup() {
 pinMode(10, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(2, INPUT_PULLUP);
 digitalWrite(10, LOW);
 digitalWrite(9, LOW);
}


void loop()
{
 if(digitalRead(2)==LOW && flaga == 0)
 {
   delay(50);
   flaga = 1;
   czas = millis();
 }
 
 if(digitalRead(2)==HIGH && flaga == 1)
 {
   delay(50);
   flaga = 0;
   czas2 = millis();
 }
 
 if(flaga == 1 && millis() - czas > 4000)
 {
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  }
 

 if(flaga == 0 && millis() - czas2 > 4000)
 {
  digitalWrite(10, LOW);
  digitalWrite(9, HIGH);
 }
}

I wszystko było by super jeżeli tak jak teraz zostawiam stan LOW  w ifie 2 ostatnich "if'ach" Teraz poprostu mam pod pin 9 i pin 10 podłączone diody i gdy zmieniam stan na pinie 2 z LOW na HIGH to jedna gaśnie a druga się zapala.
Docelowo chciałbym aby jedna diody mignęły krótko a nie świeciły się ciągle.

Kombinowałem w ten sposób:
Kod:
 if(flaga == 1 && millis() - czas > 4000)
 {
  digitalWrite(10, LOW);
  delay(200);
  digitalWrite(10, HIGH);
  delay(200);
  while (digitalRead(2)==HIGH) {}
  }
 

 if(flaga == 0 && millis() - czas2 > 4000)
 {
  digitalWrite(9, LOW);
  delay(200);
  digitalWrite(9, HIGH);
  delay(200);
  while (digitalRead(2)==LOW) {}
 }
Ale mam problem z warunkiem wyjścia z pętli while, bo gdy dam warunek jak wyżej tj. zmiana stanu na pinie 2 z LOW na HIGH to w tym momencie znowu tracę opóźnienie 4 sekund...

Czy idę w dobrą stronę w ogóle? jeżeli tak to czy ktoś mógłby podrzucić myśl  jak i dać warunek pętli while, ew. w jaki inny sposób wykonać operację mignięcia tylko raz a nie w kółko ?
Żadne delay nie są potrzebne. Żadne while również, to zadziała jeszcze gorzej w niektórych uC, to zablokowanie pracy, wywoła WDT i reset.
Masz przykład z blinkWhitoutDelay, zamiast zmieniać stan led możesz zliczać sekundy, zamiast zliczać sekundy możesz zliczać dziesiątki ms, z nich sekundy, minuty, godziny.