#include <ezButton.h> // the library to use for SW pin
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h> // library requires for IIC communication
//## ENCODER FUNCTIONS ###
#define CLK_PIN 25 // ESP32 pin GPIO25 connected to the rotary encoder's CLK pin
#define DT_PIN 26 // ESP32 pin GPIO26 connected to the rotary encoder's DT pin
#define SW_PIN 27 // ESP32 pin GPIO27 connected to the rotary encoder's SW pin
#define DIRECTION_CW 0 // clockwise direction
#define DIRECTION_CCW 1 // counter-clockwise direction
int counter = 0;
int direction = DIRECTION_CW;
int CLK_state;
int prev_CLK_state;
int button_active = 0;
int screen_state = 1; // 1: volume, 2: PS, 3 AI
int icon_number = 3; // number of total icons
ezButton button(SW_PIN); // create ezButton object that attach to pin 7;
//### OLED SCREEN FUNCTIONS
//OLED Setup
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // initialization for the used OLED display
// Icons for OLED
static const unsigned char image_AI_bits[] U8X8_PROGMEM = {0x03,0x00,0x0f,0x00,0x7f,0x00,0xff,0x03,0xf8,0x0f,0xf8,0x3f,0x38,0x7e,0x38,0x78,0x38,0x7e,0xf8,0x3f,0xf8,0x0f,0xfe,0x03,0xff,0x00,0x1f,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0xff,0x31,0xff,0x79,0xff,0x31};
static const unsigned char image_Frame_bits[] U8X8_PROGMEM = {0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0x3f,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0x07,0x00,0x00,0x00,0x38,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0x3f};
static const unsigned char image_Arrow_bits[] U8X8_PROGMEM = {0xff,0x1f,0xfe,0x0f,0xfc,0x07,0xf8,0x03,0xf0,0x01,0xe0,0x00,0x40,0x00};
static const unsigned char image_PS_bits[] U8X8_PROGMEM = {0xff,0x7f,0xff,0xff,0xff,0xff,0xf0,0xf0,0x70,0xe0,0x70,0xe0,0xe0,0x70,0xe0,0x79,0xc0,0x3f,0x80,0x1f,0x00,0x00,0x00,0x00,0xc6,0x03,0xc7,0x07,0xe7,0x0f,0x67,0x0e,0x7f,0x0e,0x7e,0x0e,0x3c,0x06};
static const unsigned char image_Volume_bits[] U8X8_PROGMEM = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x03,0x00,0x00,0xfc,0x03,0x00,0x00,0xfe,0x07,0x00,0x00,0xff,0x0f,0x00,0x80,0xff,0x1f,0x00,0xc0,0xff,0x3f,0x00,0xe0,0xff,0x7f,0x00,0xf0,0xff,0xff,0x00,0xf8,0xff,0xff,0x01,0xf8,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0c,0x00,0x00,0x07,0x0e,0x00,0x00,0xfe,0x07,0x00,0x00,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
void setup() {
Serial.begin(9600);
//## ENCODER FUNCTIONS ###
// configure encoder pins as inputs
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
button.setDebounceTime(50); // set debounce time to 50 milliseconds
// read the initial state of the rotary encoder's CLK pin
prev_CLK_state = digitalRead(CLK_PIN);
//### OLED SCREEN FUNCTIONS
// start the u8g2library for the screen
u8g2.begin();
}
void loop() {
button.loop(); // MUST call the loop() function first
// read the current state of the rotary encoder's CLK pin
CLK_state = digitalRead(CLK_PIN);
// If the state of CLK is changed, then pulse occurred
// React to only the rising edge (from LOW to HIGH) to avoid double count
if (CLK_state != prev_CLK_state && CLK_state == HIGH) {
// if the DT state is HIGH
// the encoder is rotating in counter-clockwise direction => decrease the counter
if (digitalRead(DT_PIN) == HIGH) {
counter--;
direction = DIRECTION_CCW;
// Check if the button is active
if (button_active == 0){ // if the button is not active
if (screen_state == 1){ // check if last icon
screen_state = icon_number; //return back to beginning
}
else{
screen_state--; // scroll back
}
}
}
else {
// the encoder is rotating in clockwise direction => increase the counter
counter++;
direction = DIRECTION_CW;
// Check if the button is active
if (button_active == 0){ // if the button is not active
if (screen_state == icon_number){ // check if last icon
screen_state = 1; //return back to beginning
}
else{
screen_state++; // scroll to next
}
}
}
Serial.print("Rotary Encoder:: direction: ");
if (direction == DIRECTION_CW)
Serial.print("Clockwise");
else
Serial.print("Counter-clockwise");
Serial.print(" - count: ");
Serial.println(counter);
Serial.print(" - screen_state: ");
Serial.println(screen_state);
//### SCREEN DISPLAY ###
// Show different things on display depending on the state
if (button_active == 0 && screen_state == 1){ //Volume Active
Serial.println("VolumeS Active");
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFontMode(1);
u8g2.setBitmapMode(1);
u8g2.drawXBMP(98, 20, 15, 20, image_AI_bits);
u8g2.drawXBMP(45, 13, 38, 38, image_Frame_bits);
u8g2.drawXBMP(58, 4, 13, 7, image_Arrow_bits);
u8g2.drawXBMP(14, 23, 16, 19, image_PS_bits);
u8g2.drawXBMP(50, 18, 27, 28, image_Volume_bits);
u8g2.sendBuffer();
}
else if (button_active == 0 && screen_state == 2){ //PS Active
Serial.println("PS Active");
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFontMode(1);
u8g2.setBitmapMode(1);
u8g2.drawXBMP(15, 21, 15, 20, image_AI_bits);
u8g2.drawXBMP(45, 13, 38, 38, image_Frame_bits);
u8g2.drawXBMP(58, 4, 13, 7, image_Arrow_bits);
u8g2.drawXBMP(56, 23, 16, 19, image_PS_bits);
u8g2.drawXBMP(92, 18, 27, 28, image_Volume_bits);
u8g2.sendBuffer();
}
else if (button_active == 0 && screen_state == 3){ //AI Active
Serial.println("AI Active");
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFontMode(1);
u8g2.setBitmapMode(1);
u8g2.drawXBMP(56, 21, 15, 20, image_AI_bits);
u8g2.drawXBMP(45, 13, 38, 38, image_Frame_bits);
u8g2.drawXBMP(58, 4, 13, 7, image_Arrow_bits);
u8g2.drawXBMP(98, 23, 16, 19, image_PS_bits);
u8g2.drawXBMP(8, 19, 27, 28, image_Volume_bits);
u8g2.sendBuffer();
}
}
// save last CLK state
prev_CLK_state = CLK_state;
if (button.isPressed()) {
// Toggle button_active state
button_active = !button_active;
Serial.print("Button Active: ");
Serial.println(button_active);
}
}