Skocz do zawartości
Komentator

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

Pomocna odpowiedź

do programu z dwoma diodami dorobiłem sobie trzecią-niebieską. Jednakże program nie działa tak jak powinien, tzn. jak wpiszę greenled albo redled, to po załączeniu na 3s diod zielonej lub czerwonej włącza się dioda niebieska, ktoś wie czemu tak się dzieje? tutaj kod:

String receivedData = ""; //empty string
//define leds
#define redled 2
#define greenled 3
#define blueled 4
void setup() {
 // put your setup code here, to run once:
Serial.begin(9600); //start communication
//set pins as outputs
pinMode (redled,OUTPUT);
pinMode (greenled,OUTPUT);
pinMode(blueled,OUTPUT);

//switch off leds
digitalWrite (redled,LOW);
digitalWrite(greenled,LOW);
digitalWrite(blueled,LOW);
}

void loop() {
 // put your main code here, to run repeatedly:
if(Serial.available() > 0)//check if data was received
{
 receivedData = Serial.readStringUntil('\n');//if yes, read it to EOL
                                              //and save in variable receivedData
 if(receivedData == "greenled")//if you wrote "greenled"
 {
   digitalWrite(blueled,LOW);
   digitalWrite(redled,LOW);
   digitalWrite(greenled,HIGH);
   delay(3000);
   digitalWrite(greenled,LOW);
 }
else if(receivedData == "redled")//if you wrote "ledred"
 {
   digitalWrite(blueled,LOW);
   digitalWrite(greenled,LOW);
   digitalWrite(redled,HIGH);
   delay(3000);
   digitalWrite(redled,LOW);
 }
 else if(receivedData == "blueled");
{

  digitalWrite(redled,LOW);
  digitalWrite(greenled,LOW);
  digitalWrite(blueled,HIGH);
  delay(3000);
  digitalWrite(blueled,LOW);
}
}
}

jakoś bardzo specjalnie to on się nie różni, właściwie oprócz dodanie "else if" i trzeciej diody to to jest to samo co w kursie, jestem zdziwiony działaniem.

Udostępnij ten post


Link to post
Share on other sites
  else if(receivedData == "blueled"); 

Usuń średnik.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Hm, faktycznie, dzięki 🙂 a czemu to tak działa w takim razie? Co ten średnik takiego robi?

Udostępnij ten post


Link to post
Share on other sites

Przez ten średnik nie wejdzie Ci do if'a. Po prostu uzna to za koniec instrukcji po warunku.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

No okej, dzięki bardzo, tylko w takim razie, to, że instrukcje poniżej są w klamrach nie będzie mu jakoś przeszkadzało? Albo raczej, skoro działa, to czemu mu to nie przeszkadza?

Udostępnij ten post


Link to post
Share on other sites

W sumie to nie wiem czy nie przeszkadza - ten kod noramalnie się wykona, tylko nie pod warunkiem znajdującym się w if'ie, ale za każdym obrotem pętli głownej. Spróbuj opakowac dowolny fragment kodu w nawiasy {} i zobacz że je zignoruje i się normalnie ciągiem wykona. Bo niby czemu miałby zrobić coś innego 😉 ?

Udostępnij ten post


Link to post
Share on other sites

Składnia instrukcji if w języku C wygląda następująco:

if ()

Blok instrukcji jest traktowany jako jedna instrukcja, czyli jeśli pojawią się nawiasy klamrowe { }, wykonuje się cały blok.

Średnik jest separatorem instrukcji, więc możemy przykładowo w jednej linii napisać dwie instrukcje:

printf("%d", a); a = 5

jeśli pominiemy jedną z nich i napiszemy

; a = 5

to kompilator potraktuje pierwszą, jako instrukcję pustą (często nazywaną NOP):

NOP(); a = 5

Teraz zobaczmy trudniejszy przykład:

if(receivedData == "blueled") printf("hello"); printf("world");

tutaj mamy instrukcję if, gdzie warunek to (receivedData == "blueled"). Jeśli warunek jest prawdziwy, wykonywana jest instrukcja warunkowa printf("helllo"). W tym miejscu kończy się całość związana z if, średnik oznacza koniec instrukcji. Więc printf("world") wykona się niezależnie od warunku.

Jeśli usuniemy printf, a zostawimy średnik, otrzymamy:

if(receivedData == "blueled") ; printf("world");

Kompilator zrobi dokładnie to samo, co wcześniej, czyli doda instrukcję pustą.

Kod który napisałeś, działa więc tak:

if(receivedData == "blueled") NOP();

Natomiast dodanie nawiasów klamrowych jedynie grupuje pozostały kod, co w tym wypadku nie wpływa na kod wynikowy programu.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Elvis, dzięki, to co napisałeś jest bardzo logiczne, jakoś przeoczyłem tę informację oraz działanie średnika w tym przypadku, dzięki bardzo!

