ArduWir
Вы хотите отреагировать на этот пост ? Создайте аккаунт всего в несколько кликов или войдите на форум.

Меню для Ардуино

Перейти вниз

Помогла ли Вам эта тема?

Меню для Ардуино Vote_lcap0%Меню для Ардуино Vote_rcap 0% 
[ 0 ]
Меню для Ардуино Vote_lcap0%Меню для Ардуино Vote_rcap 0% 
[ 0 ]
Меню для Ардуино Vote_lcap0%Меню для Ардуино Vote_rcap 0% 
[ 0 ]
 
Всего проголосовало : 0
 
 

Меню для Ардуино Empty Меню для Ардуино

Сообщение  Admin Ср 23 Мар 2016 - 10:22

Многим в проектах требуется создать меню выводимое на дисплей для оперативного изменения параметров устройства.
Меню работает следующим образом - при включении устройства отображается экран приветствия на 3сек. после отображается основной экран на котором отображается состояние устройства. При нажатии кнопки SET меняются страницы МЕНЮ циклически. При нажатии кнопок UP, DN происходит изменение отображаемого в данный момент параметра (на основном экране кнопки UP, DN реакцию не дают. При бездействие пользователя в течении 5сек. из любого состояния начинает отображаться основной экран.
[Вы должны быть зарегистрированы и подключены, чтобы видеть эту ссылку] (симуляция в Proteus)
Ниже представлен код простого меню.
Код:
//Пример простого меню для LCD 16x2
//V2 Taranov A. 03.2016
//В меню используется 4 экрана
//за номер отображаемого экрана отвечает переменная m
#include <LiquidCrystal.h> //Библиотека LCD
// инициализация LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
//массив надписей которые выводяться не на одном экране для экономии памяти
char* myLabel[]={//повторяющиеся надписи
  "Parametr","P1=","P2=","LED-"};
int m=0; //переменная для экранов меню
int p1=0; // переменная для примера 1
int p2=0; // -//- 2
boolean p3=0; // -//- 3
unsigned long PSTimer = 0;//таймер для обновления экрана
unsigned long KPTimer = 0;//таймер для опроса кнопок
unsigned long MSRTimer = 0;//таймер для автовозврата к MainScreen
#define MSRecovery 5000 //задержка автовозврата к MainScreen 3сек
#define nextPin 8 //кнопка меню на 8 входе
#define prevPin 11 //кнопка возврата
#define upPin 9 //увеличение значения отображаемого параметра
#define downPin 10 //уменьшение значения
boolean f_key=0;//флаг для фиксации нажатия кнопки
#define bounce 30 //задержка антидребезга
#define ledPin 13 //Светодиод

void setup() {
  //Настройка входов
  pinMode(nextPin, INPUT);
  pinMode(prevPin, INPUT);
  pinMode(upPin, INPUT);
  pinMode(downPin, INPUT);
  //Настройка выходов
  pinMode(ledPin, OUTPUT);
  //Настройка дисплея
  lcd.begin(16, 2);
  // Вывод приветствия
  lcd.print("DEMO MENU V2");
  delay (2000);
}

void loop() {
  //------Опрос кнопок-----------------------
  if (millis()-KPTimer>=bounce){//опрос кнопок раз в 10мсек
    KPTimer=millis();
    if (f_key==false){
      key_dn();//проверка нажатия кнопки
    }
    //проверка на отпускание кнопки
    if(f_key==true){
      key_up();//проверка отпускания кнопки
    }
  }
  //-----Автовозврат к основному экрану---------------
  if (millis()-MSRTimer>=MSRecovery){  //Если счетчик достиг интервала
    MSRTimer=millis();
    m=0; //то отобразить главный экран                                        
  }
  //-----------Обновление экрана--------------
  if (millis()-PSTimer>=50){//вывод экрана каждые 50мсек (20к/с)
    PSTimer=millis();
    PreentScreen(m);//обновление экрана
  }
}//end LOOP

//---------вывод лейблов в указанном месте экрана-------------
void PrintLabel(char* t, byte x, byte y){//char* t - лейбл, x-столбец, y-строка
  lcd.setCursor(x, y);
  lcd.print(t);
}

//--------Вывод экранов----------------------
void PreentScreen(int s){//Вывод меню
  lcd.clear();//отчистка экрана
  //Описание экранов меню
  switch (s){
  case 0://Экран выводимый по умолчанию (не пункт меню)
    PrintLabel("Main Screen",0,0);
    PrintLabel(myLabel[1],0,1);
    lcd.print(p1);
    PrintLabel(myLabel[2],5,1);
    lcd.print(p2);
    PrintLabel(myLabel[3],10,1);
    lcd.print(p3);
    break;

  case 1://экран изменения переменной 1
    PrintLabel(myLabel[0],0,0);
    PrintLabel(myLabel[1],0,1);
    lcd.print(p1);
    break;

  case 2://экран изменения переменной 2
    PrintLabel(myLabel[0],0,0);
    PrintLabel(myLabel[2],0,1);
    lcd.print(p2);
    break;

  case 3://экран изменения переменной 3
    PrintLabel("LED Control",0,0);
    PrintLabel(myLabel[3],0,1);
    lcd.print(p3);
    break;
  }
}

//-------------ОПРОС КНОПОК------------
void key_dn(){
  if (f_key==false){
    //Обработка нажатия кнопки NEXT
    if (digitalRead(nextPin)== HIGH)
    {
      action(0);
      f_key=true;//устанавливаем флаг
    }
    //Обработка нажатия кнопки PREV
    if (digitalRead(prevPin)== HIGH)
    {
      action(1);
      f_key=true;//устанавливаем флаг
    }
    //Обработка нажатия UP
    if (digitalRead(upPin)== HIGH)//если находимся на экране с переменной р1
    {
      action(2);
      f_key=true;//устанавливаем флаг
    }
    //Обработка нажатия DN
    if (digitalRead(downPin)== HIGH)//если находимся на экране с переменной р1
    {
      action(3);
      f_key=true;//устанавливаем флаг
    }
    if (f_key==true){
      MSRTimer=millis();//сброс таймера автовозврата к главному экрану  
    }
  }
}

void key_up(){
  if (digitalRead(nextPin)==0 && digitalRead(prevPin)==0 && digitalRead(upPin)==0 && digitalRead(downPin)==0){
    f_key=false;//сброс флага
  }
}

//--------РЕАКЦИЯ НА КНОПКИ-------------------
void action(byte x){
  switch (x){
  case 0://next
    m=var(m, 0, 3, 1, 1, 1);//увеличиваем переменную уровня меню
    break;
  case 1://prev
    m=var(m, 0, 3, 1, 0, 1);//уменьшаем переменную уровня меню
    break;
  case 2://up
    if (m==1){//если нажали UP когда экран с переменной р1
      p1= var(p1, 0, 10, 1, 1, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
    }
    if (m==2){//если нажали UP когда экран с переменной р2
      p2= var(p2, 0, 10, 1, 1, 1);
    }
    if (m==3){//если нажали UP когда экран с переменной р3
      p3= var(p3, 0, 1, 1, 1, 1);
      digitalWrite(ledPin, p3);
    }
    break;
  case 3://down
    if (m==1){//если нажали DOWN когда экран с переменной р1
      p1= var(p1, 0, 10, 1, 0, 1);//то при нажатии кнопки + увеличиваем переменную р1 на единицу
    }
    if (m==2){//если нажали DOWN когда экран с переменной р2
      p2= var(p2, 0, 10, 1, 0, 1);
    }
    if (m==3){//если нажали DOWN когда экран с переменной р3
      p3= var(p3, 0, 1, 1, 0, 1);
      digitalWrite(ledPin, p3);
    }  
    break;
  }
}

//--------------функция изменения переменной-------------------
//х=var(переменная,минимум,максимум,шаг,направление,циклически);
//переменная - переменная для изменения (int)
//минимум, максимум - пределы переменной
//шаг - шаг изменения переменной
//направление - увеличить или уменьшить
//циклически - если 0 то от мин до макс,
//если 1 то при достижение мах переходим к минимуму и наоборот
int var(int v, int mn, int mx, int stp, boolean pm, boolean c){
  switch (pm){//pm=1 увеличение pm=0 уменьшение
  case 0:
    v -= stp;//уменьшаем на шаг
    break;
  case 1:
    v += stp;//увеличиваем на шаг
    break;
  }
  switch (c){//c-1 циклически с-0 до пределов
  case 1://
    if (v<mn){
      v=mx;
    }
    if (v>mx){
      v=mn;
    }
    break;
  case 0:
    if (v<mn){
      v=mn;
    }
    if (v>mx){
      v=mx;
    }
    break;
  }
  return v;
}
//http://allduino.forum2x2.ru/t12-topic#17
//http://arduwir.netdo.ru/article/6264

Под Main Menu понимать экран выводимый по умолчанию (основной).
Меню для Ардуино Arduino_menu


Последний раз редактировалось: Admin (Чт 31 Мар 2016 - 22:46), всего редактировалось 6 раз(а) (Обоснование : Обновлен код)

Admin
Admin

Сообщения : 21
Дата регистрации : 2012-12-11

https://allduino.forum2x2.ru

Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения