#include <LiquidCrystal_I2C.h>
#include <Relay.h>
#include <PID_v1.h> // Biblioteca PID padrão do Arduino
Relay light(4, false);
// ALTERAÇÃO: LDR agora precisa estar em um pino analógico (ex: A0)
#define LDR_PIN A0
#define LED_PWM_PIN 11
LiquidCrystal_I2C lcd(0x27, 20, 4);
// --- VARIÁVEIS DO PID ---
double Setpoint; // Nível de turbidez que você deseja manter
double Input; // Leitura atual do LDR
double Output; // Saída calculada pelo PID
// Constantes de Tuning (Kp, Ki, Kd) - Ajuste esses valores conforme o seu sistema real
double Kp = 2.0;
double Ki = 5.0;
double Kd = 1.0;
// Inicializa o PID. DIRECT significa que se a turbidez aumentar, a saída aumenta.
// Se precisar do inverso, mude para REVERSE.
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE);
// --- CONTROLE DE TEMPO DO RELÉ ---
unsigned long windowStartTime;
unsigned long WindowSize = 2000; // Janela de tempo de 2 segundos (2000ms)
void setup() {
Serial.begin(9600);
light.begin();
pinMode(LED_PWM_PIN, OUTPUT);
lcd.init();
lcd.backlight();
// Definir o objetivo: ajuste esse valor (0 a 1023) para o ponto ideal de turbidez
Setpoint = 511;
// Configura o PID para trabalhar no intervalo do tamanho da nossa janela de tempo
myPID.SetOutputLimits(0, WindowSize);
myPID.SetMode(AUTOMATIC);
windowStartTime = millis();
}
void loop() {
// 1. Lê a turbidez atual (0 a 1023)
Input = analogRead(LDR_PIN);
// O led.flash original usava o pino digital. Como mudamos para A0,
// pode ser necessário ajustar a lógica da sua biblioteca LED se ela piscar baseada no sensor.
// PWM proporcional
int brilho = map((int)Input, 8, 1000, 0, 255);
brilho = constrain(brilho, 0, 255);
analogWrite(LED_PWM_PIN, brilho);
// 2. Calcula o PID
myPID.Compute();
// 3. Aplica a lógica de Janela de Tempo para o Relé
unsigned long now = millis();
if (now - windowStartTime > WindowSize) {
windowStartTime += WindowSize; // Move para a próxima janela
}
// Se o valor calculado pelo PID for maior que o tempo decorrido na janela atual, liga
if (Output > (now - windowStartTime)) {
light.turnOn();
} else {
light.turnOff();
}
// 4. Atualiza o LCD
lcd.setCursor(0, 0);
lcd.print("Turbidez: ");
lcd.print((int)Input);
lcd.print(" "); // Espaços para limpar fantasmas de números anteriores
lcd.setCursor(0, 1);
lcd.print("Set:");
lcd.print((int)Setpoint);
lcd.setCursor(8, 1);
lcd.print("PID:");
lcd.print((int)Output);
lcd.print("ms ");
delay(100);
// --- ENVIAR DADOS PARA O SERIAL PLOTTER ---
Serial.print("Setpoint:");
Serial.print(Setpoint);
Serial.print(","); // Vírgula separa as variáveis na mesma linha
Serial.print("Turbidez_Atual:");
Serial.print(Input);
Serial.print(",");
// Como a Saída (Output) vai de 0 a 2000 (ms), podemos dividir por 2 para
// ela caber melhor na escala do gráfico junto com o LDR (0 a 1023)
Serial.print("Tempo_Relé_Escalado:");
Serial.println(Output / 2); // println (com 'ln') finaliza a linha atual
}