Skocz do zawartości

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


Pomocna odpowiedź

Cieszę się, że kurs jest pomocny 🙂

Dlaczeg po wpisaniu komendy delay 25 i puszczeniu przycisku komunikat nie pojawia się co określony odstęp czasu? (interakcja z programem)

O którym dokładnie kodzie mówisz? Wklej go tutaj, tak najłatwiej będzie udzielić odpowiedzi 🙂

Dlaczego po void setup są znaki () ?

Na tym etapie nauki najlepiej przyjąć, że "tak ma być" 😉 Nawiasy te są związane z funkcjami, o których przeczytasz w dalszej części kursu: Kurs Arduino – #9 – Czujnik odległości HC-SR04, funkcje. Więcej informacji o tym jak działa Arduino znajdziesz też w poniższej serii artykułów: Arduino, co w środku piszczy – #1 – schemat

Dziękuję za odpowiedź, co do pierwszej kwesti, myślę że pytanie to lepiej będzie zobrazować na innym kodzie:

void setup() {
 pinMode(10, OUTPUT); //Dioda czerwona
 pinMode(9, OUTPUT); //Dioda żółta
 pinMode(8, OUTPUT); //Dioda zielona

 pinMode(7, INPUT_PULLUP); //Przycisk

 digitalWrite(10, LOW); //Wyłączenie diod
 digitalWrite(9, LOW);
 digitalWrite(8, LOW);
}

void loop()
{
 digitalWrite(10, LOW); //Czerwona
 digitalWrite(9, LOW); //Pomarańczowa
 digitalWrite(8, HIGH); //Zielona

 delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
 while (digitalRead(7) == HIGH) {} //Jeśli przycisk jest wciśnięty 

 digitalWrite(10, LOW); //Czerwona
 digitalWrite(9, HIGH); //Pomarańczowa
 digitalWrite(8, LOW); //Zielona

 delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
 while (digitalRead(7) == HIGH) {} //Jeśli przycisk jest wciśnięty 

 digitalWrite(10, HIGH); //Czerwona
 digitalWrite(9, LOW); //Pomarańczowa
 digitalWrite(8, LOW); //Zielona

 delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
 while (digitalRead(7) == HIGH) {} //Jeśli przycisk jest wciśnięty 

 digitalWrite(10, HIGH); //Czerwona
 digitalWrite(9, HIGH); //Pomarańczowa
 digitalWrite(8, LOW); //Zielona

 delay(1000); //Zatrzymujemy program przed wejsciem do pętli na 1 sekunde
 while (digitalRead(7) == HIGH) {} //Jeśli przycisk jest wciśnięty 
}

Z tego co rozumiem w tym samym kodzie pozbawionym delay(100) kiedy przycisk nie jest wciśnięty program przechodzi przez kolejne "funkcje"(zapalenie określonych diod) w pętli bez realizowania ich, więc kiedy wciskamy przycisk możemy trafić na dowolną. I teraz pytanie: dlaczego wpisanie komendy delay nie powoduje że przeskoki pomiędzy kolejnymi "funkcjami" są wolniejsze, tylko zatrzymuje przeskakiwanie przez kolejne "funkcje" w pętli?

Z tego co rozumiem w tym samym kodzie pozbawionym delay(100) kiedy przycisk nie jest wciśnięty program przechodzi przez kolejne "funkcje"(zapalenie określonych diod) w pętli bez realizowania ich, więc kiedy wciskamy przycisk możemy trafić na dowolną.

Czy testowałaś to w praktyce? Jeśli faktycznie uzyskałaś taki efekt to znaczy, że gdzieś popełniłaś błąd. Po usunięciu samych opóźnień program powinien wykonać jedną sekwencje i zatrzymać się do czasu wciśnięcia przycisku. Nie ma możliwości, aby samo usunięcie opóźnień powodowało przechodzenie przez wszystkie sekwencje (mowa o sytuacji, w której przycisk nie jest wciskany).

Oczywiście jeśli usuniesz opóźnienie i będziesz wciskała przycisk to faktycznie program będzie bardzo szybko przechodził przez wszystkie kombinacje, a po puszczeniu przycisku zatrzyma się na jednej "losowej" kombinacji. Dzieje się tak dlatego, że w momencie Twojego "krótkiego wciśnięcia" Arduino zdąży wykonać wszystkie instrukcje z pętli głównej wiele, wiele razy. Wykryje wciśniecie przycisku, przejdzie do następnej kombinacji, znów zdąży wykryć to, że wciskasz przycisk i tak w koło. Pamiętaj, że Arduino pracuje z prędkością 16 milionów taktów zegara na sekundę. Więc to co dla Ciebie będzie szybkim wciśnięciem dla Arduino trwa wieki i w tym samym czasie może ono wykonać ogromną liczbę instrukcji 😉

