Skocz do zawartości

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


Pomocna odpowiedź

[Kurs Arduino, #3 UART]

Cześć, mam pytanie: napis "Minęło 5 sekund" wyświetla mi się bez problemu, natomiast ten pierwszy ("Witaj na Forbocie") nie chce się pojawiać na Szeregowym monitorze... Co może być przyczyną? Jestem początkujący w te klocki, więc ciężko mi dojść czy to z mojej winy czy może ze sprzętem coś nie tak...

PS. Kod najpierw pisałem sam, później próbowałem kopiować- efekt taki sam.

Próbowałem podłączyć moje Arduino (Leonardo) na różnych portach USB, również bez skutku.

Będę wdzięczny za pomoc 🙂

PPS. Przy okazji jeszcze zapytam: na czym polegają te błędy wynikające z różnej prędkości transmisji na Arduino i ustawionej w terminalu? Niestety nie zdołałem zauważyć żadnych istotnych zmian, a skoro powinny być "dość charakterystyczne i warto o nich pamiętać", to chętnie dowiedziałbym się na co tu zwrócić uwagę.

PPPS. Czasem mam jeszcze ten problem że komputer sam zmienia nr portu do którego podłączone jest Arduino (mimo że wtyczka siedzi cały czas w tym samym gnieździe USB) i przez to są momenty kiedy nie chce przez to kompilować...

[ Dodano: 01-11-2016, 10:13 ]

I mam jeszcze jedną wątpliwość odnośnie ostatniego ćwiczenia (Interakcja z układem sterowanie diodami przez UART): dotychczas wydawało mi się że jak program wejdzie w instrukcję warunkową if to od razu przechodzi przez nią całą, natomiast tutaj

zatrzymuje się na włączeniu diody zielonej/ czerwonej i nie wyłącza diody samoistnie, do momentu gdy podam mu inną komendę. Czyli tak jakby "grzęźnie" w linijce włączającej diodę i czeka nie wykonując dwóch pozostałych (odczekaj kilka sekund i wyłącz diodę)...

Spodziewałem się trochę innego efektu (tak jak w drugiej odsłonie kursu w przykładzie: Włącznik światła z czasomierzem- tam przechodzi od razu przez całego if'a).

W takim razie na czym polega różnica pomiędzy tymi dwoma wykonaniami if'a?

Link do komentarza
Share on other sites

KarolMateusz, dzięki za wiadomość, mam nadzieję, że uda się rozwiązać Twoje problemy.

1) Jeśli pierwsza wiadomość nie pojawia się w monitorze portu szeregowego, to spróbuj w sekcji setup dodać jedną linijkę za inicjalizacją UARTa:

void setup(){
 Serial.begin(9600); //Ustawienie prędkości transmisji
 while (!Serial) {}
 Serial.println("Witaj na Forbocie!"); //Jednorazowe wysłanie tekstu
}

Dodanie tego while sprawia, że program jest zatrzymywany w pustej pętli do momentu, gdy port szeregowy będzie gotowy. Daj znać, czy pomogło 🙂

2) Błędy wynikające z ustawienia złej prędkości prowadzą do wyświetlania (mówiąc potocznie) chińskich znaków w terminalu. Spróbuj w oknie terminala zmienić prędkość na sporo mniejszą lub sporo większą, powinny zacząć pojawiać się dziwne znaki.

3) W kwestii zmian nr portu COM, to już może być wiele przyczyn związanych z Twoim konkretnym komputerem. Samo Arduino na pewnie "nie skacze" po różnych portach.

4) Program działa dokładnie tak jak piszesz, czyli przechodzi przez całą instrukcję. Dioda powinna gasnąć po 1 sekundzie. Sprawdziłem przed chwilą program dla pewności i właśnie tak się dzieje.

  • Lubię! 1
Link do komentarza
Share on other sites

Dzięki Treker za odpowiedź 🙂

1. While pomógł, teraz wyświetla się jak należy.

