Skocz do zawartości

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


Pomocna odpowiedź

(edytowany)

Zadanie domowe nr 2.5*:

#define zielona 8
#define czerwona 9


String odebraneDane = ""; //Pusty ciąg odebranych danych
boolean stanZielona = false;
boolean stanCzerwona = false;

void setup() {
  Serial.begin(9600); //Uruchomienie komunikacji
  pinMode(zielona, OUTPUT); //Konfiguracja wyjść
  pinMode(czerwona, OUTPUT);

  digitalWrite(zielona, LOW); //Wyłączenie diod
  digitalWrite(czerwona, LOW);
}

void loop() {
  if(Serial.available() > 0) { //Czy Arduino odebranło dane
    odebraneDane = Serial.readStringUntil('\n'); //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
    if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"
      if (stanZielona == false) { //Jeżeli dioda zielona jest wyłączona
        digitalWrite(zielona, HIGH); //To włącz diodę zieloną
        stanZielona = true; //Informacja o stanie diody zielonej - włączona
      } else { //W przeciwnym wypadku
        digitalWrite(zielona, LOW); //Wyłącz diodę zieloną
        stanZielona = false; //Informacja o stanie diody zielonej - wyłączona
      }
    } else if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
      if (stanCzerwona == false) { //Jeżeli dioda czerwona jest wyłączona
        digitalWrite(czerwona, HIGH); //To włącz diodę czerwoną
        stanCzerwona = true; //Informacja o stanie diody czerwonej - włączona
      } else { //W przeciwnym wypadku
        digitalWrite(czerwona, LOW); //Wyłącz diodę czerwoną
        stanCzerwona = false; //Informacja o stanie diody czerwonej - wyłączona
      }
    } else { //Jeżeli podano inne polecenie
      Serial.println("Błędne polecenie!"); //Wyświetl komunikat
    }    
  }
}

 

Edytowano przez ewgron
  • Lubię! 2
  • 5 tygodnie później...

Mam pytanie do zadania domowego 2.4.

#define zielona 8
#define czerwona 9

String odebraneDane = "";

void setup() {
  Serial.begin(9600);
  pinMode(zielona, OUTPUT);
  pinMode(czerwona, OUTPUT);

}

void loop() {
  if(Serial.available() > 0) {
    odebraneDane = Serial.readStringUntil('\n');
  }
    if (odebraneDane == "zielona") {
      digitalWrite(zielona, HIGH);
      delay(1000);
      digitalWrite(zielona, LOW);
    }

    else if (odebraneDane == "czerwona") {
      digitalWrite(czerwona, HIGH);
      delay(1000);
      digitalWrite(czerwona, LOW);
    }
    else {
      Serial.println("WYBRANO NIEPRAWIDŁOWY KOLOR SYGNALIZACJI");
    
    }  
    

  }

Kod podany wyżej działa, ale wysyła cały czas komunikat w terminalu.

Jak to rozwiązać w taki sposób, żeby wysyłał go wtedy kiedy wpiszemy błędny kolor, a nie cały czas.

