Integrate cooler PWM functions/constants

parent f9edd3ec
......@@ -178,6 +178,7 @@
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
#define TEMP_SENSOR_BED 0
#define TEMP_SENSOR_COOLER 0
//These 2 defines help to calibrate the AD595 sensor in case you get wrong temperature measurements.
//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET"
......@@ -208,6 +209,7 @@
#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// When temperature exceeds max temp, your heater will be switched off.
// When temperature exceeds max temp, your cooler cannot be activaed.
// This feature exists to protect your hotend from overheating accidentally, but *NOT* from thermistor short/failure!
// You should use MINTEMP for thermistor short/failure protection.
#define HEATER_0_MAXTEMP 275 // (degC)
......@@ -215,8 +217,10 @@
#define HEATER_2_MAXTEMP 275 // (degC)
#define HEATER_3_MAXTEMP 275 // (degC)
#define BED_MAXTEMP 150 // (degC)
#define COOLER_MAXTEMP 25 //
// The minimal temperature defines the temperature below which the heater will not be enabled It is used
// or, in case of cooler, it will switched off.
// to check that the wiring to the thermistor is not broken.
// Otherwise this would lead to the heater being powered on all the time.
#define HEATER_0_MINTEMP 5 // (degC)
......@@ -224,6 +228,7 @@
#define HEATER_2_MINTEMP 5 // (degC)
#define HEATER_3_MINTEMP 5 // (degC)
#define BED_MINTEMP 5 // (degC)
#define COOLER_MINTEMP 15 // (degC)
//Preheat Constants
#define PLA_PREHEAT_HOTEND_TEMP 190
......
......@@ -189,6 +189,47 @@
#define DEFAULT_Kc {100, 100, 100, 100} // heating power = Kc * (e_speed)
/***********************************************************************/
/***********************************************************************
************************ PID Settings - COOLER ************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* Select PID or bang-bang with PIDTEMPCOOLER. *
* If bang-bang, COOLER_LIMIT_SWITCHING will enable hysteresis *
* *
***********************************************************************/
// Uncomment this to enable PID on the cooler. It uses the same frequency PWM as the extruder
// if you use a software PWM or the frequency you select if using an hardware PWM
// If your PID_dT is the default, you use a software PWM, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W cooler.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
//#define PIDTEMPCOOLER
//#define COOLER_LIMIT_SWITCHING
#define COOLER_HYSTERESIS 2 //only disable heating if T<target-COOLER_HYSTERESIS and enable heating if T<target+COOLER_HYSTERESIS (works only if COOLER_LIMIT_SWITCHING is enabled)
#define COOLER_CHECK_INTERVAL 5000 //ms between checks in bang-bang control
// This sets the max power delivered to the bed.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPCOOLER)
#define MAX_COOLER_POWER 255 // limits duty cycle to bed; 255=full current
#define PID_COOLER_INTEGRAL_DRIVE_MAX MAX_COOLER_POWER // limit for the integral term
// 120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_coolerKp 10.00
#define DEFAULT_coolerKi .023
#define DEFAULT_coolerKd 305.4
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
//#define PID_COOLER_DEBUG // Sends debug data to the serial port.
/***********************************************************************/
/***********************************************************************
************************ PID Settings - BED ***************************
......@@ -246,13 +287,13 @@
************************ Thermal runaway protection ****************************
********************************************************************************
* *
* This protects your printer from damage and fire if a thermistor *
* This protects your device from damage and fire if a thermistor *
* falls out or temperature sensors fail in any way. *
* *
* The issue: If a thermistor falls out or a temperature sensor fails, *
* Marlin can no longer sense the actual temperature. Since a *
* disconnected thermistor reads as a low temperature, the firmware *
* will keep the heater on. *
* will keep the heater/cooler on. *
* *
* The solution: Once the temperature reaches the target, start *
* observing. If the temperature stays too far below the *
......@@ -261,6 +302,7 @@
* *
* Uncomment THERMAL_PROTECTION_HOTENDS to enable this feature for all hotends. *
* Uncomment THERMAL_PROTECTION_BED to enable this feature for the heated bed. *
* Uncomment THERMAL_PROTECTION_COOLER to enable this feature for the cooler. *
* *
********************************************************************************/
//#define THERMAL_PROTECTION_HOTENDS
......@@ -279,6 +321,25 @@
#define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius
//#define THERMAL_PROTECTION_COOLER
#define THERMAL_PROTECTION_BED_COOLER 30 // Seconds
#define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degree Celsius
// Using M141 to set cooling temperature the firmware will wait for the WATCH_COOLER_TEMP_PERIOD
// to expire, and if the temperature hasn't lowered by WATCH_TEMP_DECREASE degrees,
// the machine is halted, requiring a hard reset. This test restarts with any M141,
// but only if the current remperature is far enough exceeding the target for a reliable test
// Enable this feature by uncomment THERMAL_PROTECTION_COOLER_WATCHDOG
//#define THERMAL_PROTECTION_COOLER_WATCHDOG
#define WATCH_TEMP_COOLER_PERIOD 60 // Seconds
#define WATCH_TEMP_COOLER_DECREASE 1 // Degree Celsius
/********************************************************************************/
......
......@@ -17,14 +17,6 @@
// Uncomment the following if your laser firing pin (not the PWM pin) for two pin control requires a HIGH signal to fire rather than a low (eg Red Sail M300 RS 3040)
/// #define HIGH_TO_FIRE
// Uncomment the following to enable the use of the PWM (the one for the extruder 0) to drive a peltier cell or any PWM driven cooler for the laser
#define COOLER
#define COOLER_MAXTEMP 25
// Uncomment the following to enable COOLER PWM instead of bang-bang
#define COOLER_PWM
#define COOLER_PWM_FREQUENCY 1000 // Frequency in Hz
//// The following defines select which G codes tell the laser to fire. It's OK to uncomment more than one.
#define LASER_FIRE_G1 10 // fire the laser on a G1 move, extinguish when the move ends
#define LASER_FIRE_SPINDLE 11 // fire the laser on M3, extinguish on M5
......@@ -67,45 +59,4 @@
/***********************************************************************
************************ PID Settings - COOLER ************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* Select PID or bang-bang with PIDTEMPCOOLER. *
* If bang-bang, COOLER_LIMIT_SWITCHING will enable hysteresis *
* *
***********************************************************************/
// Uncomment this to enable PID on the bed. It uses the same frequency PWM as the extruder.
// If your PID_dT is the default, and correct for your hardware/configuration, that means 7.689Hz,
// which is fine for driving a square wave into a resistive load and does not significantly impact you FET heating.
// This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W heater.
// If your configuration is significantly different than this and you don't understand the issues involved, you probably
// shouldn't use bed PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
#define PIDTEMPCOOLER
//#define COOLER_LIMIT_SWITCHING
#define COOLER_HYSTERESIS 2 //only disable heating if T<target-COOLER_HYSTERESIS and enable heating if T<target+COOLER_HYSTERESIS (works only if COOLER_LIMIT_SWITCHING is enabled)
#define COOLER_CHECK_INTERVAL 5000 //ms between checks in bang-bang control
// This sets the max power delivered to the bed.
// all forms of bed control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the bed,
// so you shouldn't use it unless you are OK with PWM on your bed. (see the comment on enabling PIDTEMPCOOLER)
#define MAX_COOLER_POWER 255 // limits duty cycle to bed; 255=full current
#define PID_COOLER_INTEGRAL_DRIVE_MAX MAX_COOLER_POWER // limit for the integral term
// 120v 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_coolerKp 10.00
#define DEFAULT_coolerKi .023
#define DEFAULT_coolerKd 305.4
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
//#define PID_COOLER_DEBUG // Sends debug data to the serial port.
/***********************************************************************/
#endif
......@@ -254,6 +254,10 @@ extern uint8_t active_driver;
void print_heaterstates();
#endif
#if HAS(TEMP_COOLER)
void print_heaterstates();
#endif
#if ENABLED(FIRMWARE_TEST)
void FirmwareTest();
#endif
......
......@@ -591,13 +591,24 @@
#define BED_USES_THERMISTOR
#endif
#if TEMP_SENSOR_COOLER == -1
#define COOLER_USES_AD595
#elif TEMP_SENSOR_COOLER == 0
#undef COOLER_MINTEMP
#undef COOLER_MAXTEMP
#elif TEMP_SENSOR_COOLER > 0
#define THERMISTORCOOLER TEMP_SENSOR_COOLER
#define COOLER_USES_THERMISTOR
#endif
#define HEATER_USES_AD595 (ENABLED(HEATER_0_USES_AD595) || ENABLED(HEATER_1_USES_AD595) || ENABLED(HEATER_2_USES_AD595) || ENABLED(HEATER_3_USES_AD595))
/**
* Flags for PID handling
*/
#define HAS_PID_HEATING (ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED))
#define HAS_PID_HEATING (ENABLED(PIDTEMPCOOLER))
#define HAS_PID_COOLING (ENABLED(PIDTEMPCOOLER))
#define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED))
/**
......@@ -654,7 +665,7 @@
#define HAS_HEATER_2 (PIN_EXISTS(HEATER_2))
#define HAS_HEATER_3 (PIN_EXISTS(HEATER_3))
#define HAS_HEATER_BED (PIN_EXISTS(HEATER_BED))
#define HAS_COOLER (PIN_EXISTS(COOLER))
#define HAS_COOLER_DEV (PIN_EXISTS(COOLER))
#define HAS_AUTO_FAN_0 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_0_AUTO_FAN))
#define HAS_AUTO_FAN_1 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_1_AUTO_FAN))
#define HAS_AUTO_FAN_2 (ENABLED(EXTRUDER_AUTO_FAN) && PIN_EXISTS(EXTRUDER_2_AUTO_FAN))
......@@ -779,6 +790,13 @@
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,v)
#endif
#endif
#if HAS(HEATER_COOLER)
#if ENABLED(INVERTED_COOLER_PINS)
#define WRITE_COOLER(v) WRITE(COOLER_PIN,!v)
#else
#define WRITE_COOLER(v) WRITE(COOLER_PIN,v)
#endif
#endif
#if HAS(FAN)
#if ENABLED(INVERTED_HEATER_PINS)
#define WRITE_FAN(v) WRITE(FAN_PIN, !v)
......
......@@ -246,6 +246,15 @@
#error DEPENDENCY ERROR: Missing setting BED_CHECK_INTERVAL
#endif
#endif
#if ENABLED(COOLER_LIMIT_SWITCHING)
#if DISABLED(COOLER_HYSTERESIS)
#error DEPENDENCY ERROR: Missing setting COOLER_HYSTERESIS
#endif
#if DISABLED(COOLER_CHECK_INTERVAL)
#error DEPENDENCY ERROR: Missing setting COOLER_CHECK_INTERVAL
#endif
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
#if DISABLED(THERMAL_PROTECTION_PERIOD)
#error DEPENDENCY ERROR: Missing setting THERMAL_PROTECTION_PERIOD
......
......@@ -99,6 +99,7 @@ float current_temperature_bed = 0.0;
#endif
unsigned char soft_pwm_bed;
unsigned char soft_pwm_cooler;
#if ENABLED(BABYSTEPPING)
volatile int babystepsTodo[3] = { 0 };
......@@ -179,6 +180,8 @@ static volatile bool temp_meas_ready = false;
static float pid_error_cooler;
static float temp_iState_min_cooler;
static float temp_iState_max_cooler;
#else
static millis_t next_cooler_check_ms;
#endif
static unsigned char soft_pwm[HOTENDS];
......@@ -213,10 +216,10 @@ static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383);
static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
#endif
#if ENABLED(COOLER_MINTEMP)
static int cooler_minttemp_raw = COOLER_COOLER_RAW_LO_TEMP;
static int cooler_minttemp_raw = COOLER_RAW_LO_TEMP;
#endif
#if ENABLED(COOLER_MAXTEMP)
static int cooler_maxttemp_raw = COOLER_COOLER_RAW_HI_TEMP;
static int cooler_maxttemp_raw = COOLER_RAW_HI_TEMP;
#endif
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
......@@ -237,7 +240,7 @@ static void updateTemperaturesFromRawValues();
millis_t watch_heater_next_ms[HOTENDS] = { 0 };
#endif
#if ENABLED(THERMAL_PROTECTION_COOLERS)
#if ENABLED(THERMAL_PROTECTION_COOLER)
int watch_target_temp_cooler = 0;
millis_t watch_cooler_next_ms = 0;
#endif
......@@ -901,7 +904,7 @@ void manage_temp_controller() {
#if DISABLED(PIDTEMPCOOLER)
if (ms < next_cooler_check_ms) return;
next_cooler_check_ms = ms + BED_COOLER_INTERVAL;
next_cooler_check_ms = ms + COOLER_CHECK_INTERVAL;
#endif
#if TEMP_SENSOR_BED != 0
......@@ -1064,7 +1067,7 @@ static float analog2tempBed(int raw) {
static float analog2tempCooler(int raw) {
#if ENABLED(BED_COOLER_THERMISTOR)
#if ENABLED(COOLER_USES_THERMISTOR)
float celsius = 0;
byte i;
......@@ -1248,7 +1251,7 @@ void tp_init() {
#if HAS(HEATER_BED)
SET_OUTPUT(HEATER_BED_PIN);
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
SET_OUTPUT(COOLER_PIN)
#if ENABLED(COOLER_PWM)
setPwmFrequency(COOLER_PIN, 2); // No prescaling. Pwm frequency = F_CPU/256/64
......@@ -1468,15 +1471,15 @@ void tp_init() {
}
#endif
#if ENABLED(THERMAL_PROTECTION_COOLERS)
#if ENABLED(THERMAL_PROTECTION_COOLER) && ENABLED(THERMAL_PROTECTION_COOLER_WATCHDOG)
/**
* Start Cooling Sanity Check for hotends that are below
* their target temperature by a configurable margin.
* This is called when the temperature is set. (M141)
*/
void start_watching_cooler(void) {
if (degCooler() < degTargetCooler() - (WATCH_TEMP_COOLER_INCREASE + TEMP_COOLER_HYSTERESIS + 1)) {
watch_target_temp_cooler = degCooler() + WATCH_COOLER_TEMP_INCREASE;
if (degCooler() > degTargetCooler() - (WATCH_TEMP_COOLER_DECREASE - TEMP_COOLER_HYSTERESIS - 1)) {
watch_target_temp_cooler = degCooler() - WATCH_COOLER_TEMP_DECREASE;
watch_cooler_next_ms = millis() + WATCH_TEMP_COOLER_PERIOD * 1000UL;
}
else
......@@ -1591,6 +1594,18 @@ void disable_all_heaters() {
#endif
}
void disable_all_coolers() {
setTargetCooler(0);
#if HAS(TEMP_COOLER)
target_temperature_cooler = 0;
soft_pwm_cooler = 0;
#if HAS(COOLER_DEV)
WRITE_COOLER(LOW);
#endif
#endif
}
#if ENABLED(HEATER_0_USES_MAX6675)
#define MAX6675_HEAT_INTERVAL 250u
static millis_t next_max6675_ms = 0;
......@@ -1741,7 +1756,7 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
ISR_STATICS(BED);
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
ISR_STATICS(COOLER_DEVICE);
#endif
......@@ -1777,7 +1792,7 @@ ISR(TIMER0_COMPB_vect) {
soft_pwm_BED = soft_pwm_bed;
WRITE_HEATER_BED(soft_pwm_BED > 0 ? 1 : 0);
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
soft_pwm_COOLER_DEVICE = soft_pwm_cooler;
WRITE_COOLER(soft_pwm_COOLER_DEVICE > 0 ? 1 : 0);
#endif
......@@ -1820,7 +1835,7 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
if (soft_pwm_BED < pwm_count) WRITE_HEATER_BED(0);
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
if (soft_pwm_COOLER_DEVICE < pwm_count ) WRITE_COOLER(0);
#endif
......@@ -1904,7 +1919,7 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
_SLOW_PWM_ROUTINE(BED, soft_pwm_bed); // BED
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
_SLOW_PWM_SOURINT(COOLER_DEVICE, soft_pwm_cooler); // COOLER
#endif
......@@ -1923,7 +1938,7 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
PWM_OFF_ROUTINE(BED); // BED
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
PWM_OFF_ROUTINE(COOLER_DEVICE); // COOLER
#endif
......@@ -1995,7 +2010,7 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
if (state_timer_heater_BED > 0) state_timer_heater_BED--;
#endif
#if HAS(COOLER)
#if HAS(COOLER_DEV)
if(state_timer_heater_COOLER_DEVICE > 0) state_timer_heater_COOLER_DEVICE--;
#endif
} // (pwm_count % 64) == 0
......
......@@ -185,7 +185,7 @@ int getHeaterPower(int heater);
int getCoolerPower(void);
void disable_all_heaters();
#define disable_all_coolers() setTargetCooler(0)
void disable_all_coolers();
void updatePID();
#if HAS(PID_HEATING) || HAS(PID_COOLING)
......
......@@ -696,6 +696,10 @@ This does not match the normal thermistor behaviour so we need to set the follow
#define HEATER_BED_RAW_HI_TEMP 16383
#define HEATER_BED_RAW_LO_TEMP 0
#endif
#if (THERMISTORCOOLER == 20)
#define COOLER_RAW_HI_TEMP 16383
#define COOLER_RAW_LO_TEMP 0
#endif
const short temptable_20[][2] PROGMEM = {
{0 * OVERSAMPLENR, 0},
{227 * OVERSAMPLENR, 1},
......@@ -1252,6 +1256,16 @@ const short temptable_1047[][2] PROGMEM = {
#endif // BED_USES_THERMISTOR
#endif
#ifdef THERMISTORCOOLER
#define COOLERTEMPTABLE TT_NAME(THERMISTORCOOLER)
#define COOLERTEMPTABLE_LEN COUNT(COOLERTEMPTABLE)
#else
#ifdef COOLER_USES_THERMISTOR
#error No Cooler thermistor table specified
#endif // COOLER_USES_THERMISTOR
#endif
//Set the high and low raw values for the heater, this indicates which raw value is a high or low temperature
#ifndef HEATER_BED_RAW_HI_TEMP
#ifdef BED_USES_THERMISTOR //In case of a thermistor the highest temperature results in the lowest ADC value
......@@ -1263,4 +1277,15 @@ const short temptable_1047[][2] PROGMEM = {
#endif
#endif
#ifndef COOLER_RAW_HI_TEMP
#ifdef COOLER_USES_THERMISTOR //In case of a thermistor the highest temperature results in the lowest ADC value
#define COOLER_RAW_HI_TEMP 0
#define COOLER_RAW_LO_TEMP 16383
#else //In case of an thermocouple the highest temperature results in the highest ADC value
#define COOLER_RAW_HI_TEMP 16383
#define COOLER_RAW_LO_TEMP 0
#endif
#endif
#endif //THERMISTORTABLES_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment