bakardi92 Napisano Marzec 3, 2020 Udostępnij Napisano Marzec 3, 2020 Witajcie, Mam do zrobienia projekt, w którym potrzebuje rozszeżyć swoją wiedzę o wiele nowych aspektów z którymi daję radę, ale jeżeli chodzi o aspekt budowy MENU kompletnie sobie z tym nie radzę.Menu ma wyglądać +- tak jak poniżej, będzie one jeszcz bardziej rozbudowane ale teraz głownie zależy mi na tym aby poznać sposób jak zbudować menu i jak później się po nim poruszać, jak cofnąć się do poprzedniej opcji, jak wybrać opcję itp... Wybierz średnicę: 75 80 100 125 (po wybraniu w/w opcji kolejne powinny pojawić się kolejne opcję) Wybierz teraz prędkość: 1 2 3 4 5 6 (po wybraniu w/w opcji kolejne powinny pojawić się kolejne opcję) czas pracy 1 2 3 4 5 6 (po wybraniu w/w opcji kolejne powinny pojawić się kolejne opcję) czas stopu: 1 2 3(po wybraniu w/w opcji kolejne powinny pojawić się kolejne opcję) czas pracy 1 2 3 4 5 6 (po wybraniu w/w opcji kolejne powinny pojawić się kolejne opcję) Wybierz teraz ile razy ma być powtarzane: 1 2 3 Itd. Do 300 Czy jsteś gotowy na start tak/nie I teraz po wybraniu tych opcji powinien włączyć się program włączający silnik. Tą część programu już sam ogarnę ale z tym menu walczę już kilka dni i dalej nic.. Znalazłem fajny artykuł tutaj https://www.obliczeniowo.com.pl/976 ale niczego nowego on nie wniósł do mojego życia. Patrzyłem sporo tutoriali po polsku i angielsku ale widzę że jest to baaardzo trudne. Początkowo menu miało być obsługiwane przez enkoder ale to jeszcze bardziej skomplikuje temat, dlatego zostanę przy zwykłych przyciskach. Mógłbym to zrobić na serial monitorze ale program docelowo ma być obsługiwany bez komputera, stąd mikrokontroler i LCD. Gdybym mógł tam włożyć komputer nie byłoby problemu.
SOYER Marzec 3, 2020 Udostępnij Marzec 3, 2020 Cześć, takie menu to w miarę prosta sprawa, tylko kupa pisania. Użyj do tego funkcji switch case. Każdy osobny "ekran" musisz sobie rozpisać osobno, najlepiej do jakiejś funkcji i przypisać do kolejnych case-ów. W tych poszczególnych case-ach, wyświetlasz dany ekran i piszesz funkcje reagujące na przyciski i przenoszące program do pożądanego, kolejnego casa-a, kolejnego ekranu. Np. funkcja switch w podmenu pieca C.O. switch(pozycja_markera){ case 1: tempPiec_1(); wait_and_checkButton_tempPiec(); break; case 2: tempPiec_2(); wait_and_checkButton_tempPiec(); break; case 3: tempPiec_3(); wait_and_checkButton_tempPiec(); break; case 4: tempPiec_4(); wait_and_checkButton_tempPiec(); break; case 5: tempPiec_5(); wait_and_checkButton_tempPiec(); break; case 6: tempPiec_6(); wait_and_checkButton_tempPiec(); break; } funkcje tempPiec() topo prostu ekrany: void tempPiec_1(){ lcd.setCursor(0,0); lcd.print("<< Temp. Piec >>"); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,2); lcd.print(">Temp. min: "); lcd.print(temp_piec_min); lcd.print(" *C"); lcd.setCursor(0,3); lcd.print(" Data min.:"); lcd.print(dzien_temp_piec_min, DEC); lcd.print(":"); lcd.print(miesiac_temp_piec_min, DEC); lcd.print(":"); lcd.print(rok_temp_piec_min,DEC); } void tempPiec_2(){ lcd.setCursor(0,0); lcd.print("<< Temp.Piec >>"); lcd.setCursor(0,1); lcd.print(" Temp. min: "); lcd.print(temp_piec_min); lcd.print(" *C"); lcd.setCursor(0,2); lcd.print(">Data min.:"); lcd.print(dzien_temp_piec_min, DEC); lcd.print(":"); lcd.print(miesiac_temp_piec_min, DEC); lcd.print(":"); lcd.print(rok_temp_piec_min,DEC); lcd.setCursor(0,3); lcd.print(" Temp. max.: "); lcd.print(temp_piec_max); lcd.print(" *C"); } void tempPiec_3(){ lcd.setCursor(0,0); lcd.print("<< Temp.Piec >>"); lcd.setCursor(0,1); lcd.print(" Data min."); lcd.print(dzien_temp_piec_min, DEC); lcd.print(":"); lcd.print(miesiac_temp_piec_min, DEC); lcd.print(":"); lcd.print(rok_temp_piec_min,DEC); lcd.setCursor(0,2); lcd.print(">Temp. max.: "); lcd.print(temp_piec_max); lcd.print(" *C"); lcd.setCursor(0,3); lcd.print(" Data max.:"); lcd.print(dzien_temp_piec_max, DEC); lcd.print(":"); lcd.print(miesiac_temp_piec_max, DEC); lcd.print(":"); lcd.print(rok_temp_piec_max,DEC); } Przy jednej z pozycji ekranu jest znak ">" który wskazuje nam do której pozycji menu odniesiemy się po kliknięciu przycisku. Natomiast funkcja wait_and_checkButton_tempPiec(); czeka określoną ilość czasu i wykonuje coś tam, co chcemy po naciśnięciu przycisków. Dla każdego podmenu robisz osobną funkcję z osobnym switch-em, a w czasie przesuwania się po pozycjach menu, odpowiednio przeskakujesz albo wewnątrz jednej funkcji po case-ach switcha, albo pomiędzy różnymi funkcjami, switchami... Jak coś to pytaj... Może ktoś zna prostszy sposób, bo to kupa pisania tych ekranów.... 1 1
bakardi92 Marzec 3, 2020 Autor tematu Udostępnij Marzec 3, 2020 (edytowany) Hmmm, bardzo bardzo sprytnie!! W programowaniu najbardziej podoba mi się że każdy problem można rozwiązać na 100 sposobów. Zawsze kiedy nie mogę czegoś rozwiązać myślę sobie że tego nie da się zrobić, a później widzę gotowy program który rozwiązuje mój problem używając zwykłuch funkcji i jest to czasami aż tak proste że nigdy bym tego nie wymyślił. Co do mojego przypadku miałbym do zrobienia jakieś 500 różnych funkcji do napisania jeżeli chciałbym zrobić to tak jak powinienem, a to byłoby baaardzo czasochłonne, wprowadzanie kolejnych zmian byłoby bardzo uciążliwę. Czy ewentualnie ktoś jeszcze z was rozwiązał problem menu w bardzie zautomatyzowany sposób, bardziej klarowny? Widzę w internecie że jest pełno bibliotek które tworzą menu ale nie mogę nigdzie znaleźć takiego prostego step by step jak to zrobić. @SOYER w wolnej chwili na 100% spróbuje napisać program na twoim przykładzie, chcę zobaczyć jak to wyjdzie w rzeczywistości i jak będzie okej, a nie uda mi się znaleźć innego pomysłu, to zapewne zostanę przy tym. Czy ewentualnie mogę liczyć na Twoją pomoc w trakcie moich prób i błędów? Postaram się za to zabrać jak najszybciej, ale ciężko pogodzić prace dom rodzinę i do tego programowanie które zajmuje bardzo dużo czasu. W ogóle nie dodałem ale program będzie wykonywał pracę silnikiem korzystając z funkcji millis() która nie blokuje całego programu, a czasami będzie potrzeba przerwania pracy silnika w trakcie jego ruchu Pozdrawiam Edytowano Marzec 3, 2020 przez bakardi92
SOYER Marzec 3, 2020 Udostępnij Marzec 3, 2020 (edytowany) Możesz napisać co to za projekt, który będzie miał 500 funkcji? Pamiętaj, że jeśli jakieś ekrany się powtarzają dla różnych opcji, to nie trzeba pisać tego samego kilka razy... W Twoim menu chyba tylko "wybierz średnicę" jest unikalne, a reszta jest identyczna dla wszystkich średnic... Podobnie, chyba nie będziesz robił przewijanego menu do 300, w menu ilości powtórek.... Zresztą w takim menu aż się prosi o wykorzystanie klawiatury numerycznej. Wtedy i menu i kod to bułka z masłem. Edytowano Marzec 3, 2020 przez SOYER 1
bakardi92 Marzec 3, 2020 Autor tematu Udostępnij Marzec 3, 2020 (edytowany) Opisując z grubsza tak wygląda tabela (załącznik) każda kolumna to menu np 1 kolumna średnica koła, druga kolumna prędkość koła, czas pracy silnika itd. Każdy wiersz to odpowiednia wartość która będzie się znajdowała w menu. Czyli wybierająć średnicę np 200 będziemy mieć do wyboru zakres 2 prędkości 3km/h i 4 km/h (patrz tabela), po wybraninu prędkości wybieramy czas pracy silnika (tutaj będzie 3minuty z tego co widzę, ale ten czas będzie ustawiany już indywidualnie, czyli jakaś prosta zmienna która po naciśnięciu guzika zwiększa się o 1) itd. Tak jak widzisz powiązań jest dużo stąd moja zagwozdka jak to zrobić. Chciałem jeszcze na sam koniec jak już się wszystko wybierze mieć podgląd które opcję zostały wybrane. Ale jak będzie zbyt trudno to usunę niepotrzebne dane i zostawie tylke te które MUSZĄ zostać i nie będzie żadnego podglądu opcji itp.. Póki co troche mnie to przerosło, ale zobaczymy co czas pokaże. Klawiatura to dobry pomysł a gdybym zrezygnował z przycisków które mam to akurat byłoby 8 wejść więc klawiatura by weszła idealnie. Razem z klawiaturą chodzą mi po głowie troche inne pomysły bez tworzenia menu. Screen 1 wybierz srednice i wpisujesz średnicę ---> screen 2 wpisz predkosc ----> screen 3 wpisz czas pacy ----> itp itd. Każdą wartość zapisać w zmiennej i na koniec wszystkie zmienne można ładnie wyświetlić. Musze o tym pomyśleć! niemniej jednak dalej chcę się nauczyć tworzenia menu które może się jeszcz przydać. Edytowano Marzec 3, 2020 przez bakardi92
bakardi92 Marzec 13, 2020 Autor tematu Udostępnij Marzec 13, 2020 Więc tak udało mi się zrobić menu, a konkretnie kolejne screeny do wpisywania danych.Zobaczcie filmik. Koło kręci się raz w lewo raz w prawo. Czas kręcenia i stopu oczywiście ustala się na screenie. https://photos.app.goo.gl/bzjzZkpdUYvF5qov7 Mam ostatnie pytanie, czy macie pomysł jak zrealizować kręcenie kołem poprzez funkcję millis() a nie delay jak mam teraz? Delay blokuje mi kontroler na amen a millis pod tym względem byłby idealny. Oczywiście dodaję kod źródłowy, może komuś się przyda do budowy własnego menu. Całość postawiona na switch caseach. Kod jest dość nieczytelny a to dlatego że jak go pisałem to miałem sporo pomysłów do sprawdzenia, a jak chciałem zrobić go bardziej przejrzystego to już było za późno... #include <Keypad.h> #include <LiquidCrystal_I2C.h> #include <DHT.h> LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); DHT dht; const byte ROWS = 4; const byte COLS = 4; byte rowPins[ROWS] = {5, 4, 3, 2}; byte colPins[COLS] = {6, 7, 8, 9}; char keys[ROWS][COLS] = { {'.', '7', '4', '1'}, {'0', '8', '5', '2'}, {'#', '9', '6', '3'}, {'D', 'C', 'B', 'A'}}; Keypad klawiatura = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); unsigned long saveTime = 0; unsigned long currentTime = 0; // motor steering #define in2 13 #define in1 12 #define ena 11 int A = 0; //glowny switch w petli loop int B=1; //sterowanie silnikami int count=1; bool lock = 1; bool lock1=0; String string1 = String(); String string2 = String(); String string3 = String(); String string4 = String(); String string5 = String(); String string6 = String(); String string7 = String(); byte diameter = 0; float speedd = 0; byte runn = 0; byte stop1 = 0; byte reverse = 0; byte stop2 = 0; byte repeat = 0; int timee = 0; int speedd2 = 0; void setup() { Serial.begin(9600); Serial.println("It's working"); lcd.begin(16, 2); lcd.backlight(); dht.setup(10); pinMode(ena, OUTPUT); //MOTOR STEERING - PWM pinMode(in1, OUTPUT); //MOTOR STEERING - LEFT/RIGHT pinMode(in2, OUTPUT); //MOTOR STEERING - LEFT/RIGHT } void loop() { Serial.print("main loop"); char klawisz = klawiatura.getKey(); float temperature = ((analogRead(A0) * 5.0) / 1024.0) * 100; int wilgotnosc = dht.getHumidity(); int temperatura = dht.getTemperature(); switch (A) { case 0: if (lock == 1) { lcd.clear(); lcd.home(); lock = 0; lcd.print("COLSON CASTORS"); lcd.setCursor(0, 1); lcd.print("BY KEN & MARCIN"); } if (klawisz == 'A') { A++; } break; case 1: if (lock == 0) { lock = 1; lcd.clear(); lcd.print("DHT11"); lcd.setCursor(0, 1); lcd.print(temperature); //LM35 lcd.print((char)223); //LM35 lcd.print("C"); //LM35 lcd.setCursor(0, 1); lcd.print(temperature);//lm35 lcd.print((char)223); lcd.print("C"); lcd.setCursor(6, 0); lcd.print(temperatura);//dht11 lcd.print(char(223)); lcd.print("C"); lcd.setCursor(11, 0); lcd.print(wilgotnosc); lcd.print("%RH"); lcd.setCursor(9,1); lcd.print("PWM:"); lcd.print(speedd2); } /* if (dht.getStatusString() == "OK") // ta opcja tez dziala ale jest bez odswiezania 2 sekund jak poizej { saveTime = millis(); lcd.setCursor(6, 0); lcd.print(temperatura); lcd.print(char(223)); lcd.print("C"); lcd.setCursor(11, 0); lcd.print(wilgotnosc); lcd.print("%RH"); lcd.setCursor(0, 1); lcd.print(temperature);//lm35 lcd.print((char)223); lcd.print("C"); }*/ if (dht.getStatusString() == "OK" && millis() - saveTime >= 2000UL) // jesli minely 2 sekundy i dht jest gotowy to wysyla wynik { saveTime = millis(); lcd.setCursor(0, 1); lcd.print(temperature);//lm35 lcd.print((char)223); lcd.print("C"); lcd.setCursor(6, 0); lcd.print(temperatura);//dht11 lcd.print(char(223)); lcd.print("C"); lcd.setCursor(11, 0); lcd.print(wilgotnosc); lcd.print("%RH"); } if (klawisz == 'A') { A++; } break; case 2: if (lock == 1) { lcd.clear(); lcd.home(); lcd.print("WHEEL (diameter)"); lcd.setCursor(0, 1); lock = 0; if (diameter != 0){ lcd.print(diameter); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra1 = String(klawisz); string1.concat(cyfra1); diameter = string1.toInt(); } if (klawisz=='C'){ lcd.clear(); lcd.print("WHEEL (diameter)"); diameter=0; string1=""; lcd.setCursor(0, 1); } if (klawisz == 'A') { A++; } if (klawisz == 'B') { ; A--; } break; case 3: if (lock == 0) { lcd.clear(); lcd.home(); lock = 1; lcd.print("SPEED (km/h)"); lcd.setCursor(0, 1); if (speedd != 0){ lcd.print(speedd); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra2 = String(klawisz); string2.concat(cyfra2); speedd = string2.toFloat(); speedd2=map(speedd,1,6,65,255); } if (klawisz=='C'){ lcd.clear(); lcd.print("SPEED (km/h)"); speedd2=0; speedd=0; string2=""; lcd.setCursor(0, 1); } analogWrite(ena,speedd2); if (klawisz == 'A') { A++; } if (klawisz == 'B') { ; A--; } break; case 4: if (lock == 1) { lcd.clear(); lcd.home(); lock = 0; lcd.print("RUN (min)"); lcd.setCursor(0, 1); if (runn != 0){ lcd.print(runn); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra3 = String(klawisz); string3.concat(cyfra3); runn = string3.toInt(); } if (klawisz=='C'){ lcd.clear(); lcd.print("RUN (min)"); runn=0; string3=""; lcd.setCursor(0, 1); } if (klawisz == 'A') { A++; } if (klawisz == 'B') { A--; } break; case 5: if (lock == 0) { lcd.clear(); lcd.home(); lock = 1; lcd.print("STOP (min)"); lcd.setCursor(0, 1); if(stop1 != 0){ lcd.print(stop1); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra4 = String(klawisz); string4.concat(cyfra4); stop1 = string4.toInt(); } if (klawisz=='C'){ lcd.clear(); lcd.print("STOP (min)"); stop1=0; string4=""; lcd.setCursor(0, 1); } if (klawisz == 'A') { stop1 = string4.toInt(); A++; } if (klawisz == 'B') { A--; } break; case 6: if (lock == 1) { lcd.clear(); lcd.home(); lcd.print("REVERSE (min)"); lcd.setCursor(0, 1); lock = 0; if (reverse != 0){ lcd.print(reverse); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra5 = String(klawisz); string5.concat(cyfra5); reverse = string5.toInt(); } if (klawisz=='C'){ lcd.clear(); lcd.print("REVERSE (min)"); reverse=0; string5=""; lcd.setCursor(0, 1); } if (klawisz == 'A') { reverse = string5.toInt(); A++; } if (klawisz == 'B') { A--; } break; case 7: if (lock == 0) { lcd.clear(); lcd.home(); lock = 1; lcd.print("STOP (min)"); lcd.setCursor(0, 1); if (stop2 != 0){ lcd.print(stop2); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra6 = String(klawisz); string6.concat(cyfra6); stop2 = string6.toInt(); } if (klawisz=='C'){ lcd.clear(); lcd.print("STOP (min)"); stop2=0; string6=""; lcd.setCursor(0, 1); } if (klawisz == 'A') { stop2 = string6.toInt(); A++; } if (klawisz == 'B') { A--; } break; case 8: if (lock == 1) { lcd.clear(); lcd.home(); lcd.print("REPEAT"); lcd.setCursor(0, 1); lock = 0; if (repeat != 0){ lcd.print(repeat); } lcd.setCursor(0, 1); } if (klawisz && klawisz != 'A' && klawisz != 'B' && klawisz != 'C' && klawisz != 'D' && klawisz != '#' && klawisz != '*') { lcd.print(klawisz); String cyfra7 = String(klawisz); string7.concat(cyfra7); repeat = string7.toInt(); } if (klawisz=='C'){ lcd.clear(); lcd.print("REPEAT"); repeat=0; string7=""; lcd.setCursor(0, 1); } if (klawisz == 'A') { repeat = string7.toInt(); A++; } if (klawisz == 'B') { A--; } break; case 9: timee = (runn + stop1 + reverse + stop2) * repeat; if (lock == 0) { lcd.clear(); lcd.home(); lock = 1; lcd.print("TIME (min)"); lcd.setCursor(0, 1); lcd.print(timee); lcd.print(" minutes"); } if (klawisz == 'A') { A++; } if (klawisz == 'B') { A--; } break; case 10: if (lock == 1) { lock = 0; lcd.clear(); lcd.home(); lcd.print("PRESS D TO START"); } // TERAZ JAK JUŻ MAMY WPISANE WARTOŚCI RUN STOP REVERSE STOP MUSZĘ ZROBIĆ // STEROWANIE SILNIKAMI W ODNIESIENIU DO WPISANYCH WCZESNIEJ WARTOSCI //I TUTAJ TRZEBA BY ZROBIĆ STEROWANIE W OPARCIU O NOWĄ FINKCJĘ NP void sterowanie(runn,stop1,reverse,stop2) {} if (klawisz == 'D'){ lock1=1; count=1; } if (lock1==1){ sterowanie(runn,stop1,reverse,stop2); } if (klawisz == 'B') { A--; } } // END SWITCH } // END LOOP void sterowanie(unsigned long runnA,unsigned long stop1A, unsigned long reverseA, unsigned long stop2A){ runnA=runnA*1000; stop1A=stop1A*1000; reverseA=reverseA*1000; stop2A=stop2A*1000; if (runnA==0 || stop1A==0 || reverseA==0 || stop2A==0){ A=1; lock=1; lock1=0;//powrot do glownej petli loop() do case gdzie litera D wlacza program } if (runnA!=0 && stop1A!=0 && reverseA!=0 && stop2A!=0){ if (count<=repeat){ switch(B){ case 1: lcd.clear(); lcd.print("REPEAT"); lcd.setCursor(7,0); lcd.print(repeat); lcd.setCursor(0,1); lcd.print("CURRENT"); lcd.setCursor(8,1); lcd.print(count); digitalWrite(in1,1); digitalWrite(in2,0); delay(runnA); B++; break; case 2: digitalWrite(in1,0); digitalWrite(in2,0); delay(stop1A); B++; break; case 3: digitalWrite(in1,0); digitalWrite(in2,1); delay(reverseA); B++; break; case 4: digitalWrite(in1,0); digitalWrite(in2,0); delay(stop2A); B=1; count++; Serial.println(count); break; }//end switch }//end count if if (count>repeat){ lcd.clear(); lcd.print("FINISHED!"); delay(1000); A=0; lock=1; lock1=0;//powrot do glownej petli loop() do case gdzie litera D wlacza program count=1; string1 = String(); string2 = String(); string3 = String(); string4 = String(); string5 = String(); string6 = String(); string7 = String(); diameter = 0; speedd = 0; runn = 0; stop1 = 0; reverse = 0; stop2 = 0; repeat = 0; timee = 0; speedd2 = 0; } }//end of main if }// end of sterowanie /* Serial.println(runnA); Serial.println(stop1A); Serial.println(reverseA); Serial.println(stop2A); Serial.println(speedd2A); lock1=0; */ /* if(millis()-saveTime>=1000UL){ saveTime=millis(); lcd.home(); lcd.print(saveTime); } */ 1
SOYER Marzec 13, 2020 Udostępnij Marzec 13, 2020 @bakardi92 brawo Ty:) moja szkoła;) https://github.com/nettigo/Timers Bardzo fajna i prosta biblioteka do timerów. Zacznij od przykładu 'Blink'. 1
bakardi92 Marzec 15, 2020 Autor tematu Udostępnij Marzec 15, 2020 @SOYER Twoja szkoła w 100% najprostsza i najskuteczniejsza!!! Dzięki wielkie! Generalnie ten kawałek kodu który wstawiłeś wcześniej otworzył mi oczy na nowe możliwości, gdyby nie to to bym dalej z tym walczył. Czy masz może gdzieś kawałek kodu z wykorzystaniem tej biblioteki millis() ? Szukam, czytam i ciężko mi ogarnąć jak ją użyć w praktyce... A prawdopodobnie Twój kod po raz kolejny by mnie naprowadził na trop
SOYER Marzec 15, 2020 Udostępnij Marzec 15, 2020 Przecież "kawałek kodu" masz w przykładach do tej biblioteki.... Zacznij od przykładu 'Blink'. Tam nie ma nic skomplikowanego: jakisTimer. begin(długość odliczanego czasu) ; jakisTimer. available() zwraca prawdę jeśli ustawiony czas upłynął jakisTimer. restart() odpala timer od nowa jest jeszcze kilka innych, ale zacznij od tego....
Norbert7630 Styczeń 10, 2021 Udostępnij Styczeń 10, 2021 Witam Powyższy temat menu na lcd 16x2 przeglądnąłem, ale jak dla mnie dopiero stawiającego swoje kroki w środowisku Arduino, jest całkowicie nie zrozumiały. Na razie potrafię jedynie zamigać diodą led czyli ten popularny (blink), oraz uruchomić wyżej wspomniany wyświetlacz lcd 16x2. Nie mam żadnego doświadczenia w elektronice to tylko od nie dawna takie moje hobby. Chciałem zrobić sobie jakieś proste menu właśnie z tym wyświetlaczem lcd do obsługi np. silnika (włącz/wyłącz) czy oświetlenia (włącz/wyłącz), coś takiego: 1 Silnik → Start/Stop ↓ 2 Stycznik → Start/Stop Wiem że dla was to ta przysłowiowa bułka z masłem, ale dla mnie to na razie nieosiągalny szczyt. W necie znalazłem kilka poradników i przykładów, jednak to nie poziom dla początkujących takich jak ja. Starałem się jakoś metodą prób i błędów stworzyć jakiś działający program, jednak metoda wytnij → wklej → próbuj, nie wiele dała. Jedynie co mi się udało tą metodą osiągnąć przedstawiam poniżej: #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); int upButton = 9; int downButton = 10; int selectButton = 11; //int backButton = 12; int menu = 1; void setup() { lcd.begin(); lcd.backlight(); pinMode(upButton, INPUT_PULLUP); pinMode(downButton, INPUT_PULLUP); pinMode(selectButton, INPUT_PULLUP); //pinMode(backButton, INPUT_PULLUP); updateMenu(); } void loop() { if (!digitalRead(downButton)){ menu++; updateMenu(); delay(100); while (!digitalRead(downButton)); } if (!digitalRead(upButton)){ menu--; updateMenu(); delay(100); while(!digitalRead(upButton)); } if (!digitalRead(selectButton)){ executeAction(); updateMenu(); delay(100); while (!digitalRead(selectButton)); /* } if (!digitalRead(backButton)){ executeAction(); updateMenu(); delay(100); while (!digitalRead(backButton));*/ } } void updateMenu() { switch (menu) { case 0: menu = 1; break; case 1: lcd.clear(); lcd.print(">SILNIK 1"); lcd.setCursor(0, 1); lcd.print(" STYCZNIK 2"); break; case 2: lcd.clear(); lcd.print(" SILNIK "); lcd.setCursor(0, 1); lcd.print(">STYCZNIK "); menu = 2; break; } } void executeAction() { switch (menu) { case 1: action1(); break; case 2: action2(); break; } } void action1() { lcd.clear(); lcd.print(">START "); lcd.setCursor(0, 1); lcd.print(" STOP "); delay(3000); } void action2() { lcd.clear(); lcd.print(" START "); lcd.setCursor(0, 1); lcd.print(">STOP "); delay(3000); } Program niby działa bo można przełączać między opcjami menu, jednak po wejściu do opcji START/STOP wychodzi z niej po około 3 s, domyślam się że to za sprawą tych delay(3000). Ponadto program ogólnie jakoś dziwnie reaguje na przyciski raz przełączy a raz nie. W kodzie oprócz tego jest od-komentowany 4 przycisk do wychodzenia. Czy moglibyście mi pomóc zmodyfikować albo napisać jakiś prostszy program żeby działał z góry bardzo dziękuję i przepraszam Administrację jak zrobiłem coś nie tak, pozdrawiam (45 letni kierowca wózka widłowego )
SOYER Styczeń 10, 2021 Udostępnij Styczeń 10, 2021 (edytowany) @Norbert7630 Cześć, napisz może na początek co w. g. Ciebie robią te linie: 27 minut temu, Norbert7630 napisał: int upButton = 9; int downButton = 10; int selectButton = 11; ? 2 minuty temu, SOYER napisał: @Norbert7630 Czytałeś może kilka pierwszych lekcji kursu arduino na blogu Forbota? Edytowano Styczeń 10, 2021 przez SOYER
Norbert7630 Styczeń 10, 2021 Udostępnij Styczeń 10, 2021 (edytowany) Witam Czytałem poradnik na Forbocie dla początkujących coś tam zapamiętałem ale to za mało żeby napisać to menu. Z tego co pamiętam to int selectButton 11 To chyba jest zmienna przypisana czy coś takiego do przycisku podłączonego do pinu nr. 11 w Arduino np. Uno Rozumie a przynajmniej tak mi się wydaje to: void setup() void loop() To są funkcje programu: setup: tutaj są ustawienia np. pinów wejście, wyjście itp. Chyba tutaj wszystko raz się wykonuje, a w funkcji loop to chyba pętla wykonuje się cały czas. Ale już void updateMenu Nic mi nie mówi. Edytowano Styczeń 10, 2021 przez Norbert7630
SOYER Styczeń 11, 2021 Udostępnij Styczeń 11, 2021 @Norbert7630 niestety pomieszałeś podstawowe pojęcia, bez znajomości ktorych nie ruszysz do przodu. Wróć może do pierwszych 3-4 lekcji kursu arduino, potem napisz co jest nie tak z tymi liniami kodu: 13 godzin temu, Norbert7630 napisał: int upButton = 9; int downButton = 10; int selectButton = 11; Potem będziesz działać dalej.
Norbert7630 Styczeń 11, 2021 Udostępnij Styczeń 11, 2021 SOYER, nie jestem pewien tak do końca ale chyba powinienem użyć instrukcji: #define selectButton 8 a ja użyłem zmiennej ,, if " a według kursu to szufladka na przechowywanie jakiś danych np. liczbowych czy znaków.
Norbert7630 Styczeń 11, 2021 Udostępnij Styczeń 11, 2021 #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 16, 2); #define upButton 9 #define downButton 10 #define selectButton 11 //#define backButton 12 int menu = 1; Czyli początek byłby taki, nie jestem pewien co do tego ,,int menu = 1; " czy to przypadkiem także nie jest instrukcja typu ,,define" . Tłumacząc to na zmienną int to coś jakby przechowanie w pamięci liczby 1 mówiącej o jednym menu, (jeżeli byłoby więcej menu→menu2→menu3.... to zwiększa się liczba w zmiennej), sam nie wiem chyba coś pokręciłem
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ę »