Skocz do zawartości
Komentator

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

Pomocna odpowiedź

(edytowany)

Dlaczego sądzisz że nie działa?

Przeanalizuj sobie, jak działa Twój program:

Jeśli odebrane dane to słowo "dioda", należy włączyć diodę i nadać zmiennej "stanDiody" wartość true (czyli 1). Owszem, zdarza się to wtedy, gdy wpisujesz do monitora serial słowo "dioda". Jak rozumiem, dioda się zapala.

Następnie jeśli liczba 8 równa się true należy wyłączyć diodę i nadać zmiennej "stanDiody" wartość false (czyli 0). Taka sytuacja nigdy nie zachodzi, gdyż true to inaczej 1, a rzadko się zdarza aby osiem było równe jeden. Jak rozumiem dioda nie gaśnie.

Już wiesz jaki błąd popełniłeś?

Teraz jeśli go poprawisz zauważysz, że przestanie działać pierwszy if... ale o tym porozmawiamy jak poprawisz.

 

Edytowano przez ethanak
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Jak patrze na rozwiązania innych z wykorzystaniem np. " ! " zastanawiam się skąd oni to biorą , przecież nie było ani słowa o tym🤔.  Mam nadzieje że ta(3) część kursu  jest najtrudniejsza i najbardziej nie wyjaśniona (jak z tym boolean),  i jak już ruszę dalej to  będzie to dla takich naprawdę bardzo początkujących ( czytać kompletnie zielonych) w programowaniu...😨 

 

@ethanak czy chodziło o to żeby zmienić z "dioda" na "stanDiody" w drugim if-ie?

void setup() {
  Serial.begin(9600); // Uruchomienie komunikacji
  pinMode(dioda,OUTPUT); // Konfiguracja wyjścia

  digitalWrite(dioda, LOW); //Dioda w stanie niskim
}

void loop() {
  if(Serial.available() > 0) { // Czy Arduino odebrało dane
    //Jeśli tak, odczytujemy je doznaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n');
    if (odebraneDane == "dioda") { //Jeśli wpisane "dioda"
    digitalWrite(dioda, true); //Wlączamy diode 
    boolean stanDiody = true; // Przypisujemy stan diody wysoki
    }
    if (stanDiody == true){  //Jeżeeli stan diody wysoki
    digitalWrite(dioda, false); //Wylączamy diode
    boolean stanDiody = false; // Przypisujemy stan diody niski
   }
 }
}

Chyba jestem najbardziej topornym uczniem. Jakoś nie potrafię przebrnąć przez ten 3 rozdział😟 Czas na zajęcia mam dopiero po 21.00, siedzę do 1.30, wstaje o 5.00 i ni jak...

Edytowano przez Vova

Udostępnij ten post


Link to post
Share on other sites
6 godzin temu, Vova napisał:

Jak patrze na rozwiązania innych z wykorzystaniem np. " ! " zastanawiam się skąd oni to biorą , przecież nie było ani słowa o tym🤔.

Trzeba pamiętać, że niektórzy czytelnicy mają już jakieś doświadczenie z programowaniem i wplatają w zadania domowe trochę informacji, których nie było omówionych w kursie. Jeśli któryś konkretny zapis jest dla Ciebie niejasny to zawsze możesz zapytać na forum - chętnie wyjaśnimy. Akurat zapis "!=" to operator, który pozwala sprawdzać, czy porównywane wartości są od siebie różne.

6 godzin temu, Vova napisał:

Chyba jestem najbardziej topornym uczniem. Jakoś nie potrafię przebrnąć przez ten 3 rozdział😟 Czas na zajęcia mam dopiero po 21.00, siedzę do 1.30, wstaje o 5.00 i ni jak...

Spokojnie, każdy może robić zadania w swoim tempie. Jeśli nie miałeś wcześniej żadnej styczności z programowaniem to i tak dobrze Ci idzie 😉

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
7 godzin temu, Vova napisał:

Czas na zajęcia mam dopiero po 21.00, siedzę do 1.30,

