Skocz do zawartości

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


Pomocna odpowiedź

ethanak, dzięki za odpowiedź, w między czasie sobie poczytałem.

Uczyłem się kiedyś pisania w Pascal'u i ciągle mi w głowie siedzi ten język...

To normalka - ja piszę równolegle w Pythonie i w C, i czasem się zastanawiam co jest nie tak w klamrach w Pythonie albo czemu GCC nie lubi dwukropków po ifie 🙂

ADyarac, główny problem w Twoim zapisie: if (odebraneDane != "zielone" or "czerwone") był taki, że zapewne rozumiałeś go następująco: warunek jest prawdziwy jeśli zmienna odebraneDane nie równa się "zielone" lub nie równa się "czerwone". Tak byłoby, gdyby zapisał to tak: if (odebraneDane != "zielone" or odebraneDane != "czerwone"), czyli po or ponowiłbyś informacje o zmiennej, która ma być sprawdzana wraz ze znakiem nie równości. Kompilator nie domyśla się, że po or dodajesz kolejny wariant "odpowiedzi" do wcześniejszego warunku. Trzeba mu wskazać całe wyrażenie logiczne.

Co gorsze, w praktyce Twój zapis by się skompilował i by działał (ale błędnie). Podczas sprawdzania warunku wszystko co nie jest zerem jest uznawane za prawdę (czyli spełnia warunek). Inaczej mówiąc Twój zapis byłby interpretowany jako: if (odebraneDane != "zielone" or 1). Idąc dalej, załóżmy, że do Twojej zmiennej odberaneDane przypisana jest wartość "zielone", więc w wyniku warunku odebraneDane != "zielone" otrzymujesz 0/fałsz (bo "zielone" nie jest nierówne "zielone"). Twój warunek sprowadza się więc do if (0 or 1), a to daje w wyniku prawdę (kłania się technika cyfrowa), więc warunek będzie zawsze wykonywany - niezależnie od zawartości zmiennej odebraneDane 😉

  • 1 miesiąc później...
(edytowany)
#define zielona 8
#define czerwona 9

String odebraneDane="";
void setup() {
  Serial.begin(9600);
  pinMode(zielona,OUTPUT);
  pinMode(czerwona,OUTPUT);

  digitalWrite(zielona,LOW);
  digitalWrite(czerwona,LOW); 
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
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 if(odebraneDane != "czerwona"){
    Serial.println("Błedny kolor");
    delay(500);
   }
 
   
}

}

Program działa dobrze.

Edytowano przez martelka

@martelka, witam na forum 😉
Widzę, że to Twoje pierwsze kroki na Forbocie, jeśli chcesz przywitać się z innymi członkami naszej społeczności skorzystaj z tego tematu: Powitania użytkowników.

Dnia 21.09.2018 o 15:54, martelka napisał:

Program działa dobrze.

Zapewne działa, ale można tutaj trochę poprawić warunek. Zwróć uwagę na ostatni sprawdzany warunek tj. if(odebraneDane != "czerwona" ), czy jest on faktycznie potrzebny? Jeśli zmienna odebraneDane przechowywałaby wartość "czerwona" to byłby spełniony wcześniejszy warunek. Dlaczego sprawdzasz więc zawartość tej zmiennej jeszcze trzeci razy?

  • 2 miesiące później...

@drozdziak, mógłbym Ci odpowiedzieć, ale... 😉 Więcej zapamiętasz jak zrobisz eksperyment w praktyce. Napisz sobie program, który działa (mniej więcej) tak:

  1. Deklaracja zmiennej byte i przypisanie jej wartości 240.
  2. Wypisanie wartość przez UART (aby zobaczyć, że na pewno jest tam 240).
  3. Dodanie do zmiennej np. 30.
  4. Ponowne wyświetlenie zmiennej na ekranie komputera.

Zobaczysz wtedy w praktyce co dokładnie stanie się po przekroczeniu zakresu. Warto dobrze to zrozumieć, bo w praktyce ten mechanizm przepełniania zmiennych czasami jest pomocny i specjalnie wpisuje się do zmiennych zbyt duże wartości.

28 minut temu, Treker napisał:

@drozdziak, mógłbym Ci odpowiedzieć, ale... 😉 Więcej zapamiętasz jak zrobisz eksperyment w praktyce. Napisz sobie program, który działa (mniej więcej) tak:

  1. Deklaracja zmiennej byte i przypisanie jej wartości 240.
  2. Wypisanie wartość przez UART (aby zobaczyć, że na pewno jest tam 240).
  3. Dodanie do zmiennej np. 30.
  4. Ponowne wyświetlenie zmiennej na ekranie komputera.

Zobaczysz wtedy w praktyce co dokładnie stanie się po przekroczeniu zakresu. Warto dobrze to zrozumieć, bo w praktyce ten mechanizm przepełniania zmiennych czasami jest pomocny i specjalnie wpisuje się do zmiennych zbyt duże wartości.

