Convertir la salida de un sistema de control proporcional a una unidad significativa de un Peltier

0

Tratando de crear un controlador PID para el control de la temperatura usando un elemento Peltier, decidí ir paso a paso y crear primero los algoritmos Proporcional y luego el Integral y el Derivativo.

Todo el sistema se basa en un raspberry-pi zero que se controla con la ayuda de un Controlador Syren 10A un elemento Peltier.

Como ha comprendido (ya que he hablado de PID) quiero establecer una temperatura objetivo y alcanzarlo lo más cerca posible.

Inicialmente, probé un método bang-bang para hacer eso, pero los resultados no fueron tan esperanzadores. Tuve un error constante alrededor de +/- 5 grados. El código que utilicé era bastante simple y sigue:

import pigpio
import time
import os
from w1thermsensor import W1ThermSensor

pi = pigpio.pi()

FAN_PIN = 5
PLTR_PIN = 18


def FAN_ON( fanPIN ):
    print("[on] FAN")
    pi.write( fanPIN, 1 )

def FAN_OFF( fanPIN ):
    print("[off] FAN")
    pi.write( fanPIN, 0 )

def PLTR_OFF( pltrPIN ):
    print("[off] PELTIER")
    pi.set_servo_pulsewidth( pltrPIN, 1500 )

def PLTR_ON( pltrPIN ):
    print("[on] PELTIER")
    pi.set_servo_pulsewidth( pltrPIN, 2000 )
    #pi.set_servo_pulsewidth( pltrPIN, 1600 )

def PLTR_REV( pltrPIN ):
    print("[reverse] PELTIER")
    pi.set_servo_pulsewidth( pltrPIN, 1000 )

def GET_TEMP():
    sensor = W1ThermSensor()
    temp   = sensor.get_temperature()
    return temp


try:
    print("System is starting...")
    FAN_ON( FAN_PIN )
    PLTR_OFF( PLTR_PIN )

    target_temp = 55

    PLTR_ON( PLTR_PIN )
    time.sleep(3)
    PLTR_OFF( PLTR_PIN )
    time.sleep(4)

    while True:
        error = GET_TEMP() - target_temp
        print( "Error: ", error, "Temp: ", GET_TEMP() )

        if (error > 10):
            PLTR_OFF( PLTR_PIN )
            time.sleep(15)
        elif (error <= 10 and error >= 0):
            PLTR_OFF( PLTR_PIN )
            time.sleep(7)
            PLTR_ON( PLTR_PIN )
            time.sleep(1)
        elif (error < -10):
            PLTR_OFF( PLTR_PIN )
            time.sleep(2)
            PLTR_ON( PLTR_PIN )
            time.sleep(3)
        elif (error >= -10 and error <= 0):
            PLTR_OFF( PLTR_PIN )
            time.sleep(0)
            PLTR_ON( PLTR_PIN )
            time.sleep(0)

except KeyboardInterrupt:
    FAN_OFF( FAN_PIN )
    PLTR_OFF( PLTR_PIN )
    pi.stop()

Entonces pensé en probar los PID. Así que empiezo a codificar la primera parte. El proporcional y aquí está el código:

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.02

output      = 1

# MAIN PROGRAM STARTS HERE

# INITIALLY OPEN THE FAN
FAN_CTRL(1)
# AND THE PELTIER
PLTR_CTRL( PWM_ON )

try:

    while True:

        error = TARGET_TEMP - GET_TEMP()
        output += error * KP
        # Turn it in a value between 0 an 1
        output = max(min(1, output),0)

        if ( output >= 0.5 ):
            PLTR_CTRL( PWM_ON )
        else:
            PLTR_CTRL( PWM_OFF )

        print("Temperature: ", GET_TEMP(), "\tError: ", error, "\t\t\tOutput: ", output)
        sleep(SAMPLE_TIME)


except KeyboardInterrupt:
    PLTR_CTRL( PWM_OFF )
    FAN_CTRL(0)
    pi.stop()

El problema aquí es que no puedo convertir la variable de salida en un valor significativo para el control de Peltier. Quiero decir, traté de dividir los valores de la salida en la mitad y abrir el Peltier para > 0.5 y cerrarlo de lo contrario. Pero esa idea realmente no funcionó porque los valores de 0.5 output realmente pueden ocurrir desde error positivo o positivo.

Aquí hay una salida de muestra:

Temperature:  22.937    Error:  17.375                  Output:  1
Temperature:  26.437    Error:  14.875                  Output:  1
Temperature:  31.125    Error:  10.375                  Output:  1
Temperature:  35.937    Error:  5.438000000000002       Output:  1
Temperature:  39.875    Error:  1.375                   Output:  1
Temperature:  43.437    Error:  -2.375                  Output:  0.9525
Temperature:  46.625    Error:  -5.561999999999998      Output: 0.8412600000000001
Temperature:  49.5      Error:  -8.625                  Output:  0.6687600000000001
Temperature:  51.875    Error:  -11.125                 Output:  0.4462600000000001
Temperature:  52.0      Error:  -12.311999999999998     Output:  0.20002000000000014
Temperature:  50.062    Error:  -10.811999999999998     Output:  0
Temperature:  46.875    Error:  -7.936999999999998      Output:  0
Temperature:  43.437    Error:  -4.5                    Output:  0
Temperature:  40.125    Error:  -1.125                  Output:  0
Temperature:  37.062    Error:  2.0                     Output:  0.04
Temperature:  34.5      Error:  4.688000000000002       Output:  0.13376000000000005
Temperature:  32.125    Error:  7.125                   Output:  0.27626000000000006
Temperature:  30.187    Error:  9.25                    Output:  0.46126000000000006
Temperature:  28.625    Error:  10.875                  Output:  0.67876
Temperature:  29.812    Error:  11.062999999999999      Output:  0.90002
Temperature:  33.312    Error:  7.938000000000002       Output:  1
Temperature:  37.375    Error:  3.9380000000000024      Output:  1
Temperature:  41.812    Error:  -0.375                  Output:  0.9925

Si alguien tiene una idea sobre cómo darle a Peltier un significado a los valores de salida, lo apreciaría.

    
pregunta J. Doe

0 respuestas

Lea otras preguntas en las etiquetas