#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Define the menu structure. Each entry is a string for display and a pointer to either
// another menu array or a function to run when the item is selected.
struct MenuItem {
const char* text;
void (*function)();
MenuItem* submenu;
};
// Declare the menu items
void itemFunc1();
void itemFunc2();
MenuItem subMenu3[] = {
{"Subitem 1", itemFunc1, NULL},
{"Subitem 2", itemFunc2, NULL},
{NULL, NULL, NULL}
};
MenuItem subMenu2[] = {
{"Submenu 3", NULL, subMenu3},
{"Item 2-2", itemFunc2, NULL},
{NULL, NULL, NULL}
};
MenuItem mainMenu[] = {
{"Item 1", itemFunc1, NULL},
{"Submenu 2", NULL, subMenu2},
{NULL, NULL, NULL}
};
// Define variables to keep track of the current menu state
MenuItem* current_menu = mainMenu;
int current_item = 0;
unsigned long last_button_press = 0;
void setup() {
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.display();
}
void loop() {
// Display the current menu
display.clearDisplay();
display.setCursor(0,0);
display.println(current_menu[current_item].text);
display.display();
// Check for button press to select item or navigate the menu
if(digitalRead(button_pin) == LOW) {
unsigned long button_press_duration = millis() - last_button_press;
last_button_press = millis();
if(button_press_duration < short_press_duration) { // Short press: go to next item or submenu
if(current_menu[current_item].submenu != NULL) { // Enter submenu
current_menu = current_menu[current_item].submenu;
current_item = 0;
} else { // Go to next item in current menu
current_item++;
if(current_menu[current_item].text == NULL) { // Reached end of menu, wrap around
current_item = 0;
}
}
} else if(button_press_duration < double_press_duration) { // Double press: select item
current_menu[current_item].function();
} else if(button_press_duration >= long_press_duration) { // Long press: go back up a level in the menu
if(current_menu != mainMenu) {
current_menu = mainMenu;
current_item = 0;
}
}
delay(250); // debounce
}
}
void itemFunc1() {
// Do something when Item 1 is selected
}
void itemFunc2() {
// Do something when Item 2 is selected
}
示例使用了一个菜单项结构体数组来定义菜单层次结构,每个项目包括显示的文本和指向子菜单或选项功能函数的指针。在setup()
中初始化当前菜单状态,并在loop()
中显示当前菜单项并检测按钮按下事件。如果用户进行了短按,则将焦点移动到下一个菜单项或子菜单。如果进行的是双击,则调用当前菜单项上的功能函数。如果进行的是长按,则返回上一级菜单。您可以根据需要自定义短按、双击和长按的时间长度,代码中使用的是short_press_duration
(短按)、double_press_duration
(双击)和long_press_duration
(长按)这些变量来设置这些时间值。
Arduino Nano进行测试的接线方式:
- OLED VCC引脚连接到Arduino Nano的5V引脚上。
- OLED GND引脚连接到Arduino Nano的GND引脚上。
- OLED SDA引脚连接到Arduino Nano的A4引脚上。
- OLED SCL引脚连接到Arduino Nano的A5引脚上。