#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32_PWM.h> // Inclui a biblioteca ESP32PWM
#define TIMER_BASE_CLK 80000000 // Substitua pelo valor correto para o seu ESP32


// Configurações do LCD (Endereço I2C, colunas, linhas)
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Definições de pinos e configurações de PWM
const int pinoPWM = 25;         // Pino onde o sinal PWM será gerado (GPIO 25)
const int pinoPotenciometro = 34; // Pino analógico onde o potenciômetro está conectado (GPIO 34)
const int canalPWM = 0;         // Canal PWM (ESP32 possui 16 canais PWM)
const int frequenciaPWM = 5000; // Frequência do PWM
const int resolucaoPWM = 8;     // Resolução do PWM (0 a 255)

// Valores de tensão
const double tensaoMin = 2.6661301;  // Tensão mínima desejada
const double tensaoMax = 2.8623712;  // Tensão máxima desejada
const double tensaoRef = 3.3;        // Tensão de referência do ESP32

void setup() {
  // Inicializa a comunicação serial para depuração
  Serial.begin(115200);

  // Inicializa o LCD
  lcd.init();
  lcd.backlight();

  // Configura o canal PWM
  ledcSetup(canalPWM, frequenciaPWM, resolucaoPWM);
  ledcAttachPin(pinoPWM, canalPWM);
  
  // Configura o canal PWM
  ledcSetup(canalPWM, frequenciaPWM, resolucaoPWM); // Configura o PWM no canal 0, frequência 5000Hz, resolução de 8 bits
  // Anexa o canal PWM ao pino de saída
  ledcAttachPin(pinoPWM, canalPWM); // Anexa o pino PWM (GPIO 25) ao canal 0
}

void loop() {
  // Lê o valor do potenciômetro (0 a 4095)
  int leituraPot = analogRead(pinoPotenciometro);

  // Mapeia a leitura do potenciômetro para a faixa de tensão desejada (2,6661301V a 2,8623712V)
  double tensaoDesejada = map(leituraPot, 0, 4095, tensaoMin * 10000, tensaoMax * 10000) / 10000.0;

  // Converte a tensão desejada para o valor PWM correspondente
  int valorPWM = (tensaoDesejada / tensaoRef) * 255; // Como a resolução é 8 bits, o valor máximo é 255

  // Aplica o valor PWM no pino de saída
  ledcWrite(canalPWM, valorPWM); // Define o valor PWM no canal 0

  // Exibe a tensão desejada no display LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Tensao: ");
  lcd.print(tensaoDesejada, 6); // Exibe com 6 casas decimais
  lcd.print(" V");

  // Também exibe no monitor serial para depuração
  Serial.print("Tensao Desejada: ");
  Serial.println(tensaoDesejada, 6);

  // Aguarda 500ms antes da próxima leitura
  delay(500);
}