Skocz do zawartości

Kurs Arduino - #3 - UART (komunikacja z PC), zmienne


Pomocna odpowiedź

Połączone zadania 2.4 i 2.5. Wykorzystałem dwie metody przełączania stanów. Przy okazji sprawdziłem sobie, że HIGH/true/1 i LOW/false/0 są zamienne. Czy rzeczywiście jest tu dowolność? Może obowiązują jakieś reguły? Kodokieta? 🙂

#define czerwony 8
#define zolty 9
#define zielony 10
boolean czerwony_stan = LOW;
boolean zolty_stan = LOW;
boolean zielony_stan = LOW;
String odebraneDane = "";

void setup() {
  pinMode(czerwony, OUTPUT); // LED Czerwona
  pinMode(zolty, OUTPUT); // LED Zolta
  pinMode(zielony, OUTPUT); // LED Zielona
  digitalWrite(czerwony, LOW);
  digitalWrite(zolty, LOW);
  digitalWrite(zielony, LOW);
  Serial.begin(9600);
  Serial.println("Wpisz kolor bez polskich znakow");
}

void loop() {
   if (Serial.available() > 0) { // Jesli Arduino odebrało dane
    odebraneDane = Serial.readStringUntil('\n'); //zapisz dane do zmiennej

    // i wykonaj reszte kodu uzywajac danych

    if (odebraneDane == "czerwony") { //Jeśli odebrano słowo "czerwony"
      if (czerwony_stan == LOW) {     //i nie byla wlaczona
        digitalWrite(czerwony, HIGH); //to włączamy diodę czerwona
        czerwony_stan = HIGH;
      } else {
        digitalWrite(czerwony, LOW); czerwony_stan = LOW;
        }
    } else

// sprawdzenie roznicy miedzy HIGH/LOW true/false 1/0

    if (odebraneDane == "zolty") { //Jeśli odebrano słowo "zolty"
      if (zolty_stan == false) {     //i nie byla wlaczona
        digitalWrite(zolty, true); //to włączamy diodę zolta
        zolty_stan = 1;
      } else {
        digitalWrite(zolty, 0); zolty_stan = LOW;
        }
    } else

// inna metoda    
    if (odebraneDane == "zielony") { //Jeśli odebrano słowo "zielony"
      zielony_stan = !zielony_stan; //Sprawdz obecny stan i go odwroc
      digitalWrite(zielony, zielony_stan); // zmień stan LED
    } else
    
    Serial.println("Blad lub ten kolor nie jest obslugiwany."); // Wszystkie pozostale 
  
  }
}

 

Cześć, mam na imię Radek. Mam pytanko, skonfigurowałem przykład z diodami do okna, program powinien wyświetlać komunikat o otwarciu okna tylko raz, zauważyłem, że czasem wysyłam dwa lub trzy komunikaty po jednorazowym zwolnieniu przycisku. Jak to Wytłumaczyć?

19:27:29.614 -> okno otwarte
19:27:29.614 -> okno otwarte
19:27:31.511 -> okno otwarte
19:27:31.511 -> okno otwarte
19:27:33.226 -> okno otwarte
19:27:33.273 -> okno otwarte
19:27:33.273 -> okno otwarte
19:27:58.573 -> okno otwarte
19:28:03.761 -> okno otwarte
19:28:11.899 -> okno otwarte
19:28:26.690 -> okno otwarte
19:28:26.737 -> okno otwarte
19:28:29.779 -> okno otwarte
19:28:34.588 -> okno otwarte
19:28:41.073 -> okno otwarte

Przepraszam za błędne wstawienie kodu, teraz doczytałem

void setup() {
  Serial.begin(9600); //uruchomienie transmisji

  pinMode(8, OUTPUT);  //dioda czerwona
  pinMode(9, OUTPUT);  //dioda zielona
  pinMode(10, INPUT_PULLUP);  //przycisk

  digitalWrite(8, LOW); //wyłączenie obu diod
  digitalWrite(9, LOW);
}

