I've attached a thermoeletric assembly (basically a peltier with a huge heatsink and fan on the "hot" side) to an Arduino UNO R3 and a BTS7960 motor driver following the schematics found here. I also have a thermistor that monitors the temperature of the "cold" side of the peltier which I wired an programmed following this tutorial.
My aim is now to use PID to cool down the peltier to a given setpoint temperature and mantain said temperature. The peltier can of course also heat up by inverting the polarity (that's why I used an H-bridge), so ideally the PID should be able to switch to heating if for some reason the setpoint is overshot.
I've tested both the thermistors and the peltier attached to the H-bridge and they seem to be working properly: If I activate a certain amount of PWM on the heating pin I can feel my peltier getting hotter and the thermistor reads an increasing temperature. The opposite works for the cooling pin.
I therefore wrote the following code to integrate the PID in the process, but it does not work: the PID does not slow down close to the setpoint, it overshoots, and it keeps cooling the peltier.
I've tried to fiddle with the P,I,D coefficients but the most I could obtain was either a repetition of the described behaviour, either a control that was not working (always 0).
Following the code I'm using. What am I doing wrong?
#include <PID_v1.h>
int ThermistorPin = 1;
int Vo;
float R1 = 10000;
float logR2, R2;
float c1 = 1.138443396e-03, c2 = 2.325201394e-04, c3 = 0.9469069744e-07;
double T, Setpoint, Output;
PID myPID(&T, &Output, &Setpoint,Setpoint*2,Setpoint*0.1,Setpoint*0.1, REVERSE);
void setup() {
Serial.begin(9600);
pinMode(heatingPWM, OUTPUT);
pinMode(coolingPWM, OUTPUT);
pinMode(heatingEnable, OUTPUT);
pinMode(coolingEnable, OUTPUT);
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(-255,255);
Setpoint=10;
digitalWrite(heatingEnable, LOW);
analogWrite(heatingPWM, 0);
digitalWrite(coolingEnable, LOW);
analogWrite(coolingPWM, 0);
}
void loop() {
Vo = analogRead(ThermistorPin);
R2 = R1 * (1023.0 / (float)Vo - 1.0);
logR2 = log(R2);
T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
T = T - 273.15;
myPID.Compute();
Serial.print("Temperature: ");
Serial.print(T);
Serial.println(" °C");
Serial.print("PID Value: ");
Serial.println(Output);
if (Output<0) {
digitalWrite(coolingEnable, HIGH);
analogWrite(coolingPWM, 0);
digitalWrite(heatingEnable, HIGH);
analogWrite(heatingPWM, Output);
Serial.println("Heating");
}
else {
digitalWrite(heatingEnable, HIGH);
analogWrite(heatingPWM, 0);
digitalWrite(coolingEnable, HIGH);
analogWrite(coolingPWM, Output);
Serial.println("Cooling");
};
Serial.print("Setpoint: ");
Serial.println(Setpoint);
delay(500);
}