Skocz do zawartości
Komentator

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

Pomocna odpowiedź

Zrobiłem tak na początku ale jest to błędne, zauważ, że jeśli wpiszesz słowo "zielona" to warunek z czerwoną diodą nie zostanie spełniony więc zadziała funkcja else i wyświetli komunikat o złym kolorze mimo, że był dobry.

To pomyśl jak to inaczej rozwiązać 🙂 Np.: informacja o złym kolorze powinna być uzależniona od 3 warunku (i zmiennej pomocniczej) lub można połączyć warunki w taki sposób:

    if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona" 
     digitalWrite(zielona, HIGH); //To włączamy diodę zieloną 
     delay(1000); 
     digitalWrite(zielona, LOW); 
   } else if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona" 

Udostępnij ten post


Link to post
Share on other sites
Zrobiłem tak na początku ale jest to błędne, zauważ, że jeśli wpiszesz słowo "zielona" to warunek z czerwoną diodą nie zostanie spełniony więc zadziała funkcja else i wyświetli komunikat o złym kolorze mimo, że był dobry.

To pomyśl jak to inaczej rozwiązać 🙂 Np.: informacja o złym kolorze powinna być uzależniona od 3 warunku (i zmiennej pomocniczej) lub można połączyć warunki w taki sposób:

    if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona" 
     digitalWrite(zielona, HIGH); //To włączamy diodę zieloną 
     delay(1000); 
     digitalWrite(zielona, LOW); 
   } else if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona" 

Poradziłem sobie z tym zadaniem dokładnie w taki sposób (nie ukrywam że podejrzałem jakiś z wcześniejszych komentarzy myśląc, że mój sposób również zadziała, więc później miałem już gotowy pomysł) nie zdążyłem tego oznajmić bo tak wciągnęło mnie zadanie 2.5 które mi prawie działa:

jeśli włączę czerwoną diodę i następnie zieloną to wszystko jest OK, a jak włączę diodę zieloną to później mogę tylko ją włączać lub wyłączać.

Oto mój kod:

#define zielona 8
#define czerwona 9

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

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

 digitalWrite(zielona, LOW); //Wyłączamy diody
 digitalWrite(czerwona, LOW);
  ziel = false;
  czer = false;
}

void loop() {
 if(Serial.available() > 0) { //Czy Arduino odebrano 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"
     if (ziel == false) { // jeśli zielona dioda jest wyłączona
       digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
     ziel = true; // pokazujemy, że dioda jest włączona
     } else { // jeśli dioda jest włączona
       digitalWrite(zielona, LOW); //To wyłączamy diodę zieloną
     ziel = false; //  pokazujemy, że dioda zielona jest wyłączona
     }
     }

 if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
     if (czer == false) { // jeśli czerwona dioda jest wyłączona
       digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
     czer = true; // pokazujemy, że dioda jest włączona
     } else { // jeśli dioda jest włączona
       digitalWrite(czerwona, LOW); //To wyłączamy diodę czerwoną
     ziel = false; //  pokazujemy, że dioda czerwona jest wyłączona
     }
     }

     }
     }

Udostępnij ten post


Link to post
Share on other sites

Razor1996, po pierwsze zadbaj o poprawne wcięcia w kodzie. Teraz ciężko zrozumieć dokąd sięga który warunek. Nie ignoruj wcięć 😉

Udostępnij ten post


Link to post
Share on other sites
Razor1996, po pierwsze zadbaj o poprawne wcięcia w kodzie. Teraz ciężko zrozumieć dokąd sięga który warunek. Nie ignoruj wcięć 😉

Szczerze mówiąc nie znam reguł dawania wcięć, więc zrobiłem to na wyczucie 😐

Oto kod:

#define zielona 8
#define czerwona 9

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

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

 digitalWrite(zielona, LOW); //Wyłączamy diody
 digitalWrite(czerwona, LOW);
  ziel = false;
  czer = false;
}