void loop() {
  if (digitalRead(10) == LOW) { //jeśli przycisk jest wciśnięty
    digitalWrite(9, HIGH); //włączenie diody zielonej
    digitalWrite(8, LOW);   //wyłączenie diody czerwonej
  }else {//jeśli przyciskisk nie jest wcisniety
    digitalWrite(9, LOW); //wyłączenie diody zielonej
    digitalWrite(8, HIGH);  //włączenie diody czerwonej
    Serial.println("okno otwarte");

    while (digitalRead(10) == HIGH) {
      //zatrzymujemy program w pętli do ponownego nacisniecia przycisku
      delay(25); //opóźnienie wprowadzone do uniknięcia zakłóceń
    }
    
  }
}

 

12 godzin temu, Radek77 napisał:

19:27:33.226 -> okno otwarte
19:27:33.273 -> okno otwarte
19:27:33.273 -> okno otwarte

Różnice czasów są na poziomie 50 ms. A gdybyś po wykryciu otwarcia okna dodał na sztywno opóźnienie (bez warunku) rzędu 100 ms to czy rozwiąże to problem?

  • Lubię! 1

Próbowałem z różnymi opóźnieniami, nawet 500 ms, ale czasami (losowo) pojawia się więcej niż 1 komunikat podczas jednego zwolnienia przycisku. Nie rozumiem dlaczego tak się dzieje.

void setup() {
  Serial.begin(9600); //uruchomienie transmisji

  pinMode(8, OUTPUT);  //dioda czerwona
  pinMode(9, OUTPUT);  //dioda zielona
  pinMode(10, INPUT_PULLUP);  //przycisk

  digitalWrite(8, LOW); //wyłączenie obu diod
  digitalWrite(9, LOW);
}

void loop() {
  if (digitalRead(10) == LOW) 
  	{ //jeśli przycisk jest wciśnięty
    	digitalWrite(9, HIGH); //włączenie diody zielonej
    	digitalWrite(8, LOW);   //wyłączenie diody czerwonej
 	 }
  else 
  	{//jeśli przyciskisk nie jest wcisniety
    	digitalWrite(9, LOW); //wyłączenie diody zielonej
    	digitalWrite(8, HIGH);  //włączenie diody czerwonej
    	Serial.println("okno otwarte");
  	}
 delay(200);
}

A taki program jak u ciebie działa?

  • Lubię! 2
(edytowany)

Drgania styków? Jak na moje to program nie wpada w tą pętle while, można to sprawdzić dodając tam jakiś println z napisem np. "jestem w pętli while" i zobaczyć czy się wyświetli i jak tak to w jakich sytuacjach.

Edytowano przez Rogal

Rogal: Program do pętli wchodzi

16:56:24.860 -> jestem w petli
16:56:24.895 -> jestem w petli
16:56:25.582 -> okno otwarte
16:56:25.617 -> okno otwarte
16:56:25.617 -> jestem w petli
16:56:25.652 -> jestem w petli
16:56:25.652 -> jestem w petli

Belferek: Umieszczenie opóźnienia za pętlą nic nie zmienia, może nawet pogarsza.

17:01:40.438 -> okno otwarte
17:01:41.784 -> okno otwarte
17:01:43.200 -> okno otwarte
17:01:44.690 -> okno otwarte
17:01:44.890 -> okno otwarte

17:01:46.304 -> okno otwarte
17:01:46.512 -> okno otwarte

Rożnica jest tylko taka, że podwójny komunikat wyświetla się z większym opóźnieniem czasowym, ale są dwa na jedną akcję (puszczenie przycisku). To mi pasuje do tego, że brak opóźnienia wewnątrz pętli wyłapuje zakłócenia, czy mam rację? (pogrubione komunikaty pojawiły się po jednorazowym puszczeniu przycisku)

