Merge pull request #1541 from thinkyhead/fixup_temperature

Cleanup of temperature code
This commit is contained in:
Scott Lahteine 2015-03-02 05:38:10 -08:00
commit 49f471a5fc
5 changed files with 1035 additions and 1363 deletions

View file

@ -159,6 +159,43 @@
#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!"
// temperature.cpp strings
#define MSG_PID_AUTOTUNE "PID Autotune"
#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE " start"
#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE " failed!"
#define MSG_PID_BAD_EXTRUDER_NUM MSG_PID_AUTOTUNE_FAILED " Bad extruder number"
#define MSG_PID_TEMP_TOO_HIGH MSG_PID_AUTOTUNE_FAILED " Temperature too high"
#define MSG_PID_TIMEOUT MSG_PID_AUTOTUNE_FAILED " timeout"
#define MSG_BIAS " bias: "
#define MSG_D " d: "
#define MSG_MIN " min: "
#define MSG_MAX " max: "
#define MSG_KU " Ku: "
#define MSG_TU " Tu: "
#define MSG_CLASSIC_PID " Classic PID "
#define MSG_KP " Kp: "
#define MSG_KI " Ki: "
#define MSG_KD " Kd: "
#define MSG_OK_B "ok B:"
#define MSG_OK_T "ok T:"
#define MSG_AT " @:"
#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from above into Configuration.h"
#define MSG_PID_DEBUG " PID_DEBUG "
#define MSG_PID_DEBUG_INPUT ": Input "
#define MSG_PID_DEBUG_OUTPUT " Output "
#define MSG_PID_DEBUG_PTERM " pTerm "
#define MSG_PID_DEBUG_ITERM " iTerm "
#define MSG_PID_DEBUG_DTERM " dTerm "
#define MSG_HEATING_FAILED "Heating failed"
#define MSG_EXTRUDER_SWITCHED_OFF "Extruder switched off. Temperature difference between temp sensors is too high !"
#define MSG_INVALID_EXTRUDER_NUM " - Invalid extruder number !"
#define MSG_THERMAL_RUNAWAY_STOP "Thermal Runaway, system stopped! Heater_ID: "
#define MSG_SWITCHED_OFF_MAX " switched off. MAXTEMP triggered !!"
#define MSG_MINTEMP_EXTRUDER_OFF ": Extruder switched off. MINTEMP triggered !"
#define MSG_MAXTEMP_EXTRUDER_OFF ": Extruder" MSG_SWITCHED_OFF_MAX
#define MSG_MAXTEMP_BED_OFF "Heated bed" MSG_SWITCHED_OFF_MAX
// LCD Menu Messages
// Add your own character. Reference: https://github.com/MarlinFirmware/Marlin/pull/1434 photos

View file

@ -383,6 +383,24 @@
#ifndef MSG_ENDSTOP_ABORT
#define MSG_ENDSTOP_ABORT "Endstop abort"
#endif
#ifndef MSG_HEATING_FAILED_LCD
#define MSG_HEATING_FAILED_LCD "Heating failed"
#endif
#ifndef MSG_ERR_REDUNDANT_TEMP
#define MSG_ERR_REDUNDANT_TEMP "Err: REDUNDANT TEMP ERROR"
#endif
#ifndef MSG_THERMAL_RUNAWAY
#define MSG_THERMAL_RUNAWAY "THERMAL RUNAWAY"
#endif
#ifndef MSG_ERR_MAXTEMP
#define MSG_ERR_MAXTEMP "Err: MAXTEMP"
#endif
#ifndef MSG_ERR_MINTEMP
#define MSG_ERR_MINTEMP "Err: MINTEMP"
#endif
#ifndef MSG_ERR_MAXTEMP_BED
#define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED"
#endif
#ifdef DELTA_CALIBRATION_MENU
#ifndef MSG_DELTA_CALIBRATE

View file

@ -6,6 +6,10 @@
#error Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu.
#endif
#if EXTRUDERS > 3
#error RUMBA supports up to 3 extruders. Comment this line to keep going.
#endif
#define X_STEP_PIN 17
#define X_DIR_PIN 16
#define X_ENABLE_PIN 48

View file

