#include <Wire.h> // I2C communication library
#include <Adafruit_SSD1306.h> // Adafruit SSD1327 library for OLED
#include <ESP32RotaryEncoder.h> // ESP32RotaryEncoder library by Matthew Clark
// OLED display configuration (SSD1327 128x128 via I2C on ESP32 default pins)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // -1 for no reset pin
// Rotary encoder pin definitions for ESP32
#define ENCODER_PIN_A 12 // Encoder pin A (CLK)
#define ENCODER_PIN_B 14 // Encoder pin B (DT)
#define BUTTON_PIN 27 // Encoder button pin (SW)
// Initialize the rotary encoder object
RotaryEncoder encoder(ENCODER_PIN_A, ENCODER_PIN_B, BUTTON_PIN, -1);
// Menu items and variables
const char* menuItems[] = {"Start", "Settings", "About", "Exit"};
const int numItems = 4; // Number of menu items
volatile int menuIndex = 0; // Currently selected menu item index (volatile for interrupt)
volatile bool buttonPressed = false; // Flag for button press
// Declare callback functions at the top
//void onEncoderTurned(int newCount); // Declaration for rotation callback
//void onButtonPressed(unsigned long timestamp); // Declaration for button press callback with timestamp
// Draw menu function
void drawMenu() {
display.clearDisplay();
display.setTextSize(2); // Text size 2 (16 pixels high)
for (int i = 0; i < numItems; i++) {
if (i == menuIndex) {
// Highlight selected item with white background and black text
display.fillRect(0, i * 16, SCREEN_WIDTH, 16, WHITE);
display.setTextColor(BLACK);
} else {
display.setTextColor(WHITE);
}
display.setCursor(0, i * 16);
display.println(menuItems[i]);
}
display.display(); // Update the display
}
// Define callback functions
void onEncoderTurned(int newCount) {
menuIndex = newCount; // Update menuIndex with the new count
}
void onButtonPressed(unsigned long timestamp) {
buttonPressed = true; // Set flag to handle in loop (timestamp ignored)
}
void setup() {
// Start serial communication for debugging
Serial.begin(115200);
// Initialize the OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // I2C addressadjust to 0x3C if needed
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Loop forever if display fails
}
display.clearDisplay();
display.display();
// Configure the rotary encoder
encoder.setEncoderType( EncoderType::HAS_PULLUP );
encoder.setBoundaries(0, numItems - 1); // Set min/max values (0 to 3)
encoder.onTurned(onEncoderTurned); // Set rotation callback
encoder.onPressed(onButtonPressed); // Set button press callback
encoder.begin(); // Initialize encoder with interrupts
Serial.println("ESP32 Menu System Started");
}
void loop() {
// Draw the menu (menuIndex updated via callback or reset)
drawMenu();
// Handle button press (set by callback)
if (buttonPressed) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
switch (menuIndex) {
case 0: // Start
display.println("Starting...");
break;
case 1: // Settings
display.println("Settings:");
break;
case 2: // About
display.println("About:");
break;
case 3: // Exit
display.println("Exiting...");
break;
}
display.display();
delay(2000); // Show message for 2 seconds
menuIndex = 0; // Reset to first page (Start)
buttonPressed = false; // Reset flag
}
}