Hi again.
In another thread I described that I'm driving a Peltier element using the Syren 10A driver with a raspberry pi zero. According to
driver's manual, I'm using it with the R/C mode where on page 11 says the following:
A 1500us pulse is zero speed,
a 1000 us pulse is full reverse and
a 2000 us pulse is full forward
So now I'm trying to program a PID controller to make Peltier element keep a stable temperature. I'm writing it in python language and here is the code so far:
from time import sleep
from w1thermsensor import W1ThermSensor
import pigpio
pi = pigpio.pi()
def GET_TEMP():
sensor = W1ThermSensor()
temp = sensor.get_temperature()
return temp
def PLTR_CTRL( PWM_VALUE ):
pi.set_servo_pulsewidth( PLTR_PIN, PWM_VALUE )
def FAN_CTRL( FAN_VALUE ):
pi.write( FAN_PIN, FAN_VALUE )
# PIN CONFIGURATION
PLTR_PIN = 18
FAN_PIN = 5
# PARAMETERS CONFIGURATION
SAMPLE_TIME = 1
PWM_ON = 2000
PWM_OFF = 1500
PWM_REVERSE = 1000
TARGET_TEMP = 40
KP = 0.55
KD = 0.72
output = 1
OldMin = 0
OldMax = 1
NewMax = 2000
NewMin = 1500
prevError = 0 # Previous error
# MAIN PROGRAM STARTS HERE
# INITIALLY OPEN THE FAN
FAN_CTRL(1)
# AND THE PELTIER
PLTR_CTRL( PWM_ON )
# OPEN FILE
f = open("temp_data.txt", "w+")
try:
while True:
error = TARGET_TEMP - GET_TEMP()
output += (error * KP) + (prevError * KD)
# Turn it in a value between 0 an 1
output = max(min(1, output),0)
# Rescale the output into 1500 - 2000 range
newPulse = ((( output - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin
# Apply the new pulse
PLTR_CTRL( int(newPulse) )
print("Temperature: ", GET_TEMP(), "\tError: ", error, "\t\tOutput: ", int(newPulse) )
f.write( "%f\n" % GET_TEMP() )
sleep(SAMPLE_TIME)
prevError = error
except KeyboardInterrupt:
PLTR_CTRL( PWM_OFF )
FAN_CTRL(0)
f.close()
pi.stop()
So far I have implemented only the proportional and the derivative parts. As you can see I'm calculating the output variable based on the KP, KD and the error. Then I transform this output variable into a meaningful for the driver range of values by scaling it up between 1500 and 2000 usec pulses. I didn't include pulses smaller than 1000 usec because then the polarity get inverted and the Peltier element cools instead of heat.
So now I'm actually trying to tune the whole idea and because its the first time that I'm doing something like that I would be interested to read your opinions and advises on the way that I'm approaching it and of course if you have any hint or pipeline that will help me achieve a good enough tuning.