Added a menu to check info

This commit is contained in:
2026-06-23 19:27:43 +03:00
parent 5e88eee23b
commit 76606c00e3
5 changed files with 215 additions and 8 deletions
+28
View File
@@ -0,0 +1,28 @@
#ifndef MENU_H
#define MENU_H
#include <Arduino.h>
#include <U8g2lib.h>
enum class MenuAction
{
ShowHelloWorld,
BackToCarousel
};
class Menu
{
public:
Menu();
void draw(U8G2 &u8g2);
void nextOption();
MenuAction select();
bool consumeDirty();
void requestRedraw();
private:
size_t selectedIndex_;
bool dirty_;
};
#endif
+1
View File
@@ -6,6 +6,7 @@
#include "am2302_sensor.h"
void drawScreen1(U8G2 &u8g2);
void drawHelloWorldScreen(U8G2 &u8g2);
void setEnvironmentReading(Am2302Reading reading);
void drawEnvironmentScreen(U8G2 &u8g2);
void drawWeatherIconScreen(U8G2 &u8g2);
+115 -8
View File
@@ -4,23 +4,37 @@
#include "am2302_sensor.h"
#include "carousel.h"
#include "menu.h"
#include "screens.h"
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R2, U8X8_PIN_NONE);
int lastButtonNextState = LOW;
int lastButtonSelectState = LOW;
uint8_t buttonNext = A4;
uint8_t buttonSelect = A5;
Am2302Sensor am2302(A3);
enum class AppMode
{
Carousel,
Menu,
HelloWorld
};
Screen screens[] = {
{ drawScreen1 },
{ drawEnvironmentScreen },
{ drawWeatherIconScreen }
};
Carousel carousel(screens, sizeof(screens) / sizeof(screens[0]));
Menu menu;
AppMode appMode = AppMode::Carousel;
bool appDirty = true;
void setup() {
pinMode(buttonNext, INPUT);
pinMode(buttonSelect, INPUT);
am2302.begin();
u8g2.begin();
@@ -28,24 +42,117 @@ void setup() {
u8g2.sendBuffer();
}
void openMenu()
{
appMode = AppMode::Menu;
menu.requestRedraw();
appDirty = true;
}
void selectMenuOption()
{
switch (menu.select()) {
case MenuAction::ShowHelloWorld:
appMode = AppMode::HelloWorld;
break;
case MenuAction::BackToCarousel:
appMode = AppMode::Carousel;
carousel.requestRedraw();
break;
}
appDirty = true;
}
void handleNextButton()
{
switch (appMode) {
case AppMode::Carousel:
carousel.nextScreen();
break;
case AppMode::Menu:
menu.nextOption();
break;
case AppMode::HelloWorld:
break;
}
}
void handleSelectButton()
{
switch (appMode) {
case AppMode::Carousel:
case AppMode::HelloWorld:
openMenu();
break;
case AppMode::Menu:
selectMenuOption();
break;
}
}
bool displayNeedsRedraw()
{
if (appDirty) {
appDirty = false;
return true;
}
switch (appMode) {
case AppMode::Carousel:
return carousel.consumeDirty();
case AppMode::Menu:
return menu.consumeDirty();
case AppMode::HelloWorld:
return false;
}
return false;
}
void drawActiveView()
{
switch (appMode) {
case AppMode::Carousel:
carousel.draw(u8g2);
break;
case AppMode::Menu:
menu.draw(u8g2);
break;
case AppMode::HelloWorld:
drawHelloWorldScreen(u8g2);
break;
}
}
void loop(){
const unsigned long now = millis();
carousel.update(now);
if (appMode == AppMode::Carousel) {
carousel.update(now);
}
if (am2302.update(now)) {
setEnvironmentReading(am2302.reading());
carousel.requestRedraw();
if (appMode == AppMode::Carousel) {
carousel.requestRedraw();
}
}
const int currentButtonState = digitalRead(buttonNext);
if (lastButtonNextState == LOW && currentButtonState == HIGH) {
carousel.nextScreen();
const int currentButtonNextState = digitalRead(buttonNext);
if (lastButtonNextState == LOW && currentButtonNextState == HIGH) {
handleNextButton();
}
lastButtonNextState = currentButtonState;
lastButtonNextState = currentButtonNextState;
if (carousel.consumeDirty()) {
const int currentButtonSelectState = digitalRead(buttonSelect);
if (lastButtonSelectState == LOW && currentButtonSelectState == HIGH) {
handleSelectButton();
}
lastButtonSelectState = currentButtonSelectState;
if (displayNeedsRedraw()) {
u8g2.clearBuffer();
carousel.draw(u8g2);
drawActiveView();
u8g2.sendBuffer();
}
+64
View File
@@ -0,0 +1,64 @@
#include "menu.h"
namespace
{
const char *menuOptions[] = {
"Hello world",
"Back"
};
const size_t menuOptionCount = sizeof(menuOptions) / sizeof(menuOptions[0]);
MenuAction actionForIndex(size_t index)
{
switch (index) {
case 0:
return MenuAction::ShowHelloWorld;
default:
return MenuAction::BackToCarousel;
}
}
}
Menu::Menu()
: selectedIndex_(0),
dirty_(true) {}
void Menu::draw(U8G2 &u8g2)
{
u8g2.setFont(u8g2_font_6x12_tr);
u8g2.drawStr(0, 12, "Menu");
for (size_t i = 0; i < menuOptionCount; i++) {
const uint8_t y = 32 + (i * 18);
if (i == selectedIndex_) {
u8g2.drawStr(0, y, ">");
}
u8g2.drawStr(12, y, menuOptions[i]);
}
dirty_ = false;
}
void Menu::nextOption()
{
selectedIndex_ = (selectedIndex_ + 1) % menuOptionCount;
dirty_ = true;
}
MenuAction Menu::select()
{
return actionForIndex(selectedIndex_);
}
bool Menu::consumeDirty()
{
const bool d = dirty_;
dirty_ = false;
return d;
}
void Menu::requestRedraw()
{
dirty_ = true;
}
+7
View File
@@ -33,6 +33,13 @@ void drawScreen1(U8G2 &u8g2)
u8g2.drawStr(0, 20, "Screen 1");
}
void drawHelloWorldScreen(U8G2 &u8g2)
{
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.drawStr(0, 30, "Hello");
u8g2.drawStr(0, 54, "world");
}
void setEnvironmentReading(Am2302Reading reading)
{
environmentReading = reading;