Многоуровневое меню ардуино

Arduino users
Offline
Зарегистрирован: 27.03.2018

Всем здравствуйте, немогли  бы вы подсказать как правильнее сделать меню на ардуино? Делал примерно так(см. Код)

#define right 1
#define left -1
#define up 1
#define down -1
int controly=false;
int control=false;
#include <Wire.h>
#include <DHT.h>                               //библиотеки
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(3, DHT11);
unsigned long m;
int hum2 = 0;
int st = 0;                                 //строки
int pos = 0;                                //страницы
int flag = 0;
int flag1 = 0;
int flag3 =0;
int a = 0;
int b = 0;  



            
   void setup() {
pinMode(A0, INPUT);
pinMode(6,OUTPUT);
pinMode(9,OUTPUT);
pinMode(5,OUTPUT);
pinMode(3,INPUT);
dht.begin();
Serial.begin(9600);
lcd.init();
lcd.backlight();
}

    void loop() {
  boolean rel1 = digitalRead(6);
  boolean rel2 = digitalRead(5);
  boolean but = digitalRead(8);
  int hum = analogRead(A2);
  hum = map(hum, 0, 1023, 100, 0);
  int temp = dht.readTemperature();       //датчик температуры и влажности воздуха
  int hum1 = dht.readHumidity();
  int vl = val();
  int posi = i();  
  int vly = valy();
   




if(st==0&pos==0){
lcd.clear();
lcd.print("->Status");
lcd.setCursor(0,1);
lcd.print("Setup");
}
if(st==1&pos==0){
lcd.clear();
lcd.print("Status");
lcd.setCursor(0,1);
lcd.print("->Setup");
}                                        //#Меню страница 0



if(st>1){
  st=0;
 }

delay(100);
if(st==0&pos==1){
lcd.clear();
lcd.print(">Air");
lcd.setCursor(0,1);
lcd.print("Ground");
}
if(st==1&pos==1){                         //#страница 1
lcd.clear();
lcd.print("Air");
lcd.setCursor(0,1);
lcd.print(">Ground");
}                         



if(st==0&pos==2){
lcd.clear();
lcd.print("Temp:");
lcd.setCursor(5,0);
lcd.print(temp);
lcd.setCursor(7,0);
lcd.print("C°");
lcd.setCursor(9,0);
lcd.print("Hum:");
lcd.setCursor(13,0);
lcd.print(hum1);
lcd.setCursor(15,0);
lcd.print("%");
}                                                                    //#Меню страница 2
if(st==1&pos==2){
lcd.clear();
lcd.print("Temp:");
lcd.setCursor(5,0);
lcd.print(temp);
lcd.setCursor(7,0);
lcd.print("C°");
lcd.setCursor(9,0);
lcd.print("Hum:");
lcd.setCursor(13,0);
lcd.print(hum1);
lcd.setCursor(15,0);
lcd.print("%");
} 


if(pos==3){
lcd.clear();
lcd.print("Hum:");
lcd.setCursor(6,0);
lcd.print(hum);                     //#Меню страница 3
lcd.setCursor(8,0);
lcd.print("%");
}




if(st==0&pos==4){
lcd.clear();
lcd.print(">Basic setup");
lcd.setCursor(0,1);
lcd.print("Mode");
}                                                    //#страница 4
if(st==1&pos==4){
lcd.clear();
lcd.print("Basic setup");
lcd.setCursor(0,1);
lcd.print(">Mode");
}



if(st==0&pos==5){
lcd.clear();
lcd.print(">Time");
}                                                    //#страница 5 
if(st==1&pos==5){
lcd.clear();
lcd.print("Time");
}




if(st==0&pos==6){
if(a==1){
lcd.clear();
lcd.print(">Mode:auto");
lcd.setCursor(0,1);
lcd.print("Setup auto");
}
}                                                   
if(st==1&pos==6){
if(a==1){
lcd.clear();
lcd.print("Mode:auto");
lcd.setCursor(0,1);
lcd.print(">Setup auto");
}
}                                                //#страница 6

if(st==0&pos==6){
if(a==0){
lcd.clear();
lcd.print(">Mode:manual");
lcd.setCursor(0,1);
lcd.print("Setup manual");
}   
}                                                
if(st==1&pos==6){
if(a==0){
lcd.clear();
lcd.print("Mode:manual");
lcd.setCursor(0,1);
lcd.print(">Setup manual");
}
}

if(st==0&pos==6){
if(a==2){
lcd.clear();
lcd.print(">Mode:off");
}                                                   
}


if(st==0&pos==7){
lcd.clear();
lcd.print(">Set humidity");
lcd.setCursor(0,1);
lcd.print("Set time watering");
}                                                  //страница 7                       
if(st==1&pos==7){
lcd.clear();
lcd.print("Set humidity");
lcd.setCursor(0,1);
lcd.print(">Set time watering");
}                              

if(st==0&pos==8){
if(rel1==0){
lcd.clear();
lcd.print(">Status:off");
}
}                                                   //страница 8
if(st==1&pos==8){
if(rel1==1){
lcd.clear();
lcd.print("Status:on");
}
}                                      

if(st==0&pos==9){
lcd.clear();
lcd.print(hum2);
lcd.setCursor(3,0);
}

if(pos==6&st==0){
if(but==1&flag==0){
a++;
flag=1;
}
}
if(pos==6&st==0){
if(but==0&flag==1){
flag=0;
}
}

if(a>2){
a=0;
}




if(vly==1){
st++;
}






if(pos==0&st==0){
if(vl==1){
st=2;
pos=1;
}
}
if(pos==0&st==1){
if(vl==1){
st=2;
pos=4;
}
}

if(pos==4){
if(vl==-1){
pos=0;
}
}
if(pos==1){
if(vl==-1){
pos=0;
}
}
if(pos==1&st==0){
if(vl==1){
pos=2;
}
}
if(pos==2){
if(vl==-1){
pos=1;
}
}
if(pos==1&st==1){
if(vl==1){
pos=3;
}
}
if(pos==3){
if(vl==-1){
pos=1;
}
}

if(pos==4&st==0){
if(vl==1){
pos=5;
}
}

if(pos==5){
if(vl==-1){
pos=4;
}
}

if(pos==4&st==1){
if(vl==1){
st=2;
pos=6;
}
}

if(pos==6){
if(vl==-1){
st=2;
pos=4;
}
}

if(pos==6&st==1&a==1){
if(vl==1){
st=2;
pos=7;
}
}

if(pos==6&st==1&a==0){
if(vl==1){
st=2;
pos=8;
}
}
if(pos==8){
if(vl==-1){
pos=6;
}
}
if(pos==7&st==0){
if(vl==1){
pos=9;
}
}

Serial.println(vl);    
}
int valy(){
int y = analogRead(A1);
if(y>500){
controly=up;   //контроль джойстика, нейтраль = false
}
else if(y<400){
control=down;
}
else{
controly=false;
}
return controly;
}
int val(){
int x = analogRead(A0);
if(x>500){
control=right;   //контроль джойстика, нейтраль = false
}
else if(x<400){
control=left;
}
else{
control=false;
}
return control;
}
int i(){
if(val()==right&flag3==0){
if(millis()-m>100){
m=millis();
flag3=1;
}
}
else if(val()==left&flag3==0){
flag3=1;
}
else if(val()==false&flag3==1){
flag3=0;
}
if(pos<0){
pos=0;
}
}

