Olo_1994 Napisano Maj 20, 2019 Udostępnij Napisano Maj 20, 2019 Witam, Natknąłem się problem z odpowiednim wykonywaniem warunków w funkcji SwitchCase. w poniższym kodzie program nie chce wejść w case 2, oraz case 3. void sensorTypeUpDate () { switch (actualSensor) { case 1: Serial.print("wszedl w 1 petle"); int odczyt = analogRead(lightSensor); light = map(odczyt, 0, 1023, 0, 100); sensorType = "Jasnosc:"; sensorValue = String(light) + "%"; break; case 2: Serial.print("wszedl w 2 petle"); humidity = dht.getHumidity(); if (dht.getStatusString() == "OK") { sensorType = "Wilgotnosc:"; sensorValue = String(humidity) + "RH%"; } break; case 3: Serial.print("wszedl w 3 petle"); temperature = dht.getTemperature(); if (dht.getStatusString() == "OK") { sensorType = "Temperatura:"; sensorValue = String(temperature) + "*C"; } break; } } Linia Serial.print potrzebna mi była do sprawdzenia czy program wchodzi w dany warunek. O dziwo gdy zmienię kolejność warunków program działa poprawnie. Nie jest to pierwszy raz, jak się z tym spotykam. Poniższy kod działa. void sensorTypeUpDate () { switch (actualSensor) { case 3: Serial.print("wszedl w 3 petle"); temperature = dht.getTemperature(); if (dht.getStatusString() == "OK") { sensorType = "Temperatura:"; sensorValue = String(temperature) + "*C"; } break; case 2: Serial.print("wszedl w 2 petle"); humidity = dht.getHumidity(); if (dht.getStatusString() == "OK") { sensorType = "Wilgotnosc:"; sensorValue = String(humidity) + "RH%"; } break; case 1: Serial.print("wszedl w 1 petle"); int odczyt = analogRead(lightSensor); light = map(odczyt, 0, 1023, 0, 100); sensorType = "Jasnosc:"; sensorValue = String(light) + "%"; break; } } Z góry dziękuje za pomoc. Link do komentarza Share on other sites More sharing options...
Treker (Damian Szymański) Maj 20, 2019 Udostępnij Maj 20, 2019 @Olo_1994, jakiego typu jest zmienna "actualSensor"? Jakie wartości się w niej znajdują? Może tylko "wydaje Ci się", że jest tam 1/2/3? Link do komentarza Share on other sites More sharing options...
Olo_1994 Maj 20, 2019 Autor tematu Udostępnij Maj 20, 2019 actualSensor jest zmienną typu int. Wartości jakie może przyjąć to 1 lub 2 lub 3. I te wartości przyjmuje. Sprawdzałem to poprzez podglądanie ich monitorze portu szeregowego. Poza tym gdyby zmienna actualSensor nie przyjmowała wartości 1 lub 2 lub 3. To zmiana kolejności warunków w instrukcji Switch nie powinna mieć żadnego wpływu na działanie programu. A mimo to w przypadku drugiego kodu program działa poprawnie. Link do komentarza Share on other sites More sharing options...
ethanak Maj 20, 2019 Udostępnij Maj 20, 2019 przede wszystkim użyj Serial.println a nie Serial.print - wtedy masz pewność że Ci się wszystko wyświetli. Jak zmienisz i dalej będzie źle to przed switchem wrzuć println z wartością. Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
Olo_1994 Maj 20, 2019 Autor tematu Udostępnij Maj 20, 2019 @ethanak Zrobiłem tak jak mówiłeś, gdy actualSensor ma wartość 1 program wykonuje pierwszy się warunek (case 1). Niestety gdy actualSensor przyjmuje wartość 2 (sprawdzam jego wartość przed instrukcją switch), to już nie chce wejść w drugi warunek. To samo w przypadku gdy actualSensor przyjmuje wartość 3. Zastanawia mnie tylko czemu po zmienieniu kolejności warunków, program zaczyna działać poprawnie. Link do komentarza Share on other sites More sharing options...
ethanak Maj 20, 2019 Udostępnij Maj 20, 2019 trochę to dziwne... dodaj klauzulę default i wypisz w niej cokolwiek ważmego (np. wartość actualSensor). Nie znam reszty programu, ale ja bym zakomentował wszystko w case oprócz printa i breaka i zobaczył, kiedy zaczną się jaja. Link do komentarza Share on other sites More sharing options...
Olo_1994 Maj 20, 2019 Autor tematu Udostępnij Maj 20, 2019 Faktycznie zrobiłem tak jak mówiłeś i udało mi się znaleźć linie która wysypywała mi program int odczyt = analogRead(lightSensor); Co ciekawe w przypadku gdy zmienna "actualSensor" przyjmuje wartość 2 lub 3, program nie wchodzi warunek 2, 3, a nawet w warunek domyślny. Mimo że linia, która wysypuje program teoretycznie powinna go wysypywać dla actualSensor == 1, a wysypuje go dla pozostałych warunków. Chyba że warunki 2 i 3 umieścimy w kodzie programu przed warunkiem 1. Co jeszcze ciekawsze po rozbiciu wyżej podanej linii na dwie: int odczyt; odczyt = analogRead(lightSensor); Wszystko zaczyna działać poprawnie, mimo że oba zapisy są poprawne. Link do komentarza Share on other sites More sharing options...
ethanak Maj 20, 2019 Udostępnij Maj 20, 2019 poczytaj sobie o zakresach zmiennych. ogólnie c++ jest fajny bo pozwala na mieszanie deklaracji i instrukcji, ale co się wtedy dzieje na stosie to materiał na sprawę dla Sherlocka Holmesa (szczególnie przy siłowej optymalizacji wymuszanej przez Arduino IDE). ogólnie w bloku switch nie powinno się tworzyć nowych zmiennych - przepraszam, ale czytam to na komórce i po prostu nie zauważyłem 😞 1 Link do komentarza Share on other sites More sharing options...
Belferek Maj 20, 2019 Udostępnij Maj 20, 2019 Pokaż fragment gdzie actualSensor przyjmuje wartość. Pokazałeś wiele kodu ale nie to. Pokaż jak wywołujesz tę funkcję ze switch. Bez tego trudno cokolwiek powiedzieć. Link do komentarza Share on other sites More sharing options...
Olo_1994 Maj 20, 2019 Autor tematu Udostępnij Maj 20, 2019 #include "DHT.h" #include <LiquidCrystal.h> #define DHT11_PIN 2 #define lightSensor A5 #define button 7 #define redLight 6 #define greeLight 5 DHT dht; LiquidCrystal lcd(8, 9, 10, 11, 12, 13); int actualSensor = 1; //aktualnie wyświetlany sensor String sensorType; String sensorValue; //int odczyt; float light = 0; //używane sensory float humidity = 0; float temperature = 0; volatile int sensorQuantity = 3; //ilość sensorów unsigned long screenRefreshDelay = 500; //co ile milisekund ma być odświeżony ekran unsigned long screenRefreshDelayMillis = 0; //wartość pomocnicza unsigned long sensorChangeDelay = 5000; //co ile milisekund ma być zmienony aktualnie wyświetlany sensor unsigned long sensorChangeDelayMillis = 0; //wartość pomocnicza bool automaticSensorChange = true; void setup() { Serial.begin(9600); dht.setup(DHT11_PIN); pinMode(button, INPUT_PULLUP); lcd.begin(16, 2); } void loop() { sensorTypeUpDate(); screenRefreshsss(); if (automaticSensorChange == true) sensorChangeByTime(); sensorChangeByButton(); } void sensorChangeByTime () { if (millis() - sensorChangeDelayMillis > sensorChangeDelay) { sensorChangeDelayMillis = millis(); changeSensor(); lcd.clear(); } } void sensorChangeByButton () { if (digitalRead(button) == LOW) { changeSensor(); unsigned long autamaticSensorChangeDelay = millis(); bool automaticSensorChangeDone = false; while (digitalRead(button) == LOW) { if (millis() - autamaticSensorChangeDelay > 2000 && automaticSensorChangeDone == false) { automaticSensorChange = !automaticSensorChange; automaticSensorChangeDone = true; } } sensorChangeDelayMillis = millis(); lcd.clear(); } } void changeSensor () { actualSensor++; if (actualSensor > sensorQuantity) actualSensor = 1; } void sensorTypeUpDate() { Serial.println(actualSensor); switch (actualSensor) { case 1: Serial.println("wszedl w 1 petle"); int odczyt; odczyt = analogRead(A0); light = map(odczyt, 0, 1023, 0, 100); sensorType = "Jasnosc:"; sensorValue = String(light) + "%"; break; case 2: Serial.println("wszedl w 2 petle"); humidity = dht.getHumidity(); if (dht.getStatusString() == "OK") { sensorType = "Wilgotnosc:"; sensorValue = String(humidity) + "RH%"; } break; case 3: Serial.println("wszedl w 3 petle"); temperature = dht.getTemperature(); if (dht.getStatusString() == "OK") { sensorType = "Temperatura:"; sensorValue = String(temperature) + "*C"; } break; } } void screenRefreshsss () { if (millis() - screenRefreshDelayMillis > screenRefreshDelay) { screenRefreshDelayMillis = millis(); lcd.setCursor(0, 0); lcd.print(sensorType); lcd.setCursor(0, 1); lcd.print(sensorValue); } } Funkcja sensorTypeUpDate wywoływana jest w pętli głównej programu. Natomiast zmienna actualSensor, zmienia się po wciśnieciu przycisku lub po upływie 5 sekund. Zmianę po upływie czasu można wyłączyć przytrzymując przycisk przez ponad 2 sekundy. Link do komentarza Share on other sites More sharing options...
Belferek Maj 20, 2019 Udostępnij Maj 20, 2019 5 godzin temu, Olo_1994 napisał: Serial.println(actualSensor); No i co Ci wyświetla ta linijka w sensorTypeUpDate()? Tak na marginesie to do funkcji można przekazywać parametry - nigdzie tego nie stosujesz. Link do komentarza Share on other sites More sharing options...
Olo_1994 Maj 21, 2019 Autor tematu Udostępnij Maj 21, 2019 Przez 5 sekund wyświetla "1", przez kolejne 5 sekund "2", przez kolejne 5 sekund "3" i tak w pętli. Link do komentarza Share on other sites More sharing options...
Zealota Maj 21, 2019 Udostępnij Maj 21, 2019 21 godzin temu, Olo_1994 napisał: int odczyt; odczyt = analogRead(lightSensor); Wszystko zaczyna działać poprawnie, mimo że oba zapisy są poprawne. Warto doczytać o tym problemie tutaj: http://cpp0x.pl/kursy/Kurs-C++/Poziom-1/Warunek-wielokrotnego-wyboru-switch-case/17 W akapicie: "Tworzenie zmiennych wewnątrz switch'a" jest dokładnie opisane jak korzystać w takim wypadku z case. Ten problem powinien wyłapać kompilator, ale być może masz "zbyt luźno" skonfigurowany. 1 Link do komentarza Share on other sites More sharing options...
Olo_1994 Maj 21, 2019 Autor tematu Udostępnij Maj 21, 2019 @Zealota Dzięki wielkie. Link rozwiewa wszelkie wątpliwości. Link do komentarza Share on other sites More sharing options...
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ę »