dastawowy Kwiecień 16, 2021 Udostępnij Kwiecień 16, 2021 Cześć Wszystkim ! zabrałem się za zadanie 4.4 i póki co chciałbym żeby program pokazywał mi zmienną "odczytaneDane" jeszcze bez konwersji na wartości napięcia, ale... Mam problem z pętlą while(). Gdy zasłaniam dłonią fotorezystor dioda się zapala i podaje zmienną "odczytaneDane" ale gdy odsłaniam fotorezystor, czyli teoretycznie mój warunek dla pętli while(odczytanaWartosc < prog) przestaje być spełniony, program nie chce wyjść z pętli. zastanawia mnie dlaczego pętla while nie reaguje na niespełnienie warunku? proszę o pomoc i wyjaśnienie poniżej szkic: int odczytanaWartosc = 0; //Zmienna do przechowywania odczytu ADC int prog = 0; //Próg włączenia światła - ustawiany potencjometrem void setup() { pinMode(8, OUTPUT); //Konfiguracja wyjść pod diodę LED Serial.begin(9600); } void loop() { odczytanaWartosc = analogRead(A5);//Odczytanie wartości z ADC prog = analogRead(A4);//Odczytanie wartości z ADC if (odczytanaWartosc < prog) { //Czy jest ciemniej od ustawionego progu? digitalWrite(8, HIGH);//Włączenie diody Serial.println(odczytanaWartosc); while(odczytanaWartosc < prog){ delay(50); } } else { digitalWrite(8, LOW);//Wyłączenie diody } delay(50); }
Shary Kwiecień 16, 2021 Udostępnij Kwiecień 16, 2021 (edytowany) while(odczytanaWartosc < prog) { delay(50); } Program wchodzi w pętle kiedy warunek jest spełniony, ale sama pętla to tylko delay(50). Tym samym program wykonują ciągle opóźnienie i nic więcej. Musisz w tej pętli odczytać zmienną odczytanaWartosc, aby wyjść z tej pętli. while(odczytanaWartosc < prog) { delay(50); odczytanaWartosc = analogRead(A5); } Ogólnie ten warunek IF jest niepotrzebny w tym wypadku, jeśli robisz to przy użyciu WHILE - bo właściwie to powtarzasz to samo. Wystarczy np.: while (odczytanaWartosc < prog) { digitalWrite(8, HIGH); //Włączenie diody Serial.println(odczytanaWartosc); delay(50); odczytanaWartosc = analogRead(A5); //Sprawdzamy czy wychodzimy z pętli WHILE prog = analogRead(A4); //Przy okazji można dodać sprawdzenie czy próg nie został zmieniony } digitalWrite(8, LOW); //Wyłączenie diody Same odczyty możesz zrobić w osobnej funkcji np.: void odczyty() { odczytanaWartosc = analogRead(A5); prog = analogRead(A4); } void loop() { odczyty(); // teraz w dowolnym miejscu programu mozesz powolac sie na ta funkcje } Edytowano Kwiecień 16, 2021 przez Shary 1
dastawowy Kwiecień 16, 2021 Udostępnij Kwiecień 16, 2021 (edytowany) @Shary wielkie dzięki za pomoc! coś mi się rozjaśniło Trochę mnie przyblokowało podpatrzenie komendy z fragmentu lekcji nr3, tam był taki szkic: void setup(){ Serial.begin(9600); //Uruchamiamy transmisję pinMode(8, OUTPUT); //Wyjście diody czerwonej pinMode(9, OUTPUT); //Wyjście diody zielonej pinMode(10, INPUT_PULLUP); //Przycisk digitalWrite(8, LOW); //Wyłączenie obu diod digitalWrite(9, LOW); } void loop() { if (digitalRead(10) == LOW) { //Jeśli przycisk jest wciśnięty digitalWrite(9, HIGH); //Włączenie diody zielonej digitalWrite(8, LOW); //Wyłączenie diody czerwonej } else { //Jeśli przycisk nie jest wciśnięty digitalWrite(9, LOW); //Wyłączenie diody zielonej digitalWrite(8, HIGH); //Włączenie diody czerwonej Serial.println("Uwaga! Alarm! Okno nie jest zamkniete!"); while (digitalRead(10) == HIGH) { //Zatrzymujemy się w pustej pętli do ponownego zamknięcia okna delay(25); //W pętli wprowadzamy małe opóźnienie 25ms, aby niwelować zakłócenia } } } Próbowałem zrobić analogie. Myślałem że skoro w powyższej pętli while() program wychodzi z pętli gdy switch przechodzi na stan LOW, to w moim szkicu do zadania 4.4 będzie podobnie, tzn. Wychodzę z pętli gdy odsłaniam rękę (odczytanaWartosc>prog). Rozumiem Twoją propozycję i bardzo dziękuję za nią, ale też pojawia mi się pytanie czemu ten powyższy szkic nie musiał mieć "niczego w środku" pętli while a potrafił przeczytać Warunek do pętli i wyjść z niej gdy switch przeszedł w stan LOW, a ja w swoim zadaniu 4.4 musze wpisać do swojej pętli while linjkę kodu: odczytanaWartosc=analogRead(A5); bo gdy tego nie zrobię zapętlam się w nieskończoność i nie wychodzę z pętli. Edytowano Kwiecień 16, 2021 przez dastawowy
Shary Kwiecień 16, 2021 Udostępnij Kwiecień 16, 2021 (edytowany) dobre pytanie, zwróć uwagę na konstrukcję obu pętli: while (digitalRead(10) == HIGH) // robimy odczyt w warunku, czyli pętla się wykonuję póki D10 ma stan HIGH if (odczytanaWartosc < prog) lub while (odczytanaWartosc < prog) //w obu przypadkach sprawdzamy zmienną (czyli co zawiera zmienna) w pierwszym wariancie dokonujemy bezpośrednio odczytu z D10, w drugim (Twoim dokonujemy odczytu wartości zmiennej (dwóch zmiennych dokładnie). Zmienna, ma to do siebie, że sama nie zmieni wartości. Musisz na niej wykonać operację. Dlatego w Twojej pętli dokonałem odczytu w "środku" pętli, co zmieni wartość samej zmiennej jeśli odczyt ulegnie zmianie. Oczywiście analogicznie możesz zrobić warunek taki: while (analogRead(A5) < analogRead(A4)) I to będzie działać. Jednak z punktu widzenia bardziej skomplikowanych programów, łatwiej jest edytować zmienne niż cały kod. Edytowano Kwiecień 16, 2021 przez Shary 1
dastawowy Kwiecień 20, 2021 Udostępnij Kwiecień 20, 2021 Cześć mam pytanie do zadania 4.5. (gra) jakiej funkcji należy użyć by arduino odczytał zmienne typu int które chcę wprowadzić za pośrednictwem terminala? metodą prób i błędów wiem że: odebraneDane = Serial.readStringUntil('\n'); powyższy kod nie odbierze String i nie przekonwertuje tego na INT (użyłem go w pierwszej kolejności na podstawie wiedzy wyniesionej z lekcji nr 3, ale teraz już wiem że to tak nie działa ) Najbliżej było z: odebraneDane = Serial.parseInt(); jednak tutaj mam problem z tym że gdy wpisze do terminala poprawną liczbę (dioda zapali mi się na zielono) to po chwili i tak zapala mi się na pomarańczowo. Zanim okażę się że mam jakieś błędy w szkicu, chciałbym w ogóle dowiedzieć się czy dobrze kombinuje z tym zadaniem, jeśli chodzi o odbiór danych za pośrednictwem terminala. szkic jest w powijakach więc póki co nie wklejam.. Pozdrawiam
Shary Kwiecień 20, 2021 Udostępnij Kwiecień 20, 2021 (edytowany) Sprawdź pętlą IF czy serial jest aktywny, odczytaj STRING do końca lini, a następni STRING zmień na INT, coś w tej deseń: if(Serial.available() > 0) { odczyt_z_konsoli = Serial.readStringUntil('\n'); liczba = odczyt_z_konsoli.toInt(); } https://www.arduino.cc/reference/pl/language/variables/data-types/string/functions/toint/ Powinno działać. Tu masz dokumentację toInt(); Edytowano Kwiecień 20, 2021 przez Shary 1
dastawowy Kwiecień 22, 2021 Udostępnij Kwiecień 22, 2021 @Shary jesteś wielki! dzięki serdeczne, mała wskazówka a bardzo pomogła. To moja propozycja zadania 4.5 String odczyt = ""; // Liczba którą wysyłam za pośrednictwem terminala int wyslana = 0; // zmienna użyta do konwersji ze String na Int int odczytana = 0; // Liczba którą odczytuję z ADC int szansa = 0; // zmiena do liczenia ile pozostało szans void setup() { Serial.begin(9600); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(10, OUTPUT); pinMode(2, INPUT_PULLUP); digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(10, LOW); } void loop() { if(digitalRead(2)==LOW) { Serial.println("podaj liczbę"); delay(1000); szansa=0; } if(Serial.available() > 0) //czy wpisałem jakas liczbe? { odczyt = Serial.readStringUntil('\n'); //jesli tak to wpisz do zmiennej wyslana = odczyt.toInt(); odczytana = analogRead(A4); if((wyslana >= odczytana - 50) && (wyslana <= odczytana + 50)) // czy moja liczba spelnia oba warunki? { Serial.println("wygrana"); digitalWrite(10, HIGH); delay(1000); digitalWrite(10, LOW); delay(1000); szansa=0; } else if ((wyslana != odczytana) && (szansa <= 2)) //czy moja liczba spełnia warunki? { digitalWrite(9, HIGH); delay(1000); digitalWrite(9, LOW); delay(1000); szansa=szansa+1; } if (szansa >= 3) { Serial.println("przegrana"); digitalWrite(8, HIGH); delay(1000); digitalWrite(8, LOW); delay(1000); Serial.println("zresetuj grę"); } if(szansa==1) { Serial.println("zostały 2 szanse"); } if(szansa==2) { Serial.println("została 1 szansa"); } } } 1
Gwynbleidd Maj 5, 2021 Udostępnij Maj 5, 2021 4.5 #define czerwona 6 #define zolta 7 #define zielona 8 #define przycisk 3 boolean wygrana = false; int odczyt = 0; String traf = ""; int traf1 = 0; int prob = 2; boolean odnowa = false; void setup() { Serial.begin (9600); pinMode(czerwona,OUTPUT); pinMode(zolta, OUTPUT); pinMode(zielona, OUTPUT); pinMode(przycisk, INPUT_PULLUP); } void loop() { if(odnowa == true){ digitalWrite(czerwona, LOW); digitalWrite(zielona, LOW); digitalWrite(zolta, LOW); wygrana = false; prob = 2; } if(digitalRead(przycisk)==LOW){ odczyt = analogRead(A4); Serial.println ("Podaj liczbę:"); delay(200); while(Serial.available()==0){}; if(Serial.available() >0){ traf = Serial.readStringUntil ('\n'); traf1 = traf.toInt(); } if(odczyt - traf1 <= 50 && odczyt - traf1 >= -50){ digitalWrite(zielona, HIGH); odnowa = true; delay(2000); } else { digitalWrite(zolta, HIGH); if(wygrana == false){ while(prob > 0){ Serial.println ("Masz jeszcze: "); Serial.println (prob); Serial.println (" prob"); prob = prob -1; delay(200); while(Serial.available()==0){}; if(Serial.available() >0){ traf = Serial.readStringUntil ('\n'); traf1 = traf.toInt(); if(odczyt - traf1 <= 50 && odczyt - traf1 >= -50){ digitalWrite(zielona, HIGH); digitalWrite(zolta, LOW); wygrana = true; odnowa = true; delay(2000); } } } if(wygrana ==false){ digitalWrite(zolta, LOW); digitalWrite(czerwona, HIGH); odnowa = true; delay(2000); } } } } } 4.6 #define Lzielona 2 #define Lczerwona 3 #define zolta 4 #define Pczerwona 5 #define Pzielona 6 int a =0; int b = 0; void setup() { Serial.begin(9600); pinMode(Lzielona, OUTPUT); pinMode(Lczerwona, OUTPUT); pinMode(zolta, OUTPUT); pinMode(Pczerwona, OUTPUT); pinMode(Pzielona, OUTPUT); } void loop() { digitalWrite(Lzielona, LOW); digitalWrite(Lczerwona, LOW); digitalWrite(zolta, LOW); digitalWrite(Pczerwona, LOW); digitalWrite(Pzielona, LOW); a = analogRead(A5); b = analogRead(A4); a= map(a, 0, 1023, 1, 5); b = map(b, 0, 1023, 1,5); Serial.println(a); Serial.println(b); if(a==b) { digitalWrite(Lzielona, LOW); digitalWrite(Lczerwona, LOW); digitalWrite(zolta, HIGH); digitalWrite(Pczerwona, LOW); digitalWrite(Pzielona, LOW); }else if (a-b >=3) { digitalWrite(Lzielona, HIGH); digitalWrite(Lczerwona, LOW); digitalWrite(zolta, LOW); digitalWrite(Pczerwona, LOW); digitalWrite(Pzielona, LOW); } else if( a-b == 2 || a-b == 1) { digitalWrite(Lzielona, LOW); digitalWrite(Lczerwona, HIGH); digitalWrite(zolta, LOW); digitalWrite(Pczerwona, LOW); digitalWrite(Pzielona, LOW); }else if( b-a >=3) { digitalWrite(Lzielona, LOW); digitalWrite(Lczerwona, LOW); digitalWrite(zolta, LOW); digitalWrite(Pczerwona, LOW); digitalWrite(Pzielona, HIGH); }else if( b-a ==2 || b-a ==1) { digitalWrite(Lzielona, LOW); digitalWrite(Lczerwona, LOW); digitalWrite(zolta, LOW); digitalWrite(Pczerwona, HIGH); digitalWrite(Pzielona, LOW); } delay(100); } Może niezbyt optymalne rozwiązania, ale działają 2
Gieneq Maj 6, 2021 Udostępnij Maj 6, 2021 @Gwynbleidd Dobrze, że próbujesz swoich sił w zadaniach domowych Powodzenia w kolejnych zadaniach! 1
StefanekP Czerwiec 12, 2021 Udostępnij Czerwiec 12, 2021 A da się jakoś zamienić zmienną typu string na int?
Gieneq Czerwiec 14, 2021 Udostępnij Czerwiec 14, 2021 @StefanekP sprawa jest dość prosta, funkcja toInt(), która zwróci typ long. Funkcja jest doczepiona do klasy String wiec użycie wygląda pewnie tak: long liczba = napis.toInt(); Funkcja jest wraperem funkcji atol. // /*********************************************/ // /* Parsing / Conversion */ // /*********************************************/ long String::toInt(void) const { if (buffer()) return atol(buffer()); return 0; } Jej działanie widocznie bazuje na metodzie Hornera: liczba += znak * 10; 2
StefanekP Czerwiec 17, 2021 Udostępnij Czerwiec 17, 2021 Moje rozwiązania do zadań domowych: 4.5: #define zolta 8 #define czerwona 9 #define zielona 10 #define przycisk 11 String odebraneDane=""; int napiecePotencjometru=0; int lProb=3; boolean zaczetoGre=false; boolean wyslanoKomunikat=false; void setup() { // put your setup code here, to run once: pinMode(8,OUTPUT); pinMode(9,OUTPUT); pinMode(10,OUTPUT); pinMode(11,INPUT_PULLUP); Serial.begin(9600); digitalWrite(zielona,LOW); digitalWrite(czerwona,LOW); digitalWrite(zolta,LOW); } void loop() { // put your main code here, to run repeatedly: if (zaczetoGre==false){ if (digitalRead(przycisk)==LOW){ zaczetoGre=true; //if (wyslanoKomunikat=false){ Serial.println("Podaj liczbę"); wyslanoKomunikat=true; } } else{ napiecePotencjometru=analogRead(A5); if (Serial.available()>0){ odebraneDane=Serial.readStringUntil("\n"); long odebranaWartosc=odebraneDane.toInt(); if (odebranaWartosc<napiecePotencjometru+50){ if (odebranaWartosc>napiecePotencjometru-50){ digitalWrite(zielona,HIGH); digitalWrite(czerwona,LOW); digitalWrite(zolta,LOW); zaczetoGre=false; } else{ digitalWrite(zolta,HIGH); digitalWrite(zielona,LOW); digitalWrite(czerwona,LOW); lprob=lprob-1; Serial.println("Spróbuj jeszcze raz."); } } else{ Serial.println("Spróbuj jeszcze raz"); lprob=lprob-1; digitalWrite(zolta,HIGH); digitalWrite(zielona,LOW); digitalWrite(czerwona,LOW); } if (lprob==0){ digitalWrite(zolta,LOW); digitalWrite(zielona,LOW); digitalWrite(czerwona,HIGH); zaczetoGre=false; } } } } 4.6: #define srodkowa 9 //dioda środkowa #define lewaZolta 8 //dioda znajdująca się po lewej, bliżej środka #define prawaZolta 10 //dioda znajdująca się po prawej, bliżej środka #define lewaCzerwona 7 //dioda znajdująca się po lewej, dalej od środka #define prawaCzerwona 11//dioda, znajdująca się po prawej, dalej od środka int napieceLewegoDzielnika=0; int napiecePrawegoDzielnika=0; boolean wyslanoDane=false; void setup() { // put your setup code here, to run once: pinMode(9,OUTPUT); pinMode(8,OUTPUT); pinMode(10,OUTPUT); pinMode(7,OUTPUT); pinMode(11,OUTPUT); digitalWrite(9,LOW); digitalWrite(8,LOW); digitalWrite(10,LOW); digitalWrite(7,LOW); digitalWrite(11,LOW); Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: napieceLewegoDzielnika=analogRead(A4); napiecePrawegoDzielnika=analogRead(A5); if (wyslanoDane==false){ Serial.println(napieceLewegoDzielnika); Serial.println(napiecePrawegoDzielnika); wyslanoDane=true; } if (napieceLewegoDzielnika>napiecePrawegoDzielnika){ if (napieceLewegoDzielnika-napiecePrawegoDzielnika<5){ digitalWrite(srodkowa,HIGH); digitalWrite(lewaZolta,LOW); digitalWrite(prawaZolta,LOW); digitalWrite(prawaCzerwona,LOW); digitalWrite(lewaCzerwona,LOW); } else if (napieceLewegoDzielnika-napiecePrawegoDzielnika<=15){ digitalWrite(srodkowa,LOW); digitalWrite(lewaZolta,HIGH); digitalWrite(prawaZolta,LOW); digitalWrite(prawaCzerwona,LOW); digitalWrite(lewaCzerwona,LOW); } else if (napieceLewegoDzielnika-napiecePrawegoDzielnika>15){ digitalWrite(srodkowa,LOW); digitalWrite(lewaZolta,LOW); digitalWrite(prawaZolta,LOW); digitalWrite(prawaCzerwona,LOW); digitalWrite(lewaCzerwona,HIGH); } } else if (napieceLewegoDzielnika==napiecePrawegoDzielnika){ digitalWrite(srodkowa,HIGH); digitalWrite(lewaZolta,LOW); digitalWrite(prawaZolta,LOW); digitalWrite(prawaCzerwona,LOW); digitalWrite(lewaCzerwona,LOW); } else if (napiecePrawegoDzielnika>napieceLewegoDzielnika){ if (napiecePrawegoDzielnika-napieceLewegoDzielnika<5){ digitalWrite(srodkowa,HIGH); digitalWrite(lewaZolta,LOW); digitalWrite(prawaZolta,LOW); digitalWrite(prawaCzerwona,LOW); digitalWrite(lewaCzerwona,LOW); } else if (napiecePrawegoDzielnika-napieceLewegoDzielnika<=15){ digitalWrite(srodkowa,LOW); digitalWrite(lewaZolta,LOW); digitalWrite(prawaZolta,HIGH); digitalWrite(prawaCzerwona,LOW); digitalWrite(lewaCzerwona,LOW); } else if (napiecePrawegoDzielnika-napieceLewegoDzielnika>15){ digitalWrite(srodkowa,LOW); digitalWrite(lewaZolta,LOW); digitalWrite(prawaZolta,LOW); digitalWrite(prawaCzerwona,HIGH); digitalWrite(lewaCzerwona,LOW); } } } 1
Gieneq Czerwiec 18, 2021 Udostępnij Czerwiec 18, 2021 @StefanekP super że robisz dodatkowe zadania Kody wyglądają porządnie, zwłaszcza logika w pierwszym dobrze wygląda. Tylko polecam Ci zapoznać się z autoformatem w Arduino IDE, w menu znajdziesz. Zdecydowanie poprawia czytelność. Wiem, że w kursie nie ma nic o tablicach ale możesz w ramach ciekawostki poczytać ten artykuł i uprościć warunki przy pomocy tablicy i funkcji map
Pomocna odpowiedź
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ę »