Kod podany poniżej działa tak jak chcę, ale różni on się tym, że nawias klamrowy, który wcześniej wstawiłem po if(Serial.available() > 0) { odebraneDane = Serial.readStringUntil('\n'); 

teraz wstawiłem po prostu na końcu. 

#define zielona 8
#define czerwona 9

String odebraneDane = "";

void setup() {
  Serial.begin(9600);
  pinMode(zielona, OUTPUT);
  pinMode(czerwona, OUTPUT);

}

void loop() {
  if(Serial.available() > 0) {
    odebraneDane = Serial.readStringUntil('\n');
  
    if (odebraneDane == "zielona") {
      digitalWrite(zielona, HIGH);
      delay(1000);
      digitalWrite(zielona, LOW);
    }

    else if (odebraneDane == "czerwona") {
      digitalWrite(czerwona, HIGH);
      delay(1000);
      digitalWrite(czerwona, LOW);
    }
    else {
      Serial.println("WYBRANO NIEPRAWIDŁOWY KOLOR SYGNALIZACJI");
    
    }  
    }

    
  }

Proszę o wytłumaczenie jakie znaczenie ma ten nawias, ponieważ nie mogę zrozumieć jego istotności w kodzie.

@robosimon witam na forum  problem jest dość prosty - po odebraniu tego co jest w warunku coś się dzieje ale nie resetuejsz tego co sprawdzasz. Czyli kolejno: coś odebrałeś > zapisałeś do zmiennej > sprawdziłeś zgadza się > i tu trzeba tą zmienną skasować, bo będzie cały czas wyzwalać poprawny warunek, a powinno się tak stać dopiero po odebraniu nowych danych.

Drugi kod jest o tyle lepszy, że coś się wykonuje jedynie gdy odbierzesz dane z Serialu, więc już lepiej  

Poza tym polecam skrót... chyba Ctrl-T ale znadziesz to w menu - autoformatowanie, to od razu zauważysz do czego jest jaki nawias.

  • Lubię! 1
  • Pomogłeś! 1
  • 1 miesiąc później...
(edytowany)

W jaki sposób zrobić zadanie 2.4 i 2.5 z 3 części kursu z podstaw?

Dopisałem to do końca programu, lecz reszta programu przestała działać.

 

 else {
    Serial.println("Wybrano zły kolor");
    
    while(digitalRead(czerwona) == LOW){
    delay(25);
   }

 

usuwając funkcję while, wszystko działa, lecz komunikat wybrano zły kolor jest zapętlony. Chciałbym żeby komunikat wyświetlał się tylko raz

Edytowano przez Gieneq
(edytowany)

Dopiero teraz zaczynam się jarać, wzajemna komunikacja z kontrolerem daje dużo frajdy. Niby to programowanie, ale wyjście z programem poza komputer pozwala zrobić coś namacalnego, a nie tylko wirtualnego, teraz dopiero poczułem morze możliwości. Nie byłem tak zajarany 8 lat temu, jak napisałem pierwsze "hello world", jak dziś gdy "pogadałem z arduino".

Dzięki za tę możliwość Panowie. 🙂

Edytowano przez AndrzejWi
byk jak diabli :D
  • Lubię! 1
(edytowany)

@AndrzejWi a jak wyłączysz się z rozmowy i dasz pogadać 2 płytką ze sobą, to dopiero ciekawa sprawa 😄 Powodzenia w dalszej nauce!

@Daniel1235 witam na forum 🙂 

To jest kod od którego możesz wyjść:

#define zielona 8
#define czerwona 9

String odebraneDane = ""; //Pusty ciąg odebranych danych

void setup() {
  Serial.begin(9600); //Uruchomienie komunikacji
  pinMode(zielona, OUTPUT); //Konfiguracja wyjść
  pinMode(czerwona, OUTPUT);
  
  digitalWrite(zielona, LOW); //Wyłączamy diody
  digitalWrite(czerwona, LOW);
}

void loop() {
  if(Serial.available() > 0) { //Czy Arduino odebrało dane
    //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n'); 
    
    if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"
      digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
      delay(1000);
      digitalWrite(zielona, LOW); 
    }
    
    if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
      digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
      delay(1000);
      digitalWrite(czerwona, LOW); 
    }
  }
}

I masz tu 2 if'y które sprawdzają czy napisałeś jeden z 2 kolorów.

  1. Przerób to tak by tworzyły one konstrukcję if - ifelese - else lub switch-case, tak byś miał przypadek inny nie ujęty w warunkach.
  2. Wtedy dla else dodasz Serial.println("innyk kolor"); i zrobione 🙂 

W zadaniu 2.5 masz podpowiedź aby użyć zmiennej mającej pamięć, która będzie trzymać stan. Stany LOW/HIGH to w Arduino inty. W kodzie jak z zadania 2.4 wystarczy że będziesz najpierw ustawiał zmienną (wartościami LOW i HIGH), a później na bazie tej zmiennej ustawiał wyjście cyfrowe.

 

 

Edytowano przez Gieneq
  • Lubię! 1

Zadanie domowe nr 2.5*

Mnie wyszło tak:

#define czerwona 9
 
String odebraneDane = ""; //Pusty ciąg odebranych danych
boolean stan = false;
 
void setup() {
  Serial.begin(9600); //Uruchomienie komunikacji
  pinMode(czerwona, OUTPUT);
  digitalWrite(czerwona, LOW);
}
 
void loop() {
  if (stan == false) {
  
  if(Serial.available() > 0) { //Czy Arduino odebrało dane
    //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n'); 
    
    
    if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
      digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
      
      stan = true;
        
      
    }
  }
  }
    if (stan == true) {  //Jeśli stan jest true
      if(Serial.available() > 0) { //Czy Arduino odebrało dane
    //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n'); 
    
    
    if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
      digitalWrite(czerwona, LOW); //To włączamy diodę czerwoną
      
      stan = false;
    }
      }
    }
}
        

 

  • Lubię! 1

