128x64 и кнопки
Может ли кто-нибудь дать мне совет по созданию меню для ЖК-дисплея 128x64 с использованием 5 кнопок? у меня 5 экранов. btn1 для отображения MainMenu и Selection. btn2 и btn3 для прокрутки вверх и вниз btn 4 и btn4 предназначены для включения/выключения и увеличения/уменьшения значений.
Проблема, с которой я столкнулся, связана с btn2 и btn3. я не знаю, как использовать их для прокрутки на другом экране, кроме screen1 (MainMenu).
#include "U8glib.h"
U8GLIB_ST7920_128X64_1X u8g(13,12,11); //Enable, RW, RS, RESET
int selectionButton = A1, selectionButtonState, selectionButtonLastState = 0, cntSelectionButtonPressed = 0, cntSelectionButtonPressed2ForMenu2 = 0;
int menuButton = A0, menuButtonState, menuButtonLastState = 0;
int scrollDownButton = A3, scrollDownButtonState, scrollDownButtonLastState = 0;
boolean mainMenu = false;
void setup()
{
Serial.begin(9600);
if ( u8g.getMode() == U8G_MODE_R3G3B2 )
u8g.setColorIndex(255); // white
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
u8g.setColorIndex(3); // max intensity
else if ( u8g.getMode() == U8G_MODE_BW )
pinMode(selectionButton,INPUT);
pinMode(menuButton,INPUT);
pinMode(scrollDownButton,INPUT);
}
void loop()
{
scrollDownButtonState = digitalRead(A3);
selectionButton = digitalRead(A1);
menuButton = digitalRead(A0);
//pin A1 = RiGHT
if(selectionButton != selectionButtonLastState)
{
if(digitalRead(A1) == HIGH)
{
cntSelectionButtonPressed += 1;
if(cntSelectionButtonPressed == 4)
{
cntSelectionButtonPressed = 0;
}
}
selectionButtonLastState = selectionButton;
}
////////////////////////
if(menuButton != menuButtonLastState)
{
if(cntSelectionButtonPressed == 1 && digitalRead(A0) == HIGH)
{
cntSelectionButtonPressed2ForMenu2 += 1;
}
if(cntSelectionButtonPressed2ForMenu2 == 4)
{
cntSelectionButtonPressed2ForMenu2 = 0;
}
u8g.firstPage();
do{
Menu2();
}while(u8g.nextPage());
menuButtonLastState = menuButton;
}
else
{
u8g.firstPage();
do{
MainMenu();
}while(u8g.nextPage());
}
}
void MainMenu(){
switch(cntSelectionButtonPressed)
{
case 1:
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(15,15);
u8g.print("> Ceas");
u8g.setPrintPos(15,25);
u8g.print(" Interior casa");
u8g.setPrintPos(15,35);
u8g.print(" Exterior casa");
break;
case 2:
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(15,15);
u8g.print(" Ceas");
u8g.setPrintPos(15,25);
u8g.print("> Interior casa");
u8g.setPrintPos(15,35);
u8g.print(" Exterior casa");
break;
break;
case 3:
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(15,15);
u8g.print(" Ceas");
u8g.setPrintPos(15,25);
u8g.print(" Interior casa");
u8g.setPrintPos(15,35);
u8g.print("> Exterior casa");
break;
}
}
void Menu2()
{
switch(cntSelectionButtonPressed2ForMenu2)
{
case 1:
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(15,15);
u8g.print("> Stil1");
u8g.setPrintPos(15,25);
u8g.print(" Stil2");
u8g.setPrintPos(15,35);
u8g.print(" Stil3");
break;
case 2:
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(15,15);
u8g.print(" Stil1");
u8g.setPrintPos(15,25);
u8g.print("> Stil2");
u8g.setPrintPos(15,35);
u8g.print(" Stil3");
break;
break;
case 3:
u8g.setFont(u8g_font_6x13);
u8g.setPrintPos(15,15);
u8g.print(" Stil1");
u8g.setPrintPos(15,25);
u8g.print(" Stil2");
u8g.setPrintPos(15,35);
u8g.print("> Stil3");
break;
}
}
@Iulian Chirvasa, 👍0
1 ответ
Во-первых, я немного удивлен, что вы используете аналоговые контакты для проверки кнопок, а не цифровые.
Что касается кода, то, не анализируя его полностью, проще всего сначала создать диаграмму состояний в псевдокоде.
Например, вы хотите иметь следующие экраны (название/содержание экрана показано в [], переход кнопки с помощью ---(key)-->
InitScreen--- (right)--> MenuOption1Highlight---(right)-->MenuOption1Items
| ^ \---(left)----+
(down) (up)
v |
MenuOption2Highlight---(right)-->MenuOption2Items
\---(left)----+
Чтобы запрограммировать это (примерно), создайте перечисление для каждой страницы меню:
enum EMenuPage
{
None,
InitScreen,
MenuOption1Highlight,
MenuOption1Items,
MenuOption2Highlight,
MenuOption2Items
};
Затем создайте для него текущее состояние как глобальную переменную:
EMenuPage _eMenuPage;
И инициализируйте его в программе установки:
_eMenuPage = None;
Создайте перечисление для ключей:
enum EKey
{
None,
Up,
Down,
Right,
Left
};
Легче создать функцию, которая считывает ключи и возвращает один ключ, возможно, один ключ имеет приоритет над другим, или вы можете комбинировать ключи (в этом случае добавьте в EKey, например, UpAndDown). Если ни одна клавиша не была нажата, выбирается «Нет».
В цикле используйте диаграмму перехода состояний для программирования параметров:
EKey pressedKey = GetPressedKey(); // Это нужно реализовать самому, он обновляет _pressedKey;
switch (_eMenuPage)
{
case None:
InitScreen();
break;
case InitScreen:
ProcessInitScreenKeys();
break;
case MenuOptions1HighLighted:
ProcessMenuOptions1HighLightedKeys();
break;
...
default:
// Недопустимый ключ
break;
}
Для каждой страницы вы создаете функцию (например, InitScreen), которая обновляет состояние и показывает содержимое на дисплее:
void InitScreen()
{
_eMenuPage = InitScreen;
// Показать содержимое на дисплее.
}
Кроме того, вы создаете функцию Process...Keys для обработки ключей. Нравится:
void InitScreen()
{
EKey pressedKey = GetPressedKey();
switch (pressedKey)
{
case Right:
MenuOptions1HighLighted();
break;
default:
// Игнорировать другие ключи
break;
}
}
Для другой функции это будет выглядеть так:
void ProcessMenuOptions1HighLightedKeys()
{
EKey pressedKey = GetPressedKey();
switch (pressedKey)
{
case Down:
MenuOptions1HighLighted();
break;
case Right:
MenuOption1Items();
break;
default:
// Игнорировать другие ключи
break;
}
}
(Кстати, я не проверял и не компилировал код).
Возможно, есть более удобный объектно-ориентированный способ сделать это, но он требует больше памяти и является более продвинутым. Это необходимо для создания абстрактного класса Page с двумя виртуальными методами (один для отображения и один для обработки ключей) и создания производного класса для каждой страницы, реализующей две функции из базового класса.
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- устаревшее преобразование из строковой константы в 'char*'