@ -33,9 +33,43 @@
#include "ultralcd.h"
#include "temperature.h"
#include "watchdog.h"
#include "language.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 ============================
@ -71,7 +105,7 @@ float current_temperature_bed = 0.0;
unsigned char soft_pwm_bed;
#ifdef BABYSTEPPING
volatile int babystepsTodo[3]={0,0,0};
volatile int babystepsTodo[3] = { 0 };
#endif
#ifdef FILAMENT_SENSOR
@ -116,24 +150,10 @@ static volatile bool temp_meas_ready = false;
#ifdef FAN_SOFT_PWM
static unsigned char soft_pwm_fan;
#endif
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(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
static unsigned long extruder_autofan_last_check;
#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 PID_PARAMS_PER_EXTRUDER
float Kp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp);
@ -201,53 +221,41 @@ void PID_autotune(float temp, int extruder, int ncycles)
int cycles = 0;
bool heating = true;
unsigned long temp_millis = millis();
unsigned long t1=temp_millis;
unsigned long t2=temp_millis;
long t_high = 0;
long t_low = 0;
unsigned long temp_millis = millis(), t1 = temp_millis, t2 = temp_millis;
long t_high = 0, t_low = 0;
long bias, d;
float Ku, Tu;
float Kp, Ki, Kd;
float max = 0, min = 10000;
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(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();
#if HAS_AUTO_FAN
unsigned long extruder_autofan_last_check = temp_millis;
#endif
if ((extruder >= EXTRUDERS)
#if (TEMP_BED_PIN <= -1)
||(extruder < 0)
if (extruder >= EXTRUDERS
#if !HAS_TEMP_BED
|| extruder < 0
#endif
) {
SERIAL_ECHOLN("PID Autotune failed. Bad extruder number.");
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.
if (extruder < 0)
{
soft_pwm_bed = (MAX_BED_POWER)/2;
bias = d = (MAX_BED_POWER)/2;
}
soft_pwm_bed = bias = d = MAX_BED_POWER / 2;
else
{
soft_pwm[extruder] = (PID_MAX)/2;
bias = d = (PID_MAX)/2;
}
soft_pwm[extruder] = bias = d = PID_MAX / 2;
// PID Tuning loop
for(;;) {
unsigned long ms = millis();
if (temp_meas_ready == true) { // temp sample ready
updateTemperaturesFromRawValues();
@ -256,55 +264,52 @@ void PID_autotune(float temp, int extruder, int ncycles)
max = max(max, input);
min = min(min, input);
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN > -1)
if(millis() - extruder_autofan_last_check > 2500) {
#if HAS_AUTO_FAN
if (ms > extruder_autofan_last_check + 2500) {
checkExtruderAutoFans();
extruder_autofan_last_check = millis();
extruder_autofan_last_check = ms;
}
#endif
if (heating == true && input > temp) {
if(millis() - t2 > 5000) {
if (ms - t2 > 5000) {
heating = false;
if (extruder < 0)
soft_pwm_bed = (bias - d) >> 1;
else
soft_pwm[extruder] = (bias - d) >> 1;
t1=millis();
t1 = ms;
t_high = t1 - t2;
max = temp;
}
}
if (heating == false && input < temp) {
if(millis() - t1 > 5000) {
if (ms - t1 > 5000) {
heating = true;
t2=millis();
t2 = ms;
t_low = t2 - t1;
if (cycles > 0) {
long max_pow = extruder < 0 ? MAX_BED_POWER : PID_MAX;
bias += (d*(t_high - t_low))/(t_low + t_high);
bias = constrain(bias, 20 ,(extruder<0?(MAX_BED_POWER):(PID_MAX))-20);
if(bias > (extruder<0?(MAX_BED_POWER):(PID_MAX))/2) d = (extruder<0?(MAX_BED_POWER):(PID_MAX)) - 1 - bias;
else d = bias;
bias = constrain(bias, 20, max_pow - 20);
d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias);
SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d);
SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min);
SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max);
SERIAL_PROTOCOLPGM(MSG_BIAS); SERIAL_PROTOCOL(bias);
SERIAL_PROTOCOLPGM(MSG_D); SERIAL_PROTOCOL(d);
SERIAL_PROTOCOLPGM(MSG_MIN); SERIAL_PROTOCOL(min);
SERIAL_PROTOCOLPGM(MSG_MAX); SERIAL_PROTOCOLLN(max);
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);
SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku);
SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu);
SERIAL_PROTOCOLPGM(MSG_KU); SERIAL_PROTOCOL(Ku);
SERIAL_PROTOCOLPGM(MSG_TU); SERIAL_PROTOCOLLN(Tu);
Kp = 0.6 * Ku;
Ki = 2 * Kp / Tu;
Kd = Kp * Tu / 8;
SERIAL_PROTOCOLLNPGM(" Classic PID ");
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
SERIAL_PROTOCOLLNPGM(MSG_CLASSIC_PID);
SERIAL_PROTOCOLPGM(MSG_KP); SERIAL_PROTOCOLLN(Kp);
SERIAL_PROTOCOLPGM(MSG_KI); SERIAL_PROTOCOLLN(Ki);
SERIAL_PROTOCOLPGM(MSG_KD); SERIAL_PROTOCOLLN(Kd);
/*
Kp = 0.33*Ku;
Ki = Kp/Tu;
@ -332,40 +337,42 @@ void PID_autotune(float temp, int extruder, int ncycles)
}
}
}
if(input > (temp + 20)) {
SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature too high");
if (input > temp + 20) {
SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH);
return;
}
if(millis() - temp_millis > 2000) {
// Every 2 seconds...
if (ms > temp_millis + 2000) {
int p;
if (extruder < 0) {
p = soft_pwm_bed;
SERIAL_PROTOCOLPGM("ok B:");
}else{
SERIAL_PROTOCOLPGM(MSG_OK_B);
}
else {
p = soft_pwm[extruder];
SERIAL_PROTOCOLPGM("ok T:");
SERIAL_PROTOCOLPGM(MSG_OK_T);
}
SERIAL_PROTOCOL(input);
SERIAL_PROTOCOLPGM(" @:");
SERIAL_PROTOCOLPGM(MSG_AT);
SERIAL_PROTOCOLLN(p);
temp_millis = millis();
}
if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
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;
}
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;
}
lcd_update();
}
}
void updatePID()
{
void updatePID() {
#ifdef PIDTEMP
for (int e = 0; e < EXTRUDERS; e++) {
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
@ -377,16 +384,12 @@ void updatePID()
}
int getHeaterPower(int heater) {
if (heater<0)
return soft_pwm_bed;
return soft_pwm[heater];
return heater < 0 ? soft_pwm_bed : soft_pwm[heater];
}
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(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 defined(FAN_PIN) && FAN_PIN > -1
#if HAS_FAN
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
#endif
@ -396,6 +399,9 @@ int getHeaterPower(int heater) {
#if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_3_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_3_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#endif
void setExtruderAutoFanState(int pin, bool state)
@ -412,11 +418,11 @@ void checkExtruderAutoFans()
uint8_t fanState = 0;
// 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)
fanState |= 1;
#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 (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
@ -425,7 +431,7 @@ void checkExtruderAutoFans()
fanState |= 2;
}
#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 (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
@ -436,7 +442,7 @@ void checkExtruderAutoFans()
fanState |= 4;
}
#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 (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
@ -451,19 +457,19 @@ void checkExtruderAutoFans()
#endif
// 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);
#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)
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
#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
&& EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
#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
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN)
@ -473,27 +479,61 @@ void checkExtruderAutoFans()
#endif // any extruder auto fan pins set
void manage_heater()
{
float pid_input;
float pid_output;
//
// Error checking and Write Routines
//
#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
return;
void manage_heater() {
if (!temp_meas_ready) return;
float pid_input, pid_output;
updateTemperaturesFromRawValues();
#ifdef HEATER_0_USES_MAX6675
if (current_temperature[0] > 1023 || current_temperature[0] > HEATER_0_MAXTEMP) {
max_temp_error(0);
}
if (current_temperature[0] == 0 || current_temperature[0] < HEATER_0_MINTEMP) {
min_temp_error(0);
}
float ct = current_temperature[0];
if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0);
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#endif //HEATER_0_USES_MAX6675
for(int e = 0; e < EXTRUDERS; e++)
{
unsigned long ms = millis();
// Loop through all extruders
for (int e = 0; e < EXTRUDERS; e++) {
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
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);
@ -529,7 +569,8 @@ void manage_heater()
if (pid_output > PID_MAX) {
if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = PID_MAX;
} else if (pid_output < 0){
}
else if (pid_output < 0) {
if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = 0;
}
@ -538,81 +579,74 @@ void manage_heater()
#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(MSG_PID_DEBUG);
SERIAL_ECHO(e);
SERIAL_ECHO(": Input ");
SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
SERIAL_ECHO(pid_input);
SERIAL_ECHO(" Output ");
SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
SERIAL_ECHO(pid_output);
SERIAL_ECHO(" pTerm ");
SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
SERIAL_ECHO(pTerm[e]);
SERIAL_ECHO(" iTerm ");
SERIAL_ECHO(MSG_PID_DEBUG_ITERM);
SERIAL_ECHO(iTerm[e]);
SERIAL_ECHO(" dTerm ");
SERIAL_ECHO(MSG_PID_DEBUG_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;
}
if (current_temperature[e] < target_temperature[e]) pid_output = PID_MAX;
#endif
// Check if temperature is within the correct range
if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
{
soft_pwm[e] = (int)pid_output >> 1;
}
else {
soft_pwm[e] = 0;
}
soft_pwm[e] = current_temperature[e] > minttemp[e] && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0;
#ifdef WATCH_TEMP_PERIOD
if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD)
{
if(degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE)
{
if (watchmillis[e] && ms > watchmillis[e] + WATCH_TEMP_PERIOD) {
if (degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE) {
setTargetHotend(0, e);
LCD_MESSAGEPGM("Heating failed");
LCD_MESSAGEPGM(MSG_HEATING_FAILED_LCD); // translatable
SERIAL_ECHO_START;
SERIAL_ECHOLN("Heating failed");
}else{
SERIAL_ECHOLNPGM(MSG_HEATING_FAILED);
}
else {
watchmillis[e] = 0;
}
}
#endif
#endif //WATCH_TEMP_PERIOD
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
disable_heater();
if (IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Extruder switched off. Temperature difference between temp sensors is too high !");
LCD_ALERTMESSAGEPGM("Err: REDUNDANT TEMP ERROR");
SERIAL_ERRORLNPGM(MSG_EXTRUDER_SWITCHED_OFF);
LCD_ALERTMESSAGEPGM(MSG_ERR_REDUNDANT_TEMP); // translatable
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
#endif
}
#endif
} // End extruder for loop
#endif //TEMP_SENSOR_1_AS_REDUNDANT
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(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(millis() - extruder_autofan_last_check > 2500) // only need to check fan state very infrequently
{
} // Extruders Loop
#if HAS_AUTO_FAN
if (ms > extruder_autofan_last_check + 2500) { // only need to check fan state very infrequently
checkExtruderAutoFans();
extruder_autofan_last_check = millis();
extruder_autofan_last_check = ms;
}
#endif
#ifndef PIDTEMPBED
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
return;
previous_millis_bed_heater = millis();
#endif
if (ms < previous_millis_bed_heater + BED_CHECK_INTERVAL) return;
previous_millis_bed_heater = ms;
#endif //PIDTEMPBED
#if TEMP_SENSOR_BED != 0
@ -639,7 +673,8 @@ void manage_heater()
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){
}
else if (pid_output < 0) {
if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output = 0;
}
@ -648,74 +683,46 @@ void manage_heater()
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#endif //PID_OPENLOOP
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
{
soft_pwm_bed = (int)pid_output >> 1;
}
else {
soft_pwm_bed = 0;
}
soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0;
#elif !defined(BED_LIMIT_SWITCHING)
// Check if temperature is within the correct range
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
{
if(current_temperature_bed >= target_temperature_bed)
{
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;
}
else {
soft_pwm_bed = 0;
}
else
{
soft_pwm_bed = MAX_BED_POWER>>1;
}
}
else
{
soft_pwm_bed = 0;
WRITE(HEATER_BED_PIN,LOW);
WRITE_HEATER_BED(LOW);
}
#else //#ifdef BED_LIMIT_SWITCHING
// Check if temperature is within the correct band
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
{
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
{
if (current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP) {
if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS)
soft_pwm_bed = 0;
}
else if (current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
{
soft_pwm_bed = MAX_BED_POWER >> 1;
}
}
else
{
else {
soft_pwm_bed = 0;
WRITE(HEATER_BED_PIN,LOW);
WRITE_HEATER_BED(LOW);
}
#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
if(filament_sensor)
{
if (filament_sensor) {
meas_shift_index = delay_index1 - meas_delay_cm;
if(meas_shift_index<0)
meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed
if (meas_shift_index < 0) 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
//then square it to get an area
if(meas_shift_index<0)
meas_shift_index=0;
else if (meas_shift_index>MAX_MEASUREMENT_DELAY)
meas_shift_index=MAX_MEASUREMENT_DELAY;
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;
// Get the delayed info and add 100 to reconstitute to a percent of
// the nominal filament diameter then square it to get an area
meas_shift_index = constrain(meas_shift_index, 0, MAX_MEASUREMENT_DELAY);
float vm = pow((measurement_delay[meas_shift_index] + 100.0) / 100.0, 2);
if (vm < 0.01) vm = 0.01;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
}
#endif
#endif //FILAMENT_SENSOR
}
#define PGM_RD_W(x) (short)pgm_read_word(&x)
@ -730,7 +737,7 @@ static float analog2temp(int raw, uint8_t e) {
{
SERIAL_ERROR_START;
SERIAL_ERROR((int)e);
SERIAL_ERRORLNPGM(" - Invalid extruder number !");
SERIAL_ERRORLNPGM(MSG_INVALID_EXTRUDER_NUM);
kill();
return 0.0;
}
@ -799,20 +806,18 @@ static float analog2tempBed(int raw) {
/* 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 updateTemperaturesFromRawValues() {
#ifdef HEATER_0_USES_MAX6675
current_temperature_raw[0] = read_max6675();
#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_bed = analog2tempBed(current_temperature_bed_raw);
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature = analog2temp(redundant_temperature_raw, 1);
#endif
#if defined (FILAMENT_SENSOR) && (FILWIDTH_PIN > -1) //check if a sensor is supported
#if HAS_FILAMENT_SENSOR
filament_width_meas = analog2widthFil();
#endif
//Reset the watchdog after we know we have a temperature measurement.
@ -824,29 +829,22 @@ static void updateTemperaturesFromRawValues()
}
// For converting raw Filament Width to milimeters
#ifdef FILAMENT_SENSOR
// Convert raw Filament Width to millimeters
float analog2widthFil() {
return current_raw_filwidth / 16383.0 * 5.0;
//return current_raw_filwidth;
}
// For converting raw Filament Width to a ratio
// Convert 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;
return(filament_width_nominal/temp*100);
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
@ -875,22 +873,22 @@ void tp_init()
#endif //PIDTEMPBED
}
#if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1)
#if HAS_HEATER_0
SET_OUTPUT(HEATER_0_PIN);
#endif
#if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1)
#if HAS_HEATER_1
SET_OUTPUT(HEATER_1_PIN);
#endif
#if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1)
#if HAS_HEATER_2
SET_OUTPUT(HEATER_2_PIN);
#endif
#if defined(HEATER_3_PIN) && (HEATER_3_PIN > -1)
#if HAS_HEATER_3
SET_OUTPUT(HEATER_3_PIN);
#endif
#if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1)
#if HAS_HEATER_BED
SET_OUTPUT(HEATER_BED_PIN);
#endif
#if defined(FAN_PIN) && (FAN_PIN > -1)
#if HAS_FAN
SET_OUTPUT(FAN_PIN);
#ifdef FAST_PWM_FAN
setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
@ -921,57 +919,35 @@ void tp_init()
#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
ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
#if TEMP_0_PIN < 8
DIDR0 |= 1 << TEMP_0_PIN;
#else
DIDR2 |= 1<<(TEMP_0_PIN - 8);
#if HAS_TEMP_0
ANALOG_SELECT(TEMP_0_PIN);
#endif
#if HAS_TEMP_1
ANALOG_SELECT(TEMP_1_PIN);
#endif
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
#if TEMP_1_PIN < 8
DIDR0 |= 1<<TEMP_1_PIN;
#else
DIDR2 |= 1<<(TEMP_1_PIN - 8);
#if HAS_TEMP_2
ANALOG_SELECT(TEMP_2_PIN);
#endif
#if HAS_TEMP_3
ANALOG_SELECT(TEMP_3_PIN);
#endif
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
#if TEMP_2_PIN < 8
DIDR0 |= 1 << TEMP_2_PIN;
#else
DIDR2 |= 1<<(TEMP_2_PIN - 8);
#endif
#endif
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
#if TEMP_3_PIN < 8
DIDR0 |= 1 << TEMP_3_PIN;
#else
DIDR2 |= 1<<(TEMP_3_PIN - 8);
#endif
#endif
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
#if TEMP_BED_PIN < 8
DIDR0 |= 1<<TEMP_BED_PIN;
#else
DIDR2 |= 1<<(TEMP_BED_PIN - 8);
#endif
#endif
//Added for Filament Sensor
#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
#if HAS_TEMP_BED
ANALOG_SELECT(TEMP_BED_PIN);
#endif
#if HAS_FILAMENT_SENSOR
ANALOG_SELECT(FILWIDTH_PIN);
#endif
// Use timer0 for temperature measurement
@ -982,90 +958,53 @@ void tp_init()
// Wait for temperature measurement to settle
delay(250);
#define TEMP_MIN_ROUTINE(NR) \
minttemp[NR] = HEATER_ ## NR ## _MINTEMP; \
while(analog2temp(minttemp_raw[NR], NR) < HEATER_ ## NR ## _MINTEMP) { \
if (HEATER_ ## NR ## _RAW_LO_TEMP < HEATER_ ## NR ## _RAW_HI_TEMP) \
minttemp_raw[NR] += OVERSAMPLENR; \
else \
minttemp_raw[NR] -= OVERSAMPLENR; \
}
#define TEMP_MAX_ROUTINE(NR) \
maxttemp[NR] = HEATER_ ## NR ## _MAXTEMP; \
while(analog2temp(maxttemp_raw[NR], NR) > HEATER_ ## NR ## _MAXTEMP) { \
if (HEATER_ ## NR ## _RAW_LO_TEMP < HEATER_ ## NR ## _RAW_HI_TEMP) \
maxttemp_raw[NR] -= OVERSAMPLENR; \
else \
maxttemp_raw[NR] += OVERSAMPLENR; \
}
#ifdef HEATER_0_MINTEMP
minttemp[0] = HEATER_0_MINTEMP;
while(analog2temp(minttemp_raw[0], 0) < HEATER_0_MINTEMP) {
#if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
minttemp_raw[0] += OVERSAMPLENR;
#else
minttemp_raw[0] -= OVERSAMPLENR;
TEMP_MIN_ROUTINE(0);
#endif
}
#endif //MINTEMP
#ifdef HEATER_0_MAXTEMP
maxttemp[0] = HEATER_0_MAXTEMP;
while(analog2temp(maxttemp_raw[0], 0) > HEATER_0_MAXTEMP) {
#if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
maxttemp_raw[0] -= OVERSAMPLENR;
#else
maxttemp_raw[0] += OVERSAMPLENR;
TEMP_MAX_ROUTINE(0);
#endif
}
#endif //MAXTEMP
#if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
minttemp[1] = HEATER_1_MINTEMP;
while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
minttemp_raw[1] += OVERSAMPLENR;
#else
minttemp_raw[1] -= OVERSAMPLENR;
#if EXTRUDERS > 1
#ifdef HEATER_1_MINTEMP
TEMP_MIN_ROUTINE(1);
#endif
}
#endif // MINTEMP 1
#if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
maxttemp[1] = HEATER_1_MAXTEMP;
while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
maxttemp_raw[1] -= OVERSAMPLENR;
#else
maxttemp_raw[1] += OVERSAMPLENR;
#ifdef HEATER_1_MAXTEMP
TEMP_MAX_ROUTINE(1);
#endif
}
#endif //MAXTEMP 1
#if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
minttemp[2] = HEATER_2_MINTEMP;
while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
minttemp_raw[2] += OVERSAMPLENR;
#else
minttemp_raw[2] -= OVERSAMPLENR;
#if EXTRUDERS > 2
#ifdef HEATER_2_MINTEMP
TEMP_MIN_ROUTINE(2);
#endif
}
#endif //MINTEMP 2
#if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
maxttemp[2] = HEATER_2_MAXTEMP;
while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
maxttemp_raw[2] -= OVERSAMPLENR;
#else
maxttemp_raw[2] += OVERSAMPLENR;
#ifdef HEATER_2_MAXTEMP
TEMP_MAX_ROUTINE(2);
#endif
}
#endif //MAXTEMP 2
#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;
#if EXTRUDERS > 3
#ifdef HEATER_3_MINTEMP
TEMP_MIN_ROUTINE(3);
#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;
#ifdef HEATER_3_MAXTEMP
TEMP_MAX_ROUTINE(3);
#endif
}
#endif // MAXTEMP 3
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
#ifdef BED_MINTEMP
/* No bed MINTEMP error implemented?!? */ /*
@ -1089,15 +1028,13 @@ void tp_init()
#endif //BED_MAXTEMP
}
void setWatch()
{
void setWatch() {
#ifdef WATCH_TEMP_PERIOD
for (int e = 0; e < EXTRUDERS; e++)
{
if(degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2))
{
unsigned long ms = millis();
for (int e = 0; e < EXTRUDERS; e++) {
if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) {
watch_start_temp[e] = degHotend(e);
watchmillis[e] = millis();
watchmillis[e] = ms;
}
}
#endif
@ -1135,16 +1072,18 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
if (temperature >= target_temperature) *state = 2;
break;
case 2: // "Temperature Stable" state
{
unsigned long ms = millis();
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_ERRORLNPGM("Thermal Runaway, system stopped! Heater_ID: ");
SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
SERIAL_ERRORLN((int)heater_id);
LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY); // translatable
thermal_runaway = true;
while(1)
{
@ -1160,54 +1099,45 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
lcd_update();
}
}
break;
} break;
}
}
#endif
#endif //THERMAL_RUNAWAY_PROTECTION_PERIOD
void disable_heater()
{
for(int i=0;i<EXTRUDERS;i++)
setTargetHotend(0,i);
void disable_heater() {
for (int i=0; i<EXTRUDERS; i++) setTargetHotend(0, i);
setTargetBed(0);
#if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
#if HAS_TEMP_0
target_temperature[0] = 0;
soft_pwm[0] = 0;
#if defined(HEATER_0_PIN) && HEATER_0_PIN > -1
WRITE(HEATER_0_PIN,LOW);
#endif
WRITE_HEATER_0P(LOW); // If HEATERS_PARALLEL should apply, change to WRITE_HEATER_0
#endif
#if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 && EXTRUDERS > 1
#if EXTRUDERS > 1 && HAS_TEMP_1
target_temperature[1] = 0;
soft_pwm[1] = 0;
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
WRITE(HEATER_1_PIN,LOW);
#endif
WRITE_HEATER_1(LOW);
#endif
#if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 && EXTRUDERS > 2
#if EXTRUDERS > 2 && HAS_TEMP_2
target_temperature[2] = 0;
soft_pwm[2] = 0;
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
WRITE(HEATER_2_PIN,LOW);
#endif
WRITE_HEATER_2(LOW);
#endif
#if defined(TEMP_3_PIN) && TEMP_3_PIN > -1 && EXTRUDERS > 3
#if EXTRUDERS > 3 && HAS_TEMP_3
target_temperature[3] = 0;
soft_pwm[3] = 0;
#if defined(HEATER_3_PIN) && HEATER_3_PIN > -1
WRITE(HEATER_3_PIN,LOW);
#endif
WRITE_HEATER_3(LOW);
#endif
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
#if HAS_TEMP_BED
target_temperature_bed = 0;
soft_pwm_bed = 0;
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN,LOW);
#if HAS_HEATER_BED
WRITE_HEATER_BED(LOW);
#endif
#endif
}
@ -1217,8 +1147,8 @@ void max_temp_error(uint8_t e) {
if(IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLN((int)e);
SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
LCD_ALERTMESSAGEPGM("Err: MAXTEMP");
SERIAL_ERRORLNPGM(MSG_MAXTEMP_EXTRUDER_OFF);
LCD_ALERTMESSAGEPGM(MSG_ERR_MAXTEMP); // translatable
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
@ -1230,8 +1160,8 @@ void min_temp_error(uint8_t e) {
if(IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLN((int)e);
SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
LCD_ALERTMESSAGEPGM("Err: MINTEMP");
SERIAL_ERRORLNPGM(MSG_MINTEMP_EXTRUDER_OFF);
LCD_ALERTMESSAGEPGM(MSG_ERR_MINTEMP); // translatable
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
@ -1239,13 +1169,13 @@ void min_temp_error(uint8_t e) {
}
void bed_max_temp_error(void) {
#if HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN, 0);
#if HAS_HEATER_BED
WRITE_HEATER_BED(0);
#endif
if (IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!");
LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED");
SERIAL_ERRORLNPGM(MSG_MAXTEMP_BED_OFF);
LCD_ALERTMESSAGEPGM(MSG_ERR_MAXTEMP_BED); // translatable
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
@ -1257,12 +1187,13 @@ void bed_max_temp_error(void) {
long max6675_previous_millis = MAX6675_HEAT_INTERVAL;
int max6675_temp = 2000;
static int read_max6675()
{
if (millis() - max6675_previous_millis < MAX6675_HEAT_INTERVAL)
static int read_max6675() {
unsigned long ms = millis();
if (ms < max6675_previous_millis + MAX6675_HEAT_INTERVAL)
return max6675_temp;
max6675_previous_millis = millis();
max6675_previous_millis = ms;
max6675_temp = 0;
#ifdef PRR
@ -1294,13 +1225,11 @@ static int read_max6675()
// disable TT_MAX6675
WRITE(MAX6675_SS, 1);
if (max6675_temp & 4)
{
if (max6675_temp & 4) {
// thermocouple open
max6675_temp = 4000;
}
else
{
else {
max6675_temp = max6675_temp >> 3;
}
@ -1309,10 +1238,29 @@ static int read_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
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
static unsigned char temp_count = 0;
static unsigned long raw_temp_0_value = 0;
@ -1320,113 +1268,96 @@ ISR(TIMER0_COMPB_vect)
static unsigned long raw_temp_2_value = 0;
static unsigned long raw_temp_3_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 soft_pwm_0;
// Static members for each heater
#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;
#define ISR_STATICS(n) \
static unsigned char soft_pwm_ ## n; \
static unsigned char state_heater_ ## n = 0; \
static unsigned char state_timer_heater_ ## n = 0
#else
#define ISR_STATICS(n) static unsigned char soft_pwm_ ## n
#endif
// Statics per heater
ISR_STATICS(0);
#if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
static unsigned char soft_pwm_1;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_1 = 0;
static unsigned char state_timer_heater_1 = 0;
#endif
#endif
ISR_STATICS(1);
#if EXTRUDERS > 2
static unsigned char soft_pwm_2;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_2 = 0;
static unsigned char state_timer_heater_2 = 0;
#endif
#endif
ISR_STATICS(2);
#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;
ISR_STATICS(3);
#endif
#endif
#endif
#if HAS_HEATER_BED
ISR_STATICS(BED);
#endif
#if HEATER_BED_PIN > -1
static unsigned char soft_pwm_b;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_b = 0;
static unsigned char state_timer_heater_b = 0;
#endif
#endif
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
static unsigned long raw_filwidth_value = 0; //added for filament width sensor
#if HAS_FILAMENT_SENSOR
static unsigned long raw_filwidth_value = 0;
#endif
#ifndef SLOW_PWM_HEATERS
/*
/**
* 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);
WRITE_HEATER_0(1);
}
else WRITE_HEATER_0P(0); // If HEATERS_PARALLEL should apply, change to WRITE_HEATER_0
#if EXTRUDERS > 1
soft_pwm_1 = soft_pwm[1];
if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0);
#endif
WRITE_HEATER_1(soft_pwm_1 > 0 ? 1 : 0);
#if EXTRUDERS > 2
soft_pwm_2 = soft_pwm[2];
if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0);
#endif
WRITE_HEATER_2(soft_pwm_2 > 0 ? 1 : 0);
#if EXTRUDERS > 3
soft_pwm_3 = soft_pwm[3];
if(soft_pwm_3 > 0) WRITE(HEATER_3_PIN,1); else WRITE(HEATER_3_PIN,0);
WRITE_HEATER_3(soft_pwm_3 > 0 ? 1 : 0);
#endif
#endif
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
soft_pwm_b = soft_pwm_bed;
if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
#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;
if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
#endif
}
if(soft_pwm_0 < pwm_count) {
WRITE(HEATER_0_PIN,0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN,0);
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_PIN,0);
#endif
if (soft_pwm_1 < pwm_count) WRITE_HEATER_1(0);
#if EXTRUDERS > 2
if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
#endif
if (soft_pwm_2 < pwm_count) WRITE_HEATER_2(0);
#if EXTRUDERS > 3
if(soft_pwm_3 < pwm_count) WRITE(HEATER_3_PIN,0);
if (soft_pwm_3 < pwm_count) WRITE_HEATER_3(0);
#endif
#endif
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
#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_PIN,0);
if (soft_pwm_fan < pwm_count) WRITE_FAN(0);
#endif
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
#else //ifndef SLOW_PWM_HEATERS
#else // SLOW_PWM_HEATERS
/*
* SLOW PWM HEATERS
*
@ -1435,225 +1366,74 @@ ISR(TIMER0_COMPB_vect)
#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) {
// 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
}
}
SLOW_PWM_ROUTINE(0); // EXTRUDER 0
#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
SLOW_PWM_ROUTINE(1); // EXTRUDER 1
#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
SLOW_PWM_ROUTINE(2); // EXTRUDER 2
#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);
}
}
SLOW_PWM_ROUTINE(3); // EXTRUDER 3
#endif
#endif
#endif
#if HAS_HEATER_BED
_SLOW_PWM_ROUTINE(BED, soft_pwm_bed); // BED
#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
}
}
} // slow_pwm_count == 0
PWM_OFF_ROUTINE(0); // EXTRUDER 0
#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
PWM_OFF_ROUTINE(1); // EXTRUDER 1
#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
PWM_OFF_ROUTINE(2); // EXTRUDER 2
#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);
}
}
PWM_OFF_ROUTINE(3); // EXTRUDER 3
#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
#endif
#if HAS_HEATER_BED
PWM_OFF_ROUTINE(BED); // BED
#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);
WRITE_FAN(soft_pwm_fan > 0 ? 1 : 0);
}
if (soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
#endif
if (soft_pwm_fan < pwm_count) WRITE_FAN(0);
#endif //FAN_SOFT_PWM
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
@ -1663,200 +1443,150 @@ ISR(TIMER0_COMPB_vect)
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--;
// 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
#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--;
#if HAS_HEATER_BED
if (state_timer_heater_BED > 0) state_timer_heater_BED--;
#endif
} //if ((pwm_count % 64) == 0) {
} // (pwm_count % 64) == 0
#endif //ifndef SLOW_PWM_HEATERS
#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 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
ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
case PrepareTemp_0:
#if HAS_TEMP_0
START_ADC(TEMP_0_PIN);
#endif
lcd_buttons_update();
temp_state = 1;
temp_state = MeasureTemp_0;
break;
case 1: // Measure TEMP_0
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
case MeasureTemp_0:
#if HAS_TEMP_0
raw_temp_0_value += ADC;
#endif
temp_state = 2;
temp_state = PrepareTemp_BED;
break;
case 2: // Prepare TEMP_BED
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
#if TEMP_BED_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
case PrepareTemp_BED:
#if HAS_TEMP_BED
START_ADC(TEMP_BED_PIN);
#endif
lcd_buttons_update();
temp_state = 3;
temp_state = MeasureTemp_BED;
break;
case 3: // Measure TEMP_BED
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
case MeasureTemp_BED:
#if HAS_TEMP_BED
raw_temp_bed_value += ADC;
#endif
temp_state = 4;
temp_state = PrepareTemp_1;
break;
case 4: // Prepare TEMP_1
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
#if TEMP_1_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
case PrepareTemp_1:
#if HAS_TEMP_1
START_ADC(TEMP_1_PIN);
#endif
lcd_buttons_update();
temp_state = 5;
temp_state = MeasureTemp_1;
break;
case 5: // Measure TEMP_1
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
case MeasureTemp_1:
#if HAS_TEMP_1
raw_temp_1_value += ADC;
#endif
temp_state = 6;
temp_state = PrepareTemp_2;
break;
case 6: // Prepare TEMP_2
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
#if TEMP_2_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
case PrepareTemp_2:
#if HAS_TEMP_2
START_ADC(TEMP_2_PIN);
#endif
lcd_buttons_update();
temp_state = 7;
temp_state = MeasureTemp_2;
break;
case 7: // Measure TEMP_2
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
case MeasureTemp_2:
#if HAS_TEMP_2
raw_temp_2_value += ADC;
#endif
temp_state = 8;
temp_state = PrepareTemp_3;
break;
case 8: // Prepare TEMP_3
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
#if TEMP_3_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_3_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
case PrepareTemp_3:
#if HAS_TEMP_3
START_ADC(TEMP_3_PIN);
#endif
lcd_buttons_update();
temp_state = 9;
temp_state = MeasureTemp_3;
break;
case 9: // Measure TEMP_3
#if defined(TEMP_3_PIN) && (TEMP_3_PIN > -1)
case MeasureTemp_3:
#if HAS_TEMP_3
raw_temp_3_value += ADC;
#endif
temp_state = 10; //change so that Filament Width is also measured
temp_state = Prepare_FILWIDTH;
break;
case 10: //Prepare FILWIDTH
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1)
#if FILWIDTH_PIN>7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (FILWIDTH_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
case Prepare_FILWIDTH:
#if HAS_FILAMENT_SENSOR
START_ADC(FILWIDTH_PIN);
#endif
lcd_buttons_update();
temp_state = 11;
temp_state = Measure_FILWIDTH;
break;
case 11: //Measure FILWIDTH
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
case Measure_FILWIDTH:
#if HAS_FILAMENT_SENSOR
// 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
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>>7); //multiply raw_filwidth_value by 127/128
raw_filwidth_value += ((unsigned long)ADC<<7); //add new ADC reading
}
#endif
temp_state = 0;
temp_state = PrepareTemp_0;
temp_count++;
break;
case 12: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
temp_state = 0;
case StartupDelay:
temp_state = PrepareTemp_0;
break;
// default:
// SERIAL_ERROR_START;
// SERIAL_ERRORLNPGM("Temp measurement error!");
// 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.
{
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
#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;
}
} //!temp_meas_ready
//Add similar code for Filament Sensor - can be read any time since IIR filtering is used
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach
// 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_count = 0;
raw_temp_0_value = 0;
@ -1866,101 +1596,35 @@ ISR(TIMER0_COMPB_vect)
raw_temp_bed_value = 0;
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
if(current_temperature_raw[0] <= maxttemp_raw[0]) {
#define MAXTEST <=
#define MINTEST >=
#else
if(current_temperature_raw[0] >= maxttemp_raw[0]) {
#endif
#ifndef HEATER_0_USES_MAX6675
max_temp_error(0);
#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
}
#if EXTRUDERS > 1
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
if(current_temperature_raw[1] <= maxttemp_raw[1]) {
#else
if(current_temperature_raw[1] >= maxttemp_raw[1]) {
#endif
max_temp_error(1);
}
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
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);
}
#define MAXTEST >=
#define MINTEST <=
#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 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
if (current_temperature_bed_raw MAXTEST bed_maxttemp_raw) {
target_temperature_bed = 0;
bed_max_temp_error();
}
#endif
}
} // temp_count >= OVERSAMPLENR
#ifdef BABYSTEPPING
for(uint8_t axis=0;axis<3;axis++)
{
for (uint8_t axis=X_AXIS; axis<=Z_AXIS; axis++) {
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
if(curTodo>0)
{
if (curTodo > 0) {
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time
}
else
if(curTodo<0)
{
else if(curTodo < 0) {
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
}
@ -1970,26 +1634,8 @@ ISR(TIMER0_COMPB_vect)
#ifdef PIDTEMP
// 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_d(float d)
{
return d/PID_dT;
}
float unscalePID_d(float d)
{
return d*PID_dT;
}
float scalePID_i(float i) { 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

View file

@ -85,55 +85,25 @@ extern float current_temperature_bed;
//inline so that there is no performance decrease.
//deg=degreeCelsius
FORCE_INLINE float degHotend(uint8_t extruder) {
return current_temperature[extruder];
};
FORCE_INLINE float degHotend(uint8_t extruder) { return current_temperature[extruder]; }
FORCE_INLINE float degBed() { return current_temperature_bed; }
#ifdef SHOW_TEMP_ADC_VALUES
FORCE_INLINE float rawHotendTemp(uint8_t extruder) {
return current_temperature_raw[extruder];
};
FORCE_INLINE float rawBedTemp() {
return current_temperature_bed_raw;
};
FORCE_INLINE float rawHotendTemp(uint8_t extruder) { return current_temperature_raw[extruder]; }
FORCE_INLINE float rawBedTemp() { return current_temperature_bed_raw; }
#endif
FORCE_INLINE float degBed() {
return current_temperature_bed;
};
FORCE_INLINE float degTargetHotend(uint8_t extruder) { return target_temperature[extruder]; }
FORCE_INLINE float degTargetBed() { return target_temperature_bed; }
FORCE_INLINE float degTargetHotend(uint8_t extruder) {
return target_temperature[extruder];
};
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) { target_temperature[extruder] = celsius; }
FORCE_INLINE void setTargetBed(const float &celsius) { target_temperature_bed = celsius; }
FORCE_INLINE float degTargetBed() {
return target_temperature_bed;
};
FORCE_INLINE bool isHeatingHotend(uint8_t extruder) { return target_temperature[extruder] > current_temperature[extruder]; }
FORCE_INLINE bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; }
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
target_temperature[extruder] = celsius;
};
FORCE_INLINE void setTargetBed(const float &celsius) {
target_temperature_bed = celsius;
};
FORCE_INLINE bool isHeatingHotend(uint8_t extruder){
return target_temperature[extruder] > current_temperature[extruder];
};
FORCE_INLINE bool isHeatingBed() {
return target_temperature_bed > current_temperature_bed;
};
FORCE_INLINE bool isCoolingHotend(uint8_t extruder) {
return target_temperature[extruder] < current_temperature[extruder];
};
FORCE_INLINE bool isCoolingBed() {
return target_temperature_bed < current_temperature_bed;
};
FORCE_INLINE bool isCoolingHotend(uint8_t extruder) { return target_temperature[extruder] < current_temperature[extruder]; }
FORCE_INLINE bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; }
#define degHotend0() degHotend(0)
#define degTargetHotend0() degTargetHotend(0)
@ -171,8 +141,6 @@ FORCE_INLINE bool isCoolingBed() {
#error Invalid number of extruders
#endif
int getHeaterPower(int heater);
void disable_heater();
void setWatch();
@ -191,8 +159,7 @@ static bool thermal_runaway = false;
FORCE_INLINE void autotempShutdown() {
#ifdef AUTOTEMP
if(autotemp_enabled)
{
if (autotemp_enabled) {
autotemp_enabled = false;
if (degTargetHotend(active_extruder) > autotemp_min)
setTargetHotend(0, active_extruder);