#include <U8g2lib.h>
// Pin definions
#define ENCODER_CLK 0
#define ENCODER_DT 4
#define ENCODER_SW 16
#define BUZZER 13
#define BUTTON_UP 2
#define BUTTON_DW 15
#define POT_1 34
#define POT_2 35
#define POT_3 32
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
volatile bool switchPressed = false; // Flag to indicate switch press
enum Modes{
ECO = 1,
LINEAR = 2,
ATAQUE = 3,
MAX_MODES // This will automatically be set to the total number of modes
};
const char* modeNames[] = {
"ECO",
"LINEAR",
"ATAQUE"
};
int currentMode = LINEAR;
int refreshInterval = 100; // Interval between screen updates
// Selective Screen Update Logic
int lastUpdate = -1;
int lastSpeed = -1;
int lastThrottle = -1;
int lastBattery = -1;
int lastMode = -1;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
attachInterrupt(digitalPinToInterrupt(ENCODER_SW), encoderISR, FALLING);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DW, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
pinMode(POT_1, INPUT);
pinMode(POT_2, INPUT);
pinMode(POT_3, INPUT);
lastMode = currentMode;
u8g2.begin();
u8g2.setPowerSave(0);
u8g2.clearBuffer();
u8g2.setFontMode(1);
u8g2.setBitmapMode(1);
u8g2.setFont(u8g2_font_profont29_tr);
u8g2.drawStr(8, 30, "ESP-NOW");
u8g2.setFont(u8g2_font_profont12_tr);
u8g2.drawStr(1, 50, "A Estabelecer Conexao");
u8g2.sendBuffer();
tone(BUZZER, 1000, 10);
delay(50);
tone(BUZZER, 1200, 10);
delay(50);
tone(BUZZER, 1500, 10);
while (digitalRead(BUTTON_UP) + digitalRead(BUTTON_DW) == 2){
}
}
int lastClk = HIGH;
void encoderISR(){
switchPressed = true;
}
void home(int mode, int throttlePosition, int speed, int battery){
u8g2.clearBuffer();
u8g2.setFontMode(1);
u8g2.setBitmapMode(1);
u8g2.setFont(u8g2_font_profont15_tr);
// Map mode
u8g2.drawStr(2, 11, "Modo:");
u8g2.setCursor(44, 11);
u8g2.print(modeNames[mode - 1]);
u8g2.setFont(u8g2_font_profont11_tr);
// Throttle Position
u8g2.setCursor(100, 11);
u8g2.print(throttlePosition);
u8g2.drawStr(120, 11, "%");
// Speed
u8g2.drawStr(2, 39, "Velocidade:");
u8g2.setCursor(74, 39);
u8g2.print(speed);
u8g2.drawStr(92, 39, "km/h");
// Battery
u8g2.drawStr(2, 51, "Bateria:");
u8g2.setCursor(56, 51);
u8g2.print(battery);
u8g2.drawStr(70, 51, "%");
u8g2.sendBuffer();
lastUpdate = millis();
}
void loop() {
int throttlePosition = map(analogRead(POT_1), 0, 4095, 0, 100);
int speed = map(analogRead(POT_2), 0, 4095, 0, 100);
int battery = map(analogRead(POT_3), 0, 4095, 0, 100);
int newClk = digitalRead(ENCODER_CLK);
if (digitalRead(BUTTON_UP) == LOW) { // Button pressed for UP
currentMode++;
if (currentMode >= MAX_MODES) {
currentMode = ECO; // Wrap around to the first mode
}
}
if (digitalRead(BUTTON_DW) == LOW) { // Button pressed for DOWN
currentMode--;
if (currentMode < ECO) {
currentMode = ATAQUE; // Wrap around to the last mode
}
}
if(switchPressed){
Serial.println("Switch Pressed 🔘");
tone(BUZZER, 1000, 10);
switchPressed = false;
}
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
int dtValue = digitalRead(ENCODER_DT);
if (newClk == LOW && dtValue == HIGH) {
Serial.println("Rotated clockwise ⏩");
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_profont29_tr);
u8g2.drawStr(56, 40, "R");
u8g2.sendBuffer();
tone(BUZZER, 1200, 10);
}
if (newClk == LOW && dtValue == LOW) {
Serial.println("Rotated counterclockwise ⏪");
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_profont29_tr);
u8g2.drawStr(56, 40, "L");
u8g2.sendBuffer();
tone(BUZZER, 800, 10);
}
}
if(millis() > lastUpdate + refreshInterval){
if(currentMode != lastMode){
switch(currentMode){
case 1:
tone(BUZZER, 800, 10);
break;
case 2: // LINEAR
tone(BUZZER, 1000, 10);
break;
case 3:
tone(BUZZER, 1200, 10);
break;
default:
break;
}
}
if(throttlePosition != lastThrottle || speed != lastSpeed || battery != lastBattery || currentMode != lastMode){
home(currentMode, throttlePosition, speed, battery);
lastThrottle = throttlePosition;
lastSpeed = speed;
lastBattery = battery;
lastMode = currentMode;
}
}
}