void loop() {
 if(Serial.available() > 0) { //Czy Arduino odebrano 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"

         if (ziel == false) { // jeśli zielona dioda jest wyłączona
         digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
         ziel = true; // pokazujemy, że dioda jest włączona
         }   
         else { // jeśli dioda jest włączona
         digitalWrite(zielona, LOW); //To wyłączamy diodę zieloną
         ziel = false; //  pokazujemy, że dioda zielona jest wyłączona
       }
     }

   if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"

        if (czer == false) { // jeśli czerwona dioda jest wyłączona
        digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
        czer = true; // pokazujemy, że dioda jest włączona
        } 
        else { // jeśli dioda jest włączona
        digitalWrite(czerwona, LOW); //To wyłączamy diodę czerwoną
        ziel = false; //  pokazujemy, że dioda czerwona jest wyłączona
       }
     }
   }
 }

Udostępnij ten post


Link to post
Share on other sites

Już blisko, ale jeszcze zamiast:

        } 
        else {

Powinieneś robić tak:

         } else {

Dodatkowo, to co jest między nawiasami klamrowymi powinno być wcięte o 1 poziom bardziej od nawiasów, czyli zamiast:

{
coś
}

Powinno być:

{
   coś
}

Udostępnij ten post


Link to post
Share on other sites

Ok, dziękuje zaraz zastosuje się do w/w wskazówek.

Dodam, że błąd już znalazłem nie chciało mi się pisać dla diody czerwonej osobno linijek więc przekopiowałem dla zielonej i pozmieniałem nazwy, jednej nie zmieniłem i temu nie działało.

Gotowy działający program:

#define zielona 8
#define czerwona 9

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

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

 digitalWrite(zielona, LOW); //Wyłączamy diody
 digitalWrite(czerwona, LOW);
  ziel = false;
  czer = false;
}

void loop() {


   odebraneDane = Serial.readStringUntil('\n'); 

   if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"

         if (ziel == false) { // jeśli zielona dioda jest wyłączona
           digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
           ziel = true; // pokazujemy, że dioda jest włączona
         } else { // jeśli dioda jest włączona
             digitalWrite(zielona, LOW); //To wyłączamy diodę zieloną
             ziel = false; //  pokazujemy, że dioda zielona jest wyłączona
       }
     }

   if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"

        if (czer == false) { // jeśli czerwona dioda jest wyłączona
         digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
         czer = true; // pokazujemy, że dioda jest włączona
        } else { // jeśli dioda jest włączona
           digitalWrite(czerwona, LOW); //To wyłączamy diodę czerwoną
           czer = false; //  pokazujemy, że dioda czerwona jest wyłączona
       }
     }
   }

Edit: Czy teraz estetycznie jest OK oraz czy w dobry sposób rozwiązałem zadanie? 😉

Udostępnij ten post


Link to post
Share on other sites

Nie warto kopiować kodu, to są najczęstsze miejsca późniejszych błędów... Ogólnie idziemy w dobrą stronę, ale nawiasy nie są jeszcze równe, zerknij jak to wygląda na spokojnie i porównaj czy nawiasy otwierające i zamykające są w tych samych kolumnach.

Udostępnij ten post


Link to post
Share on other sites
Nie warto kopiować kodu, to są najczęstsze miejsca późniejszych błędów... Ogólnie idziemy w dobrą stronę, ale nawiasy nie są jeszcze równe, zerknij jak to wygląda na spokojnie i porównaj czy nawiasy otwierające i zamykające są w tych samych kolumnach.