To siedź krócej, bo na siłę się niczego nie nauczysz.

Dam Ci przykład:

Deklaracja zmiennej w C/C++ to (w najkrótszym przypadku) nazwa typu i nazwa zmiennej. Przykładowo:

boolean stanDiody;

Przy czym jest oczywiste, że deklaracja taka występuje raz. Tylko raz nazywasz i określasz zmienną - podobnie jak tylko raz nadaje się komuś imię.

Oczywiście, deklaracja może być połączona z inicjalizacją, czyli w Twoim przypadku byłoby to:

boolean stanDiody = false;

I znów inicjalizacja (jak sama nazwa wskazuje) występuje tylko raz (bo za drugim razem nie byłaby to inicjalizacja).

Zauważ, że instrukcja podstawienia wygląda bardzo podobnie:

stanDiody = false;

Ale jest zasadnicza różnica: ponieważ zmienna stanDiody jest już wcześniej określona jako boolean (no i kompilator zrobił swoje różne kompilatorowe machloje, np. przydzielił jej pamięć) nie próbujesz tworzyć nowej zmiennej poprzez nową inicjalizację, prawda?

Nie mów, że nie zauważyłeś we własnym kodzie tego że cały czas próbujesz tworzyć nowe zmienne, i że w kodach które o pierwszej w nocy czytałeś te instrukcje wyglądają nieco inaczej.

7 godzin temu, Vova napisał:

chodziło o to żeby zmienić z "dioda" na "stanDiody" w drugim if-ie

Jeśli uważasz to za drobny błąd (oj, trzeba zamienić X na Y, w sumie ciekawe czemu) to lepiej wróć do pierwszej lekcji kursu. Nie, nie żartuję. Po prostu jest to tak ewidentny babol że jeśli go nie widziałeś, to nie rozumiesz na czym polega i próbujesz losowo zamienić X na jakąś inna literę mając nadzieję, że kiedyś tam się znajdzie właściwa. Tak nie można. Nie ucz się na siłę bo to nie siłownia i nie trening bicepsa, nic to nie da. Poświęć więcej czasu na czytanie kodów, nie zaczynaj następnego dopóki w 100% nie będziesz rozumiał poprzedniego. Zrób sobie herbatę/kawę/cokolwiek fajnego do popicia, zrób przerwę, obejrzyj odcinek np. "Policjantów" (bo tam akurat myśleć nie trzeba i to świetny odpoczynek od nauki), poczytaj kod, poczytaj o jakichś nowych rzeczach... i gwarantuję, że w ten sposób nauczysz się szybciej, a już na 100% lepiej.

7 godzin temu, Vova napisał:

zastanawiam się skąd oni to biorą , przecież nie było ani słowa o tym

Widzisz - co poniektórzy coś tam wiedzą i swoją wiedzę stosują. Ja na przykład (i pewnie znalazłoby się więcej takich na tym forum) miałem w ogólniaku algebrę Boola i operatory logiczne w C (a tak naprawdę w FORTRAN-ie) to dla mnie od początku było coś w stu procentach znanego. Koledzy w jakiejkolwiek szkole kształcącej elektryków (łącznie z zawodówkami) mieli liczby zespolone (w sumie niezbędne każdemu elektronikowi). Dla kogoś, kto w szkole średniej poznał dobrze geometrię analityczną kinematyka odwrotna jest czymś dobrze znanym, co nie wiadomo dlaczego tak dziwnie się tutaj nazywa. Trudno więc próbować ograniczyć się do wiedzy z przedostatnich klas podstawówki (np. komuś, kto ma lat prawie 70 i jest emerytowanym inżynierem górnictwa, a na emeryturze postanowił zabrać się za Arduino).

Z drugiej strony widząc taki zapis ja bym - nie znając go - zastanowił się co to oznacza, może bym poszukał (np. hasła "operatory w języku C"), może bym zapytał (np. autora) - choćby z samej ciekawości. Bo przecież tu uczymy się nie na stopień, tylko dla samych siebie.

