Created
March 6, 2025 04:42
-
-
Save davay42/013df7a7869431bdf1fafb803977f6e2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* ESP32 Counter with OLED Display and Encoder | |
* | |
* Hardware required: | |
* - ESP32 development board | |
* - SH1106 128x64 OLED Display (I2C) | |
* - Rotary Encoder with push button | |
* - 2 additional buttons | |
* | |
* Wiring: | |
* ESP32 Component | |
* ------------------------------------ | |
* GPIO16 (RX2) Encoder Push | |
* GPIO17 Encoder A | |
* GPIO18 Encoder B | |
* GPIO25 BACK Button | |
* GPIO26 CONFIRM Button | |
* GPIO21 (SDA) OLED SDA | |
* GPIO22 (SCL) OLED SCL | |
* 3.3V VCC (OLED, Encoder, Buttons) | |
* GND GND (All components) | |
* | |
* Functionality: | |
* 1. Encoder rotation changes counter value | |
* 2. Any button press (encoder push, BACK, or CONFIRM) resets counter to 0 | |
* 3. Display shows current value (divided by 2 for smoother counting) | |
* 4. Serial monitor shows detailed counter updates | |
*/ | |
#include <Arduino.h> | |
#include <Wire.h> | |
#include <U8g2lib.h> | |
// Pin definitions | |
const uint8_t ENC_PUSH = 16; // Encoder push button | |
const uint8_t ENC_A = 17; // Encoder signal A | |
const uint8_t ENC_B = 18; // Encoder signal B | |
const uint8_t BTN_BACK = 25; // Back button | |
const uint8_t BTN_CONFIRM = 26; // Confirm button | |
// Global variables | |
volatile int32_t encoderValue = 0; | |
volatile uint8_t lastEncA = HIGH; | |
volatile uint8_t lastEncB = HIGH; | |
int lastEncPush = HIGH; | |
int lastBackBtn = HIGH; | |
int lastConfirmBtn = HIGH; | |
// Initialize OLED display | |
U8G2_SH1106_128X64_NONAME_F_HW_I2C display(U8G2_R0, U8X8_PIN_NONE); | |
// Encoder interrupt service routine | |
void IRAM_ATTR encoderISR() { | |
uint8_t a = digitalRead(ENC_A); | |
uint8_t b = digitalRead(ENC_B); | |
if (a != lastEncA) { | |
lastEncA = a; | |
if (a != b) { | |
encoderValue++; | |
} else { | |
encoderValue--; | |
} | |
} | |
} | |
// Display update function | |
void updateDisplay(int32_t value) { | |
display.clearBuffer(); | |
char str[10]; | |
sprintf(str, "%d", value / 2); | |
display.drawStr(10, 35, str); | |
display.sendBuffer(); | |
} | |
void setup() { | |
// Initialize serial communication | |
Serial.begin(115200); | |
Serial.println("ESP32 Counter Example Starting..."); | |
// Configure pins | |
pinMode(ENC_PUSH, INPUT_PULLUP); | |
pinMode(ENC_A, INPUT_PULLUP); | |
pinMode(ENC_B, INPUT_PULLUP); | |
pinMode(BTN_BACK, INPUT_PULLUP); | |
pinMode(BTN_CONFIRM, INPUT_PULLUP); | |
// Initialize display | |
display.begin(); | |
display.setFont(u8g2_font_ncenB14_tr); | |
updateDisplay(0); | |
// Attach encoder interrupt | |
attachInterrupt(digitalPinToInterrupt(ENC_A), encoderISR, CHANGE); | |
Serial.println("Setup complete. Rotate encoder or press any button."); | |
} | |
void loop() { | |
static int32_t lastDisplayedValue = 0; | |
// Update display if value changed | |
if (encoderValue != lastDisplayedValue) { | |
Serial.printf("Encoder value: %d (displayed: %d)\n", encoderValue, encoderValue / 2); | |
updateDisplay(encoderValue); | |
lastDisplayedValue = encoderValue; | |
} | |
// Read all buttons | |
int encPush = digitalRead(ENC_PUSH); | |
int backBtn = digitalRead(BTN_BACK); | |
int confirmBtn = digitalRead(BTN_CONFIRM); | |
// Check for button presses and reset counter | |
if ((encPush != lastEncPush && encPush == LOW) || | |
(backBtn != lastBackBtn && backBtn == LOW) || | |
(confirmBtn != lastConfirmBtn && confirmBtn == LOW)) { | |
encoderValue = 0; | |
updateDisplay(encoderValue); | |
Serial.println("Counter reset by button press"); | |
} | |
// Update button states | |
lastEncPush = encPush; | |
lastBackBtn = backBtn; | |
lastConfirmBtn = confirmBtn; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment