Skocz do zawartości
Komentator

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

Pomocna odpowiedź

Witam, udało mi się wykonać program do ostatniego zadania, działa poprawnie:

#define zielona 8
#define czerwona 9

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

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"
     if (zmiennaZielona == false) {        //i zielona dioda jest wyłączona
     digitalWrite(zielona, HIGH);          //to ją włączamy
     zmiennaZielona = true;                //i zapamiętujemy stan
     } //end of włączanie zielonej
     else if (zmiennaZielona == true) {    //i zielona dioda jest włączona
     digitalWrite(zielona, LOW);           //to ją wyłączamy
     zmiennaZielona = false;               //i zapamiętujemy stan
     } //end of wyłączanie zielonej
   } //end of badanie zielonej

   if (odebraneDane == "czerwona") {       //Jeśli odebrano słowo "czerwona"
     if (zmiennaCzerwona == false) {       //i czerwona dioda jest wyłączona
     digitalWrite(czerwona, HIGH);         //to ją włączamy
     zmiennaCzerwona = true;               //i zapamiętujemy stan
     } //end of włączanie czerwonej
     else if (zmiennaCzerwona == true) {   // i czerwona dioda jest włączona
     digitalWrite(czerwona, LOW);          //to ją wyłączamy
     zmiennaCzerwona = false;              //i zapamiętujemy stan
     } //end of wyłączanie czerwonej
   } //end of badanie czerwonej
 } //end of odebranie danych
} //end of loop

Chciałem się przy tym zapytać, jak w tym języku zapisać coś takiego:

if (warunek a) ∧ (warunek b)

Chciałem początkowo napisać program w stylu "jeśli odebrano słowo "czerwona" oraz czerwona dioda jest włączona to zostaje wyłączona", ale nie wiedziałem jak przedstawić koniunkcję w tym języku, więc zastosowałem podwójne if. Istnieje w ogóle taka możliwość, czy lepiej rozwiązać to w inny sposób? Chyba że odpowiedź znajduje się w dalszej części kursu, gdzie jeszcze nie dotarłem, to poproszę o link. 😉

Udostępnij ten post


Link to post
Share on other sites

Zrobiłem zadanie z gwiazdką, czy można tutaj coś ulepszyć?

#define zielona 5
#define czerwona 6

void setup() {

Serial.begin(9600);
pinMode(zielona, OUTPUT);
pinMode(czerwona, OUTPUT);
//ustawiamy odpowiednie piny jako wyjścia
}

void loop() {

static String od = "";
static boolean stanCz = 0;
static boolean stanZ = 0;
//tworzymy zmienne statyczne

if(Serial.available() > 0)
 {
 od = Serial.readStringUntil('\n');
 if(od == "zielona") 
   stanZ = !stanZ;
   //zmieniamy stan na przeciwny

 else if(od == "czerwona")
   stanCz = !stanCz;
   //tak samo jak wyżej

 else
   Serial.println("nieznana komenda");
   //jak sie wpisze głupotę, to program reaguje

 }
if(stanZ > 0)
 digitalWrite(zielona, HIGH);    //w zależności od stanu
else                              //zapalamy bądź gasimy diody
 digitalWrite(zielona, LOW);

if(stanCz > 0)
 digitalWrite(czerwona, HIGH);
else
 digitalWrite(czerwona, LOW);
}

EDIT

Zmieniłem, jest trochę krótszy. Mam pytanie, po wpisaniu komendy trzeba stosunkowo długo poczekać zanim zapali się odpowiednia dioda, które operacje zajmują kontrolerowi najwięcej czasu?

#define zielona 5
#define czerwona 6

void setup() {

Serial.begin(9600);
pinMode(zielona, OUTPUT);
pinMode(czerwona, OUTPUT);
}

void loop() {

static String od = "";
static boolean stanCz = 0;
static boolean stanZ = 0;

if(Serial.available() > 0)
 {
 od = Serial.readStringUntil('\n');
 if(od == "zielona") {
   stanZ = !stanZ;
   digitalWrite(zielona, stanZ);
 }

 else if(od == "czerwona") {
   stanCz = !stanCz;
   digitalWrite(czerwona, stanCz);
 }

 else
   Serial.println("nieznana komenda"); 
 }
}