Teraz już wszystko powinno być ok, ale mam pytanie co do funkcji if, bo w Twoich kodach nie dajesz "{" w nowej lini tylko po nawiesie if () { i wtedy jest problem z tym aby druga klamra była w tej samej kolumnie.

Inaczej mówiąc jak lepiej robić:

if (ziel == false) 
   { // jeśli zielona dioda jest wyłączona
     digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
     ziel = true; // pokazujemy, że dioda jest włączona
   } else { // jeśli dioda jest włączona

czy

if (ziel == false) { // jeśli zielona dioda jest wyłączona
     digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
     ziel = true; // pokazujemy, że dioda jest włączona
   } else { // jeśli dioda jest włączona

(tylko wtedy nawiasy klamrowe nie są w jednej kolumnie)

Oto kod:

#define zielona 8
#define czerwona 9

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

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

 digitalWrite(zielona, LOW); //Wyłączamy diody
 digitalWrite(czerwona, LOW);
 ziel = false;
 czer = false;
}

void loop()
{
 odebraneDane = Serial.readStringUntil('\n'); 

 if (odebraneDane == "zielona") 
 { //Jeśli odebrano słowo "zielona"

   if (ziel == false) 
   { // jeśli zielona dioda jest wyłączona
     digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
     ziel = true; // pokazujemy, że dioda jest włączona
   } else { // jeśli dioda jest włączona
       digitalWrite(zielona, LOW); //To wyłączamy diodę zieloną
       ziel = false; //  pokazujemy, że dioda zielona jest wyłączona
          }
  }

   if (odebraneDane == "czerwona") 
   { //Jeśli odebrano słowo "czerwona"

     if (czer == false) 
     { // jeśli czerwona dioda jest wyłączona
       digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
       czer = true; // pokazujemy, że dioda jest włączona
     } else { // jeśli dioda jest włączona
       digitalWrite(czerwona, LOW); //To wyłączamy diodę czerwoną
       czer = false; //  pokazujemy, że dioda czerwona jest wyłączona
            }
   }
}

Udostępnij ten post


Link to post
Share on other sites

Razor1996, w zasadzie to nie ma różnicy. Kwestia przyzwyczajenia. Dla mnie osobiście przenoszenie klamry przy if'ach do kolejnej lini jest czystym marnotrawieniem miejsca i zaciemnianiem kodu. Ale każdy pisze jak mu wygodnie.

Udostępnij ten post


Link to post
Share on other sites

Razor1996, może źle się wyraziłem. Nie nawias otwierający i zamykający powinien być tej samej kolumnie, ale nawias zamykający powinien być równo z początkiem wyrażenia, po którym jest nawias otwierający. Brzmi zawile, dlatego przykład:

cośTam {
|
|	cośTamDWa {
|	|
|	}	
|
}

Chodzi o zwykłą estetykę 🙂 Widzę, że przydałby się osobny artykuł na temat formatowania kodu. na ten moment mogę Ci polecić się poniższe teksty:

- Sekrety profesjonalnego programowania

- Jak unikać pułapek języka C?

Udostępnij ten post


Link to post
Share on other sites

igor,

Igor, co oznacza

digitalWrite(zielona, stanZielonej);

digitalWrite(czerwona, stanCzerwonej);

stanZielonej i stanCzerwonej to chyba nie jest LOW , ani HIGH , tylko true lub false

Udostępnij ten post


Link to post
Share on other sites

Jak chodzi o boolean to obaj macie rację.

Program z wykorzystaniem false i true, jako LOW i HIGH będzie działał, a jednocześnie będzie niepoprawny.

Będzie działał, ponieważ (przypadkiem) wartość false jest zdefiniowana jako 0, a LOW też jest zerem (podobnie true i HIGH to 1).

Jednocześnie program jest niepoprawny - boolean i int to zupełnie różne typy. Wykorzystanie ich zamiennie to błąd logiczny.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Nie chodziło mi o konwersję bool na uin8_t. To raczej chodzi o rozumienie abstrakcji jaką jest typ danych.

Boolean to wartość logiczna - liczba całkowita, to liczba całkowita. W przypadku LOW, HIGH, to typ wyliczeniowy. Oczywiście można rzutować typ wyliczeniowy na np. boolean, ale trzeba na takie konwersje uważać. Widziałem kod, który rzutuje float na uint32_t, żeby szybciej wykonywać pewne operacje - to są sztuczki które jak najbardziej można stosować, ale dla kogoś kto dopiero się uczy lepiej nie wnikać w takie "hakerstwa".

Pomyśl jak bardzo nieprzenośny kod tworzysz - jeśli przykładowo w następnej wersji Arduino ktoś zmieni wartości stałych LOW i HIGH, np. na 1 i 2 - kod przestanie działać.

Nieco nowocześniejsze języki jak. np. C#, czy Java, ale nawet stary dobry Pascal nie traktują boolean-ów i wyliczeń jako integer-ów.

Więc kod z if-ami jest dłuższy, ale za to poprawny logicznie. Używanie true/false jako LOW/HIGH, chociaż działa, może świadczyć albo o bardzo dobrym rozumieniu mechanizmów i potrzebie optymalizacji kodu, albo wręcz przeciwnie.

A jak już jesteśmy przy kodowaniu w C, to taki kod byłby dużo wydajniejszy, ale pokazuję go tylko żeby tak nie robić:

    if (odebraneDane == "czerwona") 
       digitalWrite(czerwona, czer ^= 1); 

Udostępnij ten post


Link to post
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!

Gość
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...