2. (Nie)stety przy różnych prędkościach nadal wyświetla mi tak samo- nawet przy max i min prędkości ustawionej w terminalu, ale wierzę na słowo 😉.

4. Tutaj też bez zmian, z małym wyjątkiem: z ciekawości zrobiłem eksperyment i uruchomiłem dla porównania 2 programy (z tak samo zmontowanym układem):

jeden z zastosowaniem instrukcji #define (identyczny z ostatnim zadaniem tej części kursu: "Interakcja z układem – sterowanie diodami przez UART")- efekt nadal był taki, że dioda zielona/ czerwona świeciła się do momentu kiedy podałem na terminalu hasło żeby zaświeciła się druga z nich (i to też z pewnym opóźnieniem: przy krótkim delay'u równym np. 1s szybko się przełączały, natomiast gdy dałem delay równy 10s to przełącza po kilku sekundach- po dokładnym sprawdzeniu ok.6-7 sekund, nie dobija do 10);

drugi- bez #define, wpisując po prostu w każdym miejscu nr pinu (tak jak to było robione np. w drugiej odsłonie kursu) i co ciekawe, tutaj już dioda po sekundzie gasła tak jak powinna.

Dla mnie na razie to magia 😃

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

2) W takim razie przy najbliższej okazji postaram się wygenerować takie błędy i umieszczę zrzut ekranu w artykule.

3) Niestety na ten moment nie mam pomysłu skąd bierze się Twój błąd. W moim przypadku kompilacja programu z artykułu (identycznego) powoduje poprawne działanie układu. Której wersji kompilatora używasz? Jak dokładnie masz podłączone diody (przez rezystor do masy, czy do plusa)?

Link do komentarza
Share on other sites

KarolMateusz, jeśli w obu przypadkach podłączenia diod program działał tak samo, to na pewno coś jest źle. Jeśli podłączyłeś je przez rezystor do masy, to powinny świecić tylko przez sekundę, jeśli podłączyłeś odwrotnie, czyli przez rezystor do plusa, to powinny cały czas świecić i gasną tylko na sekundę.

Miałem na myśli kompilator, czyli wersję Twojego Arduino IDE. Wstaw też najlepiej zdjęcie swojego układu.

Spróbuj uruchomić taką wersję programu i powiedz, jakie są efekty w monitorze portu szeregowego:

#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 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"
     Serial.println("Wlaczenie diody zielonej");
     digitalWrite(zielona, HIGH); //To włączamy diodę zieloną
     delay(1000);
     Serial.println("Wylaczenie diody zielonej");
     digitalWrite(zielona, LOW); 
   }

   if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
     Serial.println("Wlaczenie diody czerwonej");
     digitalWrite(czerwona, HIGH); //To włączamy diodę czerwoną
     delay(1000);
     Serial.println("Wylaczenie diody czerwonej");
     digitalWrite(czerwona, LOW); 
   }
 }
}
Link do komentarza
Share on other sites

Witam,
chciałbym zapytać tak w roli uzupełnienia, co właściwie oznacza ten zapis:

while(!Serial)

while oczywiście wiem, ale co daje ten zapis z wykrzyknikiem. Nie kojarzę żeby we wcześniejszych kursach pojawiał się taki zapis.

Link do komentarza
Share on other sites

Wersja kompilatora to 1.6.7.

I już chyba doszedłem co i jak, bo śmiga poprawnie 🙂

Przy właściwym podłączeniu układu (przez rezystor do masy), poprawieniu delay'a na 1s (wcześniej próbowałem go zmieniać, zostało przy 10s... i chyba tu był główny winowajca 😃 ) i poprawieniu jednego nawiasu domykającego (dopiero zauważyłem że postawiłem go w niewłaściwym miejscu) działa tak jak powinno- świeci przez sekundę i gaśnie.

Treker, jeszcze raz dzięki za pomoc! 🙂

Link do komentarza
Share on other sites

