Создание "меню" на arduino

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Можно с помощью Switch Case попробовать. Заменить строки со 196 и до конца.

buttonupWasUp = buttonupIsUp;
	buttondownWasUp = buttondownIsUp;
	buttonnextWasUp = buttonnextIsUp;
	buttonprevWasUp = buttonprevIsUp;
        //вывод меню
	switch (m){
        case 0:
        lcd.setCursor(0, 0);
	lcd.print( "Main Menu" );
	lcd.setCursor(0, 1);
	lcd.print( "P1=" );
	lcd.print(p1);
	lcd.print( " P2=" );
	lcd.print(p2);
	lcd.print( " LED=" );
	lcd.print(p3);
        break;
        case 1:  
	lcd.setCursor(0, 0);
	lcd.print( "Parametr-1" );
	lcd.setCursor(0, 1);
	lcd.print( "P1 = " );
	lcd.print(p1);
        break;
        case 2:
	lcd.setCursor(0, 0);
	lcd.print( "Parametr-2" );
	lcd.setCursor(0, 1);
	lcd.print( "P2 = " );
	lcd.print(p2);
        break;
        case 3:
	lcd.setCursor(0, 0);
	lcd.print( "LED Control" );
	lcd.setCursor(0, 1);
	lcd.print( "LED = " );
	lcd.print(p3);
	break;
        }

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Здравствуйте!Спасибо за хорошую и понятную програмку меню.Подскажите,как можно это меню "спрятать " в программе.Т.е вызывать его когда необходимо?Планирую сделать следующее : управление давлением в нескольких емкостях.Всего их три(как раз ваше меню то-что нужно).Программа должна постоянно показывать давление в емкостях опрашивая три датчика давления,причем если давление в емкости превышает заданный предел(наполняется),то при помощи клапана отключается от насоса.С вашим меню все понятно.Как опрашивать датчики то-же.А вот как все соединить?Не пойму как меню вызывать и прятать,допустим при нажатии кнопки меню "открылось меню" ввел параметры,меню закрылось и пошла индикация давления и других вещей.Прерывания нужно использывать или как или что?Смотрю аналогию как в часах вызывается меню,и не могу понять.Создать переменню int Vizovmenu = 0 и при ее переходе в 1 как то включать переменные m ( переменная меню в ваших кодах),но как?Тогда ведь и значения в других переменных могут не сохранится?И вообще значения в переменных "параметр" сохранятся? как сделать чтоб они сохранялись при запуске и выходе из меню?

varvik85
Offline
Зарегистрирован: 28.01.2013

В решении свой задачи попробовал объявить в начале кода переменную Mymenu и присвоил ей все переменные с которыми работает менюшка int Mymenu (int m,int p1,int p2,int p3);

В результате теперь можно выйти из меню присвоив ей int Mymenu =0; и очистив дисплей lcd.clear(); можно дальше выводить на дисплей чтонибудь.Но работает это все хозяйство некорректно.А как бы так сделать чтоб удобно вызывать меню когда надо а когда не надо прятать его обратно?Не мешая выводить на дисплей другую информацию?как то его в отдельный цикл loop запихнуть,а когда надо вызывать?но как?

Tekasijimo
Offline
Зарегистрирован: 06.08.2015

Я скорее всего ошибаюсь но можно попробывать перенести все меню в отдельный цикл 

void MyMenu()

И вызывать в 

void loop(){
 MyMenu();
}

Где то видел в поисках менюшки для себя похожий вариант.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Tekasijimo пишет:

Я скорее всего ошибаюсь но можно попробывать перенести все меню в отдельный цикл 

void MyMenu()

И вызывать в 

void loop(){
 MyMenu();
}

Где то видел в поисках менюшки для себя похожий вариант.

А цикл-то где? Отдельный или там ещё какой?

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

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

romanti4ok
Offline
Зарегистрирован: 29.01.2016

Классный пример!. Для новичков то, что нужно. Единственное, что закоментированные функции очистки экранов в блоках if лучше использовать, вместо lcd.clear в основном цикле loop, иначе идет мерцание экрана вследствие его постоянного обновлния...

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

romanti4ok пишет:

Классный пример!. Для новичков то, что нужно. Единственное, что закоментированные функции очистки экранов в блоках if лучше использовать, вместо lcd.clear в основном цикле loop, иначе идет мерцание экрана вследствие его постоянного обновлния...