Но я думаю, что это не слишком правильно, знаю что надо делать это всё за счет массивов, но не понимаю, как правильно написать. Можете ли дать шаблон и немного объяснить?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
nik182
Онлайн
Зарегистрирован: 04.05.2015

Поищите micro menu.

Logik
Онлайн
Зарегистрирован: 05.08.2014

//немогли  бы вы подсказать как правильнее сделать меню на ардуино?

Правильно будет так:

1. Еще раз подумать, нужно ли меню в ардуине. Как правило вне её проще и удобней, но если таки да то п.2

2. Правильное меню будет иметь разделение кода обеспечивающего его функционирование (он не должен менятся при развитии проекта и при переносе в другой проект) и данных описывающих его структуру (пункты меню,  вложеные подменю, конечные экраны для просмотра и редактирования). Очевидно код выше этому не соответствует.

3. Сильно правильное меню должно соответствовать п.2 и дополнительно быть построено на не блокирующих вызовах.

4. Очень правильное меню должно соответствовать всему из п.3 и поддерживать динамическое обнавление данных.  Например значение с датчика во время нахождения в пункте просмотра этого значения должно обновлятся в реалтайм, хотя опрос датчика должен( или может) быть не в системе меню, т.к. некоторые датчики опросить бывает очень долго или принципиально не возможно в произвольный момент.  А редактирование, например яркости лампочки должно тут же менять яркость свечения этой гребаной лампы.

5. Совершенно правильное меню, кроме вышеперечисленного, еще не должно тормозить код. Все его вызовы должны обрабатыватся быстро. Тут стоит обратить внимание на очистку экрана и скролинг. Ну и пункты перерисовывать только те что нужно.

Как найдете или напишете такое - код в тему бросайте.