michgda, wykrzyknik oznacza negację. W tym wypadku while(!Serial) {} oznacza przebywanie w pustej pętli do momentu, gdy interfejs Serial będzie gotowy do pracy. Nie korzystaliśmy z tego w kursie, bo nie jest to zawsze potrzebne 🙂 Sprawdzając stan "Serial" można się właśnie dowiedzieć, czy interfejs ten jest już gotowy do transmisji danych.

Link do komentarza
Share on other sites

Ja mam pewien problem.

Nie rozumiem, po co deklarowąć na początku zmienną boolean jako true lub false (rozumiem, że chodzi o 0 lub 1?)

W pierwotnej wersji programu, gdy program ma reagować na komunikat "zielona" lub "czerwona" zmieniając stan diod LED na przeciwny jest ok. Problem występuje gdy chcę aby pod uwagę była brana wielkość liter tzn aby wprowadzenie komunikatu "zielona" lub "Zielona" albo "czerwona" lub "Czerwona" działało tak jak w wersji pierwotnej.

Nie mogę dopatrzeć się błędu. Kursy Arduino przeczytałem wszystkie dostępne na Forbot jednak po pewnym czasie postanowiłem wykonać cały kurs od początku(od podstaw).

Problem polega na tym, że niezależnie co wpiszę zapala tylko diodę zieloną. Nawet jeśli komunikat wysyłany do arduino poprzez UART będzie losowy np "egrthejy". Po czymś takim powinien (w założeniu) wyświetlić się komunikat o błędzie, a tymczasem układ reaguje jak już wspomniałem wcześniej - zapalaniem lub gaszeniem diody zielonej.

#define zielona 8                                // dioda zielona na pinie 8
#define czerwona 10                              // dioda czerwona na pinie 10

boolean zielonaStatus = false;
boolean czerwonaStatus = false;

String odebraneDane = "";                        // ciąg doebranych 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) {                   // oczekiwanie na odebranie danych

   odebraneDane = Serial.readStringUntil('\n'); // jeśli odebrało dane to odczytaj je do końca lini

   if (odebraneDane == "zielona" || "Zielona") {             // Jeśli odebrano słowo "zielona"
     zielonaStatus = !zielonaStatus;            // zmień stan zmiennej "zielonaStatus" na przeciwny
     digitalWrite(zielona, zielonaStatus);      // zapal lub zgaś diode zieloną
   }else{
     if (odebraneDane == "czerwona" || "Czerwona") {          // Jeśli odebrano słowo "czerwona"
       czerwonaStatus = !czerwonaStatus;        // zmień stan zmiennej "czerwonaStan"
       digitalWrite(czerwona, czerwonaStatus);  // zapal lub zgaś czerwoną diodę
     }else{
       Serial.println("Bledne polecenie");
      }

    }  
 }
}
Link do komentarza
Share on other sites

Nie rozumiem, po co deklarowąć na początku zmienną boolean jako true lub false (rozumiem, że chodzi o 0 lub 1?)

Dobrą praktyką jest, aby podczas deklaracji zmiennych ustawiać ich wartości początkowe. Czasami może się zdarzyć, że zmienna po inicjalizacji przyjmie "losową wartość". Dla pewności został im tutaj przypisany fałsz, czyli 0.

Błąd, który opisujesz jest w obu warunkach. Zwróć uwagę na zapis:

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

Dodając nawiasy dla lepszej czytelności, wygląda on tak:

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

Jak widać sprawdzasz, czy zmienna odebraneDane ma wartość "zielona" lub, czy... ciąg znaków "Zielona" jest prawdą. Przypominam, że wartości różne od zera traktowane są w warunkach jako prawda. Stąd Twój program zawsze wchodzi w ten warunek, bo uważa go za prawdziwy. W celu naprawy błędu musisz poprawnie sprawdzić stan zmiennej odebraneDane, czyli:

if (odebraneDane == "zielona" || odebraneDane == "Zielona") {             // Jeśli odebrano słowo "zielona" 
  • Lubię! 1
Link do komentarza
Share on other sites

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

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.