#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 icon_selected = 0;
int icon_hovered = 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 (icon_selected == 0){ // if the button is not active
if (icon_hovered == 1){ // check if first icon
icon_hovered = icon_number; //return back to end
}
else{
icon_hovered--; // scroll back
}
}
// Different actions dependig on program when button is active
if (icon_selected == 1){
if (icon_hovered == 1){ // if first icon
Serial.println("Decreasing Volume");
}
if (icon_hovered == 2){ // if first icon
Serial.println("Decreasing Brush Size");
}
if (icon_hovered == 3){ // if first icon
Serial.println("Action Ai");
}
}
}
else {
// the encoder is rotating in clockwise direction => increase the counter
counter++;
direction = DIRECTION_CW;
// Check if the button is active
if (icon_selected == 0){ // if the button is not active
if (icon_hovered == icon_number){ // check if last icon
icon_hovered = 1; //return back to beginning
}
else{
icon_hovered++; // scroll to next
}
}
// Different actions dependig on program when button is active
if (icon_selected == 1){
if (icon_hovered == 1){ // if first icon
Serial.println("Increasing Volume");
}
if (icon_hovered == 2){ // if first icon
Serial.println("Increasing Brush Size");
}
if (icon_hovered == 3){ // if first icon
Serial.println("Action Ai");
}
}
}
// 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(" - icon_hovered: ");
// Serial.println(icon_hovered);
//### SCREEN DISPLAY ###
// Show different things on display depending on the state
if (icon_selected == 0){
u8g2.setDrawColor(1);
if (icon_hovered == 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(14, 23, 16, 19, image_PS_bits);
u8g2.drawXBMP(50, 18, 27, 28, image_Volume_bits);
u8g2.sendBuffer();
}
else if (icon_hovered == 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(56, 23, 16, 19, image_PS_bits);
u8g2.drawXBMP(92, 18, 27, 28, image_Volume_bits);
u8g2.sendBuffer();
}
else if (icon_hovered == 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(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.isReleased()) {
// Toggle icon_selected state
icon_selected = !icon_selected;
if (icon_selected == 1){
u8g2.setDrawColor(1);
u8g2.drawXBMP(58, 4, 13, 7, image_Arrow_bits);
u8g2.sendBuffer();
if (icon_hovered == 1){ //Volume Active
Serial.println("Volumne Engaged");
}
else if (icon_hovered == 2){ //PS Active
Serial.println("PS Engaged");
}
else if (icon_hovered == 3){ //AI Active
Serial.println("AI Engaged");
}
}
if (icon_selected == 0){
Serial.println("Button is off");
u8g2.setDrawColor(0);
u8g2.drawXBMP(58, 4, 13, 7, image_Arrow_bits);
u8g2.sendBuffer();
}
}
}