Dziękuję,  i (prawie) wszystko jasne 🙂

co prawda trochę nie rozumiem jak to może być pomocne i po co miałbym celowo wpisywać zbyt duże wartości, ale przynajmniej już wiem jak to działa 😄

(edytowany)

Zadanie 2.4 😉

void loop()
{
  if(Serial.available() > 0) //czy arduino odebrało dane
  {
    odebraneDane = Serial.readStringUntil('\n'); // jeżeli tak to zczytaj do końca lini 
                                                 // i zapisz w zmiennej 
    if(odebraneDane == "zielona")
    {
      digitalWrite(zielona, HIGH);
      delay(2000);
      digitalWrite(zielona, LOW);
    }

    else if(odebraneDane == "czerwona")
    {
      digitalWrite(czerwona, HIGH);
      delay(2000);
      digitalWrite(czerwona, LOW);
    }
    else
    {
    Serial.println("Błędna komenda!");
    }
  }
}

 

Edytowano przez Treker
Poprawiłem formatowanie.
  • Lubię! 1

@Masteroreo13, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.

9 godzin temu, Masteroreo13 napisał:

Zadanie 2.4 😉

Super, powodzenia przy dalszych eksperymentach!

PS Na przyszłość pamiętaj, że kody programów należy umieszczać przez narzędzie KOD (znajdziesz je w edytorze pod ikonką "<>"). Dzięki niemu programy są odpowiednio formatowane i kolorowane, a wtedy wszystkim znacznie łatwiej analizować wklejone programy. Tym razem poprawiłem to za Ciebie, ale z góry dziękuję za zrozumienie i pomoc przy utrzymaniu porządku na forum w przyszłości 🚀

  • Lubię! 1
  • 2 tygodnie później...

Zadanie 2.4

#define zielona 8
#define czerwona 9

String odebraneDane = "";

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

digitalWrite(zielona, LOW);
digitalWrite(czerwona, LOW);
}

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(odebraneDane +"- taki kolor nie został zdefiniowany");

 }

 

Zadanie 2.5

#define zielona 8
#define czerwona 9

String odebraneDane = "";
boolean stanzielona = false;
boolean stanczerwona = false;

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

digitalWrite(zielona, LOW);
digitalWrite(czerwona, LOW);
}

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

  else if (odebraneDane == "czerwona"){
    
    if (stanczerwona){
        digitalWrite(czerwona, LOW);}
    else{
        digitalWrite(czerwona, HIGH);
    }
    stanczerwona = !stanczerwona;}
  else
 Serial.println(odebraneDane +"- taki kolor nie został zdefiniowany");

 }
}

 

  • Lubię! 1

@Maszynyodsrodka, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.
20 godzin temu, Maszynyodsrodka napisał:

Zadanie 2.4

Oj, coś tu trochę pod koniec formatowanie kodu zaczęło kuleć  - nie zgubiłeś pary nawiasów po else? Nawet jeśli taka forma działa to trochę prosisz się o kłopoty, później dopiszesz jakąś kolejną linię po else i całość już nie będzie działała poprawnie.

To kwestia tego że nie napisałeś nawiasów po else. Nawet jeżeli ci to teraz działa poprawnie to:

//kod z warunkiem if
else
 Serial.println(odebraneDane +"- taki kolor nie został zdefiniowany");
 digitalWrite(zielona,HIGH);//to by ci się nie wykonało dla else

Po else należy mieć nawiasy. One dyktują co się wykona w przypadku nie spełnienia warunków.

//Kod z warunkiem if
else{
 Serial.println(odebraneDane +"- taki kolor nie został zdefiniowany");
  digitalWrite(zielona,HIGH);//Teraz ta linia by się wykonała
}

 

  • Lubię! 1
30 minut temu, Maszynyodsrodka napisał:

czy to jednie, albo aż kwestia dodatkowych nawiasów i z nimi będzie wszystko?

Według mnie jest to "aż" kwestia nawiasów 🙂 Oczywiście można w prostych warunkach nie stosować nawiasów klamrowych, ale takie mieszanie dwóch podejść doprowadzi szybko do wielu błędów. Szczególnie, że w innych miejscach masz po else nawiasy klamrowe.

Do tego w złym miejscu zostawiasz nawiasy zamykające, przez co bardzo obniżasz czytelność swojego kodu. Chodzi mi o te fragmenty:

293c0-2019-01-06_19-42-32-5409.png

Wyłamujesz się ze wszystkich popularnych konwencji formatowania kodu. W kursie cały czas trzymałem się poniższej wersji i polecam formatować kod podobnie. Będziesz miał wtedy mniejsze szanse na popełnienie przypadkowych błędów w przyszłości (związanych z dopisywaniem czegoś do programu lub kopiowaniem jego fragmentów).

if (warunek) {
	//Instrukcje jeśli prawda
} else {
	//Instrukcje jeśli fałsz
}

 

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...