Arduino-PID-Library
Arduino-PID-Library copied to clipboard
Output is nan after several hours of successful running
Full code is 20220308_my_working_kiln_more_logging_reduce_memory.zip but most relevant bits pasted here. I'm controlling a relay to heat a kiln, and it works perfectly for a few hours, but then after about 3 or 5 hrs Output (here variable is pidOutput) keeps being nan.
In variables section:
#include <PID_v1.h>
const int pidCycle = 2500; // Time for a complete PID on/off cycle for the heating elements (ms)
double pidInput; // Input for PID loop (actual temp reading from thermocouple).
double pidOutput; // Output for PID loop (relay for heater).
double pidSetPoint; // Setpoint for PID loop (temp you are trying to reach).
PID pidCont = {PID(&pidInput, &pidOutput, &pidSetPoint, 800, 47.37, 4.93, DIRECT)};
Setup run once:
void setupPIDs() {
pidCont.SetSampleTime(pidCycle);
pidCont.SetOutputLimits(0, pidCycle);
pidCont.SetMode(AUTOMATIC);
}
Update loop:
// Update PID's / turn on heaters / update segment info
if (screenNum < 4) {
if (millis() - pidStart >= pidCycle) {
pidStart = millis();
updatePIDs();
}
htrControl();
updateSeg();
}
updatePIDs basically just calls pidCont.Compute();
Turn on heaters:
void htrControl() {
if (pidOutput >= millis() - pidStart) {
digitalWrite(heaterPin, HIGH);
}
else {
digitalWrite(heaterPin, LOW);
}
}
I've confirmed pidInput and pidSetPoint are behaving correctly. I'm using an Arduino Uno and am using 79% of program storage and 74% of dynamic memory (at 75% it says warning low memory, may cause stability issue) - not sure if being close to this limit could be my issue.
I've reproduced this issue about 5 times now, but once it did run the full ~10hr with no nans.
Thank you very much for your thoughts!
I do not have something to comment about since I haven't run into something similar. But I can confirm that I have successfully run multiple PIDs in the same program (>5), for days. I use this library since its birth. I am very interested to learn the cause of your issue.
Just a few comments on your code:
- The PID Controller is just a small part of your code. Why do you think the error is in PID code?
- Your calculation of pidSetPoint looks very complicated and a potential source of this error.
- The usage of pidCycle in pidCont.SetOutputLimits(0, pidCycle); makes logicaly no sense for me.
- This kind of code if (millis() - pidStart >= pidCycle) is already included in teh PID-Lib unsigned long timeChange = (now - lastTime); if(timeChange>=SampleTime) ... The SampleTime is set to 100ms in PID code. Does this fit with your concept?
In an Input was ever a nan, it will propagate through into Output and persist. You can check and protect against it in userspace before your compute step:
if(isnan(pidOutput)){
pidCont.setMode(MANUAL);
pidOutput = 0;
pidCont.setMode(AUTOMATIC); // bumpless reset of the PID internal values to match Output.
}