Tak więc głowa do góry, więcej uwagi i proś o wyjaśnienie jeśli czegoś nie rozumiesz.

  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

@Treker @ethanak Dziękuje za odpowiedzi i cierpliwość. Chyba faktycznie powinienem  wrócić do pierwszej lekcji kursu.   

Udostępnij ten post


Link to post
Share on other sites
#define dioda 8
String odebraneDane = ""; // Pusty ciąg odebranych danych
boolean stanDiody = false; // Przypisanie zielonej stanu

void setup() {
  Serial.begin(9600); // Uruchomienie komunikacji
  pinMode(dioda,OUTPUT); // Konfiguracja wyjścia

  digitalWrite(dioda, LOW); //Dioda w stanie niskim
}

void loop() {
  if(Serial.available() > 0) { // Czy Arduino odebrało dane
    //Jeśli tak, odczytujemy je doznaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n');
    
    if (odebraneDane == "dioda") { //Gdy wpisane "dioda"
      if (stanDiody == false){ // Gdy zmienna w stanie niskim  
    digitalWrite(dioda,HIGH); // Właczamy diodę
    stanDiody = true; // Zmienna przechodzi w stan wysoki 
    
 }else if (odebraneDane =="dioda") {//Gdy wpisane słowo "dioda"
  if (stanDiody == true) {// Gdy zmienna w stanie wysokim
  digitalWrite(dioda,LOW); // Wyłączamy diodę
  stanDiody = false; // Zmienna przechodzi w stan niski 
    }
   }
  }
 }
}

@ethanak @Treker  Witam ponownie. Może być taki rozwiązanie zadania 2.5*😉

Udostępnij ten post


Link to post
Share on other sites

Nie może być.

Przede wszystkim: masz jeszcze tylko jeden błąd, jak go poprawisz to będę Twoje rozwiązanie pokazywać jako prawidłowe co poniektórym kolegom którzy jakoś nie potrafią zrozumieć do czego służy "if" 🙂

Ale do rzeczy.

Spróbuj formatować kod jakoś bardziej po ludzku, trzymać wcięcia tak, aby było widać który nawias do którego pasuje i który blok do którego ifa należy. Może spróbuj programu "clang-format"? Bo oto Twój kod po prozepuszczeniu przez formater:

#define dioda 8
String odebraneDane = "";  // Pusty ciąg odebranych danych
boolean stanDiody = false; // Przypisanie zielonej stanu

void setup()
{
    Serial.begin(9600);     // Uruchomienie komunikacji
    pinMode(dioda, OUTPUT); // Konfiguracja wyjścia

    digitalWrite(dioda, LOW); //Dioda w stanie niskim
}

void loop()
{
    if (Serial.available() > 0) { // Czy Arduino odebrało dane
        //Jeśli tak, odczytujemy je doznaku końca linii i zapisz w zmiennej odebraneDane
        odebraneDane = Serial.readStringUntil('\n');

        if (odebraneDane == "dioda") {     //Gdy wpisane "dioda"
            if (stanDiody == false) {      // Gdy zmienna w stanie niskim
                digitalWrite(dioda, HIGH); // Właczamy diodę
                stanDiody = true;          // Zmienna przechodzi w stan wysoki

            } else if (odebraneDane == "dioda") { // *** Kiedy tam będzie coś innego? ***
                if (stanDiody == true) {          // Gdy zmienna w stanie wysokim
                    digitalWrite(dioda, LOW);     // Wyłączamy diodę
                    stanDiody = false;            // Zmienna przechodzi w stan niski
                }
            }
        }
    }
}

Zwróć uwagę na niepotrzebny nadmiarowy kod. W linijce oznaczonej komentarzem z trzema gwiazdkami - podaj przykład, kiedy program dojdzie do tej linijki a w "odebraneDane" będzie coś innego niż "dioda". Da się? Raczej nie, prawda? Więc czy ten if jest w ogóle potrzebny?

