Example #1
0
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);
}
Example #2
0
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
}