#define ENCODER_CLK_PIN 34 // CLK-Pin des Rotary Encoders
#define ENCODER_DT_PIN 35 // DT-Pin des Rotary Encoders
#define BUTTON_PIN 32 // Externer Button Pin
#define OLED_RESET -1 // OLED Reset Pin
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET);
int menuIndex = 0;
int submenuIndex = 0;
int value1 = 200;
int value2 = 300;
bool maindisplayActive = true;
bool submenuActive = false;
volatile int encoderPos = 0;
//volatile int lastEncoded = 0;
int lastClk = HIGH;
//For ESP32 we can use all GPIO pins for external interrupt except for GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, and GPIO11.
//This pins are connected to the integrated SPI flas integrated on ESP-WROOM-32 and are not recommended for other use
void IRAM_ATTR updateEncoder(); //It is recommended to add the flag IRAM_ATTR so that the function code is stored in RAM (and not in Flash) so that the function runs faster.
void setup() {
Serial.begin(9600);
pinMode(ENCODER_CLK_PIN, INPUT_PULLUP);
pinMode(ENCODER_DT_PIN, INPUT_PULLUP);
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK_PIN), updateEncoder, CHANGE);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.print("Main Display");
display.display();
}
void loop() {
if (maindisplayActive){
handleMainDisplay();
}else {
if (!submenuActive) {
displayMainMenu();
if (digitalRead(BUTTON_PIN) == LOW) {
handleMainMenuSelection();
}
} else {
displaySubMenu();
if (digitalRead(BUTTON_PIN) == LOW) {
if (menuIndex == 3){
submenuActive = false;
menuIndex = 0;
}
handleSubMenuSelection();
}
}
}
}
void IRAM_ATTR updateEncoder() {
Serial.println("updateEncoder");
int newClk = digitalRead(ENCODER_CLK_PIN);
if (newClk != lastClk) {
// There was a change on the CLK pin
Serial.println("There was a change on the CLK pin");
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT_PIN);
if (newClk == LOW && dtValue == HIGH) {
Serial.println("Rotated clockwise ⏩");
if (!submenuActive && !maindisplayActive && encoderPos < 3){
encoderPos++;
}else if (submenuActive && encoderPos < 3) {
encoderPos++;
}else{
encoderPos = 0;
}
Serial.println(encoderPos);
}
if (newClk == LOW && dtValue == LOW) {
Serial.println("Rotated counterclockwise ⏪");
if (!submenuActive && !maindisplayActive && encoderPos > 0){
encoderPos--;
}else if (submenuActive && encoderPos > 0) {
encoderPos--;
}else{
encoderPos = 0;
}
Serial.println(encoderPos);
}
menuIndex = encoderPos;
}
}
void handleMainDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
display.print("Main Display");
display.display();
if (digitalRead(BUTTON_PIN) == LOW) {
maindisplayActive = false;
}
}
void displayMainMenu() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
for (int i = 0; i < 4; i++) {
if (i == menuIndex) {
display.print(">");
}
if (i < 3) {
display.print("Menu");
display.println(i + 1);
} else {
display.println("Exit");
}
}
//display.println("Exit");
display.display();
}
void handleMainMenuSelection() {
if (menuIndex == 3) {
submenuActive = false;
maindisplayActive = true;
menuIndex = 0;
return;
}
submenuActive = true;
}
void displaySubMenu() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
switch (menuIndex) {
case 0:
display.println("SubMenu1:");
display.print("Value1: ");
display.println(value1);
display.print("Value2: ");
display.println(value2);
break;
case 1:
display.println("SubMenu2:");
break;
case 2:
display.println("SubMenu3:");
break;
case 3:
display.println("Back");
break;
}
display.display();
}
void handleSubMenuSelection() {
if (menuIndex == 0) {
// Submenu 1
submenu1Selection();
}
// Weitere Fälle für andere Untermenüs...
}
void submenu1Selection() {
// Navigation und Wertänderung mit dem Encoder
if (digitalRead(BUTTON_PIN) == LOW) {
// Externer Button gedrückt, Wert ändern
switch (submenuIndex) {
case 0:
// Wert 1 ausgewählt
// Hier kannst du den Wert ändern, z.B. durch Inkrementierung/ Dekrementierung
value1++;
break;
case 1:
// Wert 2 ausgewählt
// Hier kannst du den Wert ändern, z.B. durch Inkrementierung/ Dekrementierung
value2++;
break;
}
// Hier kannst du die Änderungen auf dem Display anzeigen
}
}