Za chwilę odpowiesz, że "program przecież działa" i "dwa razy sprawdzić nie zawadzi". Otóż owszem, zawadzi. Wyobraź sobie, że to coś co siedzi w ifie ma jakieś skutki uboczne (typowe funkcje to digitalRead czy analogRead). Wartość odczytana za drugim razem może być zupełnie inna niż za pierwszym.

Popraw i będzie świetnie.

 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Do ostatniego przykładu dodałem moduł bluetooth pod piny 0 i 1 i wszystko simiga przez telefon.

Udostępnij ten post


Link to post
Share on other sites

@ethanak Faktycznie ta linijka  kody z gwiazdkami nie potrzebna. Jakoś myślałem że bez tego ten drugi IF nie będzie działać...

  Skorzystałem z automatycznego formatowania i tak to wyszło:

#define dioda 8
String odebraneDane = ""; // Pusty ciąg odebranych danych
boolean stanDiody = false; // Przypisanie zielonej stanu

void setup() {
  Serial.begin(9600); // Uruchomienie komunikacji
  pinMode(dioda, OUTPUT); // Konfiguracja wyjścia

  digitalWrite(dioda, LOW); //Dioda w stanie niskim
}

void loop() {
  if (Serial.available() > 0) { // Czy Arduino odebrało dane
    //Jeśli tak, odczytujemy je doznaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n');

    if (odebraneDane == "dioda") { //Gdy wpisane "dioda"
      if (stanDiody == false) { // Gdy zmienna w stanie niskim
        digitalWrite(dioda, HIGH); // Właczamy diodę
        stanDiody = true; // Zmienna przechodzi w stan wysoki

      } else if (stanDiody == true) { // Gdy zmienna w stanie wysokim
        digitalWrite(dioda, LOW); // Wyłączamy diodę
        stanDiody = false; // Zmienna przechodzi w stan niski
      }
    }
  }
}

 

Udostępnij ten post


Link to post
Share on other sites

Dalej masz niepotrzebny kawałek kodu.

