boolean GrillPid::doWork(void) { unsigned int elapsed = millis() - _lastWorkMillis; if (elapsed < (TEMP_MEASURE_PERIOD / TEMP_AVG_COUNT)) return false; _lastWorkMillis = millis(); #if defined(GRILLPID_FAN_BOOST_ENABLED) // If boost has been active for one period (TEMP_MEASURE_PERIOD / TEMP_AVG_COUNT // milliseconds) disable it if (_fanBoostActive) { // Really we just need to turn the OVF interupt back on but there's no // function for that, so re-write the proper blower output analogWrite(_fanPin, _lastBlowerOutput); _fanBoostActive = false; } #endif #if defined(GRILLPID_CALC_TEMP) for (unsigned char i=0; i<TEMP_COUNT; i++) if (Probes[i]->getProbeType() == PROBETYPE_INTERNAL || Probes[i]->getProbeType() == PROBETYPE_TC_ANALOG) Probes[i]->readTemp(); ++_periodCounter; if (_periodCounter < TEMP_AVG_COUNT) return false; _periodCounter = 0; for (unsigned char i=0; i<TEMP_COUNT; i++) Probes[i]->calcTemp(); if (!_manualOutputMode) { // Always calculate the output // calcPidOutput() will bail if it isn't supposed to be in control calcPidOutput(); int pitTemp = (int)Probes[TEMP_PIT]->Temperature; if ((pitTemp >= _setPoint) && (_lidOpenDuration - LidOpenResumeCountdown > LIDOPEN_MIN_AUTORESUME)) { // When we first achieve temperature, reduce any I sum we accumulated during startup // If we actually neded that sum to achieve temperature we'll rebuild it, and it // prevents bouncing around above the temperature when you first start up if (!_pitTemperatureReached) { _pitTemperatureReached = true; _pidCurrent[PIDI] *= 0.25f; } LidOpenResumeCountdown = 0; } else if (LidOpenResumeCountdown != 0) { LidOpenResumeCountdown = LidOpenResumeCountdown - (TEMP_MEASURE_PERIOD / 1000); } // If the pit temperature has been reached // and if the pit temperature is [lidOpenOffset]% less that the setpoint // and if the fan has been running less than 90% (more than 90% would indicate probable out of fuel) // Note that the code assumes we're not currently counting down else if (_pitTemperatureReached && (((_setPoint-pitTemp)*100/_setPoint) >= (int)LidOpenOffset) && ((int)PidOutputAvg < 90)) { resetLidOpenResumeCountdown(); } } /* if !manualFanMode */ #endif commitPidOutput(); return true; }
boolean GrillPid::doWork(void) { unsigned long m = millis(); // If this is the first invocation, force an immediate read and temperature // update to display a value as soon as possible after booting unsigned int elapsed = m - _lastTempRead; if (elapsed < (TEMP_MEASURE_PERIOD / TEMP_AVG_COUNT)) return false; _lastTempRead = m; for (unsigned char i=0; i<TEMP_COUNT; i++) if (Probes[i]->getProbeType() == PROBETYPE_INTERNAL) Probes[i]->readTemp(); ++_periodCounter; if (_periodCounter < TEMP_AVG_COUNT) return false; for (unsigned char i=0; i<TEMP_COUNT; i++) Probes[i]->calcTemp(); if (!_manualOutputMode) { // Always calculate the output // calcPidOutput() will bail if it isn't supposed to be in control calcPidOutput(); int pitTemp = (int)Probes[TEMP_PIT]->Temperature; if ((pitTemp >= _setPoint) && (_lidOpenDuration - LidOpenResumeCountdown > LIDOPEN_MIN_AUTORESUME)) { // When we first achieve temperature, reset any P sum we accumulated during startup // If we actually neded that sum to achieve temperature we'll rebuild it, and it // prevents bouncing around above the temperature when you first start up if (!_pitTemperatureReached) { _pitTemperatureReached = true; _pidCurrent[PIDI] = 0.0f; } LidOpenResumeCountdown = 0; } else if (LidOpenResumeCountdown != 0) { LidOpenResumeCountdown = LidOpenResumeCountdown - (TEMP_MEASURE_PERIOD / 1000); } // If the pit temperature has been reached // and if the pit temperature is [lidOpenOffset]% less that the setpoint // and if the fan has been running less than 90% (more than 90% would indicate probable out of fuel) // Note that the code assumes we're not currently counting down else if (_pitTemperatureReached && (((_setPoint-pitTemp)*100/_setPoint) >= (int)LidOpenOffset) && ((int)PidOutputAvg < 90)) { resetLidOpenResumeCountdown(); } } /* if !manualFanMode */ commitPidOutput(); _periodCounter = 0; return true; }