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

Auto tune relay example? #63

Closed zekageri closed 1 year ago

zekageri commented 1 year ago

First of all, great library and i appreciate your work.

Can you add an auto tune realy example?

I have a heating system where a user can add any number of heating circuits. Each has it's own class and each class has it's own temperature measure sensor. User can place each sensor to different rooms and get the readings. Each reading controlls a separate valve with one single boiler.

So i want to gave an option to the user to be able to controll each heating with PID. It should auto tune itself by default.

Every class has one boiler attached to it, so each heating turns one boiler on/off based on the measured and setted temperature. User can ofc set the temperature for each heating individually.

For now, it works with set temp + hysteresis but i want to give the user the option to switch to PID routine.

Right now i'm using your library as follows:

/*
* This function gets called on class initialization.
*/
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);

    myPID->SetOutputLimits(0, PID_LIMIT);
    myPID->SetSampleTimeUs(100000);
    myPID->SetMode(myPID->Control::automatic);
}

/*
* This function gets called on every iteration of the thermSystem task.
*/
void thermSystem::pidLOOP() {
    if( !isModuleExists( thermModule.address ) || isModuleFaulted(thermModule.address) ){return;}
    unsigned long msNow = millis();
    myPID->Compute();

    if( lastPidOUT != pidOUT ){
        lastPidOUT = pidOUT;
        Serial.printf("[PID] - %s Output: %.2f\n",name,pidOUT);
    }

    if( pidOUT == PID_LIMIT && !shouldStartHeat ){
        shouldStartHeat = true;
        Serial.printf("[PID] - %s heating should turn on!\n",name);
    }else if( pidOUT == 0 && shouldStartHeat ){
        shouldStartHeat = false;
        Serial.printf("[PID] - %s heating should turn off!\n",name);
    }
}

Currently this implementation is identical to the setTemp + hysteresis method. It turns the boiler on if the pidOUT reached 100 and turns the boiler on if it reached 0.

I need an auto tune functionality so the temperature controlled by each thermSystem is automatic. Like the heating should start even if the temperature did not got below the set temperature but is on it's way.