static void contrtemp_run(fixpt_t r) { fixpt_t dt, y, y_current; uint8_t emergency_flags; if (!contrtemp.enabled) return; if (contrtemp.emergency) return; /* Get delta-t that elapsed since last run, in seconds */ dt = fixpt_div(int_to_fixpt(timer_ms_since(&contrtemp.dt_timer)), int_to_fixpt(1000)); timer_set_now(&contrtemp.dt_timer); /* Run the PID controller */ y = pid_run(&contrtemp.pid, dt, r); debug_report_fixpt(DEBUG_PFX1("ty1"), &contrtemp.old_temp_control1, y); /* Map the requested temperature to a heater current. */ y_current = temp_to_amps(y); emergency_flags = contrcurr_get_emerg(); if (r > float_to_fixpt(CONTRTEMP_POSLIM)) { /* The measured temperature is higher than the maximum. * We need to avoid damage. * Disable current by requesting an emergency in * the current controller. */ emergency_flags |= CONTRCURR_EMERG_HIGH_TEMP; y_current = float_to_fixpt(CONTRCURR_NEGLIM); } else { emergency_flags &= (uint8_t)~CONTRCURR_EMERG_HIGH_TEMP; } contrcurr_set_emerg(emergency_flags); debug_report_fixpt(DEBUG_PFX1("ty2"), &contrtemp.old_temp_control2, y_current); /* Set the current controller setpoint to the requested current. */ contrcurr_set_setpoint(y_current); }
uint32_t ReflowOven::timerService (uint32_t currentTime) { unsigned long ms = millis (); // using millis because currentTime rolls over every ~107secs and millis rolls over every 50 days if (ms - ms1000 >= 1000) { ms1000 = ms; double cjt; bool open, sGnd, sVcc; double lastTemp = temp; bool fault = tc.readMAX31855 (&temp, &cjt, &open, &sGnd, &sVcc, false); if (fault) { if (faultCount == 1000) { turnOvenOff (); soundOn (); if (open) ovenGraph.showInfo ("TC Not Connected"); else if (sGnd) ovenGraph.showInfo ("TC Grounded"); else if (sVcc) ovenGraph.showInfo ("TC Shorted to Vcc"); } else { ++faultCount; temp = lastTemp; } } else faultCount = 0; if (myBui.isCurrentScreen (OVEN_GRAPH)) ovenGraph.update ((float)temp, runtime); if (ovenOn) { ++runtime; if ((temp > TEMP_ALARM) || (temp > (setpoint + MAX_OVER_SETPOINT))) { if (reflowState != COOLDOWN) { turnOvenOff (); soundOn (); ovenGraph.showInfo ("Oven Overheat"); } } switch (reflowState) { case PREHEAT: setpoint += reflowVars.preheatRamp; if (setpoint >= reflowVars.soakTemp) { setpoint = reflowVars.soakTemp; ovenGraph.updateStage ("Soak"); reflowState = SOAK; } break; case SOAK: setpoint += (reflowVars.soakTempIncrease / reflowVars.soakTime); if (runtime >= (reflowVars.preheatTime + reflowVars.soakTime)) { reflowState = RAMP; ovenGraph.updateStage ("Ramp"); } break; case RAMP: setpoint += reflowVars.ramp; if (setpoint >= reflowVars.peakTemp) { setpoint = reflowVars.peakTemp; reflowState = PEAK; ovenGraph.updateStage ("Peak"); } break; case PEAK: if (runtime >= (reflowVars.preheatTime + reflowVars.soakTime + reflowVars.rampTime + reflowVars.peakTime)) { soundOn (); ovenGraph.showInfo ("Reflow Complete"); reflowState = COOLDOWN; ovenGraph.updateStage ("Cooldown"); } break; case COOLDOWN: setpoint -= reflowVars.cooldownRamp; if (runtime >= reflowVars.totalTime) { turnOvenOff (); reflowState = PREHEAT; ovenGraph.updateButtons (); } default: break; } } } if (ovenOn) { if (temp > (startingTemp + 10)) { if (ms - msPTerm >= pidVars.sampleTime) { msPTerm = ms; ovenGraph.updateSetpoint (setpoint); float pv = (float)temp / MAX_TEMPERATURE; float sp = setpoint / MAX_TEMPERATURE; //Serial.print ("Present value: "); //Serial.println (pv); //Serial.print ("Setpoint: "); //Serial.println (sp); float dutyCycle = pid_run (pid, pv, sp); elementOffTime = pidVars.sampleTime * dutyCycle + ms; if (dutyCycle != 0.0f) turnElementOn (); //Serial.print ("Current time: "); //Serial.println (ms); //Serial.print ("Duty cycle: "); //Serial.println (dutyCycle); //Serial.print ("Element off time: "); //Serial.println (elementOffTime); //Serial.println (); } // this needs to be after the new elementOffTime is calculated because a duty cycle of 1.0 was getting turned off if (elementOn) { if (ms >= elementOffTime) { turnElementOff (); } } if (pidVars.iTime != 0) { if (ms - msITerm >= pidVars.iTime) { msITerm = ms; pid_calcI (pid); } } if (pidVars.dTime != 0) { if (ms - msDTerm >= pidVars.dTime) { msDTerm = ms; pid_calcD (pid); } } } } return (currentTime + CORE_TICK_RATE); // CORE_TICK_RATE is the number of ticks in 1msec }