Мне нужна помощь в создании меню с использованием библиотеки u8g2
Я хочу создать проект с дисплеем (Nokia 5110) с использованием библиотеки u8g2. Вот код моей программы:
#include <Arduino.h>
#include <U8g2lib.h>
#include <TM1637Display.h>
#include <EEPROM.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#define LED_PIN 5
#define BUTTON_PIN 6
#define BUZZ_PIN 7
#define BUTTON_L 2
#define BUTTON_R 3
#define BUTTON_START 4
//48x84 дисп.
U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R2, 13, 11, 10, 12, 8); //поворот, clk, DIN, CE, DC, RST//
byte lastButtonState = 0;
byte ledState;
float cpu_gauge = 0.0;
char buffer[40];
int move = 7;
float cpu_gauge_step = 0.5;
byte eeprom_led;
void set_led(){
if( digitalRead(LED_PIN) == 1 ) ledState = 1;
if( digitalRead(LED_PIN) == 0 ) ledState = 0;}
void backlight(){
byte buttonState = digitalRead(BUTTON_PIN); //следим за состоянием кнопки
if (buttonState != lastButtonState) { //проверить, если не равно
lastButtonState = buttonState; //если пред. правда, сделать равным
if (buttonState == HIGH) {
ledState = (ledState == HIGH) ? LOW : HIGH;
digitalWrite(LED_PIN, ledState); }}}
void status_bar(){
if (cpu_gauge > cpu_gauge_step*1) u8g2.drawBox(2,13,6,8); //x, y, размер по x, размер по y
if (cpu_gauge > cpu_gauge_step*2) u8g2.drawBox(2 + 1*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*3) u8g2.drawBox(2 + 2*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*4) u8g2.drawBox(2 + 3*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*5) u8g2.drawBox(2 + 4*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*6) u8g2.drawBox(2 + 5*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*7) u8g2.drawBox(2 + 6*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*8) u8g2.drawBox(2 + 7*move,13,6,8);
if (cpu_gauge > cpu_gauge_step*9) u8g2.drawBox(2 + 8*move,13,6,8);
if (cpu_gauge >= cpu_gauge_step*10) u8g2.drawBox(2 + 9*move,13,6,8);
}
void setup(void) {
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
pinMode(BUZZ_PIN, OUTPUT);
pinMode(BUTTON_L, INPUT);
pinMode(BUTTON_R, INPUT);
pinMode(A7, INPUT);
pinMode(BUTTON_START, INPUT);
eeprom_led = EEPROM.read(0);
digitalWrite(LED_PIN, eeprom_led);
set_led(); //устанавливает состояние светодиода на 1 или 0 в зависимости от цифровой записи
Serial.begin(9600);
u8g2.begin();
}
void loop(void) {
EEPROM.update(0,ledState);
/*pomiar = EEPROM[ 0 ];
delay(2500);//
Serial.println(pomiar);//
Serial.println(cpu_gauge);
int pomiar = digitalRead(BUTTON_START);
Serial.println(pomiar);*/
backlight();
cpu_gauge = analogRead(A7) * (5.0/1022);
u8g2.firstPage();
do {
u8g2.drawRFrame(0,12,74,10,3); //позиция X,Y длина, ширина, угол
status_bar();
u8g2.setFont(u8g2_font_busdisplay8x5_tr);
u8g2.setCursor(0,8);
char pomiar_str[5];
dtostrf(cpu_gauge,0,2, pomiar_str);
sprintf(buffer, "LOAD: %sV", pomiar_str);
u8g2.print(buffer);
u8g2.setCursor(0,36);
u8g2.print("bckgrnd_tsks:");
u8g2.setCursor(48,48);
sprintf(buffer, "led: %d", ledState);
u8g2.print(buffer);
u8g2.drawStr(0,48,"buzz:");
if (cpu_gauge > 4.80){
digitalWrite(7,1);
u8g2.setCursor(0,48);
u8g2.setFont(u8g2_font_busdisplay8x5_tr);
u8g2.setFont(u8g2_font_open_iconic_play_1x_t);
u8g2.drawGlyph(27, 48, 0x0040);}
else
digitalWrite(7,0);
} while ( u8g2.nextPage() );}
Я успешно создал программу, которая:
-Имеет кнопку выключения и включения подсветки при каждом нажатии
-Записывает в EEPROM состояние светодиода и считывает его при запуске
-Отображает значение AnalogRead от потенциометра, а также отображает индикатор выполнения заданного значения
-Отображает состояние подсветки
-Включает зуммер, если значение AnalogRead превышает какое-то значение
-Отображает индикатор, если зуммер включен
Теперь давайте предположим, что то, что делает эта программа, называется опцией "А", и А в этом примере работает все время, потому что ничего другого нет. Я хочу создать меню, в котором будут варианты A, B, C, D. Предположим, что форматирование и действия кнопок пока не имеют значения.
A: Это то, что было описано ранее.
Б: Часы. Просто покажите часы.
C: Секундомер.
D: Установка времени.
Я вижу два способа создания такого меню.
1: создать выбираемое/прокручиваемое меню с метками, и, выбирая и нажимая кнопку, мы могли бы входить в нужную функцию.
2: отказаться от выбираемого меню. Одна кнопка переключает с варианта A на D. Что-то вроде часов Casio.
Я бы предпочел второй вариант, думаю, так будет проще
Чего я не понимаю, так это справочного руководства по U8G2. Я не очень понимаю концепцию буфера, sendBuffer, userInterfaceSelectionList и еще кое-чего, что пока не могу назвать.
Я понимаю, что мне нужно сделать некоторый массив функций. Нравится:
Array [] = {default_display();, clock();, stopwatch();, setting();)
И с помощью кнопки я бы прошел через этот массив следующим образом:
Array = 0;
If (digitalRead(some_button_pin) == High){
Array + 1;}
If (Array > 3){
Array = 0;}
И в этих функциях были бы реализованы опции, например включение подсветки или что-то еще, что угодно,
Теперь я не знаю, имеет ли это какой-то смысл. Если это можно перевести в код. Я не знаю, нужно ли мне очищать дисплей и как это сделать только один раз перед вводом опции. Как мне сделать так, чтобы все переменные, связанные с часами, секундомером все еще работали, даже если я его не показываю. Я, честно говоря, растерялся, и мне просто нужно руководство по этому поводу, потому что у меня был только C в течение 1 семестра по электротехнике. Я не програмист, но очень хочется, чтобы это работало, но просто не объяснено так, как я не знаю, подтягивающие резисторы, где можно сделать какие-то предположения, и с их помощью объяснить, как что-то работает . Нет, это выглядит так:
void u8g2_SetBufferPtr(u8g2_t *u8g2, uint8_t *buf)
И да, я просто не знаю, как мне его обойти, как мне в нем ориентироваться. Спасибо за любую помощь.
@kshysztof, 👍-1
Обсуждение1 ответ
Лучший ответ:
Я разобрался. Первое, что нужно сказать. Если вы привыкли создавать определения функций перед установкой, вы не сможете сделать это с библиотекой u8g2. Вы можете создавать определения функций после вызова u8g2.begin в настройках. Теперь есть два способа, как вы можете это сделать, в "часах Casio" fashion, но сначала создайте переменную, которая будет считывать, сколько раз вы нажали, и сохраните ее где-нибудь, а также добавьте условие, которое вернет ее к 1 после некоторого количества кликов. 1-й способ: Создайте кейс-переключатель, где переменная будет вашим переключателем, а в кейсах (от x до n) напишите что хотите, графику, текст, что угодно. Теперь проблема, с которой я столкнулся, заключается в том, что когда я вставил тот же код и изменил только небольшой текст, все это дало сбой. Прошел 1 и 2, нормально, а потом все из дела 3 и 4 слилось воедино, а дело 4 было пустым, как и экран. Я не мог это исправить, поэтому я придумал второй подход. Создайте столько условий ЕСЛИ, сколько у вас есть в меню. Итак, это выглядит так: If (menu_counter == 1){ //ваш ввод на экран// } И так для остальных. Насколько я проверял, это работает, даже если код одинаков для обоих операторов IF. Теперь мне нужно реализовать список выбора меню сверху. Оставляю ответ на свой вопрос, надеюсь, кому-то он будет полезен.
- Есть ли подробные примеры Si4463?
- Ошибка: "'lcd' does not name a type" при использовании библиотеки LiquidCrystal.
- Как инициализировать RepRap Discount 12864 на u8glib?
- Отобразить изображение с SD-карты на ЖК-дисплей ILI9486
- Использование Broadcom AFBR-S50 с Arduino
- ST7735s 1.8" SPI 128x160 TFT Модуль - Белый экран
- ST7920 и u8g2 используют только часть дисплея 128x64.
- Библиотека LiquidCrystal и таймеры кажутся несовместимыми.
ваш код очень плохо отформатирован... например, операторы
if
внутри функцииvoid status_bar()
не являются вложенными, все они должны иметь одинаковый отступ... то же самое со строками программы вsetup( )
функция, @jsotolaИзвините, меня не учили/не изучали этику кодирования, в смысле форматирования. Код был легко читаем для меня, и я мог легко найти нужные мне части :) В следующий раз я буду использовать автоформатирование перед публикацией, @kshysztof
Кстати, почему вы используете программный SPI для дисплея?, @Juraj
Потому что это дисплей 5110, и, насколько я знаю, он поддерживает только связь SPI., @kshysztof