#include <TimerOne.h>
const int termQuente = A0; //Termometro lado Quente
const int termFrio = A1; //Termometro lado Frio
const int peltier = 10; //Pastilha Peltier -> pin 9 e 10 são controlados pelo Timer1
const int pot = A4; //Potenciometro
double tempQuente; //Temperatura lado Quente
double tempFrio; //Temperatura lado Frio
double tempAlvo; //Temperatura alvo para o lado Frio
//Variaveis PID
double P = 0.0, I = 0.0, D = 0.0, PID = 0, Kp = 2, Ki = 0.5, Kd = 0.1;
double lastTemperature = 0, error = 0, lastProcessTime = 0;
void setup() {
//Inicia a comunicação serial
Serial.begin(9600);
//Seta o modo dos pinos utilizados (entrada/saida)
pinMode(termQuente, INPUT);
pinMode(termFrio, INPUT);
pinMode(pot, INPUT);
pinMode(peltier, OUTPUT);
readAll();
//Inicializa o timer, pwm e interrupção por tempo
Timer1.initialize(1000);
Timer1.pwm(peltier, int(PID));
Timer1.attachInterrupt(tempControl);
}
void loop() {
//Lê todos os sensores
readAll();
//Calcula o pid
unsigned long currentTime = millis();
unsigned long deltaTime = currentTime - lastProcessTime;
lastProcessTime = currentTime;
double deltaTimeSeconds = deltaTime / 1000.0;
error = abs(tempAlvo - tempFrio);
if (error == 0) {
PID = 0.0;
} else {
P = error * Kp;
I = (I + error * Ki) * deltaTimeSeconds;
D = ((lastTemperature - tempFrio) * Kd) / deltaTimeSeconds;
lastTemperature = tempFrio;
PID = P + I + D;
}
if (PID < 0) {
Serial.print("PID alterado de ");
Serial.print(PID);
Serial.println(" para 0.0");
PID = 0.0;
} else if (PID > 1023) {
Serial.print("PID alterado de ");
Serial.print(PID);
Serial.println(" para 0.0");
PID = 1023.0;
}
//Printa os valores
printTemp();
//Muda o pulso do pwm
Timer1.pwm(peltier, int(PID));
delay(1000);
}
void tempControl() {
//50 == temperatura definida como máximo em que o lado quente poderá chegar
if (tempQuente >= 50) {
Serial.println("Temperatura do lado quente excedida. Peltier sera desligado.");
Timer1.pwm(peltier, 0);
}
}
float calcTemp(int pin) {
return (double(analogRead(pin)) * 5 / (1023)) / 0.01; //5 = tensão Max; 1023 = valor analogico max; 0.01 = 10mV
}
void printTemp() {
Serial.println("#########################################");
Serial.print("Temperatura do lado quente: ");
Serial.print(tempQuente);
Serial.println(" C");
Serial.print("Temperatura do lado frio: ");
Serial.print(tempFrio);
Serial.println(" C");
Serial.print("Temperatura alvo: ");
Serial.print(tempAlvo);
Serial.println(" C");
Serial.print("PID: ");
Serial.println(int(PID));
}
void readAll() {
tempQuente = calcTemp(termQuente);
tempFrio = calcTemp(termFrio);
tempAlvo = map(analogRead(pot), 0, 1023, -10, 30);
}