Example #1
0
void TempProbe::calcTemp(void)
{
  const float ADCmax = (1 << (10+TEMP_OVERSAMPLE_BITS)) - 1;
  if (_accumulatedCount != 0)
  {
    unsigned int ADCval = _accumulator / _accumulatedCount;
    _accumulatedCount = 0;

    // Units 'A' = ADC value
    if (pid.getUnits() == 'A')
    {
      Temperature = ADCval;
      return;
    }

    if (ADCval != 0)  // Vout >= MAX is reduced in readTemp()
    {
      float R, T;
      // If you put the fixed resistor on the Vcc side of the thermistor, use the following
      R = Steinhart[3] / ((ADCmax / (float)ADCval) - 1.0f);
      // If you put the thermistor on the Vcc side of the fixed resistor use the following
      //R = Steinhart[3] * ADCmax / (float)Vout - Steinhart[3];

      // Units 'R' = resistance, unless this is the pit probe (which should spit out Celsius)
      if (pid.getUnits() == 'R' && this != pid.Probes[TEMP_PIT])
      {
        Temperature = R;
        return;
      };

      // Compute degrees K
      R = log(R);
      T = 1.0f / ((Steinhart[2] * R * R + Steinhart[1]) * R + Steinhart[0]);

      setTemperatureC(T - 273.15f);
    } /* if ADCval */
    else
      Temperature = NAN;
  } /* if accumulatedcount */

  if (hasTemperature())
  {
    calcExpMovingAverage(TEMPPROBE_AVG_SMOOTH, &TemperatureAvg, Temperature);
    Alarms.updateStatus(Temperature);
  }
  else
    Alarms.silenceAll();
}
Example #2
0
inline void GrillPid::commitPidOutput(void)
{
  calcExpMovingAverage(PIDOUTPUT_AVG_SMOOTH, &PidOutputAvg, _pidOutput);
  commitFanOutput();
  commitServoOutput();
}
Example #3
0
void TempProbe::calcTemp(void)
{
  const float ADCmax = (1 << (10+TEMP_OVERSAMPLE_BITS)) - 1;
  if (_accumulatedCount != 0)
  {
    unsigned int ADCval = _accumulator / _accumulatedCount;
    _accumulatedCount = 0;

    // Units 'A' = ADC value
    if (pid.getUnits() == 'A')
    {
      Temperature = ADCval;
      return;
    }

    if (ADCval != 0)  // Vout >= MAX is reduced in readTemp()
    {
      if (_probeType == PROBETYPE_TC_ANALOG)
      {
        float mvScale = Steinhart[3];
        // Commented out because there's no "divide by zero" exception so
        // just allow undefined results to save prog space
        //if (mvScale == 0.0f)
        //  mvScale = 1.0f;
        // If scale is <100 it is assumed to be mV/C with a 3.3V reference
        if (mvScale < 100.0f)
          mvScale = 3300.0f / mvScale;
        setTemperatureC(ADCval / ADCmax * mvScale);
      }
      else {
        float R, T;
        // If you put the fixed resistor on the Vcc side of the thermistor, use the following
        R = Steinhart[3] / ((ADCmax / (float)ADCval) - 1.0f);
        // If you put the thermistor on the Vcc side of the fixed resistor use the following
        //R = Steinhart[3] * ADCmax / (float)Vout - Steinhart[3];

        // Units 'R' = resistance, unless this is the pit probe (which should spit out Celsius)
        if (pid.getUnits() == 'R' && this != pid.Probes[TEMP_PIT])
        {
          Temperature = R;
          return;
        };

        // Compute degrees K
        R = log(R);
        T = 1.0f / ((Steinhart[2] * R * R + Steinhart[1]) * R + Steinhart[0]);

        setTemperatureC(T - 273.15f);
      } /* if PROBETYPE_INTERNAL */
    } /* if ADCval */
    else
      Temperature = NAN;
  } /* if accumulatedcount */

  if (hasTemperature())
  {
    calcExpMovingAverage(TEMPPROBE_AVG_SMOOTH, &TemperatureAvg, Temperature);
    Alarms.updateStatus(Temperature);
  }
  else
    Alarms.silenceAll();
}
Example #4
0
inline void GrillPid::commitFanSpeed(void)
{
  /* Long PWM period is 10 sec */
  const unsigned int LONG_PWM_PERIOD = 10000;
  const unsigned int PERIOD_SCALE = (LONG_PWM_PERIOD / TEMP_MEASURE_PERIOD);

  calcExpMovingAverage(FANSPEED_AVG_SMOOTH, &FanSpeedAvg, _fanSpeed);

  if (_outputDevice == PIDOUTPUT_Fan)
  {
    /* For anything above _minFanSpeed, do a nomal PWM write.
       For below _minFanSpeed we use a "long pulse PWM", where
       the pulse is 10 seconds in length.  For each percent we are
       emulating, run the fan for one interval. */
    unsigned char output;
    if (_fanSpeed >= _minFanSpeed)
    {
      output = _fanSpeed;
      _longPwmTmr = 0;
    }
    else
    {
      // Simple PWM, ON for first [FanSpeed] intervals then OFF
      // for the remainder of the period
      if (((PERIOD_SCALE * _fanSpeed / _minFanSpeed) > _longPwmTmr))
        output = _minFanSpeed;
      else
        output = 0;

      if (++_longPwmTmr > (PERIOD_SCALE - 1))
        _longPwmTmr = 0;
    }  /* long PWM */

    if (_invertPwm)
      output = _maxFanSpeed - output;
    OCR1B = (unsigned int)output * 512 / 100;
  }
  else
  {
    // GrillPidOutput::Servo
    unsigned char output;
    if (_invertPwm)
      output = 100 - _fanSpeed;
    else
      output = _fanSpeed;
    // Get the output speed in 10x usec by LERPing between min and max
    output = ((_maxFanSpeed - _minFanSpeed) * (unsigned int)output / 100) + _minFanSpeed;
    OCR1B = uSecToTicks(10U * output);
  }

#if defined(TIMER1_DEBUG)
  SerialX.print("HMLG,0,");
  SerialX.print(" ICR1="); SerialX.print(ICR1, DEC);
  SerialX.print(" OCR1B="); SerialX.print(OCR1B, DEC);
  SerialX.print(" TCCR1A=x"); SerialX.print(TCCR1A, HEX);
  SerialX.print(" TCCR1B=x"); SerialX.print(TCCR1B, HEX);
  SerialX.print(" TCCR1C=x"); SerialX.print(TCCR1C, HEX);
  SerialX.print(" TIMSK1=x"); SerialX.print(TIMSK1, HEX);
  if (ovf) { ovf = false; SerialX.print(" ovf"); }
  if (rst) { SerialX.print(' '); SerialX.print(rst, DEC); rst = 0; }
  if (bit_is_set(TIFR1, TOV1)) { SerialX.print(" TOV1"); TIFR1 = bit(TOV1); }
  SerialX.nl();
#endif
}