Udostępnij ten post


Link to post
Share on other sites

Moje wersje z diodą sterowaną przez UART


///////////////////////////////////ZADANIE 1///////////////////////////////////

#define czerwona 8
#define niebieska 9

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

}

void loop()
{
 String dane = "";
 if (Serial.available() > 0)
 {
   dane = Serial.readStringUntil('\n');
   if (dane == "on")
   {
     digitalWrite(czerwona, HIGH);
     Serial.println("diode ON");
   }
   if (dane == "off")
   {
     digitalWrite(czerwona, LOW);
     Serial.println("diode OFF");
   }
   if(dane != "on" && dane !="off")
   {
     Serial.println("wpisales zla nazwe");

   }
 }


}

///////////////////////////////////ZADANIE 2///////////////////////////////////


#define red 8
#define blue 9

void setup() {
 Serial.begin(9600);
 pinMode(red, OUTPUT);
 digitalWrite(red, LOW);
  pinMode(blue, OUTPUT);
 digitalWrite(blue, LOW);

}

void loop()
{
 String dane = "";
 if (Serial.available() > 0)
 {
   dane = Serial.readStringUntil('\n');
   if (dane == "red")
   {
     digitalWrite(blue, HIGH);
     digitalWrite(red, LOW);
     Serial.println("diode blue");
   }
   if (dane == "blue")
   {
     digitalWrite(red, HIGH);
     digitalWrite(blue, LOW);
     Serial.println("diode red");
   }
   if(dane != "red" && dane !="blue")
   {
     Serial.println("wpisales zla nazwe");

   }
 }


}

Udostępnij ten post


Link to post
Share on other sites

matito, działa? Bo nie pochwaliłeś się 🙂

Udostępnij ten post


Link to post
Share on other sites

Czy takie rozwiązanie trudniejszego zadania będzie mniej czy bardziej odpowiednie

String odebrane = "";

#define led 8

void setup()

{

pinMode(led, OUTPUT);

digitalWrite(led, LOW);

Serial.begin(9600); //ustawienie prędkości transmisji

}

void loop()

{

if(Serial.available() > 0) //czy odebrano jakies dane

{

odebrane = Serial.readStringUntil('\n'); //odczytaj dane az do znaku konca linii

if(odebrane == "led")

{

if (digitalRead(led) == HIGH)

digitalWrite(led, LOW );

else

digitalWrite(led,HIGH);

}

else

Serial.println("bledny kod");

}

}

Udostępnij ten post


Link to post
Share on other sites

Witam, wydawało mi się, że w ten sposób uda mi się sprostać temu zadaniu. Niestety jednak komunikat nie chce się wyświetlać,a ja nie mogę za nic znaleźć błędu.

Wklejam kod:

#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(odebraneDane == "zielona","czerwona"){ //Jeśli odebrano słowo "zielona" lub "czerwona"
 if(Serial.available() > 0) { //Czy Arduino odebrało dane
   //Jeśli tak, to odczytaj 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); 
  }
 }
 } else { // Jeśli nie odebrano słowa "zielona" lub "czerwona"
   Serial.println("Podano zly kolor"); //Wyświetl komunikat
 }  
 }

Udostępnij ten post


Link to post
Share on other sites
#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 odczytaj 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); 
  } 
  else { // Jeśli nie odebrano słowa "zielona" lub "czerwona" 
   Serial.println("Podano zly kolor"); //Wyświetl komunikat 
 }
}  
 }

Spróbuj coś takiego.

Udostępnij ten post


Link to post
Share on other sites

Razor1996, po pierwsze przecinek nie służy do łączenia warunków. Specjalnie jeszcze nie podawałem jak to zrobić, bo nie jest to konieczne w tej chwili.

Po drugie, zwróć uwagę, ze Twój pierwszy warunek:

if(odebraneDane == "zielona","czerwona"){

Oprócz tego, że jest błędny, to sprawdza zawartość zmiennej odebraneDane, zwróć jednak uwagę, że informacje do tej zmiennej przypisywane są dopiero w tym warunku (a nawet w jeszcze jednym). W związku z tym podczas sprawdzania warunku zmienna odebraneDane jest zawsze pusta, bo nigdy nie dochodzisz do momentu zapisania do niej informacji 🙂

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
#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 odczytaj 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); 
  } 
  else { // Jeśli nie odebrano słowa "zielona" lub "czerwona" 
   Serial.println("Podano zly kolor"); //Wyświetl komunikat 
 }
}  
 }

Spróbuj coś takiego.

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.

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ść
Napisz odpowiedź...

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