Udostępnij ten post


Link to post
Share on other sites
stosunkowo długo

To znaczy ile?

Udostępnij ten post


Link to post
Share on other sites

Lukaszm, no z sekunde, do dwóch, to jest dość długi czas jak na taktowanie 8Mhz

Udostępnij ten post


Link to post
Share on other sites

Czym mierzysz ten czas?

Samo przesyłanie 10 bajtów przy prędkości 9600bps zajmuje około 10ms.

Udostępnij ten post


Link to post
Share on other sites

Witam serdecznie

To mój pierwszy wpis na tym forum.

Na wstępie chciałbym podziękować za kurs arduino.

Mając 32 lata i będąc humanistą zainteresowałem się tą małą, ale jakże ciekawą płytką.

Wasz kurs bardzo pomaga w zrozumieniu o co chodzi w tym "tajemnym programowaniu".

Jestem na początku drogi i pewnie jeszcze długo będę się czuł jak dziecko we mgle, ale postanowiłem podzielić się rozwiązaniem zadania nr 2.4. Program zdaje się działać prawidłowo, ale wolałbym by ktoś mądrzejszy to ocenił.

#define zielona 8
#define czerwona 9

String odebraneDane = ""; // pusty ciag odebranych danych

void setup () {
 Serial.begin(9600); // inicjalizacja połaczenia z pc
 pinMode(zielona, OUTPUT); // konfiguracja wyjsc
 pinMode(czerwona, OUTPUT);

 digitalWrite(zielona, LOW); // wyłaczamy diody na starcie
 digitalWrite(czerwona, LOW); 
}
void loop () {
 if(Serial.available() > 0) { //czy arduino odebrało dane
   //jesli tak, to odczytaj je do znaku konca linii i zapisz w zmiennej odebraneDane
   odebraneDane = Serial.readStringUntil('\n'); 

   if (odebraneDane == "zielona"){ // jesli odebrano słowo "zielona"
     digitalWrite(zielona, HIGH); //to włączamy diode zielona
     delay(1000);
     digitalWrite(zielona, LOW);
     }


    if (odebraneDane == "czerwona") {
     digitalWrite(czerwona, HIGH); // to włącz diodę czerwoną
     delay(1000);
     digitalWrite(czerwona, LOW);
    }  
    if (odebraneDane !="czerwona" and odebraneDane!="zielona")  {   


     Serial.println("Podales zly kolor!");

    }

 }}


  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Rasted, witaj na forum, ciesze się, że kurs nadal jest pomocny 🙂 Wszystko wygląda dobrze, jedynie proponowałbym poprawić formatowanie końcówki kodu, aby była lepiej czytelna, czyli zamiast:

     if (odebraneDane !="czerwona" and odebraneDane!="zielona")  {    


     Serial.println("Podales zly kolor!"); 

    } 

 }} 

Zrobiłbym:

     if (odebraneDane !="czerwona" and odebraneDane != "zielona")  {    
     Serial.println("Podales zly kolor!"); 
    }   
 }
} 

Można też zamiast 3 osobnych if'ów skorzystać z konstrukcji if else, wtedy uda się zrealizować całość bez ostatniego warunku 🙂

Udostępnij ten post


Link to post
Share on other sites

Treker, dziękuję za uwagi.

Pamiętam, że próbowałem użyć else, ale coś nie działało mi prawidłowo. Nie mam teraz czasu sprawdzać tego "doświadczalnie", więc pozwalę sobie po prostu zapytać:

Czyli zamiast warunku:

if (odebraneDane !="czerwona" and odebraneDane!="zielona") 

...wystarczy jak użyję instrukcji else i zadziała ona do obu if'ów?

Co do klamerek to fakt, często kompilator "krzyczy", że jakiejś nie domknąłem itp, więc dopisuję je już bez zwracania uwagi na formatowanie. Postaram się zwrócić na to większa uwagę.

