Skocz do zawartości

Proste menu w Arduino i obsługa LCD I2C po raz enty...


Pomocna odpowiedź

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.

Link to post
Share on other sites

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

  • Lubię! 1
  • Pomogłeś! 1
Link to post
Share on other sites
(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 przez bakardi92
Link to post
Share on other sites

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 przez SOYER
  • Pomogłeś! 1
Link to post
Share on other sites
(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.

 

image.thumb.png.04bc42c8859774f410573a3d7f0b8d07.png

 

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 przez bakardi92
Link to post
Share on other sites

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);
 }
 */

 

  • Lubię! 1
Link to post
Share on other sites

@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

Link to post
Share on other sites

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

Link to post
Share on other sites

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 😉)

 

Link to post
Share on other sites
(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ł:

Czytałeś może kilka pierwszych lekcji kursu arduino na blogu Forbota? 

Edytowano przez SOYER
Link to post
Share on other sites
(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 przez Norbert7630
Link to post
Share on other sites

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

Link to post
Share on other sites

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.

Link to post
Share on other sites
#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 😔

Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

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!

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

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.