Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Output is nan after several hours of successful running #118

Open
bellabrez opened this issue Mar 19, 2022 · 3 comments
Open

Output is nan after several hours of successful running #118

bellabrez opened this issue Mar 19, 2022 · 3 comments

Comments

@bellabrez
Copy link

bellabrez commented Mar 19, 2022

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!

@T81
Copy link

T81 commented Mar 20, 2022

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.

@TuxLeon
Copy link

TuxLeon commented Mar 20, 2022

Just a few comments on your code:

  1. The PID Controller is just a small part of your code. Why do you think the error is in PID code?
  2. Your calculation of pidSetPoint looks very complicated and a potential source of this error.
  3. The usage of pidCycle in pidCont.SetOutputLimits(0, pidCycle); makes logicaly no sense for me.
  4. 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?

@drf5n
Copy link

drf5n commented Mar 11, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants