Split temperature management into it's own ISR
Use a new low-priority "temp_mgr_isr" running at constant rate for temperature management. This is done so that the temperatures are sampled at a constant independent interval *and* with reduced jitter. Likewise for actual PID management. This will require further adjustment for the min/max/runaway display, which cannot be done directly into this function anymore (the code will need to disable heaters but flag for display to be handled in manage_heaters).
This commit is contained in:
parent
2ca16a06cd
commit
c6d0494cbc
@ -1279,8 +1279,9 @@ void setup()
|
||||
// performed inside the soft_pwm_isr)
|
||||
SdFatUtil::set_stack_guard();
|
||||
|
||||
// Initialize temperature loop
|
||||
// Initialize pwm/temperature loops
|
||||
soft_pwm_init();
|
||||
temp_mgr_init();
|
||||
|
||||
#ifdef EXTRUDER_ALTFAN_DETECT
|
||||
SERIAL_ECHORPGM(_n("Extruder fan type: "));
|
||||
@ -1365,7 +1366,9 @@ void setup()
|
||||
|
||||
setup_photpin();
|
||||
|
||||
#if 0
|
||||
servo_init();
|
||||
#endif
|
||||
|
||||
// Reset the machine correction matrix.
|
||||
// It does not make sense to load the correction matrix until the machine is homed.
|
||||
|
@ -97,7 +97,6 @@ unsigned char soft_pwm_bed;
|
||||
//===========================================================================
|
||||
//=============================private variables============================
|
||||
//===========================================================================
|
||||
#define TEMP_MEAS_RATE 250
|
||||
static volatile bool temp_meas_ready = false;
|
||||
|
||||
#ifdef PIDTEMP
|
||||
@ -442,208 +441,7 @@ void manage_heater()
|
||||
#ifdef WATCHDOG
|
||||
wdt_reset();
|
||||
#endif //WATCHDOG
|
||||
|
||||
float pid_input;
|
||||
float pid_output;
|
||||
|
||||
// run at TEMP_MEAS_RATE
|
||||
if(temp_meas_ready != true) return;
|
||||
static unsigned long old_stamp = _millis();
|
||||
unsigned long new_stamp = _millis();
|
||||
unsigned long diff = new_stamp - old_stamp;
|
||||
if(diff < TEMP_MEAS_RATE) return;
|
||||
old_stamp = new_stamp;
|
||||
|
||||
// ADC values need to be converted before checking: converted values are later used in MINTEMP
|
||||
updateTemperaturesFromRawValues();
|
||||
|
||||
check_max_temp();
|
||||
check_min_temp();
|
||||
|
||||
#ifdef TEMP_RUNAWAY_BED_HYSTERESIS
|
||||
temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
|
||||
#endif
|
||||
|
||||
for(uint8_t e = 0; e < EXTRUDERS; e++)
|
||||
{
|
||||
|
||||
#ifdef TEMP_RUNAWAY_EXTRUDER_HYSTERESIS
|
||||
temp_runaway_check(e+1, target_temperature[e], current_temperature[e], (int)soft_pwm[e], false);
|
||||
#endif
|
||||
|
||||
#ifdef PIDTEMP
|
||||
pid_input = current_temperature[e];
|
||||
|
||||
#ifndef PID_OPENLOOP
|
||||
if(target_temperature[e] == 0) {
|
||||
pid_output = 0;
|
||||
pid_reset[e] = true;
|
||||
} else {
|
||||
pid_error[e] = target_temperature[e] - pid_input;
|
||||
if(pid_reset[e]) {
|
||||
iState_sum[e] = 0.0;
|
||||
dTerm[e] = 0.0; // 'dState_last[e]' initial setting is not necessary (see end of if-statement)
|
||||
pid_reset[e] = false;
|
||||
}
|
||||
#ifndef PonM
|
||||
pTerm[e] = cs.Kp * pid_error[e];
|
||||
iState_sum[e] += pid_error[e];
|
||||
iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
|
||||
iTerm[e] = cs.Ki * iState_sum[e];
|
||||
// PID_K1 defined in Configuration.h in the PID settings
|
||||
#define K2 (1.0-PID_K1)
|
||||
dTerm[e] = (cs.Kd * (pid_input - dState_last[e]))*K2 + (PID_K1 * dTerm[e]); // e.g. digital filtration of derivative term changes
|
||||
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||
if (pid_output > PID_MAX) {
|
||||
if (pid_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||
pid_output=PID_MAX;
|
||||
} else if (pid_output < 0) {
|
||||
if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||
pid_output=0;
|
||||
}
|
||||
#else // PonM ("Proportional on Measurement" method)
|
||||
iState_sum[e] += cs.Ki * pid_error[e];
|
||||
iState_sum[e] -= cs.Kp * (pid_input - dState_last[e]);
|
||||
iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX);
|
||||
dTerm[e] = cs.Kd * (pid_input - dState_last[e]);
|
||||
pid_output = iState_sum[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||
pid_output = constrain(pid_output, 0, PID_MAX);
|
||||
#endif // PonM
|
||||
}
|
||||
dState_last[e] = pid_input;
|
||||
#else
|
||||
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
||||
#endif //PID_OPENLOOP
|
||||
#ifdef PID_DEBUG
|
||||
SERIAL_ECHO_START;
|
||||
SERIAL_ECHO(" PID_DEBUG ");
|
||||
SERIAL_ECHO(e);
|
||||
SERIAL_ECHO(": Input ");
|
||||
SERIAL_ECHO(pid_input);
|
||||
SERIAL_ECHO(" Output ");
|
||||
SERIAL_ECHO(pid_output);
|
||||
SERIAL_ECHO(" pTerm ");
|
||||
SERIAL_ECHO(pTerm[e]);
|
||||
SERIAL_ECHO(" iTerm ");
|
||||
SERIAL_ECHO(iTerm[e]);
|
||||
SERIAL_ECHO(" dTerm ");
|
||||
SERIAL_ECHOLN(-dTerm[e]);
|
||||
#endif //PID_DEBUG
|
||||
#else /* PID off */
|
||||
pid_output = 0;
|
||||
if(current_temperature[e] < target_temperature[e]) {
|
||||
pid_output = PID_MAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if temperature is within the correct range
|
||||
if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
|
||||
{
|
||||
soft_pwm[e] = (int)pid_output >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm[e] = 0;
|
||||
}
|
||||
} // End extruder for loop
|
||||
|
||||
checkFans();
|
||||
|
||||
#ifndef PIDTEMPBED
|
||||
if(_millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
|
||||
return;
|
||||
previous_millis_bed_heater = _millis();
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_BED != 0
|
||||
|
||||
#ifdef PIDTEMPBED
|
||||
pid_input = current_temperature_bed;
|
||||
|
||||
#ifndef PID_OPENLOOP
|
||||
pid_error_bed = target_temperature_bed - pid_input;
|
||||
pTerm_bed = cs.bedKp * pid_error_bed;
|
||||
temp_iState_bed += pid_error_bed;
|
||||
temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
|
||||
iTerm_bed = cs.bedKi * temp_iState_bed;
|
||||
|
||||
//PID_K1 defined in Configuration.h in the PID settings
|
||||
#define K2 (1.0-PID_K1)
|
||||
dTerm_bed= (cs.bedKd * (pid_input - temp_dState_bed))*K2 + (PID_K1 * dTerm_bed);
|
||||
temp_dState_bed = pid_input;
|
||||
|
||||
pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
|
||||
if (pid_output > MAX_BED_POWER) {
|
||||
if (pid_error_bed > 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
||||
pid_output=MAX_BED_POWER;
|
||||
} else if (pid_output < 0){
|
||||
if (pid_error_bed < 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
||||
pid_output=0;
|
||||
}
|
||||
|
||||
#else
|
||||
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
||||
#endif //PID_OPENLOOP
|
||||
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
soft_pwm_bed = (int)pid_output >> 1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else {
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
|
||||
#elif !defined(BED_LIMIT_SWITCHING)
|
||||
// Check if temperature is within the correct range
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
if(current_temperature_bed >= target_temperature_bed)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
}
|
||||
#else //#ifdef BED_LIMIT_SWITCHING
|
||||
// Check if temperature is within the correct band
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
|
||||
{
|
||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
}
|
||||
#endif
|
||||
if(target_temperature_bed==0)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
#endif
|
||||
checkFans();
|
||||
}
|
||||
|
||||
#define PGM_RD_W(x) (short)pgm_read_word(&x)
|
||||
@ -769,15 +567,8 @@ static float analog2tempAmbient(int raw)
|
||||
}
|
||||
#endif //AMBIENT_THERMISTOR
|
||||
|
||||
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
|
||||
and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
|
||||
static void updateTemperaturesFromRawValues()
|
||||
static void setTemperaturesFromRawValues()
|
||||
{
|
||||
CRITICAL_SECTION_START;
|
||||
adc_start_cycle();
|
||||
temp_meas_ready = false;
|
||||
CRITICAL_SECTION_END;
|
||||
|
||||
for(uint8_t e=0;e<EXTRUDERS;e++)
|
||||
{
|
||||
current_temperature[e] = analog2temp(current_temperature_raw[e], e);
|
||||
@ -799,6 +590,20 @@ static void updateTemperaturesFromRawValues()
|
||||
#endif //DEBUG_HEATER_BED_SIM
|
||||
}
|
||||
|
||||
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
|
||||
and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
|
||||
static void updateTemperaturesFromRawValues()
|
||||
{
|
||||
// restart a new adc conversion
|
||||
CRITICAL_SECTION_START;
|
||||
adc_start_cycle();
|
||||
temp_meas_ready = false;
|
||||
CRITICAL_SECTION_END;
|
||||
|
||||
// update the previous values
|
||||
setTemperaturesFromRawValues();
|
||||
}
|
||||
|
||||
void soft_pwm_init()
|
||||
{
|
||||
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
|
||||
@ -863,10 +668,6 @@ void soft_pwm_init()
|
||||
digitalWrite(MAX6675_SS,1);
|
||||
#endif
|
||||
|
||||
// initialize the ADC and start a conversion
|
||||
adc_init();
|
||||
adc_start_cycle();
|
||||
|
||||
timer0_init(); //enables the heatbed timer.
|
||||
|
||||
// timer2 already enabled earlier in the code
|
||||
@ -875,9 +676,6 @@ void soft_pwm_init()
|
||||
ENABLE_SOFT_PWM_INTERRUPT();
|
||||
|
||||
timer4_init(); //for tone and Extruder fan PWM
|
||||
|
||||
// Wait for temperature measurement to settle
|
||||
_delay(250);
|
||||
|
||||
#ifdef HEATER_0_MINTEMP
|
||||
minttemp[0] = HEATER_0_MINTEMP;
|
||||
@ -2036,3 +1834,265 @@ bool has_temperature_compensation()
|
||||
}
|
||||
#endif //PINDA_THERMISTOR
|
||||
|
||||
|
||||
#define TEMP_MGR_INTV 0.3 // seconds, 33.3Hz
|
||||
#define TIMER5_PRESCALE 256
|
||||
#define TIMER5_OCRA_OVF (uint16_t)(TEMP_MGR_INTV / ((long double)TIMER5_PRESCALE / F_CPU))
|
||||
#define ENABLE_TEMP_MGR_INTERRUPT() TIMSK5 |= (1<<OCIE5A)
|
||||
#define DISABLE_TEMP_MGR_INTERRUPT() TIMSK5 &= ~(1<<OCIE5A)
|
||||
|
||||
void temp_mgr_init()
|
||||
{
|
||||
// initialize the ADC and start a conversion
|
||||
adc_init();
|
||||
adc_start_cycle();
|
||||
|
||||
// initialize timer5
|
||||
CRITICAL_SECTION_START;
|
||||
|
||||
// CTC
|
||||
TCCR5B &= ~(1<<WGM53);
|
||||
TCCR5B |= (1<<WGM52);
|
||||
TCCR5A &= ~(1<<WGM51);
|
||||
TCCR5A &= ~(1<<WGM50);
|
||||
|
||||
// output mode = 00 (disconnected)
|
||||
TCCR5A &= ~(3<<COM5A0);
|
||||
TCCR5A &= ~(3<<COM5B0);
|
||||
|
||||
// x/256 prescaler
|
||||
TCCR5B |= (1<<CS52);
|
||||
TCCR5B &= ~(1<<CS51);
|
||||
TCCR5B &= ~(1<<CS50);
|
||||
|
||||
// reset counter
|
||||
TCNT5 = 0;
|
||||
OCR5A = TIMER5_OCRA_OVF;
|
||||
|
||||
// clear pending interrupts, enable COMPA
|
||||
TIFR5 |= (1<<OCF5A);
|
||||
ENABLE_TEMP_MGR_INTERRUPT();
|
||||
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
static void pid_heater(uint8_t e)
|
||||
{
|
||||
float pid_input;
|
||||
float pid_output;
|
||||
|
||||
#ifdef TEMP_RUNAWAY_EXTRUDER_HYSTERESIS
|
||||
temp_runaway_check(e+1, target_temperature[e], current_temperature[e], (int)soft_pwm[e], false);
|
||||
#endif
|
||||
|
||||
#ifdef PIDTEMP
|
||||
pid_input = current_temperature[e];
|
||||
|
||||
#ifndef PID_OPENLOOP
|
||||
if(target_temperature[e] == 0) {
|
||||
pid_output = 0;
|
||||
pid_reset[e] = true;
|
||||
} else {
|
||||
pid_error[e] = target_temperature[e] - pid_input;
|
||||
if(pid_reset[e]) {
|
||||
iState_sum[e] = 0.0;
|
||||
dTerm[e] = 0.0; // 'dState_last[e]' initial setting is not necessary (see end of if-statement)
|
||||
pid_reset[e] = false;
|
||||
}
|
||||
#ifndef PonM
|
||||
pTerm[e] = cs.Kp * pid_error[e];
|
||||
iState_sum[e] += pid_error[e];
|
||||
iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
|
||||
iTerm[e] = cs.Ki * iState_sum[e];
|
||||
// PID_K1 defined in Configuration.h in the PID settings
|
||||
#define K2 (1.0-PID_K1)
|
||||
dTerm[e] = (cs.Kd * (pid_input - dState_last[e]))*K2 + (PID_K1 * dTerm[e]); // e.g. digital filtration of derivative term changes
|
||||
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||
if (pid_output > PID_MAX) {
|
||||
if (pid_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||
pid_output=PID_MAX;
|
||||
} else if (pid_output < 0) {
|
||||
if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
|
||||
pid_output=0;
|
||||
}
|
||||
#else // PonM ("Proportional on Measurement" method)
|
||||
iState_sum[e] += cs.Ki * pid_error[e];
|
||||
iState_sum[e] -= cs.Kp * (pid_input - dState_last[e]);
|
||||
iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX);
|
||||
dTerm[e] = cs.Kd * (pid_input - dState_last[e]);
|
||||
pid_output = iState_sum[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
|
||||
pid_output = constrain(pid_output, 0, PID_MAX);
|
||||
#endif // PonM
|
||||
}
|
||||
dState_last[e] = pid_input;
|
||||
#else //PID_OPENLOOP
|
||||
pid_output = constrain(target_temperature[e], 0, PID_MAX);
|
||||
#endif //PID_OPENLOOP
|
||||
|
||||
#ifdef PID_DEBUG
|
||||
SERIAL_ECHO_START;
|
||||
SERIAL_ECHO(" PID_DEBUG ");
|
||||
SERIAL_ECHO(e);
|
||||
SERIAL_ECHO(": Input ");
|
||||
SERIAL_ECHO(pid_input);
|
||||
SERIAL_ECHO(" Output ");
|
||||
SERIAL_ECHO(pid_output);
|
||||
SERIAL_ECHO(" pTerm ");
|
||||
SERIAL_ECHO(pTerm[e]);
|
||||
SERIAL_ECHO(" iTerm ");
|
||||
SERIAL_ECHO(iTerm[e]);
|
||||
SERIAL_ECHO(" dTerm ");
|
||||
SERIAL_ECHOLN(-dTerm[e]);
|
||||
#endif //PID_DEBUG
|
||||
|
||||
#else /* PID off */
|
||||
pid_output = 0;
|
||||
if(current_temperature[e] < target_temperature[e]) {
|
||||
pid_output = PID_MAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if temperature is within the correct range
|
||||
if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
|
||||
soft_pwm[e] = (int)pid_output >> 1;
|
||||
else
|
||||
soft_pwm[e] = 0;
|
||||
}
|
||||
|
||||
static void pid_bed()
|
||||
{
|
||||
float pid_input;
|
||||
float pid_output;
|
||||
|
||||
#ifdef TEMP_RUNAWAY_BED_HYSTERESIS
|
||||
temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
|
||||
#endif
|
||||
|
||||
#ifndef PIDTEMPBED
|
||||
if(_millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
|
||||
return;
|
||||
previous_millis_bed_heater = _millis();
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_BED != 0
|
||||
|
||||
#ifdef PIDTEMPBED
|
||||
pid_input = current_temperature_bed;
|
||||
|
||||
#ifndef PID_OPENLOOP
|
||||
pid_error_bed = target_temperature_bed - pid_input;
|
||||
pTerm_bed = cs.bedKp * pid_error_bed;
|
||||
temp_iState_bed += pid_error_bed;
|
||||
temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
|
||||
iTerm_bed = cs.bedKi * temp_iState_bed;
|
||||
|
||||
//PID_K1 defined in Configuration.h in the PID settings
|
||||
#define K2 (1.0-PID_K1)
|
||||
dTerm_bed= (cs.bedKd * (pid_input - temp_dState_bed))*K2 + (PID_K1 * dTerm_bed);
|
||||
temp_dState_bed = pid_input;
|
||||
|
||||
pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
|
||||
if (pid_output > MAX_BED_POWER) {
|
||||
if (pid_error_bed > 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
||||
pid_output=MAX_BED_POWER;
|
||||
} else if (pid_output < 0){
|
||||
if (pid_error_bed < 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
|
||||
pid_output=0;
|
||||
}
|
||||
|
||||
#else
|
||||
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
|
||||
#endif //PID_OPENLOOP
|
||||
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
soft_pwm_bed = (int)pid_output >> 1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
|
||||
#elif !defined(BED_LIMIT_SWITCHING)
|
||||
// Check if temperature is within the correct range
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
if(current_temperature_bed >= target_temperature_bed)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
}
|
||||
#else //#ifdef BED_LIMIT_SWITCHING
|
||||
// Check if temperature is within the correct band
|
||||
if(current_temperature_bed < BED_MAXTEMP)
|
||||
{
|
||||
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
|
||||
{
|
||||
soft_pwm_bed = MAX_BED_POWER>>1;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
WRITE(HEATER_BED_PIN,LOW);
|
||||
}
|
||||
#endif //BED_LIMIT_SWITCHING
|
||||
|
||||
if(target_temperature_bed==0)
|
||||
{
|
||||
soft_pwm_bed = 0;
|
||||
timer02_set_pwm0(soft_pwm_bed << 1);
|
||||
}
|
||||
#endif //TEMP_SENSOR_BED
|
||||
}
|
||||
|
||||
static void temp_mgr_isr()
|
||||
{
|
||||
// ADC values need to be converted before checking: converted values are later used in MINTEMP
|
||||
setTemperaturesFromRawValues();
|
||||
|
||||
// TODO: this is now running inside an isr and cannot directly manipulate the lcd,
|
||||
// this needs to disable temperatures and flag the error to be shown in manage_heaters!
|
||||
check_max_temp();
|
||||
check_min_temp();
|
||||
|
||||
for(uint8_t e = 0; e < EXTRUDERS; e++)
|
||||
pid_heater(e);
|
||||
pid_bed();
|
||||
}
|
||||
|
||||
ISR(TIMER5_COMPA_vect)
|
||||
{
|
||||
// immediately schedule a new conversion
|
||||
if(temp_meas_ready != true) return;
|
||||
adc_start_cycle();
|
||||
temp_meas_ready = false;
|
||||
|
||||
// run temperature management with interrupts enabled to reduce latency
|
||||
DISABLE_TEMP_MGR_INTERRUPT();
|
||||
sei();
|
||||
temp_mgr_isr();
|
||||
cli();
|
||||
ENABLE_TEMP_MGR_INTERRUPT();
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
|
||||
// public functions
|
||||
void soft_pwm_init(); //initialize the soft pwm isr
|
||||
void temp_mgr_init(); //initialize the temperature handler
|
||||
void manage_heater(); //it is critical that this is called periodically.
|
||||
|
||||
extern bool checkAllHotends(void);
|
||||
|
Loading…
Reference in New Issue
Block a user