Hallo zusammen,

bei meinem Projekt (Auswertung einer Breitbandlambdasonde) brauche ich eine Heizungsregelung und irgendwie komme ich nicht weiter.

Also, ich habe den Sensor mit einer integrierten Heizung. Diese Sonde hängt an einem Auswertechip. Über diesen Chip wird die Temperatur der Heizung indirekt gemessen... Der Chip hat einen Kalibrierungsmodus, in dem er sagt was die "Zielspannung" (Ur reference) ist, also die Referenz. Diese Zielspannung liegt bei 1 Volt. Nach der Kalibierung wird der Chip ist den normalen Modus geschaltet und in der Applikation die aktuelle Spannung (und damit auch die Temperatur des Sensors bzw. dessen Heizung) gemessen. Dabei ist es so, dass die niedrigere Spannung einen heißeren Sensor bedeutet und somit die Heizung gedrosselt werden soll, bis man die Referenz erreicht, also den 1V. Die Heizung wird über PWM geregelt.

Mein PID-Code sieht so aus:

Code:
uint16_t calc_pid (uint16_t referenceValue, uint16_t measuredValue)
{
    // calculation error:
    int16_t error = (int16_t) referenceValue - (int16_t) measuredValue;
    int16_t position = (int16_t) measuredValue;
    
    // calculate p-term;
    float pTerm = pidController.pGain * error;
    
    //Calculate the integral state
    pidController.iState += error;
    
    // check limits of iState
    if (pidController.iState > pidController.iMax) pidController.iState = pidController.iMax;
    if (pidController.iState < pidController.iMin) pidController.iState = pidController.iMin;
    
    //Calculate the integral term.
    float iTerm = pidController.iGain * pidController.iState;
    
    //Calculate the derivative term.
    float dTerm = pidController.dGain * (pidController.dState - position);
    pidController.dState = position;
    
    //Calculate regulation (PI).
    int16_t RegulationOutput = pTerm + iTerm + dTerm;
    
    // check limits of pwm here....
    
    if (RegulationOutput > pidController.pwmMax) RegulationOutput = pidController.pwmMax;
    if (RegulationOutput < pidController.pwmMin) RegulationOutput = pidController.pwmMin;
        
    return  (uint16_t) RegulationOutput;
}
Die Parameter für den PID-Controller sehen so aus:

Code:
    // init PID controller...
    pidController.pGain = 120;
    pidController.iGain = 0.8;
    pidController.dGain = 10;
    
    pidController.iMin = -250;
    pidController.iMax = 250;
    pidController.pwmMin = 0;
    pidController.pwmMax = 240;
Dadurch, dass "niedrigere Spannung heißeren Sensor" bedeutet, rufe ich referenceValue und measuredValue andersrum auf, also referenceValue ist die aktuell gemessene Spannung und measuredValue ist die Referenz aus dem Kalibrierungsmodus. Beide Werrte sind Werte vom ADC, ohne Wandlung in Volt.

Mein Problem: die Funktion liefert immer 240 zurück, also Vollgas für die Heizung und die gemessene Spannung hängt immer bei 0,42V...

Hat jemand eine Idee? Ich blicke es nicht...

Danke Euch!