W linijce:

} else if (stanDiody == true) {

czy jest jakaś możliwość, aby stanDiody w tym miejscu był czymś innym niż true?

A co do formatowania: lepiej się to czyta, prawda?

 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@ethanak Wychodzi na to że w poprzednich próbach za mocno utrudniałem sobie życie, w ty sensie że kod okazał się dużo prostszy niż zakładałem. 

Co do formatowania, to nie wiem może to kwestia przeglądarki czy innego czynnika , ale jak dla mnie różnica jest nie wielka między 1 a 2 wersją🤔

#define dioda 8
String odebraneDane = ""; // Pusty ciąg odebranych danych
boolean stanDiody = false; // Przypisanie zielonej stanu

void setup() {
  Serial.begin(9600); // Uruchomienie komunikacji
  pinMode(dioda, OUTPUT); // Konfiguracja wyjścia

  digitalWrite(dioda, LOW); //Dioda w stanie niskim
}

void loop() {
  if (Serial.available() > 0) { // Czy Arduino odebrało dane
    //Jeśli tak, odczytujemy je doznaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n');

    if (odebraneDane == "dioda") { //Gdy wpisane "dioda"
      if (stanDiody == false) { // Gdy zmienna w stanie niskim
        digitalWrite(dioda, HIGH); // Właczamy diodę
        stanDiody = true;// Zmienna przechodzi w stan niski

      } else {
        digitalWrite(dioda, LOW); // Wyłączamy diodę
      }
    }
  }
}

 

Udostępnij ten post


Link to post
Share on other sites

O czymś zapomniałeś... warto by było uaktualnić stanDiody przy wyłączeniu, bo potem się już więcej nie włączy.

A tak w ogóle kod może być jeszcze prostszy, ale najpierw zrób prawidłowo tą wersję 🙂

3 minuty temu, Vova napisał:

Co do formatowania, to nie wiem może to kwestia przeglądarki czy innego czynnika , ale jak dla mnie różnica jest nie wielka między 1 a 2 wersją🤔

Nie wiem co uważasz za 1 i 2 wersję, ale zwróć uwagę na jedno: w prawidłowo sformatowanym kodzie każda linijka ma swoje wcięcie i od razu można zobaczyć, do którego bloku należy. W Twoim kodzie sprzed kilku postów było coś takiego:

    if (cośtam) {
  zrób_cośtam;
      

kawałek dalej:

   if (cośtam) {
     if (cośtamjeszcze) {
     zrób_coś;

Czy to Twoim zdaniem czytelne? Czy nie licząc pracowicie nawiasów będziesz w stanie stwierdzić, do którego bloku należą linie "zrób"?

Twój kod ma kilka linii. Co będzie w przypadku kilkuset czy kilku tysięcy?

 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@ethanak Zrobione. Jak sprawdzałem działanie kodu z poprzedniego postu , to raz włączyłem i raz wyłączyłem diodę i zadziałało. Więc pomyślałem że jest ok. A trzeba było jeszcze raz spróbować włączyć...

#define dioda 8
String odebraneDane = ""; // Pusty ciąg odebranych danych
boolean stanDiody = false; // Przypisanie zielonej stanu

void setup() {
  Serial.begin(9600); // Uruchomienie komunikacji
  pinMode(dioda, OUTPUT); // Konfiguracja wyjścia

  digitalWrite(dioda, LOW); //Dioda w stanie niskim
}

void loop() {
  if (Serial.available() > 0) { // Czy Arduino odebrało dane
    //Jeśli tak, odczytujemy je doznaku końca linii i zapisz w zmiennej odebraneDane
    odebraneDane = Serial.readStringUntil('\n');

    if (odebraneDane == "dioda") { //Gdy wpisane "dioda"
      if (stanDiody == false) { // Gdy zmienna w stanie niskim
        digitalWrite(dioda, HIGH); // Właczamy diodę
        stanDiody = true;// Zmienna przechodzi w stan wysoki

      } else {
        digitalWrite(dioda, LOW); // Wyłączamy diodę
        stanDiody = false;//Zmienna przechodzi w stan niski
      }
    }
  }
}

 

Udostępnij ten post


Link to post
Share on other sites

rozwiązałem zadanie 2.5 trochę posiedziałem żeby zrozumieć i wychodzi na to że zadziałało mogę kontynuować kurs trochę jeszcze przede mną mam zestawy do kursu 1 i 2.

#define czerwona 8
String odebraneDane = "";
boolean acz = false;
void setup() {
  Serial.begin(9600); //Uruchamiamy transmisję
	  pinMode (czerwona, OUTPUT);
  digitalWrite ( czerwona, LOW);
	}
	void loop() {
  if (Serial.available() > 0) { // czy arduino odebrało dane
    odebraneDane = Serial.readStringUntil('\n'); // jeśli tak to odczytujemy
	    if (odebraneDane == "czerwona") { // jeśli odebrano słow czerwona
      if (acz == false) { // jeśli acz ma stan niski
        digitalWrite(czerwona, HIGH); // zapal diode
        acz = true;  // przypisz do acz stan wysoki
      } else {
        acz == true;  // jeśli acz jest w stanie wysokim
        digitalWrite(czerwona, LOW); // wyłącz diode
        acz = false; // przypisz do acz stan niski
      }
    } else {
      Serial.println(" zły wybór"); // jeśli odebraneDane nie jest czerwona wpisz w konsoli zły wybór
	    }
	  }
}

 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@kristof900 super, że działa! Jeśli mogę coś doradzić to zwróć uwagę na 2 sprawy. Pierwsza to formatowanie kodu - odpowiednie wcięcia w kodzie znacznie zwiększają czytelność programów. Zwróć uwagę jak wyglądają programy umieszczone w kursie i porównaj ze swoim 😉 Po drugie, dobrze byłoby nazywać zmienne w taki sposób, aby ich nazwy mówiły coś np. o ich przeznaczeniu. Zmienna "acz" to raczej dość enigmatyczny zapis 😉

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