Udostępnij ten post


Link to post
Share on other sites
Ja zrobiłem tak:
#define zielona 8
#define czerwona 9

String odebraneDane = "";
boolean stanCzerwonej = false;
boolean stanZielonej = 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") {
     stanZielonej = !stanZielonej;
   }

   if (odebraneDane == "czerwona") {
     stanCzerwonej = !stanCzerwonej;
   }

   if (odebraneDane != "czerwona" && odebraneDane != "zielona") {
     Serial.println("Nieprawidlowy kolor! Wpisz 'zielona' lub 'czerwona'.");
   }

   digitalWrite(zielona, stanZielonej);
   digitalWrite(czerwona, stanCzerwonej);
 }

}

Może być?

Igor możesz mi wytłumaczyć czemu użyłeś && and i to działa? Przecież żeby and się zgadzało dwie wartości muszą być prawdziwe. zamieniłęm to na or || i nie działa i nie rozumiem dlaczego. Z góry dzięki

Udostępnij ten post


Link to post
Share on other sites
...wystarczy jak użyję instrukcji else i zadziała ona do obu if'ów?

Nie wiem gdzie chcesz ją użyć, więc ciężko odpowiedzieć. Zachęcam jednak do testów w praktyce, w tym wypadku powinna wystarczyć konstrukcja tego typu:

if (...) {

} else if (...) {

} else {

}
Co do klamerek to fakt, często kompilator "krzyczy", że jakiejś nie domknąłem itp, więc dopisuję je już bez zwracania uwagi na formatowanie.

Najbezpieczniej od razu stawiać dwa nawiasy klamrowe {}, później cofać kursorem i pisać już w ich wnętrzu. Inaczej szybko można się pogubić i później trzeba właśnie dopisywać klamerki w losowych miejscach.

Igor możesz mi wytłumaczyć czemu użyłeś && and i to działa? Przecież żeby and się zgadzało dwie wartości muszą być prawdziwe. zamieniłęm to na or || i nie działa i nie rozumiem dlaczego. Z góry dzięki

Odpowiem za Igora. Sprawdź, co dokładnie robi ten warunek, nie ma sensu zamieniać "na ślepo" AND z OR'ami. W tym przypadku chcemy sprawdzić, czy odebraneDane nie zawierają słowa czerwona i nie zawierają słowa zielona. Najlepiej rozpisywać sobie takie warunki pełnym zdaniem, wtedy widać, co dokładnie się dzieje podczas ich wykonywania 🙂

Udostępnij ten post


Link to post
Share on other sites
boolean stan = false;
void setup() {
 pinMode(7, OUTPUT);
}
void loop() {
   stan = !stan;
   digitalWrite(7, stan);
}

Tak napisany kod spowoduje, ze dioda będzie swieciła cały czas. Jednak jesli zmieie na true:

boolean stan = true;
void setup() {
 pinMode(7, OUTPUT);
}
void loop() {
   stan = !stan;
   digitalWrite(7, stan);
}

dioda świeci nadal.

Proszę o interpretację zapisu:

boolean stan = false;

oraz

boolean stan = true;

Dzięki

Udostępnij ten post


Link to post
Share on other sites

"dioda będzie swieciła cały czas"

Nieprawda. Dioda świeci przez połowę czasu a przez drugą połowę jest zgaszona, niezależnie od tego czy zaczniesz od true czy false. Procesory są szybkie a ten sterowany Twoim programem zmienia stan diody kilkaset tysięcy razy na sekundę. Nie masz szans tego zauważyć i widzisz tylko jakąś wartość średnią. Dla pewności wywal z pętli negację stanu. Wtedy raz dostaniesz ciemność (gdy zaczniesz od false) a raz jasność i ta jasność będzie silniejsza niż to co masz teraz, bo będzie stanem true przez 100% czasu.

Albo po prostu wstaw jakieś opóźnienie np. delay(500) do pętli.

  • Lubię! 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!

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