#include <LiquidCrystal.h>
// LCD
const int LCD_RS = 21;
const int LCD_E = 22;
const int LCD_D4 = 19;
const int LCD_D5 = 18;
const int LCD_D6 = 5;
const int LCD_D7 = 17;
LiquidCrystal lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
// AD (Knob)
const int potPin = 34;
int potValue = 0;
// Led e PWM
#define LED_PIN 16
#define PWM_FREQ 5000
#define PWM_RESOLUTION 8 // 0..255
#define MAX_STEP 20 // 0..20 -> ~5% por passo
// Botoes
#define BTN_DOWN_PIN 12
#define BTN_UP_PIN 14
int brilhoStep = 0;
bool lastBtnOnOff = HIGH;
bool lastbtnLcdMode = HIGH;
// Sistema inicia desligado, LCD começa no Modo 1
bool systemState = false;
bool lcdMode = false;
int duty = 0;
// Blink withou delay ( https://docs.arduino.cc/built-in-examples/digital/BlinkWithoutDelay/ )
// Debounce ( https://docs.arduino.cc/built-in-examples/digital/Debounce/ )
unsigned long previousMillis = 0;
const long interval = 5; // interval at which to blink (milliseconds)
void setup() {
// Inicializa comunicação serial apenas para depuração
Serial.begin(115200);
// Inicializa o LCD com 16 colunas e 2 linhas
lcd.begin(16, 2);
// Escreve mensagem inicial
lcd.setCursor(0, 0); // coluna 0, linha 0
lcd.print("ESP32 + LCD");
lcd.setCursor(0, 1); // coluna 0, linha 1
lcd.print("Iniciando...");
delay(1000);
// Limpa o display antes de entrar no loop principal
lcd.clear();
// Setup Conversor AD
analogSetPinAttenuation(potPin, ADC_11db);
// Botoes e PWM
pinMode(BTN_DOWN_PIN, INPUT_PULLUP);
pinMode(BTN_UP_PIN, INPUT_PULLUP);
// API nova do Arduino-ESP32 3.x
ledcAttach(LED_PIN, PWM_FREQ, PWM_RESOLUTION);
}
void handleButtons (bool btnOnOff, bool btnLcdMode) {
// Botão 12: Liga/Desliga
if (lastBtnOnOff == HIGH && btnOnOff == LOW) {
if (systemState) { // Ligado -> Desligado
Serial.println("Sistema Desligado");
systemState = false;
ledcWrite(LED_PIN, 0);
} else {
Serial.println("Sistema Ligado");
systemState = true;
}
} else if (lastbtnLcdMode == HIGH && btnLcdMode == LOW) {
lcdMode = !lcdMode;
Serial.print("Modo LCD ");
if (!lcdMode) {
Serial.println("1");
} else {
Serial.println("2");
}
}
}
void updatePWM() {
if (systemState) {
duty = (potValue * 255) / 4095;
ledcWrite(LED_PIN, duty);
}
}
void renderDisplay() {
// Primeira linha
lcd.setCursor(0, 0);
if (!systemState){
lcd.print("Sistema Desligado ");
lcd.setCursor(0, 1);
lcd.print(" ");
} else {
// Modo 1
if (!lcdMode){
lcd.print("Sistema Ligado ");
lcd.setCursor(0, 1);
// Escreve os percent
unsigned long percent = (potValue * 100) / 4095;
lcd.print("Brilho: ");
lcd.print(percent);
lcd.print(" % ");
} else { // Modo 2
lcd.print("ADC: ");
lcd.print(potValue);
lcd.print(" ");
lcd.setCursor(0, 1);
unsigned long percent = (potValue * 100) / 4095;
lcd.print("PWM: ");
lcd.print(duty);
lcd.print(" ");
}
}
}
void loop() {
// Reads Button presses
bool btnOnOff = digitalRead(BTN_DOWN_PIN);
bool btnLcdMode = digitalRead(BTN_UP_PIN);
// Reading potentiometer value
potValue = analogRead(potPin);
// Debounce
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// Botoes
handleButtons(btnOnOff, btnLcdMode);
lastBtnOnOff = btnOnOff;
lastbtnLcdMode = btnLcdMode;
}
// PWM e LED Responsivo
updatePWM();
// Blink w/o delay no LCD para evitar flicker
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
renderDisplay();
}
}