Меню сайта
Календарь
|
Меню для Arduino(Atmega32)The menu for the Arduino (Atmega32). Заинтересовался вопросом : меню для Arduino.На помощь пришел всемогущий Google.На его бескрайних просторах нашелся и источник для вдохновения www.coagula.org . Структура меню : Главное меню | Меню_1 -------------------------------------------------- Меню_2 ------------------------------------------------------------------ Меню_3 | | Подменю 1_1 ---- Подменю 1_2 Подменю 2_1 ---- Подменю 2_2 ---- Подменю 2_3 Используется LCD MTC-16204X на контролере HD44780,совместимый с обычным LCD 1602 и поддерживающий кирилицу. Для навигации по меню используются четыре кнопки.Для удобства мной был изготовлен "самопальный" шилд ,плата которог по-быстрому вырезана малярным ножиком (эх "тряхнул стариной"). Cхема подключений : Фото собраной схемы : Скетч. Библиотека MenuBackend для Arduino IDE 1.0.4 - cкачать . Первым делом я занялся переводом статьи и скетча с www.coagula.org .Оказалось что для нормальной компиляции и работы скетча необходимо вносить изменения в файл MenuBackend.h. Добавляются следующие строки в линии 195 MenuBackend.h файла, непосредственно перед строкой "private" : void toRoot ( ) { setCurrent ( &getRoot ( ) ); Это сделано для того, чтобы иметь возможность легко вернуться c любого подменю в корень меню, нажатием кнопки ESC. В самом скетче организована програмная реализация "антидребезга" кнопок. Для LCD применяется библиотека LiquidCrystalRus - скачать . /* IMPORTANT: to use the menubackend library by Alexander Brevig download it at http://www.arduino.cc/playground/uploads/Profiles/MenuBackend_1-4.zip and add the next code at line 195 void toRoot() { setCurrent( &getRoot() ); } */ #include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig #include <LiquidCrystalRus.h> //this library is included in the Arduino IDE const int buttonPinLeft = 12; // pin for the Up button // контакт для кнопки "Вверх" const int buttonPinRight = 11; // pin for the Down button "вниз" const int buttonPinEsc = 14; // pin for the Esc button "выход" const int buttonPinEnter = 15; // pin for the Enter button "вход" int lastButtonPushed = 0; int lastButtonEnterState = LOW; // the previous reading from the Enter input pin int lastButtonEscState = LOW; // the previous reading from the Esc input pin int lastButtonLeftState = LOW; // the previous reading from the Left input pin int lastButtonRightState = LOW; // the previous reading from the Right input pin long lastEnterDebounceTime = 0; // the last time the output pin was toggled long lastEscDebounceTime = 0; // the last time the output pin was toggled long lastLeftDebounceTime = 0; // the last time the output pin was toggled long lastRightDebounceTime = 0; // the last time the output pin was toggled long debounceDelay = 500; // the debounce time // LiquidCrystal display with: LiquidCrystalRus lcd(9, 6, 5, 4, 3, 2); //Menu variables MenuBackend menu = MenuBackend(menuUsed,menuChanged); //initialize menuitems //инициализации пунктов меню MenuItem menu1Item1 = MenuItem("меню_1"); MenuItem menuItem1SubItem1 = MenuItem("подменю1_1"); MenuItem menuItem1SubItem2 = MenuItem("подменю1_2"); MenuItem menu1Item2 = MenuItem("меню_2"); MenuItem menuItem2SubItem1 = MenuItem("подменю2_1"); MenuItem menuItem2SubItem2 = MenuItem("подменю2_2"); MenuItem menuItem3SubItem3 = MenuItem("подменю2_3"); MenuItem menu1Item3 = MenuItem("меню_3"); void setup() { pinMode(buttonPinLeft, INPUT); pinMode(buttonPinRight, INPUT); pinMode(buttonPinEnter, INPUT); pinMode(buttonPinEsc, INPUT); lcd.begin(16, 2); //configure menu //настроить меню menu.getRoot().add(menu1Item1); menu1Item1.addRight(menu1Item2).addRight(menu1Item3); menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2); menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2).addRight(menuItem3SubItem3); menu.toRoot(); lcd.setCursor(0,0); lcd.print("Меню для Arduino"); } // setup()... void loop() { readButtons(); //I splitted button reading and navigation in two procedures because //Я разделил чтения и навигации кнопки в двух процедур, поскольку navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings) //В некоторых ситуациях я хочу использовать кнопки для других целей (например, для изменения настроек) } //loop()... void menuChanged(MenuChangeEvent changed){ MenuItem newMenuItem=changed.to; //get the destination menu lcd.setCursor(0,1); //set the start position for lcd printing to the second row if(newMenuItem.getName()==menu.getRoot()){ lcd.print("Главное меню "); }else if(newMenuItem.getName()=="меню_1"){ lcd.print("меню_1 "); }else if(newMenuItem.getName()=="подменю1_1"){ lcd.print("подменю1_1 "); }else if(newMenuItem.getName()=="подменю1_2"){ lcd.print("подменю1_2 "); }else if(newMenuItem.getName()=="меню_2"){ lcd.print("меню_2 "); }else if(newMenuItem.getName()=="подменю2_1"){ lcd.print("подменю2_1 "); }else if(newMenuItem.getName()=="подменю2_2"){ lcd.print("подменю2_2 "); }else if(newMenuItem.getName()=="подменю2_3"){ lcd.print("подменю2_3 "); }else if(newMenuItem.getName()=="меню_3"){ lcd.print("меню_3 "); } } void menuUsed(MenuUseEvent used){ lcd.setCursor(0,0); lcd.print("Вы использовали "); lcd.setCursor(0,1); lcd.print(used.item.getName()); delay(3000); //delay to allow message reading - чтобы задержать чтении сообщение lcd.setCursor(0,0); lcd.print("Меню для Arduino"); menu.toRoot(); //back to Main } void readButtons(){ //read buttons status int reading; int buttonEnterState=LOW; // the current reading from the Enter input pin int buttonEscState=LOW; // the current reading from the input pin int buttonLeftState=LOW; // the current reading from the input pin int buttonRightState=LOW; // the current reading from the input pin //Enter button - кнопка Enter // read the state of the switch into a local variable: // читать состояние переключателя в локальную переменную: reading = digitalRead(buttonPinEnter); // check to see if you just pressed the enter button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // Проверяем, если вы только что нажал на кнопку ввода // (Т.е. входные пошел от низкой до высокой), а вы ждали // Достаточно долго, с момента последней пресс игнорировать любые шумы: // If the switch changed, due to noise or pressing: // Если переключатель изменилась, из-за шума или нажатие: if (reading != lastButtonEnterState) { // reset the debouncing timer // Сброс таймера дребезга lastEnterDebounceTime = millis(); } if ((millis() - lastEnterDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: // Все, что показания на, он был там дольше // Чем дребезга задержки, так что принять его в качестве фактического текущего состояния: buttonEnterState=reading; lastEnterDebounceTime=millis(); } // save the reading. Next time through the loop, // it'll be the lastButtonState: // Сохранить чтении. В следующий раз через loop, // Это будет lastButtonState: lastButtonEnterState = reading; //Esc button // read the state of the switch into a local variable: reading = digitalRead(buttonPinEsc); // check to see if you just pressed the Down button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != lastButtonEscState) { // reset the debouncing timer lastEscDebounceTime = millis(); } if ((millis() - lastEscDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: buttonEscState = reading; lastEscDebounceTime=millis(); } // save the reading. Next time through the loop, // it'll be the lastButtonState: lastButtonEscState = reading; //Down button // read the state of the switch into a local variable: reading = digitalRead(buttonPinRight); // check to see if you just pressed the Down button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != lastButtonRightState) { // reset the debouncing timer lastRightDebounceTime = millis(); } if ((millis() - lastRightDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: buttonRightState = reading; lastRightDebounceTime =millis(); } // save the reading. Next time through the loop, // it'll be the lastButtonState: lastButtonRightState = reading; //Up button // read the state of the switch into a local variable: reading = digitalRead(buttonPinLeft); // check to see if you just pressed the Down button // (i.e. the input went from LOW to HIGH), and you've waited // long enough since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != lastButtonLeftState) { // reset the debouncing timer lastLeftDebounceTime = millis(); } if ((millis() - lastLeftDebounceTime) > debounceDelay) { // whatever the reading is at, it's been there for longer // than the debounce delay, so take it as the actual current state: buttonLeftState = reading; lastLeftDebounceTime=millis();; } // save the reading. Next time through the loop, // it'll be the lastButtonState: lastButtonLeftState = reading; //records which button has been pressed //запись, какая кнопка была нажата if (buttonEnterState==HIGH){ lastButtonPushed=buttonPinEnter; }else if(buttonEscState==HIGH){ lastButtonPushed=buttonPinEsc; }else if(buttonRightState==HIGH){ lastButtonPushed=buttonPinRight; }else if(buttonLeftState==HIGH){ lastButtonPushed=buttonPinLeft; }else{ lastButtonPushed=0; } } void navigateMenus() { MenuItem currentMenu=menu.getCurrent(); switch (lastButtonPushed){ case buttonPinEnter: if(!(currentMenu.moveDown())){ //if the current menu has a child and has been pressed enter then menu navigate to item below //Если в текущем меню есть подменю, и была нажата, то введите меню перейдите к пункту ниже menu.use(); }else{ //otherwise, if menu has no child and has been pressed enter the current menu is used //Иначе, если меню не имеет подменю и была нажата Enter текущее меню используется menu.moveDown(); } break; case buttonPinEsc: menu.toRoot(); //back to main - Вернуться на главную break; case buttonPinRight: menu.moveRight(); break; case buttonPinLeft: menu.moveLeft(); break; } lastButtonPushed=0; //reset the lastButtonPushed variable //сбросить переменную lastButtonPushed } |
Архив записей
Друзья сайта
Статистика
Онлайн всього: 1 Гостей: 1 Користувачів: 0 |