@jendrekpk witam na forum i pochwalę Cię, że zabrałeś się za zadania dodatkowe. Jednak mam kilka konstruktywnych uwag 😉 

  1. Po pierwsze polecam skrót klawiszowy chyba Ctrl-T autoformat, bo położenie nawiasów nie ułatwia czytania bloków warunkowych.
  2. Nie jest to dobry pomysł dawać 2 takei same bloki kodu - 2x używasz Serial.available(), gdzie logiczny przepływ danych jest inny: odbierz dane > zinterpretuj > zareaguj.
  3. Powiązane z powyższym - zmienna stanu nie powinna być na zewnątrz odczytu Seriala bo może to spowodować zacięcie kodu.

Lepsze podejście to:

  1. odczyt Seriala, jeżeli odebrał to:
  2. sprawdź czy napis to "Czerwona", tak tak to:
  3. zmień wartość zmiennej na przeciwny i zareaguj ustawiając pin
  4. jak nie to nie rób nic,

Jak zmienić wartość na przeciwny to zależy od podejścia - najprościej w if-else, ale możesz też bardziej fikuśnym sposobem, ale to na później. Najpierw działający kod 🙂 

  • Lubię! 2

Mam nadzieję, że teraz jest lepiej.

#define czerwona 9

String odebraneDane = ""; //Pusty ciąg odebranych danych
boolean stan = false;

void setup() {
  Serial.begin(9600); //Uruchomienie komunikacji
  pinMode(czerwona, OUTPUT);
  digitalWrite(czerwona, LOW);
}

void loop() {

  if (Serial.available() > 0) { //Czy Arduino odebrało dane
    //Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n');

    if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
      if (stan == false) {
        stan = true; // ustaw stan na true
        digitalWrite(czerwona, HIGH); // Włączamy diodę czerwoną

      } else  {

        stan = false; // ustaw stan na true
        digitalWrite(czerwona, LOW); // Włączamy diodę czerwoną
      }

    } else {

      Serial.println("bledny kolor !");

    }
  }
}

 

@jendrekpk teraz wygląda dużo lepiej 🙂 

Jak masz warunki jak ten, gdzie w środku jest tylko 1 linia:

else {

      Serial.println("bledny kolor !");

    }

to dla skrócenia kodu możesz pominąć nawiasy:

else
      Serial.println("bledny kolor !");

Powodzenia 🙂 

(edytowany)

Jestem całkiem zadowolony z tego kodu (zadanie 2.5). Macie jakieś rady, jak można to skrócić?

[code]
#define greenLight 8
#define redLight 9

String receivedData = "";
bool greenLightState = false;
bool redLightState = false;

void setup() {
  Serial.begin(9600);
  pinMode(greenLight, OUTPUT);
  pinMode(redLight, OUTPUT);

  digitalWrite(greenLight, LOW);
  digitalWrite(redLight, LOW);
}

void loop() {
  if (Serial.available() > 0) {
    receivedData = Serial.readStringUntil('\n');

    if (receivedData == "zielona" && greenLightState == false) {
      digitalWrite(greenLight, HIGH);
      digitalWrite(redLight, LOW);
      greenLightState = true;
    }
    else if (receivedData == "zielona" && greenLightState == true) {
      digitalWrite(greenLight, LOW);
      digitalWrite(redLight, LOW);
      greenLightState = false;
    }

    else if (receivedData == "czerwona" && redLightState == false) {
      digitalWrite(redLight, HIGH);
      digitalWrite(greenLight, LOW);
      redLightState = true;
    }
    else if (receivedData == "czerwona" && redLightState == true) {
      digitalWrite(redLight, LOW);
      digitalWrite(greenLight, LOW);
      redLightState = false;
    }

    else {
      Serial.println("Wpisz odpowiedni kolor!");
      digitalWrite(greenLight, LOW);
      digitalWrite(redLight, LOW);
      greenLightState = false;
      redLightState = false;
    }
  }
}
[/code]

 

Edytowano przez HaroldWinter
  • Lubię! 1

@HaroldWinter witam na forum i fajnie że podzieliłeś się swoim rozwiązaniem 🙂 

Tak na to patrzę to możesz zlepić to co w warunkach występuje kilka razy - np sprawdzasz czy string to zielona / czerwona po 2 razy. Możesz dać to w spólny warunek a wewnątrz sprawdzać jaki był ostatnio stan.

Jeżeli stan determinuje kolor świecenia diod to go użyj 🙂 tylko zamiast true i false niech stan będzie intem i sprawdzaj czy miał HIGH/LOW.

  • Pomogłeś! 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...