Просто отрисовку надо выполнять не в основном цикле, а вынести её в отдельную функцию и вызывать её например каждые 50 - 100мсек (10 - 20 кадров в сек)



if (premillis > millis()){//защита от переполнения счетчика
         premillis = 0;
}
//вызов функции отображения
if (millis() - premillis >= 100) {//проверка не подошло ли время обновить 50 - 100мсек
         lcd.clear();//очищаем        
         void GUI(m);//выводим
}


	 void GUI(byte screen){ //вывод меню (передаем переменную m)
	switch (screen){  
case 0:
	  lcd.setCursor(0, 0);
	  lcd.print("Main Menu");
	  lcd.setCursor(0, 1);
	  lcd.print("P1=");
	  lcd.print(p1);
	  lcd.print(" P2=");
	  lcd.print(p2);
	  lcd.print(" LED=");
	  lcd.print(p3);
break;

case 1:
	  lcd.setCursor(0, 0);
	  lcd.print("Parametr-1");
	  lcd.setCursor(0, 1);
	  lcd.print("P1 = ");
	  lcd.print(p1);
break;

case 2:
	  lcd.setCursor(0, 0);
	  lcd.print("Parametr-2");
	  lcd.setCursor(0, 1);
	  lcd.print("P2 = ");
	  lcd.print(p2);
break;

case 3:
	  lcd.setCursor(0, 0);
	  lcd.print("LED Control");
	  lcd.setCursor(0, 1);
	  lcd.print("LED = ");
	  lcd.print(p3);
break;
}
	//yul-i-an@gmail.com http://arduwir.netdo.ru

 

hudik
Offline
Зарегистрирован: 07.06.2016

добрый день. а случаем не сделали меню с энкодером?

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

меню с энкодером это тоже самое что и меню с кнопками, просто когда энкодер вращается в лево присваиваем какой нибудь bool left=true, когда вправо bool right=true. Когда он не двигается все ЛОЖЬ. это будет аналогично нажатию на кнопки left и rigtht.

hudik
Offline
Зарегистрирован: 07.06.2016

я еще совсем новичек в програмировании, не могли бы фрагмент где и что поменять в коде?

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

yul-i-an пишет:

romanti4ok пишет:

Классный пример!. Для новичков то, что нужно. Единственное, что закоментированные функции очистки экранов в блоках if лучше использовать, вместо lcd.clear в основном цикле loop, иначе идет мерцание экрана вследствие его постоянного обновлния...

Просто отрисовку надо выполнять не в основном цикле, а вынести её в отдельную функцию и вызывать её например каждые 50 - 100мсек (10 - 20 кадров в сек)



if (premillis > millis()){//защита от переполнения счетчика
         premillis = 0;
}
//вызов функции отображения
if (millis() - premillis >= 100) {//проверка не подошло ли время обновить 50 - 100мсек
         lcd.clear();//очищаем        
         void GUI(m);//выводим
}


	 void GUI(byte screen){ //вывод меню (передаем переменную m)
	switch (screen){  
case 0:
	  lcd.setCursor(0, 0);
	  lcd.print("Main Menu");
	  lcd.setCursor(0, 1);
	  lcd.print("P1=");
	  lcd.print(p1);
	  lcd.print(" P2=");
	  lcd.print(p2);
	  lcd.print(" LED=");
	  lcd.print(p3);
break;

case 1:
	  lcd.setCursor(0, 0);
	  lcd.print("Parametr-1");
	  lcd.setCursor(0, 1);
	  lcd.print("P1 = ");
	  lcd.print(p1);
break;

case 2:
	  lcd.setCursor(0, 0);
	  lcd.print("Parametr-2");
	  lcd.setCursor(0, 1);
	  lcd.print("P2 = ");
	  lcd.print(p2);
break;

case 3:
	  lcd.setCursor(0, 0);
	  lcd.print("LED Control");
	  lcd.setCursor(0, 1);
	  lcd.print("LED = ");
	  lcd.print(p3);
break;
}
	//yul-i-an@gmail.com http://arduwir.netdo.ru

 

отрисовку нужно делать тогда когда меняется какое то значение либо нажимается кнопка, на пример для цифровых датчиков температуры измерения проводятся раз в 1-2 сек, чаще обновлять данные нет смысла. Я делал флажек screen_update, который "поднимается" когда данные меняются или нажимается кнопка, и "опускаюется" когда данные отрисованы

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот еще один похожий вариант на 10 окон.

//программа Меню на LCD_Keypad_Shield
//http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)
// последнюю ) ссылка теряет. Поставьте ) и выйдете куда надо.
// Написал:qwone

// -- выводы ардуины UNO -------------------------------
#define pinA0 A0 // analogRead: кнопки   SELECT,LEFT,UP,DOWN,RIGHT
#define pinA1 A1 // свободнo
#define pinA2 A2 // свободнo
#define pinA3 A3 // свободнo
#define pinA4 A4 // свободнo
#define pinA5 A5 // свободнo

#define pin0  0  // Serial
#define pin1  1  // Serial
#define pin2  2  // свободнo
#define pin3  3  // свободнo
#define pin4  4  // digitalWrite: D4          LiquidCrystal
#define pin5  5  // digitalWrite: D5          LiquidCrystal
#define pin6  6  // digitalWrite: D6          LiquidCrystal
#define pin7  7  // digitalWrite: D7          LiquidCrystal
#define pin8  8  // digitalWrite: rs          LiquidCrystal
#define pin9  9  // digitalWrite: enable      LiquidCrystal
#define pin10 10 // digitalWrite: подсветка=1 LiquidCrystal
#define pin11 11 // свободнo
#define pin12 12 // свободнo
#define pin13 13 // свободнo

//------ драйвер клавиш -----------------
#define btnRIGHT  0// кнопка RIGHT
#define btnUP     1// кнопка  UP
#define btnDOWN   2// кнопка  DOWN
#define btnLEFT   3// кнопка  LEFT
#define btnSELECT 4// кнопка  SELECT
#define btnNONE   5// кнопки  не нажаты

int _dA0 = 0;
int btn(){
 _dA0 = analogRead(  pinA0 ); 
 if (_dA0 > 1000) return btnNONE;   // не нажата=1023 => 5
 if (_dA0 < 50)   return btnRIGHT;  // right=0        => 0
 if (_dA0 < 250)  return btnUP;     // up=131         => 1
 if (_dA0 < 450)  return btnDOWN;   // down=305       => 2
 if (_dA0 < 650)  return btnLEFT;   // left=478       => 3 
 return btnSELECT;                  // select=722     => 4                  
};
byte key_N;
void keys(){       // выполнять процедуру раз в цикл 
                   // перем. key_N номер наж кнопки
  key_N= btn();
};

//------ LiquidCrystal -----------------
#include <LiquidCrystal.h>
LiquidCrystal lcd(pin8, pin9, pin4, pin5, pin6 , pin7);

//========== драйвер меню ========

byte frame_N=0; // номер показ окна
boolean N0=0;   // перем. в 0 окна
byte N1=0;   // перем. в 1 окна
byte N2=0;   // перем. в 2 окна
byte N3=0;   // перем. в 3 окна
byte N4=0;   // перем. в 4 окна
byte N5=0;   // перем. в 5 окна
byte N6=0;   // перем. в 6 окна
byte N7=0;   // перем. в 7 окна
byte N8=0;   // перем. в 8 окна
byte N9=0;   // перем. в 9 окна
byte N10=0;  // перем. в 10 окна

// --------------Окно №0------------------
void frame_0(){ 
 lcd.print("podsvetka : ");
 lcd.setCursor(0,1);
 lcd.print(N0,BIN);
  switch (key_N) {
    case 0:N0=1;        // right
      digitalWrite(pin10,N0);
      break;   
    case 1:frame_N=1;   // up
      break;
    case 2:frame_N=10;  // down
      break;
    case 3: N0=0 ;      // left
      digitalWrite(pin10,N0);
      break;
    case 4: ;           // select
      break;
            ;
 } 
};

// --------------Окно №1------------------
void frame_1(){ 
 lcd.print("window_1 : ");
 lcd.setCursor(0,1);
 lcd.print(N1,DEC);
  switch (key_N) {
    case 0:N1++; // right
      break;   
    case 1:frame_N=2; // up
      break;
    case 2:frame_N=0; // down
      break;
    case 3: N1-- ; // left
      break;
    case 4: ; // select
      break;
 } 
};

// --------------Окно №2------------------
void frame_2(){ 
 lcd.print("window_2 : ");
 lcd.setCursor(0,1);
 lcd.print(N2,DEC);
   switch (key_N) {
    case 0:N2++; // right
      break;   
    case 1:frame_N=3; // up
      break;
    case 2:frame_N=1; // down
      break;
    case 3: N2-- ; // left
      break;
    case 4: ; // select
      break;
 } 
};

// --------------Окно №3------------------
void frame_3(){ 
 lcd.print("window_3 : ");
 lcd.setCursor(0,1);
 lcd.print(N3,DEC);
   switch (key_N) {
    case 0:N3++; // right
      break;   
    case 1:frame_N=4; // up
      break;
    case 2:frame_N=2; // down
      break;
    case 3: N3-- ; // left
      break;
    case 4:// select
      break;
 } 
};

// --------------Окно №4------------------
void frame_4(){ 
 lcd.print("window_4 : ");
 lcd.setCursor(0,1);
 lcd.print(N4,DEC);
   switch (key_N) {
    case 0: N4++ ; // right
      break;   
    case 1:frame_N=5; // up
      break;
    case 2:frame_N=3; // down
      break;
    case 3: N4--; // left
      break;
    case 4:; // select
      break;
 } 
};
// --------------Окно №5------------------
void frame_5(){ 
 lcd.print("window_5 : ");
 lcd.setCursor(0,1);
 lcd.print(N5,DEC);
   switch (key_N) {
    case 0:N5++; // right
      break;   
    case 1:frame_N=6; // up
      break;
    case 2:frame_N=4; // down
      break;
    case 3: N5-- ; // left
      break;
    case 4:// select
      break;
 } 
};
// --------------Окно №6------------------
void frame_6(){ 
 lcd.print("window_6 : ");
 lcd.setCursor(0,1);
 lcd.print(N6,DEC);
   switch (key_N) {
    case 0:N6++; // right
      break;   
    case 1:frame_N=7; // up
      break;
    case 2:frame_N=5; // down
      break;
    case 3: N6-- ; // left
      break;
    case 4:// select
      break;
    default:   // не нажата
              ;
 } 
};
// --------------Окно №7------------------
void frame_7(){ 
 lcd.print("window_7 : ");
 lcd.setCursor(0,1);
 lcd.print(N7,DEC);
   switch (key_N) {
    case 0:N7++; // right
      break;   
    case 1:frame_N=8; // up
      break;
    case 2:frame_N=6; // down
      break;
    case 3: N7-- ; // left
      break;
    case 4:// select
      break;
 } 
};
// --------------Окно №8------------------
void frame_8(){ 
 lcd.print("window_8 : ");
 lcd.setCursor(0,1);
 lcd.print(N8,DEC);
   switch (key_N) {
    case 0:N8++; // right
      break;   
    case 1:frame_N=9; // up
      break;
    case 2:frame_N=7; // down
      break;
    case 3: N8-- ; // left
      break;
    case 4:// select
      break;
 } 
};
// --------------Окно №9------------------
void frame_9(){ 
 lcd.print("window_9 : ");
 lcd.setCursor(0,1);
 lcd.print(N9,DEC);
   switch (key_N) {
    case 0:N9++; // right
      break;   
    case 1:frame_N=10; // up
      break;
    case 2:frame_N=8; // down
      break;
    case 3: N9-- ; // left
      break;
    case 4:// select
      break;
 } 
};
// --------------Окно №10------------------
void frame_10(){ 
 lcd.print("window_10 : ");
 lcd.setCursor(0,1);
 lcd.print(N10,DEC);
   switch (key_N) {
    case 0:N10++; // right
      break;   
    case 1:frame_N=0; // up
      break;
    case 2:frame_N=9; // down
      break;
    case 3: N10-- ; // left
      break;
    case 4:// select
      break;
 } 
};


// ===============Программа==============
void setup() {
 // программирование выв.Arduino
 Serial.begin(9600);// выв.1 и 2 UART
 lcd.begin(16, 2);// экран LCD 16x2
 
 pinMode(pin10, OUTPUT);
 N0=1;
 digitalWrite(pin10,N0);
}

void loop() {
 delay(200);// пауза 0,2 сек на цикл
 keys();
 // ввод

 // анализ

 // вывод  
 lcd.clear();
 switch (frame_N) {
    case 0:frame_0();
      break;
    case 1:frame_1();
      break;
    case 2:frame_2();
      break;
    case 3:frame_3();
      break;
    case 4: frame_4();
      break;
    case 5:frame_5();
      break;
    case 6:frame_6();
      break;
    case 7:frame_7();
      break;
    case 8:frame_8();
      break;
    case 9:frame_9();
      break;
    case 10:frame_10();
      break;
 }
}