Revert default conf and temperature.cpp

This commit is contained in:
chrono 2015-03-02 13:56:37 +00:00
parent 7f060d7caf
commit 187d336665

View file

@ -33,9 +33,43 @@
#include "ultralcd.h" #include "ultralcd.h"
#include "temperature.h" #include "temperature.h"
#include "watchdog.h" #include "watchdog.h"
#include "language.h"
#include "Sd2PinMap.h" #include "Sd2PinMap.h"
//===========================================================================
//================================== macros =================================
//===========================================================================
#if EXTRUDERS > 4
#error Unsupported number of extruders
#elif EXTRUDERS > 3
#define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3, v4 }
#elif EXTRUDERS > 2
#define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3 }
#elif EXTRUDERS > 1
#define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2 }
#else
#define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1 }
#endif
#define HAS_TEMP_0 (defined(TEMP_0_PIN) && TEMP_0_PIN >= 0)
#define HAS_TEMP_1 (defined(TEMP_1_PIN) && TEMP_1_PIN >= 0)
#define HAS_TEMP_2 (defined(TEMP_2_PIN) && TEMP_2_PIN >= 0)
#define HAS_TEMP_3 (defined(TEMP_3_PIN) && TEMP_3_PIN >= 0)
#define HAS_TEMP_BED (defined(TEMP_BED_PIN) && TEMP_BED_PIN >= 0)
#define HAS_FILAMENT_SENSOR (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0)
#define HAS_HEATER_0 (defined(HEATER_0_PIN) && HEATER_0_PIN >= 0)
#define HAS_HEATER_1 (defined(HEATER_1_PIN) && HEATER_1_PIN >= 0)
#define HAS_HEATER_2 (defined(HEATER_2_PIN) && HEATER_2_PIN >= 0)
#define HAS_HEATER_3 (defined(HEATER_3_PIN) && HEATER_3_PIN >= 0)
#define HAS_HEATER_BED (defined(HEATER_BED_PIN) && HEATER_BED_PIN >= 0)
#define HAS_AUTO_FAN_0 (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_1 (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_2 (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_3 (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3
#define HAS_FAN (defined(FAN_PIN) && FAN_PIN >= 0)
//=========================================================================== //===========================================================================
//============================= public variables ============================ //============================= public variables ============================
@ -71,7 +105,7 @@ float current_temperature_bed = 0.0;
unsigned char soft_pwm_bed; unsigned char soft_pwm_bed;
#ifdef BABYSTEPPING #ifdef BABYSTEPPING
volatile int babystepsTodo[3]={0,0,0}; volatile int babystepsTodo[3] = { 0 };
#endif #endif
#ifdef FILAMENT_SENSOR #ifdef FILAMENT_SENSOR
@ -116,40 +150,26 @@ static volatile bool temp_meas_ready = false;
#ifdef FAN_SOFT_PWM #ifdef FAN_SOFT_PWM
static unsigned char soft_pwm_fan; static unsigned char soft_pwm_fan;
#endif #endif
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ #if HAS_AUTO_FAN
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
static unsigned long extruder_autofan_last_check; static unsigned long extruder_autofan_last_check;
#endif #endif
#if EXTRUDERS > 4
# error Unsupported number of extruders
#elif EXTRUDERS > 3
# define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3, v4 }
#elif EXTRUDERS > 2
# define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2, v3 }
#elif EXTRUDERS > 1
# define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1, v2 }
#else
# define ARRAY_BY_EXTRUDERS(v1, v2, v3, v4) { v1 }
#endif
#ifdef PIDTEMP #ifdef PIDTEMP
#ifdef PID_PARAMS_PER_EXTRUDER #ifdef PID_PARAMS_PER_EXTRUDER
float Kp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp); float Kp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp);
float Ki[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT); float Ki[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT);
float Kd[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT); float Kd[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT);
#ifdef PID_ADD_EXTRUSION_RATE #ifdef PID_ADD_EXTRUSION_RATE
float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc); float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc);
#endif // PID_ADD_EXTRUSION_RATE #endif // PID_ADD_EXTRUSION_RATE
#else //PID_PARAMS_PER_EXTRUDER #else //PID_PARAMS_PER_EXTRUDER
float Kp = DEFAULT_Kp; float Kp = DEFAULT_Kp;
float Ki = DEFAULT_Ki * PID_dT; float Ki = DEFAULT_Ki * PID_dT;
float Kd = DEFAULT_Kd / PID_dT; float Kd = DEFAULT_Kd / PID_dT;
#ifdef PID_ADD_EXTRUSION_RATE #ifdef PID_ADD_EXTRUSION_RATE
float Kc = DEFAULT_Kc; float Kc = DEFAULT_Kc;
#endif // PID_ADD_EXTRUSION_RATE #endif // PID_ADD_EXTRUSION_RATE
#endif // PID_PARAMS_PER_EXTRUDER #endif // PID_PARAMS_PER_EXTRUDER
#endif //PIDTEMP #endif //PIDTEMP
// Init min and max temp with extreme values to prevent false errors during startup // Init min and max temp with extreme values to prevent false errors during startup
@ -159,7 +179,7 @@ static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0, 0 );
static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383, 16383 ); static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383, 16383 );
//static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */ //static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */
#ifdef BED_MAXTEMP #ifdef BED_MAXTEMP
static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP; static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
#endif #endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
@ -175,12 +195,12 @@ static float analog2tempBed(int raw);
static void updateTemperaturesFromRawValues(); static void updateTemperaturesFromRawValues();
#ifdef WATCH_TEMP_PERIOD #ifdef WATCH_TEMP_PERIOD
int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0); int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0); unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
#endif //WATCH_TEMP_PERIOD #endif //WATCH_TEMP_PERIOD
#ifndef SOFT_PWM_SCALE #ifndef SOFT_PWM_SCALE
#define SOFT_PWM_SCALE 0 #define SOFT_PWM_SCALE 0
#endif #endif
#ifdef FILAMENT_SENSOR #ifdef FILAMENT_SENSOR
@ -198,113 +218,98 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0,0);
void PID_autotune(float temp, int extruder, int ncycles) void PID_autotune(float temp, int extruder, int ncycles)
{ {
float input = 0.0; float input = 0.0;
int cycles=0; int cycles = 0;
bool heating = true; bool heating = true;
unsigned long temp_millis = millis(); unsigned long temp_millis = millis(), t1 = temp_millis, t2 = temp_millis;
unsigned long t1=temp_millis; long t_high = 0, t_low = 0;
unsigned long t2=temp_millis;
long t_high = 0;
long t_low = 0;
long bias, d; long bias, d;
float Ku, Tu; float Ku, Tu;
float Kp, Ki, Kd; float Kp, Ki, Kd;
float max = 0, min = 10000; float max = 0, min = 10000;
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ #if HAS_AUTO_FAN
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ unsigned long extruder_autofan_last_check = temp_millis;
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1)
unsigned long extruder_autofan_last_check = millis();
#endif
if ((extruder >= EXTRUDERS)
#if (TEMP_BED_PIN <= -1)
||(extruder < 0)
#endif #endif
){
SERIAL_ECHOLN("PID Autotune failed. Bad extruder number."); if (extruder >= EXTRUDERS
return; #if !HAS_TEMP_BED
} || extruder < 0
#endif
) {
SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
return;
}
SERIAL_ECHOLN("PID Autotune start"); SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
disable_heater(); // switch off all heaters. disable_heater(); // switch off all heaters.
if (extruder<0) if (extruder < 0)
{ soft_pwm_bed = bias = d = MAX_BED_POWER / 2;
soft_pwm_bed = (MAX_BED_POWER)/2; else
bias = d = (MAX_BED_POWER)/2; soft_pwm[extruder] = bias = d = PID_MAX / 2;
}
else
{
soft_pwm[extruder] = (PID_MAX)/2;
bias = d = (PID_MAX)/2;
}
// PID Tuning loop
for(;;) {
unsigned long ms = millis();
if (temp_meas_ready == true) { // temp sample ready
for(;;) {
if(temp_meas_ready == true) { // temp sample ready
updateTemperaturesFromRawValues(); updateTemperaturesFromRawValues();
input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; input = (extruder<0)?current_temperature_bed:current_temperature[extruder];
max=max(max,input); max = max(max, input);
min=min(min,input); min = min(min, input);
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ #if HAS_AUTO_FAN
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \ if (ms > extruder_autofan_last_check + 2500) {
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \ checkExtruderAutoFans();
(defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1) extruder_autofan_last_check = ms;
if(millis() - extruder_autofan_last_check > 2500) { }
checkExtruderAutoFans();
extruder_autofan_last_check = millis();
}
#endif #endif
if(heating == true && input > temp) { if (heating == true && input > temp) {
if(millis() - t2 > 5000) { if (ms - t2 > 5000) {
heating=false; heating = false;
if (extruder<0) if (extruder < 0)
soft_pwm_bed = (bias - d) >> 1; soft_pwm_bed = (bias - d) >> 1;
else else
soft_pwm[extruder] = (bias - d) >> 1; soft_pwm[extruder] = (bias - d) >> 1;
t1=millis(); t1 = ms;
t_high=t1 - t2; t_high = t1 - t2;
max=temp; max = temp;
} }
} }
if(heating == false && input < temp) { if (heating == false && input < temp) {
if(millis() - t1 > 5000) { if (ms - t1 > 5000) {
heating=true; heating = true;
t2=millis(); t2 = ms;
t_low=t2 - t1; t_low = t2 - t1;
if(cycles > 0) { if (cycles > 0) {
long max_pow = extruder < 0 ? MAX_BED_POWER : PID_MAX;
bias += (d*(t_high - t_low))/(t_low + t_high); bias += (d*(t_high - t_low))/(t_low + t_high);
bias = constrain(bias, 20 ,(extruder<0?(MAX_BED_POWER):(PID_MAX))-20); bias = constrain(bias, 20, max_pow - 20);
if(bias > (extruder<0?(MAX_BED_POWER):(PID_MAX))/2) d = (extruder<0?(MAX_BED_POWER):(PID_MAX)) - 1 - bias; d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
else d = bias;
SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias); SERIAL_PROTOCOLPGM(MSG_BIAS); SERIAL_PROTOCOL(bias);
SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d); SERIAL_PROTOCOLPGM(MSG_D); SERIAL_PROTOCOL(d);
SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min); SERIAL_PROTOCOLPGM(MSG_MIN); SERIAL_PROTOCOL(min);
SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max); SERIAL_PROTOCOLPGM(MSG_MAX); SERIAL_PROTOCOLLN(max);
if(cycles > 2) { if (cycles > 2) {
Ku = (4.0*d)/(3.14159*(max-min)/2.0); Ku = (4.0 * d) / (3.14159265 * (max - min) / 2.0);
Tu = ((float)(t_low + t_high)/1000.0); Tu = ((float)(t_low + t_high) / 1000.0);
SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku); SERIAL_PROTOCOLPGM(MSG_KU); SERIAL_PROTOCOL(Ku);
SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu); SERIAL_PROTOCOLPGM(MSG_TU); SERIAL_PROTOCOLLN(Tu);
Kp = 0.6*Ku; Kp = 0.6 * Ku;
Ki = 2*Kp/Tu; Ki = 2 * Kp / Tu;
Kd = Kp*Tu/8; Kd = Kp * Tu / 8;
SERIAL_PROTOCOLLNPGM(" Classic PID "); SERIAL_PROTOCOLLNPGM(MSG_CLASSIC_PID);
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); SERIAL_PROTOCOLPGM(MSG_KP); SERIAL_PROTOCOLLN(Kp);
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); SERIAL_PROTOCOLPGM(MSG_KI); SERIAL_PROTOCOLLN(Ki);
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); SERIAL_PROTOCOLPGM(MSG_KD); SERIAL_PROTOCOLLN(Kd);
/* /*
Kp = 0.33*Ku; Kp = 0.33*Ku;
Ki = Kp/Tu; Ki = Kp/Tu;
@ -323,79 +328,80 @@ void PID_autotune(float temp, int extruder, int ncycles)
*/ */
} }
} }
if (extruder<0) if (extruder < 0)
soft_pwm_bed = (bias + d) >> 1; soft_pwm_bed = (bias + d) >> 1;
else else
soft_pwm[extruder] = (bias + d) >> 1; soft_pwm[extruder] = (bias + d) >> 1;
cycles++; cycles++;
min=temp; min = temp;
} }
} }
} }
if(input > (temp + 20)) { if (input > temp + 20) {
SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature too high"); SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH);
return; return;
} }
if(millis() - temp_millis > 2000) { // Every 2 seconds...
if (ms > temp_millis + 2000) {
int p; int p;
if (extruder<0){ if (extruder < 0) {
p=soft_pwm_bed; p = soft_pwm_bed;
SERIAL_PROTOCOLPGM("ok B:"); SERIAL_PROTOCOLPGM(MSG_OK_B);
}else{ }
p=soft_pwm[extruder]; else {
SERIAL_PROTOCOLPGM("ok T:"); p = soft_pwm[extruder];
SERIAL_PROTOCOLPGM(MSG_OK_T);
} }
SERIAL_PROTOCOL(input);
SERIAL_PROTOCOLPGM(" @:");
SERIAL_PROTOCOLLN(p);
temp_millis = millis(); SERIAL_PROTOCOL(input);
} SERIAL_PROTOCOLPGM(MSG_AT);
if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) { SERIAL_PROTOCOLLN(p);
SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
temp_millis = ms;
} // every 2 seconds
// Over 2 minutes?
if (((ms - t1) + (ms - t2)) > (10L*60L*1000L*2L)) {
SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT);
return; return;
} }
if(cycles > ncycles) { if (cycles > ncycles) {
SERIAL_PROTOCOLLNPGM("PID Autotune finished! Put the last Kp, Ki and Kd constants from above into Configuration.h"); SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
return; return;
} }
lcd_update(); lcd_update();
} }
} }
void updatePID() void updatePID() {
{ #ifdef PIDTEMP
#ifdef PIDTEMP for (int e = 0; e < EXTRUDERS; e++) {
for(int e = 0; e < EXTRUDERS; e++) { temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e); }
} #endif
#endif #ifdef PIDTEMPBED
#ifdef PIDTEMPBED temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi; #endif
#endif
} }
int getHeaterPower(int heater) { int getHeaterPower(int heater) {
if (heater<0) return heater < 0 ? soft_pwm_bed : soft_pwm[heater];
return soft_pwm_bed;
return soft_pwm[heater];
} }
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ #if HAS_AUTO_FAN
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
#if defined(FAN_PIN) && FAN_PIN > -1 #if HAS_FAN
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN #if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN" #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
#endif #endif
#if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN #if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN" #error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
#endif #endif
#if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN #if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN" #error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
#endif #endif
#if EXTRUDER_3_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_3_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#endif #endif
void setExtruderAutoFanState(int pin, bool state) void setExtruderAutoFanState(int pin, bool state)
@ -412,20 +418,20 @@ void checkExtruderAutoFans()
uint8_t fanState = 0; uint8_t fanState = 0;
// which fan pins need to be turned on? // which fan pins need to be turned on?
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_0
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1; fanState |= 1;
#endif #endif
#if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_1
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{ {
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1; fanState |= 1;
else else
fanState |= 2; fanState |= 2;
} }
#endif #endif
#if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_2
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{ {
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
@ -436,7 +442,7 @@ void checkExtruderAutoFans()
fanState |= 4; fanState |= 4;
} }
#endif #endif
#if defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_3
if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{ {
if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
@ -451,19 +457,19 @@ void checkExtruderAutoFans()
#endif #endif
// update extruder auto fan states // update extruder auto fan states
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_0
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0); setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif #endif
#if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_1
if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0); setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
#endif #endif
#if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_2
if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
&& EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0); setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
#endif #endif
#if defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1 #if HAS_AUTO_FAN_3
if (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN if (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN)
@ -473,47 +479,81 @@ void checkExtruderAutoFans()
#endif // any extruder auto fan pins set #endif // any extruder auto fan pins set
void manage_heater() //
{ // Error checking and Write Routines
float pid_input; //
float pid_output; #if !HAS_HEATER_0
#error HEATER_0_PIN not defined for this board
#endif
#define WRITE_HEATER_0P(v) WRITE(HEATER_0_PIN, v)
#if EXTRUDERS > 1 || defined(HEATERS_PARALLEL)
#if !HAS_HEATER_1
#error HEATER_1_PIN not defined for this board
#endif
#define WRITE_HEATER_1(v) WRITE(HEATER_1_PIN, v)
#if EXTRUDERS > 2
#if !HAS_HEATER_2
#error HEATER_2_PIN not defined for this board
#endif
#define WRITE_HEATER_2(v) WRITE(HEATER_2_PIN, v)
#if EXTRUDERS > 3
#if !HAS_HEATER_3
#error HEATER_3_PIN not defined for this board
#endif
#define WRITE_HEATER_3(v) WRITE(HEATER_3_PIN, v)
#endif
#endif
#endif
#ifdef HEATERS_PARALLEL
#define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); }
#else
#define WRITE_HEATER_0(v) WRITE_HEATER_0P(v)
#endif
#if HAS_HEATER_BED
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN, v)
#endif
#if HAS_FAN
#define WRITE_FAN(v) WRITE(FAN_PIN, v)
#endif
if(temp_meas_ready != true) //better readability void manage_heater() {
return;
if (!temp_meas_ready) return;
float pid_input, pid_output;
updateTemperaturesFromRawValues(); updateTemperaturesFromRawValues();
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
if (current_temperature[0] > 1023 || current_temperature[0] > HEATER_0_MAXTEMP) { float ct = current_temperature[0];
max_temp_error(0); if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0);
} if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
if (current_temperature[0] == 0 || current_temperature[0] < HEATER_0_MINTEMP) {
min_temp_error(0);
}
#endif //HEATER_0_USES_MAX6675 #endif //HEATER_0_USES_MAX6675
for(int e = 0; e < EXTRUDERS; e++) unsigned long ms = millis();
{
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 // Loop through all extruders
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS); for (int e = 0; e < EXTRUDERS; e++) {
#endif
#ifdef PIDTEMP #if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
pid_input = current_temperature[e]; thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
#endif
#ifndef PID_OPENLOOP #ifdef PIDTEMP
pid_input = current_temperature[e];
#ifndef PID_OPENLOOP
pid_error[e] = target_temperature[e] - pid_input; pid_error[e] = target_temperature[e] - pid_input;
if(pid_error[e] > PID_FUNCTIONAL_RANGE) { if (pid_error[e] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX; pid_output = BANG_MAX;
pid_reset[e] = true; pid_reset[e] = true;
} }
else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) { else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
pid_output = 0; pid_output = 0;
pid_reset[e] = true; pid_reset[e] = true;
} }
else { else {
if(pid_reset[e] == true) { if (pid_reset[e] == true) {
temp_iState[e] = 0.0; temp_iState[e] = 0.0;
pid_reset[e] = false; pid_reset[e] = false;
} }
@ -524,95 +564,89 @@ void manage_heater()
//K1 defined in Configuration.h in the PID settings //K1 defined in Configuration.h in the PID settings
#define K2 (1.0-K1) #define K2 (1.0-K1)
dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]); dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e])) * K2 + (K1 * dTerm[e]);
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; pid_output = pTerm[e] + iTerm[e] - dTerm[e];
if (pid_output > PID_MAX) { if (pid_output > PID_MAX) {
if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output=PID_MAX; pid_output = PID_MAX;
} else if (pid_output < 0){ }
if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration else if (pid_output < 0) {
pid_output=0; if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = 0;
} }
} }
temp_dState[e] = pid_input; temp_dState[e] = pid_input;
#else #else
pid_output = constrain(target_temperature[e], 0, PID_MAX); pid_output = constrain(target_temperature[e], 0, PID_MAX);
#endif //PID_OPENLOOP #endif //PID_OPENLOOP
#ifdef PID_DEBUG
SERIAL_ECHO_START; #ifdef PID_DEBUG
SERIAL_ECHO(" PID_DEBUG "); SERIAL_ECHO_START;
SERIAL_ECHO(e); SERIAL_ECHO(MSG_PID_DEBUG);
SERIAL_ECHO(": Input "); SERIAL_ECHO(e);
SERIAL_ECHO(pid_input); SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
SERIAL_ECHO(" Output "); SERIAL_ECHO(pid_input);
SERIAL_ECHO(pid_output); SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
SERIAL_ECHO(" pTerm "); SERIAL_ECHO(pid_output);
SERIAL_ECHO(pTerm[e]); SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
SERIAL_ECHO(" iTerm "); SERIAL_ECHO(pTerm[e]);
SERIAL_ECHO(iTerm[e]); SERIAL_ECHO(MSG_PID_DEBUG_ITERM);
SERIAL_ECHO(" dTerm "); SERIAL_ECHO(iTerm[e]);
SERIAL_ECHOLN(dTerm[e]); SERIAL_ECHO(MSG_PID_DEBUG_DTERM);
#endif //PID_DEBUG SERIAL_ECHOLN(dTerm[e]);
#else /* PID off */ #endif //PID_DEBUG
pid_output = 0;
if(current_temperature[e] < target_temperature[e]) { #else /* PID off */
pid_output = PID_MAX;
} pid_output = 0;
#endif if (current_temperature[e] < target_temperature[e]) pid_output = PID_MAX;
#endif
// Check if temperature is within the correct range // Check if temperature is within the correct range
if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e])) soft_pwm[e] = current_temperature[e] > minttemp[e] && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0;
{
soft_pwm[e] = (int)pid_output >> 1;
}
else {
soft_pwm[e] = 0;
}
#ifdef WATCH_TEMP_PERIOD #ifdef WATCH_TEMP_PERIOD
if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD) if (watchmillis[e] && ms > watchmillis[e] + WATCH_TEMP_PERIOD) {
{ if (degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE) {
if(degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE) setTargetHotend(0, e);
{ LCD_MESSAGEPGM(MSG_HEATING_FAILED_LCD); // translatable
setTargetHotend(0, e); SERIAL_ECHO_START;
LCD_MESSAGEPGM("Heating failed"); SERIAL_ECHOLNPGM(MSG_HEATING_FAILED);
SERIAL_ECHO_START;
SERIAL_ECHOLN("Heating failed");
}else{
watchmillis[e] = 0;
} }
} else {
#endif watchmillis[e] = 0;
}
}
#endif //WATCH_TEMP_PERIOD
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
if(fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) { if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
disable_heater(); disable_heater();
if(IsStopped() == false) { if (IsStopped() == false) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Extruder switched off. Temperature difference between temp sensors is too high !"); SERIAL_ERRORLNPGM(MSG_EXTRUDER_SWITCHED_OFF);
LCD_ALERTMESSAGEPGM("Err: REDUNDANT TEMP ERROR"); LCD_ALERTMESSAGEPGM(MSG_ERR_REDUNDANT_TEMP); // translatable
} }
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop(); Stop();
#endif #endif
} }
#endif #endif //TEMP_SENSOR_1_AS_REDUNDANT
} // End extruder for loop
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \ } // Extruders Loop
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) #if HAS_AUTO_FAN
if(millis() - extruder_autofan_last_check > 2500) // only need to check fan state very infrequently if (ms > extruder_autofan_last_check + 2500) { // only need to check fan state very infrequently
{ checkExtruderAutoFans();
checkExtruderAutoFans(); extruder_autofan_last_check = ms;
extruder_autofan_last_check = millis(); }
}
#endif #endif
#ifndef PIDTEMPBED #ifndef PIDTEMPBED
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) if (ms < previous_millis_bed_heater + BED_CHECK_INTERVAL) return;
return; previous_millis_bed_heater = ms;
previous_millis_bed_heater = millis(); #endif //PIDTEMPBED
#endif
#if TEMP_SENSOR_BED != 0 #if TEMP_SENSOR_BED != 0
@ -620,102 +654,75 @@ void manage_heater()
thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, 9, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS); thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, 9, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS);
#endif #endif
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
pid_input = current_temperature_bed; pid_input = current_temperature_bed;
#ifndef PID_OPENLOOP #ifndef PID_OPENLOOP
pid_error_bed = target_temperature_bed - pid_input; pid_error_bed = target_temperature_bed - pid_input;
pTerm_bed = bedKp * pid_error_bed; pTerm_bed = bedKp * pid_error_bed;
temp_iState_bed += pid_error_bed; temp_iState_bed += pid_error_bed;
temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed); temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
iTerm_bed = bedKi * temp_iState_bed; iTerm_bed = bedKi * temp_iState_bed;
//K1 defined in Configuration.h in the PID settings //K1 defined in Configuration.h in the PID settings
#define K2 (1.0-K1) #define K2 (1.0-K1)
dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed); dTerm_bed = (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
temp_dState_bed = pid_input; temp_dState_bed = pid_input;
pid_output = pTerm_bed + iTerm_bed - dTerm_bed; pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
if (pid_output > MAX_BED_POWER) { if (pid_output > MAX_BED_POWER) {
if (pid_error_bed > 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output=MAX_BED_POWER; pid_output = MAX_BED_POWER;
} else if (pid_output < 0){ }
if (pid_error_bed < 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration else if (pid_output < 0) {
pid_output=0; if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
} pid_output = 0;
}
#else #else
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#endif //PID_OPENLOOP #endif //PID_OPENLOOP
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0;
{
soft_pwm_bed = (int)pid_output >> 1;
}
else {
soft_pwm_bed = 0;
}
#elif !defined(BED_LIMIT_SWITCHING) #elif !defined(BED_LIMIT_SWITCHING)
// Check if temperature is within the correct range // Check if temperature is within the correct range
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
{ soft_pwm_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0;
if(current_temperature_bed >= target_temperature_bed)
{
soft_pwm_bed = 0;
}
else
{
soft_pwm_bed = MAX_BED_POWER>>1;
}
} }
else else {
{
soft_pwm_bed = 0; soft_pwm_bed = 0;
WRITE(HEATER_BED_PIN,LOW); WRITE_HEATER_BED(LOW);
} }
#else //#ifdef BED_LIMIT_SWITCHING #else //#ifdef BED_LIMIT_SWITCHING
// Check if temperature is within the correct band // Check if temperature is within the correct band
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
{ if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS)
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
{
soft_pwm_bed = 0; soft_pwm_bed = 0;
} else if (current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS) soft_pwm_bed = MAX_BED_POWER >> 1;
{
soft_pwm_bed = MAX_BED_POWER>>1;
}
} }
else else {
{
soft_pwm_bed = 0; soft_pwm_bed = 0;
WRITE(HEATER_BED_PIN,LOW); WRITE_HEATER_BED(LOW);
} }
#endif #endif
#endif #endif //TEMP_SENSOR_BED != 0
//code for controlling the extruder rate based on the width sensor // Control the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR #ifdef FILAMENT_SENSOR
if(filament_sensor) if (filament_sensor) {
{ meas_shift_index = delay_index1 - meas_delay_cm;
meas_shift_index=delay_index1-meas_delay_cm; if (meas_shift_index < 0) meas_shift_index += MAX_MEASUREMENT_DELAY + 1; //loop around buffer if needed
if(meas_shift_index<0)
meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed
//get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter // Get the delayed info and add 100 to reconstitute to a percent of
//then square it to get an area // the nominal filament diameter then square it to get an area
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
if(meas_shift_index<0) float vm = pow((measurement_delay[meas_shift_index] + 100.0) / 100.0, 2);
meas_shift_index=0; if (vm < 0.01) vm = 0.01;
else if (meas_shift_index>MAX_MEASUREMENT_DELAY) volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
meas_shift_index=MAX_MEASUREMENT_DELAY; }
#endif //FILAMENT_SENSOR
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/100.0,2);
if (volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] <0.01)
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01;
}
#endif
} }
#define PGM_RD_W(x) (short)pgm_read_word(&x) #define PGM_RD_W(x) (short)pgm_read_word(&x)
@ -723,14 +730,14 @@ void manage_heater()
// For hot end temperature measurement. // For hot end temperature measurement.
static float analog2temp(int raw, uint8_t e) { static float analog2temp(int raw, uint8_t e) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
if(e > EXTRUDERS) if (e > EXTRUDERS)
#else #else
if(e >= EXTRUDERS) if (e >= EXTRUDERS)
#endif #endif
{ {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERROR((int)e); SERIAL_ERROR((int)e);
SERIAL_ERRORLNPGM(" - Invalid extruder number !"); SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER_NUM);
kill(); kill();
return 0.0; return 0.0;
} }
@ -799,54 +806,45 @@ static float analog2tempBed(int raw) {
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context, /* 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 */ 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 updateTemperaturesFromRawValues() {
{ #ifdef HEATER_0_USES_MAX6675
#ifdef HEATER_0_USES_MAX6675 current_temperature_raw[0] = read_max6675();
current_temperature_raw[0] = read_max6675(); #endif
#endif for(uint8_t e = 0; e < EXTRUDERS; e++) {
for(uint8_t e=0;e<EXTRUDERS;e++) current_temperature[e] = analog2temp(current_temperature_raw[e], e);
{ }
current_temperature[e] = analog2temp(current_temperature_raw[e], e); current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
} #ifdef TEMP_SENSOR_1_AS_REDUNDANT
current_temperature_bed = analog2tempBed(current_temperature_bed_raw); redundant_temperature = analog2temp(redundant_temperature_raw, 1);
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #endif
redundant_temperature = analog2temp(redundant_temperature_raw, 1); #if HAS_FILAMENT_SENSOR
#endif filament_width_meas = analog2widthFil();
#if defined (FILAMENT_SENSOR) && (FILWIDTH_PIN > -1) //check if a sensor is supported #endif
filament_width_meas = analog2widthFil(); //Reset the watchdog after we know we have a temperature measurement.
#endif watchdog_reset();
//Reset the watchdog after we know we have a temperature measurement.
watchdog_reset();
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
temp_meas_ready = false; temp_meas_ready = false;
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
} }
// For converting raw Filament Width to milimeters
#ifdef FILAMENT_SENSOR #ifdef FILAMENT_SENSOR
float analog2widthFil() {
return current_raw_filwidth/16383.0*5.0;
//return current_raw_filwidth;
}
// For converting raw Filament Width to a ratio
int widthFil_to_size_ratio() {
float temp;
temp=filament_width_meas;
if(filament_width_meas<MEASURED_LOWER_LIMIT)
temp=filament_width_nominal; //assume sensor cut out
else if (filament_width_meas>MEASURED_UPPER_LIMIT)
temp= MEASURED_UPPER_LIMIT;
// Convert raw Filament Width to millimeters
float analog2widthFil() {
return current_raw_filwidth / 16383.0 * 5.0;
//return current_raw_filwidth;
}
return(filament_width_nominal/temp*100); // Convert raw Filament Width to a ratio
int widthFil_to_size_ratio() {
float temp = filament_width_meas;
if (temp < MEASURED_LOWER_LIMIT) temp = filament_width_nominal; //assume sensor cut out
else if (temp > MEASURED_UPPER_LIMIT) temp = MEASURED_UPPER_LIMIT;
return filament_width_nominal / temp * 100;
}
}
#endif #endif
@ -855,50 +853,50 @@ return(filament_width_nominal/temp*100);
void tp_init() void tp_init()
{ {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)) #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
//disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector //disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=(1<<JTD); MCUCR=(1<<JTD);
MCUCR=(1<<JTD); MCUCR=(1<<JTD);
#endif #endif
// Finish init of mult extruder arrays // Finish init of mult extruder arrays
for(int e = 0; e < EXTRUDERS; e++) { for (int e = 0; e < EXTRUDERS; e++) {
// populate with the first value // populate with the first value
maxttemp[e] = maxttemp[0]; maxttemp[e] = maxttemp[0];
#ifdef PIDTEMP #ifdef PIDTEMP
temp_iState_min[e] = 0.0; temp_iState_min[e] = 0.0;
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e); temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
#endif //PIDTEMP #endif //PIDTEMP
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
temp_iState_min_bed = 0.0; temp_iState_min_bed = 0.0;
temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi; temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
#endif //PIDTEMPBED #endif //PIDTEMPBED
} }
#if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1) #if HAS_HEATER_0
SET_OUTPUT(HEATER_0_PIN); SET_OUTPUT(HEATER_0_PIN);
#endif #endif
#if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1) #if HAS_HEATER_1
SET_OUTPUT(HEATER_1_PIN); SET_OUTPUT(HEATER_1_PIN);
#endif #endif
#if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1) #if HAS_HEATER_2
SET_OUTPUT(HEATER_2_PIN); SET_OUTPUT(HEATER_2_PIN);
#endif #endif
#if defined(HEATER_3_PIN) && (HEATER_3_PIN > -1) #if HAS_HEATER_3
SET_OUTPUT(HEATER_3_PIN); SET_OUTPUT(HEATER_3_PIN);
#endif #endif
#if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1) #if HAS_HEATER_BED
SET_OUTPUT(HEATER_BED_PIN); SET_OUTPUT(HEATER_BED_PIN);
#endif #endif
#if defined(FAN_PIN) && (FAN_PIN > -1) #if HAS_FAN
SET_OUTPUT(FAN_PIN); SET_OUTPUT(FAN_PIN);
#ifdef FAST_PWM_FAN #ifdef FAST_PWM_FAN
setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8 setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
#endif #endif
#ifdef FAN_SOFT_PWM #ifdef FAN_SOFT_PWM
soft_pwm_fan = fanSpeedSoftPwm / 2; soft_pwm_fan = fanSpeedSoftPwm / 2;
#endif #endif
#endif #endif
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
@ -921,57 +919,35 @@ void tp_init()
#endif //HEATER_0_USES_MAX6675 #endif //HEATER_0_USES_MAX6675
#ifdef DIDR2
#define ANALOG_SELECT(pin) do{ if (pin < 8) DIDR0 |= 1 << pin; else DIDR2 |= 1 << (pin - 8); }while(0)
#else
#define ANALOG_SELECT(pin) do{ DIDR0 |= 1 << pin; }while(0)
#endif
// Set analog inputs // Set analog inputs
ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07; ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
DIDR0 = 0; DIDR0 = 0;
#ifdef DIDR2 #ifdef DIDR2
DIDR2 = 0; DIDR2 = 0;
#endif #endif
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1) #if HAS_TEMP_0
#if TEMP_0_PIN < 8 ANALOG_SELECT(TEMP_0_PIN);
DIDR0 |= 1 << TEMP_0_PIN;
#else
DIDR2 |= 1<<(TEMP_0_PIN - 8);
#endif
#endif #endif
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1) #if HAS_TEMP_1
#if TEMP_1_PIN < 8 ANALOG_SELECT(TEMP_1_PIN);
DIDR0 |= 1<<TEMP_1_PIN;
#else
DIDR2 |= 1<<(TEMP_1_PIN - 8);
#endif
#endif #endif
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1) #if HAS_TEMP_2
#if TEMP_2_PIN < 8 ANALOG_SELECT(TEMP_2_PIN);
DIDR0 |= 1 << TEMP_2_PIN;
#else
DIDR2 |= 1<<(TEMP_2_PIN - 8);
#endif
#endif #endif
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1) #if HAS_TEMP_3
#if TEMP_3_PIN < 8 ANALOG_SELECT(TEMP_3_PIN);
DIDR0 |= 1 << TEMP_3_PIN;
#else
DIDR2 |= 1<<(TEMP_3_PIN - 8);
#endif
#endif #endif
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1) #if HAS_TEMP_BED
#if TEMP_BED_PIN < 8 ANALOG_SELECT(TEMP_BED_PIN);
DIDR0 |= 1<<TEMP_BED_PIN;
#else
DIDR2 |= 1<<(TEMP_BED_PIN - 8);
#endif
#endif #endif
#if HAS_FILAMENT_SENSOR
//Added for Filament Sensor ANALOG_SELECT(FILWIDTH_PIN);
#ifdef FILAMENT_SENSOR
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1)
#if FILWIDTH_PIN < 8
DIDR0 |= 1<<FILWIDTH_PIN;
#else
DIDR2 |= 1<<(FILWIDTH_PIN - 8);
#endif
#endif
#endif #endif
// Use timer0 for temperature measurement // Use timer0 for temperature measurement
@ -982,128 +958,89 @@ void tp_init()
// Wait for temperature measurement to settle // Wait for temperature measurement to settle
delay(250); delay(250);
#ifdef HEATER_0_MINTEMP #define TEMP_MIN_ROUTINE(NR) \
minttemp[0] = HEATER_0_MINTEMP; minttemp[NR] = HEATER_ ## NR ## _MINTEMP; \
while(analog2temp(minttemp_raw[0], 0) < HEATER_0_MINTEMP) { while(analog2temp(minttemp_raw[NR], NR) < HEATER_ ## NR ## _MINTEMP) { \
#if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP if (HEATER_ ## NR ## _RAW_LO_TEMP < HEATER_ ## NR ## _RAW_HI_TEMP) \
minttemp_raw[0] += OVERSAMPLENR; minttemp_raw[NR] += OVERSAMPLENR; \
#else else \
minttemp_raw[0] -= OVERSAMPLENR; minttemp_raw[NR] -= OVERSAMPLENR; \
#endif }
} #define TEMP_MAX_ROUTINE(NR) \
#endif //MINTEMP maxttemp[NR] = HEATER_ ## NR ## _MAXTEMP; \
#ifdef HEATER_0_MAXTEMP while(analog2temp(maxttemp_raw[NR], NR) > HEATER_ ## NR ## _MAXTEMP) { \
maxttemp[0] = HEATER_0_MAXTEMP; if (HEATER_ ## NR ## _RAW_LO_TEMP < HEATER_ ## NR ## _RAW_HI_TEMP) \
while(analog2temp(maxttemp_raw[0], 0) > HEATER_0_MAXTEMP) { maxttemp_raw[NR] -= OVERSAMPLENR; \
#if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP else \
maxttemp_raw[0] -= OVERSAMPLENR; maxttemp_raw[NR] += OVERSAMPLENR; \
#else }
maxttemp_raw[0] += OVERSAMPLENR;
#endif
}
#endif //MAXTEMP
#if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP) #ifdef HEATER_0_MINTEMP
minttemp[1] = HEATER_1_MINTEMP; TEMP_MIN_ROUTINE(0);
while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) { #endif
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP #ifdef HEATER_0_MAXTEMP
minttemp_raw[1] += OVERSAMPLENR; TEMP_MAX_ROUTINE(0);
#else #endif
minttemp_raw[1] -= OVERSAMPLENR; #if EXTRUDERS > 1
#endif #ifdef HEATER_1_MINTEMP
} TEMP_MIN_ROUTINE(1);
#endif // MINTEMP 1 #endif
#if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP) #ifdef HEATER_1_MAXTEMP
maxttemp[1] = HEATER_1_MAXTEMP; TEMP_MAX_ROUTINE(1);
while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) { #endif
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP #if EXTRUDERS > 2
maxttemp_raw[1] -= OVERSAMPLENR; #ifdef HEATER_2_MINTEMP
#else TEMP_MIN_ROUTINE(2);
maxttemp_raw[1] += OVERSAMPLENR; #endif
#endif #ifdef HEATER_2_MAXTEMP
} TEMP_MAX_ROUTINE(2);
#endif //MAXTEMP 1 #endif
#if EXTRUDERS > 3
#ifdef HEATER_3_MINTEMP
TEMP_MIN_ROUTINE(3);
#endif
#ifdef HEATER_3_MAXTEMP
TEMP_MAX_ROUTINE(3);
#endif
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
#if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP) #ifdef BED_MINTEMP
minttemp[2] = HEATER_2_MINTEMP; /* No bed MINTEMP error implemented?!? */ /*
while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) { while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
minttemp_raw[2] += OVERSAMPLENR; bed_minttemp_raw += OVERSAMPLENR;
#else #else
minttemp_raw[2] -= OVERSAMPLENR; bed_minttemp_raw -= OVERSAMPLENR;
#endif #endif
} }
#endif //MINTEMP 2 */
#if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP) #endif //BED_MINTEMP
maxttemp[2] = HEATER_2_MAXTEMP; #ifdef BED_MAXTEMP
while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) { while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
maxttemp_raw[2] -= OVERSAMPLENR; bed_maxttemp_raw -= OVERSAMPLENR;
#else #else
maxttemp_raw[2] += OVERSAMPLENR; bed_maxttemp_raw += OVERSAMPLENR;
#endif #endif
} }
#endif //MAXTEMP 2 #endif //BED_MAXTEMP
#if (EXTRUDERS > 3) && defined(HEATER_3_MINTEMP)
minttemp[3] = HEATER_3_MINTEMP;
while(analog2temp(minttemp_raw[3], 3) < HEATER_3_MINTEMP) {
#if HEATER_3_RAW_LO_TEMP < HEATER_3_RAW_HI_TEMP
minttemp_raw[3] += OVERSAMPLENR;
#else
minttemp_raw[3] -= OVERSAMPLENR;
#endif
}
#endif //MINTEMP 3
#if (EXTRUDERS > 3) && defined(HEATER_3_MAXTEMP)
maxttemp[3] = HEATER_3_MAXTEMP;
while(analog2temp(maxttemp_raw[3], 3) > HEATER_3_MAXTEMP) {
#if HEATER_3_RAW_LO_TEMP < HEATER_3_RAW_HI_TEMP
maxttemp_raw[3] -= OVERSAMPLENR;
#else
maxttemp_raw[3] += OVERSAMPLENR;
#endif
}
#endif // MAXTEMP 3
#ifdef BED_MINTEMP
/* No bed MINTEMP error implemented?!? */ /*
while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
#if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
bed_minttemp_raw += OVERSAMPLENR;
#else
bed_minttemp_raw -= OVERSAMPLENR;
#endif
}
*/
#endif //BED_MINTEMP
#ifdef BED_MAXTEMP
while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
#if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
bed_maxttemp_raw -= OVERSAMPLENR;
#else
bed_maxttemp_raw += OVERSAMPLENR;
#endif
}
#endif //BED_MAXTEMP
} }
void setWatch() void setWatch() {
{ #ifdef WATCH_TEMP_PERIOD
#ifdef WATCH_TEMP_PERIOD unsigned long ms = millis();
for (int e = 0; e < EXTRUDERS; e++) for (int e = 0; e < EXTRUDERS; e++) {
{ if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) {
if(degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) watch_start_temp[e] = degHotend(e);
{ watchmillis[e] = ms;
watch_start_temp[e] = degHotend(e); }
watchmillis[e] = millis(); }
} #endif
}
#endif
} }
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 #if defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc)
{ {
/* /*
@ -1135,16 +1072,18 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
if (temperature >= target_temperature) *state = 2; if (temperature >= target_temperature) *state = 2;
break; break;
case 2: // "Temperature Stable" state case 2: // "Temperature Stable" state
{
unsigned long ms = millis();
if (temperature >= (target_temperature - hysteresis_degc)) if (temperature >= (target_temperature - hysteresis_degc))
{ {
*timer = millis(); *timer = ms;
} }
else if ( (millis() - *timer) > ((unsigned long) period_seconds) * 1000) else if ( (ms - *timer) > ((unsigned long) period_seconds) * 1000)
{ {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Thermal Runaway, system stopped! Heater_ID: "); SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
SERIAL_ERRORLN((int)heater_id); SERIAL_ERRORLN((int)heater_id);
LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY"); LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY); // translatable
thermal_runaway = true; thermal_runaway = true;
while(1) while(1)
{ {
@ -1160,56 +1099,47 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
lcd_update(); lcd_update();
} }
} }
break; } break;
} }
} }
#endif #endif //THERMAL_RUNAWAY_PROTECTION_PERIOD
void disable_heater()
{ void disable_heater() {
for(int i=0;i<EXTRUDERS;i++) for (int i=0; i<EXTRUDERS; i++) setTargetHotend(0, i);
setTargetHotend(0,i);
setTargetBed(0); setTargetBed(0);
#if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
target_temperature[0]=0; #if HAS_TEMP_0
soft_pwm[0]=0; target_temperature[0] = 0;
#if defined(HEATER_0_PIN) && HEATER_0_PIN > -1 soft_pwm[0] = 0;
WRITE(HEATER_0_PIN,LOW); WRITE_HEATER_0P(LOW); // If HEATERS_PARALLEL should apply, change to WRITE_HEATER_0
#endif
#endif
#if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 && EXTRUDERS > 1
target_temperature[1]=0;
soft_pwm[1]=0;
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
WRITE(HEATER_1_PIN,LOW);
#endif
#endif
#if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 && EXTRUDERS > 2
target_temperature[2]=0;
soft_pwm[2]=0;
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
WRITE(HEATER_2_PIN,LOW);
#endif
#endif #endif
#if defined(TEMP_3_PIN) && TEMP_3_PIN > -1 && EXTRUDERS > 3 #if EXTRUDERS > 1 && HAS_TEMP_1
target_temperature[3]=0; target_temperature[1] = 0;
soft_pwm[3]=0; soft_pwm[1] = 0;
#if defined(HEATER_3_PIN) && HEATER_3_PIN > -1 WRITE_HEATER_1(LOW);
WRITE(HEATER_3_PIN,LOW); #endif
#endif
#endif
#if EXTRUDERS > 2 && HAS_TEMP_2
target_temperature[2] = 0;
soft_pwm[2] = 0;
WRITE_HEATER_2(LOW);
#endif
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1 #if EXTRUDERS > 3 && HAS_TEMP_3
target_temperature_bed=0; target_temperature[3] = 0;
soft_pwm_bed=0; soft_pwm[3] = 0;
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 WRITE_HEATER_3(LOW);
WRITE(HEATER_BED_PIN,LOW); #endif
#if HAS_TEMP_BED
target_temperature_bed = 0;
soft_pwm_bed = 0;
#if HAS_HEATER_BED
WRITE_HEATER_BED(LOW);
#endif #endif
#endif #endif
} }
void max_temp_error(uint8_t e) { void max_temp_error(uint8_t e) {
@ -1217,8 +1147,8 @@ void max_temp_error(uint8_t e) {
if(IsStopped() == false) { if(IsStopped() == false) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORLN((int)e); SERIAL_ERRORLN((int)e);
SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !"); SERIAL_ERRORLNPGM(MSG_MAXTEMP_EXTRUDER_OFF);
LCD_ALERTMESSAGEPGM("Err: MAXTEMP"); LCD_ALERTMESSAGEPGM(MSG_ERR_MAXTEMP); // translatable
} }
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop(); Stop();
@ -1230,8 +1160,8 @@ void min_temp_error(uint8_t e) {
if(IsStopped() == false) { if(IsStopped() == false) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORLN((int)e); SERIAL_ERRORLN((int)e);
SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !"); SERIAL_ERRORLNPGM(MSG_MINTEMP_EXTRUDER_OFF);
LCD_ALERTMESSAGEPGM("Err: MINTEMP"); LCD_ALERTMESSAGEPGM(MSG_ERR_MINTEMP); // translatable
} }
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop(); Stop();
@ -1239,13 +1169,13 @@ void min_temp_error(uint8_t e) {
} }
void bed_max_temp_error(void) { void bed_max_temp_error(void) {
#if HEATER_BED_PIN > -1 #if HAS_HEATER_BED
WRITE(HEATER_BED_PIN, 0); WRITE_HEATER_BED(0);
#endif #endif
if(IsStopped() == false) { if (IsStopped() == false) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!"); SERIAL_ERRORLNPGM(MSG_MAXTEMP_BED_OFF);
LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED"); LCD_ALERTMESSAGEPGM(MSG_ERR_MAXTEMP_BED); // translatable
} }
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop(); Stop();
@ -1253,66 +1183,84 @@ void bed_max_temp_error(void) {
} }
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
#define MAX6675_HEAT_INTERVAL 250 #define MAX6675_HEAT_INTERVAL 250
long max6675_previous_millis = MAX6675_HEAT_INTERVAL; long max6675_previous_millis = MAX6675_HEAT_INTERVAL;
int max6675_temp = 2000; int max6675_temp = 2000;
static int read_max6675() static int read_max6675() {
{
if (millis() - max6675_previous_millis < MAX6675_HEAT_INTERVAL) unsigned long ms = millis();
return max6675_temp; if (ms < max6675_previous_millis + MAX6675_HEAT_INTERVAL)
return max6675_temp;
max6675_previous_millis = millis();
max6675_temp = 0;
#ifdef PRR max6675_previous_millis = ms;
PRR &= ~(1<<PRSPI); max6675_temp = 0;
#elif defined(PRR0)
PRR0 &= ~(1<<PRSPI);
#endif
SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
// enable TT_MAX6675
WRITE(MAX6675_SS, 0);
// ensure 100ns delay - a bit extra is fine
asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
// read MSB
SPDR = 0;
for (;(SPSR & (1<<SPIF)) == 0;);
max6675_temp = SPDR;
max6675_temp <<= 8;
// read LSB
SPDR = 0;
for (;(SPSR & (1<<SPIF)) == 0;);
max6675_temp |= SPDR;
// disable TT_MAX6675
WRITE(MAX6675_SS, 1);
if (max6675_temp & 4) #ifdef PRR
{ PRR &= ~(1<<PRSPI);
// thermocouple open #elif defined(PRR0)
max6675_temp = 4000; PRR0 &= ~(1<<PRSPI);
} #endif
else
{
max6675_temp = max6675_temp >> 3;
}
return max6675_temp; SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
}
// enable TT_MAX6675
WRITE(MAX6675_SS, 0);
// ensure 100ns delay - a bit extra is fine
asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
// read MSB
SPDR = 0;
for (;(SPSR & (1<<SPIF)) == 0;);
max6675_temp = SPDR;
max6675_temp <<= 8;
// read LSB
SPDR = 0;
for (;(SPSR & (1<<SPIF)) == 0;);
max6675_temp |= SPDR;
// disable TT_MAX6675
WRITE(MAX6675_SS, 1);
if (max6675_temp & 4) {
// thermocouple open
max6675_temp = 4000;
}
else {
max6675_temp = max6675_temp >> 3;
}
return max6675_temp;
}
#endif //HEATER_0_USES_MAX6675 #endif //HEATER_0_USES_MAX6675
/**
* Stages in the ISR loop
*/
enum TempState {
PrepareTemp_0,
MeasureTemp_0,
PrepareTemp_BED,
MeasureTemp_BED,
PrepareTemp_1,
MeasureTemp_1,
PrepareTemp_2,
MeasureTemp_2,
PrepareTemp_3,
MeasureTemp_3,
Prepare_FILWIDTH,
Measure_FILWIDTH,
StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle
};
//
// Timer 0 is shared with millies // Timer 0 is shared with millies
ISR(TIMER0_COMPB_vect) //
{ ISR(TIMER0_COMPB_vect) {
//these variables are only accesible from the ISR, but static, so they don't lose their value //these variables are only accesible from the ISR, but static, so they don't lose their value
static unsigned char temp_count = 0; static unsigned char temp_count = 0;
static unsigned long raw_temp_0_value = 0; static unsigned long raw_temp_0_value = 0;
@ -1320,542 +1268,324 @@ ISR(TIMER0_COMPB_vect)
static unsigned long raw_temp_2_value = 0; static unsigned long raw_temp_2_value = 0;
static unsigned long raw_temp_3_value = 0; static unsigned long raw_temp_3_value = 0;
static unsigned long raw_temp_bed_value = 0; static unsigned long raw_temp_bed_value = 0;
static unsigned char temp_state = 12; static TempState temp_state = StartupDelay;
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE); static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
static unsigned char soft_pwm_0;
#ifdef SLOW_PWM_HEATERS
static unsigned char slow_pwm_count = 0;
static unsigned char state_heater_0 = 0;
static unsigned char state_timer_heater_0 = 0;
#endif
#if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL) // Static members for each heater
static unsigned char soft_pwm_1; #ifdef SLOW_PWM_HEATERS
#ifdef SLOW_PWM_HEATERS static unsigned char slow_pwm_count = 0;
static unsigned char state_heater_1 = 0; #define ISR_STATICS(n) \
static unsigned char state_timer_heater_1 = 0; static unsigned char soft_pwm_ ## n; \
#endif static unsigned char state_heater_ ## n = 0; \
#endif static unsigned char state_timer_heater_ ## n = 0
#if EXTRUDERS > 2 #else
static unsigned char soft_pwm_2; #define ISR_STATICS(n) static unsigned char soft_pwm_ ## n
#ifdef SLOW_PWM_HEATERS #endif
static unsigned char state_heater_2 = 0;
static unsigned char state_timer_heater_2 = 0;
#endif
#endif
#if EXTRUDERS > 3
static unsigned char soft_pwm_3;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_3 = 0;
static unsigned char state_timer_heater_3 = 0;
#endif
#endif
#if HEATER_BED_PIN > -1 // Statics per heater
static unsigned char soft_pwm_b; ISR_STATICS(0);
#ifdef SLOW_PWM_HEATERS #if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
static unsigned char state_heater_b = 0; ISR_STATICS(1);
static unsigned char state_timer_heater_b = 0; #if EXTRUDERS > 2
#endif ISR_STATICS(2);
#endif #if EXTRUDERS > 3
ISR_STATICS(3);
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1) #endif
static unsigned long raw_filwidth_value = 0; //added for filament width sensor #endif
#endif #endif
#if HAS_HEATER_BED
#ifndef SLOW_PWM_HEATERS ISR_STATICS(BED);
/* #endif
* standard PWM modulation
*/
if(pwm_count == 0){
soft_pwm_0 = soft_pwm[0];
if(soft_pwm_0 > 0) {
WRITE(HEATER_0_PIN,1);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN,1);
#endif
} else WRITE(HEATER_0_PIN,0);
#if EXTRUDERS > 1 #if HAS_FILAMENT_SENSOR
soft_pwm_1 = soft_pwm[1]; static unsigned long raw_filwidth_value = 0;
if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0); #endif
#endif
#if EXTRUDERS > 2 #ifndef SLOW_PWM_HEATERS
soft_pwm_2 = soft_pwm[2]; /**
if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0); * standard PWM modulation
#endif */
#if EXTRUDERS > 3 if (pwm_count == 0) {
soft_pwm_3 = soft_pwm[3]; soft_pwm_0 = soft_pwm[0];
if(soft_pwm_3 > 0) WRITE(HEATER_3_PIN,1); else WRITE(HEATER_3_PIN,0); if (soft_pwm_0 > 0) {
#endif WRITE_HEATER_0(1);
}
else WRITE_HEATER_0P(0); // If HEATERS_PARALLEL should apply, change to WRITE_HEATER_0
#if EXTRUDERS > 1
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1 soft_pwm_1 = soft_pwm[1];
soft_pwm_b = soft_pwm_bed; WRITE_HEATER_1(soft_pwm_1 > 0 ? 1 : 0);
if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0); #if EXTRUDERS > 2
#endif soft_pwm_2 = soft_pwm[2];
#ifdef FAN_SOFT_PWM WRITE_HEATER_2(soft_pwm_2 > 0 ? 1 : 0);
soft_pwm_fan = fanSpeedSoftPwm / 2; #if EXTRUDERS > 3
if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0); soft_pwm_3 = soft_pwm[3];
#endif WRITE_HEATER_3(soft_pwm_3 > 0 ? 1 : 0);
} #endif
if(soft_pwm_0 < pwm_count) {
WRITE(HEATER_0_PIN,0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN,0);
#endif
}
#if EXTRUDERS > 1
if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0);
#endif
#if EXTRUDERS > 2
if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
#endif
#if EXTRUDERS > 3
if(soft_pwm_3 < pwm_count) WRITE(HEATER_3_PIN,0);
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
#endif
#ifdef FAN_SOFT_PWM
if(soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
#endif
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
#else //ifndef SLOW_PWM_HEATERS
/*
* SLOW PWM HEATERS
*
* for heaters drived by relay
*/
#ifndef MIN_STATE_TIME
#define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds
#endif
if (slow_pwm_count == 0) {
// EXTRUDER 0
soft_pwm_0 = soft_pwm[0];
if (soft_pwm_0 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_0 == 0) {
// if change state set timer
if (state_heater_0 == 0) {
state_timer_heater_0 = MIN_STATE_TIME;
}
state_heater_0 = 1;
WRITE(HEATER_0_PIN, 1);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN, 1);
#endif
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_0 == 0) {
// if change state set timer
if (state_heater_0 == 1) {
state_timer_heater_0 = MIN_STATE_TIME;
}
state_heater_0 = 0;
WRITE(HEATER_0_PIN, 0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN, 0);
#endif
}
}
#if EXTRUDERS > 1
// EXTRUDER 1
soft_pwm_1 = soft_pwm[1];
if (soft_pwm_1 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 0) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 1;
WRITE(HEATER_1_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 1) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 0;
WRITE(HEATER_1_PIN, 0);
}
}
#endif
#if EXTRUDERS > 2
// EXTRUDER 2
soft_pwm_2 = soft_pwm[2];
if (soft_pwm_2 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 0) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 1;
WRITE(HEATER_2_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 1) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 0;
WRITE(HEATER_2_PIN, 0);
}
}
#endif
#if EXTRUDERS > 3
// EXTRUDER 3
soft_pwm_3 = soft_pwm[3];
if (soft_pwm_3 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_3 == 0) {
// if change state set timer
if (state_heater_3 == 0) {
state_timer_heater_3 = MIN_STATE_TIME;
}
state_heater_3 = 1;
WRITE(HEATER_3_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_3 == 0) {
// if change state set timer
if (state_heater_3 == 1) {
state_timer_heater_3 = MIN_STATE_TIME;
}
state_heater_3 = 0;
WRITE(HEATER_3_PIN, 0);
}
}
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// BED
soft_pwm_b = soft_pwm_bed;
if (soft_pwm_b > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_b == 0) {
// if change state set timer
if (state_heater_b == 0) {
state_timer_heater_b = MIN_STATE_TIME;
}
state_heater_b = 1;
WRITE(HEATER_BED_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_b == 0) {
// if change state set timer
if (state_heater_b == 1) {
state_timer_heater_b = MIN_STATE_TIME;
}
state_heater_b = 0;
WRITE(HEATER_BED_PIN, 0);
}
}
#endif
} // if (slow_pwm_count == 0)
// EXTRUDER 0
if (soft_pwm_0 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_0 == 0) {
// if change state set timer
if (state_heater_0 == 1) {
state_timer_heater_0 = MIN_STATE_TIME;
}
state_heater_0 = 0;
WRITE(HEATER_0_PIN, 0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN, 0);
#endif
}
}
#if EXTRUDERS > 1
// EXTRUDER 1
if (soft_pwm_1 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 1) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 0;
WRITE(HEATER_1_PIN, 0);
}
}
#endif
#if EXTRUDERS > 2
// EXTRUDER 2
if (soft_pwm_2 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 1) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 0;
WRITE(HEATER_2_PIN, 0);
}
}
#endif
#if EXTRUDERS > 3
// EXTRUDER 3
if (soft_pwm_3 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_3 == 0) {
// if change state set timer
if (state_heater_3 == 1) {
state_timer_heater_3 = MIN_STATE_TIME;
}
state_heater_3 = 0;
WRITE(HEATER_3_PIN, 0);
}
}
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// BED
if (soft_pwm_b < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_b == 0) {
// if change state set timer
if (state_heater_b == 1) {
state_timer_heater_b = MIN_STATE_TIME;
}
state_heater_b = 0;
WRITE(HEATER_BED_PIN, 0);
}
}
#endif
#ifdef FAN_SOFT_PWM
if (pwm_count == 0){
soft_pwm_fan = fanSpeedSoftPwm / 2;
if (soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
}
if (soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
#endif
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
// increment slow_pwm_count only every 64 pwm_count circa 65.5ms
if ((pwm_count % 64) == 0) {
slow_pwm_count++;
slow_pwm_count &= 0x7f;
// Extruder 0
if (state_timer_heater_0 > 0) {
state_timer_heater_0--;
}
#if EXTRUDERS > 1
// Extruder 1
if (state_timer_heater_1 > 0)
state_timer_heater_1--;
#endif
#if EXTRUDERS > 2
// Extruder 2
if (state_timer_heater_2 > 0)
state_timer_heater_2--;
#endif
#if EXTRUDERS > 3
// Extruder 3
if (state_timer_heater_3 > 0)
state_timer_heater_3--;
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// Bed
if (state_timer_heater_b > 0)
state_timer_heater_b--;
#endif
} //if ((pwm_count % 64) == 0) {
#endif //ifndef SLOW_PWM_HEATERS
switch(temp_state) {
case 0: // Prepare TEMP_0
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
#if TEMP_0_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif #endif
ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07)); #endif
ADCSRA |= 1<<ADSC; // Start conversion
#if HAS_HEATER_BED
soft_pwm_BED = soft_pwm_bed;
WRITE_HEATER_BED(soft_pwm_BED > 0 ? 1 : 0);
#endif
#ifdef FAN_SOFT_PWM
soft_pwm_fan = fanSpeedSoftPwm / 2;
WRITE_FAN(soft_pwm_fan > 0 ? 1 : 0);
#endif
}
if (soft_pwm_0 < pwm_count) { WRITE_HEATER_0(0); }
#if EXTRUDERS > 1
if (soft_pwm_1 < pwm_count) WRITE_HEATER_1(0);
#if EXTRUDERS > 2
if (soft_pwm_2 < pwm_count) WRITE_HEATER_2(0);
#if EXTRUDERS > 3
if (soft_pwm_3 < pwm_count) WRITE_HEATER_3(0);
#endif
#endif
#endif
#if HAS_HEATER_BED
if (soft_pwm_BED < pwm_count) WRITE_HEATER_BED(0);
#endif
#ifdef FAN_SOFT_PWM
if (soft_pwm_fan < pwm_count) WRITE_FAN(0);
#endif
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
#else // SLOW_PWM_HEATERS
/*
* SLOW PWM HEATERS
*
* for heaters drived by relay
*/
#ifndef MIN_STATE_TIME
#define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds
#endif
// Macros for Slow PWM timer logic - HEATERS_PARALLEL applies
#define _SLOW_PWM_ROUTINE(NR, src) \
soft_pwm_ ## NR = src; \
if (soft_pwm_ ## NR > 0) { \
if (state_timer_heater_ ## NR == 0) { \
if (state_heater_ ## NR == 0) state_timer_heater_ ## NR = MIN_STATE_TIME; \
state_heater_ ## NR = 1; \
WRITE_HEATER_ ## NR(1); \
} \
} \
else { \
if (state_timer_heater_ ## NR == 0) { \
if (state_heater_ ## NR == 1) state_timer_heater_ ## NR = MIN_STATE_TIME; \
state_heater_ ## NR = 0; \
WRITE_HEATER_ ## NR(0); \
} \
}
#define SLOW_PWM_ROUTINE(n) _SLOW_PWM_ROUTINE(n, soft_pwm[n])
#define PWM_OFF_ROUTINE(NR) \
if (soft_pwm_ ## NR < slow_pwm_count) { \
if (state_timer_heater_ ## NR == 0) { \
if (state_heater_ ## NR == 1) state_timer_heater_ ## NR = MIN_STATE_TIME; \
state_heater_ ## NR = 0; \
WRITE_HEATER_ ## NR (0); \
} \
}
if (slow_pwm_count == 0) {
SLOW_PWM_ROUTINE(0); // EXTRUDER 0
#if EXTRUDERS > 1
SLOW_PWM_ROUTINE(1); // EXTRUDER 1
#if EXTRUDERS > 2
SLOW_PWM_ROUTINE(2); // EXTRUDER 2
#if EXTRUDERS > 3
SLOW_PWM_ROUTINE(3); // EXTRUDER 3
#endif
#endif
#endif
#if HAS_HEATER_BED
_SLOW_PWM_ROUTINE(BED, soft_pwm_bed); // BED
#endif
} // slow_pwm_count == 0
PWM_OFF_ROUTINE(0); // EXTRUDER 0
#if EXTRUDERS > 1
PWM_OFF_ROUTINE(1); // EXTRUDER 1
#if EXTRUDERS > 2
PWM_OFF_ROUTINE(2); // EXTRUDER 2
#if EXTRUDERS > 3
PWM_OFF_ROUTINE(3); // EXTRUDER 3
#endif
#endif
#endif
#if HAS_HEATER_BED
PWM_OFF_ROUTINE(BED); // BED
#endif
#ifdef FAN_SOFT_PWM
if (pwm_count == 0) {
soft_pwm_fan = fanSpeedSoftPwm / 2;
WRITE_FAN(soft_pwm_fan > 0 ? 1 : 0);
}
if (soft_pwm_fan < pwm_count) WRITE_FAN(0);
#endif //FAN_SOFT_PWM
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
// increment slow_pwm_count only every 64 pwm_count circa 65.5ms
if ((pwm_count % 64) == 0) {
slow_pwm_count++;
slow_pwm_count &= 0x7f;
// EXTRUDER 0
if (state_timer_heater_0 > 0) state_timer_heater_0--;
#if EXTRUDERS > 1 // EXTRUDER 1
if (state_timer_heater_1 > 0) state_timer_heater_1--;
#if EXTRUDERS > 2 // EXTRUDER 2
if (state_timer_heater_2 > 0) state_timer_heater_2--;
#if EXTRUDERS > 3 // EXTRUDER 3
if (state_timer_heater_3 > 0) state_timer_heater_3--;
#endif
#endif
#endif
#if HAS_HEATER_BED
if (state_timer_heater_BED > 0) state_timer_heater_BED--;
#endif
} // (pwm_count % 64) == 0
#endif // SLOW_PWM_HEATERS
#define SET_ADMUX_ADCSRA(pin) ADMUX = (1 << REFS0) | (pin & 0x07); ADCSRA |= 1<<ADSC
#ifdef MUX5
#define START_ADC(pin) if (pin > 7) ADCSRB = 1 << MUX5; else ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#else
#define START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
switch(temp_state) {
case PrepareTemp_0:
#if HAS_TEMP_0
START_ADC(TEMP_0_PIN);
#endif #endif
lcd_buttons_update(); lcd_buttons_update();
temp_state = 1; temp_state = MeasureTemp_0;
break; break;
case 1: // Measure TEMP_0 case MeasureTemp_0:
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1) #if HAS_TEMP_0
raw_temp_0_value += ADC; raw_temp_0_value += ADC;
#endif #endif
temp_state = 2; temp_state = PrepareTemp_BED;
break; break;
case 2: // Prepare TEMP_BED case PrepareTemp_BED:
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1) #if HAS_TEMP_BED
#if TEMP_BED_PIN > 7 START_ADC(TEMP_BED_PIN);
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif #endif
lcd_buttons_update(); lcd_buttons_update();
temp_state = 3; temp_state = MeasureTemp_BED;
break; break;
case 3: // Measure TEMP_BED case MeasureTemp_BED:
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1) #if HAS_TEMP_BED
raw_temp_bed_value += ADC; raw_temp_bed_value += ADC;
#endif #endif
temp_state = 4; temp_state = PrepareTemp_1;
break; break;
case 4: // Prepare TEMP_1 case PrepareTemp_1:
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1) #if HAS_TEMP_1
#if TEMP_1_PIN > 7 START_ADC(TEMP_1_PIN);
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif #endif
lcd_buttons_update(); lcd_buttons_update();
temp_state = 5; temp_state = MeasureTemp_1;
break; break;
case 5: // Measure TEMP_1 case MeasureTemp_1:
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1) #if HAS_TEMP_1
raw_temp_1_value += ADC; raw_temp_1_value += ADC;
#endif #endif
temp_state = 6; temp_state = PrepareTemp_2;
break; break;
case 6: // Prepare TEMP_2 case PrepareTemp_2:
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1) #if HAS_TEMP_2
#if TEMP_2_PIN > 7 START_ADC(TEMP_2_PIN);
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif #endif
lcd_buttons_update(); lcd_buttons_update();
temp_state = 7; temp_state = MeasureTemp_2;
break; break;
case 7: // Measure TEMP_2 case MeasureTemp_2:
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1) #if HAS_TEMP_2
raw_temp_2_value += ADC; raw_temp_2_value += ADC;
#endif #endif
temp_state = 8; temp_state = PrepareTemp_3;
break; break;
case 8: // Prepare TEMP_3 case PrepareTemp_3:
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1) #if HAS_TEMP_3
#if TEMP_3_PIN > 7 START_ADC(TEMP_3_PIN);
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_3_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif #endif
lcd_buttons_update(); lcd_buttons_update();
temp_state = 9; temp_state = MeasureTemp_3;
break; break;
case 9: // Measure TEMP_3 case MeasureTemp_3:
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1) #if HAS_TEMP_3
raw_temp_3_value += ADC; raw_temp_3_value += ADC;
#endif #endif
temp_state = 10; //change so that Filament Width is also measured temp_state = Prepare_FILWIDTH;
break; break;
case 10: //Prepare FILWIDTH case Prepare_FILWIDTH:
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1) #if HAS_FILAMENT_SENSOR
#if FILWIDTH_PIN>7 START_ADC(FILWIDTH_PIN);
ADCSRB = 1<<MUX5; #endif
#else lcd_buttons_update();
ADCSRB = 0; temp_state = Measure_FILWIDTH;
#endif break;
ADMUX = ((1 << REFS0) | (FILWIDTH_PIN & 0x07)); case Measure_FILWIDTH:
ADCSRA |= 1<<ADSC; // Start conversion #if HAS_FILAMENT_SENSOR
#endif // raw_filwidth_value += ADC; //remove to use an IIR filter approach
lcd_buttons_update(); if (ADC > 102) { //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
temp_state = 11; raw_filwidth_value -= (raw_filwidth_value>>7); //multiply raw_filwidth_value by 127/128
break; raw_filwidth_value += ((unsigned long)ADC<<7); //add new ADC reading
case 11: //Measure FILWIDTH
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
//raw_filwidth_value += ADC; //remove to use an IIR filter approach
if(ADC>102) //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
{
raw_filwidth_value= raw_filwidth_value-(raw_filwidth_value>>7); //multipliy raw_filwidth_value by 127/128
raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading
} }
#endif #endif
temp_state = 0; temp_state = PrepareTemp_0;
temp_count++;
temp_count++; break;
break; case StartupDelay:
temp_state = PrepareTemp_0;
case 12: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
temp_state = 0;
break; break;
// default:
// SERIAL_ERROR_START;
// SERIAL_ERRORLNPGM("Temp measurement error!");
// break;
}
if(temp_count >= OVERSAMPLENR) // 10 * 16 * 1/(16000000/64/256) = 164ms.
{
if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
{
#ifndef HEATER_0_USES_MAX6675
current_temperature_raw[0] = raw_temp_0_value;
#endif
#if EXTRUDERS > 1
current_temperature_raw[1] = raw_temp_1_value;
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature_raw = raw_temp_1_value;
#endif
#if EXTRUDERS > 2
current_temperature_raw[2] = raw_temp_2_value;
#endif
#if EXTRUDERS > 3
current_temperature_raw[3] = raw_temp_3_value;
#endif
current_temperature_bed_raw = raw_temp_bed_value;
}
//Add similar code for Filament Sensor - can be read any time since IIR filtering is used // default:
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1) // SERIAL_ERROR_START;
current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach // SERIAL_ERRORLNPGM("Temp measurement error!");
#endif // break;
} // switch(temp_state)
if (temp_count >= OVERSAMPLENR) { // 10 * 16 * 1/(16000000/64/256) = 164ms.
if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading.
#ifndef HEATER_0_USES_MAX6675
current_temperature_raw[0] = raw_temp_0_value;
#endif
#if EXTRUDERS > 1
current_temperature_raw[1] = raw_temp_1_value;
#if EXTRUDERS > 2
current_temperature_raw[2] = raw_temp_2_value;
#if EXTRUDERS > 3
current_temperature_raw[3] = raw_temp_3_value;
#endif
#endif
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature_raw = raw_temp_1_value;
#endif
current_temperature_bed_raw = raw_temp_bed_value;
} //!temp_meas_ready
// Filament Sensor - can be read any time since IIR filtering is used
#if HAS_FILAMENT_SENSOR
current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach
#endif
temp_meas_ready = true; temp_meas_ready = true;
temp_count = 0; temp_count = 0;
@ -1865,131 +1595,47 @@ ISR(TIMER0_COMPB_vect)
raw_temp_3_value = 0; raw_temp_3_value = 0;
raw_temp_bed_value = 0; raw_temp_bed_value = 0;
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
if(current_temperature_raw[0] <= maxttemp_raw[0]) { #define MAXTEST <=
#else #define MINTEST >=
if(current_temperature_raw[0] >= maxttemp_raw[0]) { #else
#endif #define MAXTEST >=
#ifndef HEATER_0_USES_MAX6675 #define MINTEST <=
max_temp_error(0); #endif
#endif
}
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
if(current_temperature_raw[0] >= minttemp_raw[0]) {
#else
if(current_temperature_raw[0] <= minttemp_raw[0]) {
#endif
#ifndef HEATER_0_USES_MAX6675
min_temp_error(0);
#endif
}
for (int i=0; i<EXTRUDERS; i++) {
if (current_temperature_raw[i] MAXTEST maxttemp_raw[i]) max_temp_error(i);
else if (current_temperature_raw[i] MINTEST minttemp_raw[i]) min_temp_error(i);
}
/* No bed MINTEMP error? */
#if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
if (current_temperature_bed_raw MAXTEST bed_maxttemp_raw) {
target_temperature_bed = 0;
bed_max_temp_error();
}
#endif
} // temp_count >= OVERSAMPLENR
#if EXTRUDERS > 1 #ifdef BABYSTEPPING
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP for (uint8_t axis=X_AXIS; axis<=Z_AXIS; axis++) {
if(current_temperature_raw[1] <= maxttemp_raw[1]) { int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
#else
if(current_temperature_raw[1] >= maxttemp_raw[1]) { if (curTodo > 0) {
#endif babystep(axis,/*fwd*/true);
max_temp_error(1); babystepsTodo[axis]--; //less to do next time
}
else if(curTodo < 0) {
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
}
} }
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP #endif //BABYSTEPPING
if(current_temperature_raw[1] >= minttemp_raw[1]) {
#else
if(current_temperature_raw[1] <= minttemp_raw[1]) {
#endif
min_temp_error(1);
}
#endif
#if EXTRUDERS > 2
#if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
if(current_temperature_raw[2] <= maxttemp_raw[2]) {
#else
if(current_temperature_raw[2] >= maxttemp_raw[2]) {
#endif
max_temp_error(2);
}
#if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
if(current_temperature_raw[2] >= minttemp_raw[2]) {
#else
if(current_temperature_raw[2] <= minttemp_raw[2]) {
#endif
min_temp_error(2);
}
#endif
#if EXTRUDERS > 3
#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
if(current_temperature_raw[3] <= maxttemp_raw[3]) {
#else
if(current_temperature_raw[3] >= maxttemp_raw[3]) {
#endif
max_temp_error(3);
}
#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
if(current_temperature_raw[3] >= minttemp_raw[3]) {
#else
if(current_temperature_raw[3] <= minttemp_raw[3]) {
#endif
min_temp_error(3);
}
#endif
/* No bed MINTEMP error? */
#if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
# if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
if(current_temperature_bed_raw <= bed_maxttemp_raw) {
#else
if(current_temperature_bed_raw >= bed_maxttemp_raw) {
#endif
target_temperature_bed = 0;
bed_max_temp_error();
}
#endif
}
#ifdef BABYSTEPPING
for(uint8_t axis=0;axis<3;axis++)
{
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
if(curTodo>0)
{
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time
}
else
if(curTodo<0)
{
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
}
}
#endif //BABYSTEPPING
} }
#ifdef PIDTEMP #ifdef PIDTEMP
// Apply the scale factors to the PID values // Apply the scale factors to the PID values
float scalePID_i(float i) { return i * PID_dT; }
float unscalePID_i(float i) { return i / PID_dT; }
float scalePID_i(float i) float scalePID_d(float d) { return d / PID_dT; }
{ float unscalePID_d(float d) { return d * PID_dT; }
return i*PID_dT;
}
float unscalePID_i(float i)
{
return i/PID_dT;
}
float scalePID_d(float d)
{
return d/PID_dT;
}
float unscalePID_d(float d)
{
return d*PID_dT;
}
#endif //PIDTEMP #endif //PIDTEMP