Treker mi się udało odtworzyć problem i znalazłem przyczynę ale nie wiem jak ją wyeliminować. W każdym razie odczytywanie komend z terminala działa poprawnie gdy mam wybraną opcję "Brak zakończenia linii", gdy mam "Zarówno NL, jak i CR" to arduino nie reaguje na wpisane komendy. Nie wiem od czego to zależy, czy może biblioteka arduino ma taką specyfikę czy da się to jakoś inaczej zrobić.

Dzięki za zainteresowanie.

Mechano, jak rozumiem nie mówisz o problemie koleżanki Agara7 tylko o wcześniejszych postach z tego tematu? W tamtym programie chcieliśmy, aby Arduino czytało wejście do znaku nowej linii "Serial.readStringUntil('\n');", więc należy odpowiednio ustawić terminal (tak jak na moim zrzucie ekranu). To, że program działa "dziwnie" w innych konfiguracjach jest raczej normalne 🙂

  • 2 tygodnie później...

Dziękuję bardzo za odpowiedź, teraz już rozumiem,(16 milionów taktów robi wrażenie) po przerobieniu jeszcze dziewięciu części kursu i powrocie do tego zagadnienia wydaje się być proste 😃

  • 3 tygodnie później...

podczas prób przez pomyłke ustawiłem wyj 8 jako wyj7 gzie już wcześniej zdeklarowałem 7 jako wej.ale kompilator nie pokazał żadnego błedu

koragreg, witam na forum! Niestety nie rozumiem Twojej wiadomości, czy możesz trochę staranniej opisać swój problem 🙂?

  • 3 tygodnie później...

Na wstępie wypadałoby się przywitać - cześć wszystkim! 🙂

Przejdźmy do rzeczy - ja sobie poradziłem w następujący sposób:

#define zielona 9
#define czerwona 8

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

boolean zielonaONczyOFF = false; //zmienna logiczna, czy zielona (9) ON 
boolean czerwonaONczyOFF = false; //zmienna logiczna, czy czerwona (8) ON 

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
   odebraneDane = Serial.readStringUntil('\n');    //Jesli tak, to odczytujemy je do końca linii i zapisujemy w zmiennej

   if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"
     zielonaONczyOFF =!zielonaONczyOFF; //negacja wartości booleana
     digitalWrite(zielona, zielonaONczyOFF); //to zmieniamy stan diody zielonej
     Serial.println("Zmieniono stan diody zielonej");
       }

   if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"
     czerwonaONczyOFF =!czerwonaONczyOFF; //negacja wartości booleana
     digitalWrite(czerwona, czerwonaONczyOFF); //to zmieniamy stan diody czerwonej
     Serial.println("Zmieniono stan diody czerwonej");
       }

   if (odebraneDane != "zielona" && odebraneDane != "czerwona") {
     Serial.println("Chyba żartujesz, " + odebraneDane + " dioda nie jest podłączona!");
       }
   }
 }

Muszę się jednak przyznać do korzystania z wygooglowanego cheat sheeta, bo brakowało mi operatorów != oraz && 🙂

  • Lubię! 1

G-Root, witam na forum! Super, że sobie poradziłeś - szukanie dodatkowych informacji to ważna umiejętność w życiu programisty 😉

G-Root, wszedłem na forum aby pochwalić się rozwiązaniem którego nie widziałem wcześniej a tu widzę że mnie ktoś ubiegł... tylko ja negację na początku robiłem: "/=", coś mi się przypomniało z technikum.

BTW. Witam forumowiczów!

#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);
   }
   if (odebraneDane == "czerwone") {
     digitalWrite(czerwona, HIGH);
     delay(1000);
     digitalWrite(czerwona, LOW);
   }
   if (odebraneDane != "zielone" or "czerwone") {
     Serial.println("Błędny kolor");
   }
   }
   }


ADyarac, witam na forum! Dzięki za podzielenie się Twoim rozwiązaniem tego zadania 🙂 Jednak coś tutaj się nie zgadza - zerknij na ten warunek:

    if (odebraneDane != "zielone" or "czerwone") { 
     Serial.println("Błędny kolor"); 
   } 

To nie jest prawidłowy zapis. Masz pomysł co trzeba zmienić, aby było dobrze?

Treker,

 if (odebraneDane != "zielona" && odebraneDane != "czerwona") {
     Serial.println("Błędny kolor");
   }

Czy o to chodzi?

A czym jest "or"?

or to inaczej "albo" (w rzeczywistości jest to operator "or else" a nie "or" ale to wykracza poza ramy odpowiedzi). Oznacza się go dwiema pałkami - czyli ||.

A takie dwie śmiszne ósemki (czyli &&) to nie or tylko and (w rzeczywistości "and then" ale to wykracza poza ramy odpowiedzi).

Ot, taka drobna różnica 😉

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