Z tego co zrozumiałem to opóźnienie w pętli while jest po to, żeby uniknąć zakłóceń w czasie przełączania przycisku. Dlaczego w takim razie czasem pojawia się podwójny komunikat o tym, że wartość na przycisku jest LOW? 

@BelferekPoprawka, jak umieściłem delay za warunkami, bez pętli while, to program cały czas wyświetla komunikat o otwarciu co 200 ms.

(edytowany)

Kilka postów wyżej zaproponowałem rozwiązanie, ale pewnie go nie zauważyłeś:

#define ZAMKNIETE 1
#define OTWARTE 0
boolean ostatni_stan=digitalRead(2);
void loop() 
{

  if (digitalRead(2) == LOW && ostatni_stan==ZAMKNIETE )      //jesli okno otwarte a bylo zamkniete
  {
    digitalWrite(8, LOW);
    digitalWrite(9, HIGH);
    ostatni_stan=OTWARTE;
    Serial.println("Uwaga! Okno otwarte!");
  }
  else if (digitalRead(2) == HIGH && ostatni_stan==OTWARTE )  //jesli okno zamkniete a bylo otwarte
  {
    digitalWrite(8, HIGH);
    digitalWrite(9, LOW);
    ostatni_stan=ZAMKNIETE;
    Serial.println("Uwaga! Okno zamkniete!");
  }
  delay(1000);
}

A jesteś pewien, że Twoje Arduino się nie resetuje? Dodaj sobie na końcu funkcji setup() coś takiego Serial.println("Reset..."); Czy ten kod także nie działa właściwie? Już pisałem, że cudów raczej nie ma. Posprawdzaj wszystkie połączenia, kabelki itp. no i spróbuj tego programiku. No i poczytaj o debouncing i bilbiotece Bounce2.

Edytowano przez Belferek
  • Lubię! 1
(edytowany)
35 minut temu, Radek77 napisał:

Rogal: Program do pętli wchodzi

16:56:24.860 -> jestem w petli
16:56:24.895 -> jestem w petli
16:56:25.582 -> okno otwarte
16:56:25.617 -> okno otwarte
16:56:25.617 -> jestem w petli
16:56:25.652 -> jestem w petli
16:56:25.652 -> jestem w petli

Wchodzi ale też z niej wychodzi - otrzymałeś 2 komunikaty o otwartym oknie bez indykacji, że program wszedł do pętli pomiędzy nimi. To powinno wyglądać tak, że masz 1 komunikat o otwartym oknie a później tylko, że program jest w pętli. To co wyżej napisał Belferek ma dla mnie dużo sensu warto by było to sprawdzić przed dalszą diagnozą. Na późniejszym etapie nauki można by było się pokusić o filtr RC na tym przycisku.

https://forbot.pl/blog/czym-jest-filtr-rc-jak-dziala-i-co-warto-o-nim-wiedziec-id40448

Edytowano przez Rogal
  • Lubię! 1
(edytowany)

Belferek, zastosowałem Twój kod, działa 👍 studiuję teraz o debouncingu. Bardzo Wam dziękuję za pomoc i wskazówki 🙂

Filtr RC pomógł w przypadku kodu w pętlą while.

Edytowano przez Radek77
  • Lubię! 2
  • 1 miesiąc później...

cześć mam pytanie kupiłem zestaw do kursu arduino i przeczytałem 2 artykuły i nie rozumiem niektórych rzeczy czy powinienem najpierw przerobić kurs elektroniki?

 

@wojtomir cześć, witam na forum 🙂 Myślę, że kurs elektroniki pomoże Ci jeżeli nigdy wcześniej nie miałeś do czynienia z elektroniką. Wytłumaczone są tam podstawowe prawa, które trzeba uwzględniać przy budowie własnych układów elektronicznych. 

  • Lubię! 1

@wojtomir zadaj też pytania w komentarzu do danego artykułu to postaramy się pomóc - zobaczysz jak Ci pójdzie dalej, może to tylko drobne początkowe problemy, które da się szybko rozwiązać 😉

  • Lubię! 1

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...