Dlloydev / QuickPID

A fast PID controller with multiple options. Various Integral anti-windup, Proportional, Derivative and timer control modes.
MIT License
195 stars 50 forks source link

Compute fails for some reason. #62

Closed zekageri closed 1 year ago

zekageri commented 1 year ago

Hi! Great library. I have a problem on ESP32.

Here is my sketch:

/* variables */
int windowSize = 1000;
unsigned long windowStartTime, nextSwitchTime;
boolean relayStatus = false;
const byte debounce = 50;
float pidCurrTemp,
    pidSetTemp,
    pidOUT = 0,
    Kp = 2,
    Ki = 5,
    Kd = 1;
QuickPID *myPID;
void initPID();
void pidLOOP();
void printPID_Details();

void thermSystem::initPID() {
    printPID_Details();
    myPID = new QuickPID(&pidCurrTemp, &pidOUT, &pidSetTemp, Kp, Ki, Kd,
                         myPID->pMode::pOnError,
                         myPID->dMode::dOnMeas,
                         myPID->iAwMode::iAwClamp,
                         myPID->Action::direct);

    windowStartTime = millis();
    myPID->SetOutputLimits(0, windowSize);
    myPID->SetSampleTimeUs(windowSize * 1000);
    myPID->SetMode(myPID->Control::automatic);
}

void thermSystem::pidLOOP() {
    unsigned long msNow = millis();
    if (myPID->Compute()){
        windowStartTime = msNow;
    }else{
        Serial.println("[PID] - Failed to compute.");
    }

    if (!relayStatus && pidOUT > (msNow - windowStartTime)) {
        if (msNow > nextSwitchTime) {
            nextSwitchTime = msNow + debounce;
            relayStatus = true;
            Serial.println("[PID] - HIGH!");
        }
    } else if (relayStatus && pidOUT < (msNow - windowStartTime)) {
        if (msNow > nextSwitchTime) {
            nextSwitchTime = msNow + debounce;
            relayStatus = false;
            Serial.println("[PID] - LOW!");
        }
    }
}

I have a bunch of thermostats, each thermostat have it's own class and it's own loop function which called from the main loop. These classes are dynamically created at runtime. Each thermostat class should initialize it's own PID routine. For some reason the Compute() method always returns false and does not compute anything. pidCurrTemp and pidSetTemp will be set durint runtime. pidSetTemp is equal with a user defined set temperature and the pidCurrTemp is equal with the measured temperature which the thermostat is setting.

pidCurrTemp is ranging between 0 and 350 which represents 0 min and 35 max celsius degree. pidSetTemp also in these ranges.

If i set the set temperature and waiting it does not do anything.

This gets printed when i set the desired temperature. Current temp: 211.00, pidOUT: 0.00, setTemp: 230.00

zekageri commented 1 year ago

Finally i got some pidOUT but the loop does not print me anything usefull. I just want to start or stop the heating process with a boolean value.

PID controller: Current temp: 220.00, pidOUT: 950.00, setTemp: 210.00
PID controller: Current temp: 220.00, pidOUT: 175.00, setTemp: 235.00
PID controller: Current temp: 222.00, pidOUT: 1000.00, setTemp: 180.00

When the setTemp is below the current temp it should print [PID] - HIGH! and if the set temp is equal or more then the current temp it should print [PID] - LOW!

zekageri commented 1 year ago

Sorry, i can see the problem now. It was my fault.