Skocz do zawartości

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


Pomocna odpowiedź

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
Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

@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
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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
Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

@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
Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

@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
Link do komentarza
Share on other sites

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 !");

    }
  }
}

 

Link do komentarza
Share on other sites

@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 🙂 

Link do komentarza
Share on other sites

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
Link do komentarza
Share on other sites

@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
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.