sync with upstream

parent c3a55864
Pipeline #49 skipped
......@@ -7,10 +7,9 @@
* - Board type
* - Mechanism type
* - Extruders number
* - Thermistor type
* - Temperature limits
*
* Mechanisms-settings can be found in Configuration_Xxxxxx.h (where Xxxxxx can be: Cartesian - Delta - Core - Scara)
* Temperature settings can be found in Configuration_Temperature.h
* Feature-settings can be found in Configuration_Feature.h
* Pins-settings can be found in "Configuration_Pins.h"
*/
......@@ -116,16 +115,6 @@
//#define PS_DEFAULT_OFF
/*************************************************************************************/
/***********************************************************************
******************************* Cooler ********************************
***********************************************************************
* *
* Uncomment the following line to enable COOLER support *
* *
***********************************************************************/
//#define COOLER
/***********************************************************************
************************** Extruders number ***************************
......@@ -137,128 +126,4 @@
#define DRIVER_EXTRUDERS 1
/***********************************************************************/
/*****************************************************************************************************
************************************** Thermistor type **********************************************
*****************************************************************************************************
* *
* 4.7kohm PULLUP! *
* This is a normal value, if you use a 1k pullup thermistor see below *
* Please choose the one that matches your setup and set to TEMP_SENSOR_. *
* *
* Temperature sensor settings (4.7kohm PULLUP): *
* -2 is thermocouple with MAX6675 (only for sensor 0) *
* -1 is thermocouple with AD595 or AD597 *
* 0 is not used *
* 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup) *
* 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) *
* 3 is Mendel-parts thermistor (4.7k pullup) *
* 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! *
* 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) *
* 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) *
* 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) *
* 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) *
* 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) *
* 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) *
* 10 is 100k RS thermistor 198-961 (4.7k pullup) *
* 11 is 100k beta 3950 1% thermistor (4.7k pullup) *
* 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) *
* 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" *
* 20 is the PT100 circuit found in the Ultimainboard V2.x *
* 40 is the 10k Carel NTC015WH01 or ELIWELL SN8T6A1502 (4.7k pullup) *
* 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 *
* *
* 1kohm PULLUP! *
* This is not normal, you would have to have changed out your 4.7k for 1k *
* (but gives greater accuracy and more stable PID) *
* Please choose the one that matches your setup. *
* *
* Temperature sensor settings (1kohm PULLUP): *
* 51 is 100k thermistor - EPCOS (1k pullup) *
* 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup) *
* 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) *
* *
* 1047 is Pt1000 with 4k7 pullup *
* 1010 is Pt1000 with 1k pullup (non standard) *
* 147 is Pt100 with 4k7 pullup *
* 110 is Pt100 with 1k pullup (non standard) *
* 998 and 999 are Dummy Tables. ALWAYS read 25°C or DUMMY_THERMISTOR_998_VALUE temperature *
* *
*****************************************************************************************************/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
#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"
#define TEMP_SENSOR_AD595_OFFSET 0.0
#define TEMP_SENSOR_AD595_GAIN 1.0
// Use it for Testing or Development purposes. NEVER for production machine.
#define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_999_VALUE 25
//Show Temperature ADC value
//The M105 command return, besides traditional information, the ADC value read from temperature sensors.
//#define SHOW_TEMP_ADC_VALUES
/*****************************************************************************************************/
/***********************************************************************
************************* Temperature limits ***************************
***********************************************************************/
// Hotend temperature must be close to target for this long before M109 returns success
#define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// Bed temperature must be close to target for this long before M190 returns success
#define TEMP_BED_RESIDENCY_TIME 0 // (seconds)
#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// Cooler temperature must be close to target for this long before M190 returns success
#define TEMP_COOLER_RESIDENCY_TIME 0 // (seconds)
#define TEMP_COOLER_HYSTERESIS 1 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_COOLER_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)
#define HEATER_1_MAXTEMP 275 // (degC)
#define HEATER_2_MAXTEMP 275 // (degC)
#define HEATER_3_MAXTEMP 275 // (degC)
#define BED_MAXTEMP 150 // (degC)
#define COOLER_MAXTEMP 35 //
// 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)
#define HEATER_1_MINTEMP 5 // (degC)
#define HEATER_2_MINTEMP 5 // (degC)
#define HEATER_3_MINTEMP 5 // (degC)
#define BED_MINTEMP 5 // (degC)
#define COOLER_MINTEMP 10 // (degC)
//Preheat Constants
#define PLA_PREHEAT_HOTEND_TEMP 190
#define PLA_PREHEAT_HPB_TEMP 60
#define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
#define ABS_PREHEAT_HOTEND_TEMP 240
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
#define GUM_PREHEAT_HOTEND_TEMP 230
#define GUM_PREHEAT_HPB_TEMP 60
#define GUM_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
/*****************************************************************************************************/
#endif
......@@ -467,4 +467,4 @@
#define DEFAULT_ZWOBBLE 0, 0, 0 // A, W, P
/*****************************************************************************************/
#endif
\ No newline at end of file
#endif
......@@ -4,19 +4,8 @@
/*
* This configuration file contains all features that can be enabled.
*
* TEMPERATURE FEATURES:
* - Automatic temperature
* - Wattage report
* - Parallel heaters
* - Redundant thermistor
* - Temperature status LEDs
* - PID Settings - HOTEND
* - PID Settings - BED
* - Inverted PINS
* - Thermal runaway protection
* - Fan configuration
* - Mediancount (ONLY FOR DUE)
* EXTRUDER FEATURES:
* - Fan configuration
* - Default nominal filament diameter
* - Dangerous extrution prevention
* - Single nozzle
......@@ -51,6 +40,7 @@
* - Filament Runout sensor
* - Power consumption sensor
* - RFID card sensor
* - Flow sensor
* ADDON FEATURES:
* - EEPROM
* - SDCARD
......@@ -83,289 +73,9 @@
*/
//===========================================================================
//=========================== TEMPERATURE FEATURES ==========================
//============================= EXTRUDER FEATURES ===========================
//===========================================================================
/*****************************************************************************************
******************************** Automatic temperature **********************************
*****************************************************************************************
* *
* The hotend target temperature is calculated by all the buffered lines of gcode. *
* The maximum buffered steps/sec of the extruder motor is called "se". *
* Start autotemp mode with M109 S<mintemp> B<maxtemp> F<factor> *
* The target temperature is set to mintemp+factor*se[steps/sec] and is limited by *
* mintemp and maxtemp. Turn this off by excuting M109 without F* *
* Also, if the temperature is set to a value below mintemp, it will not be changed *
* by autotemp. *
* On an Ultimaker, some initial testing worked with M109 S215 B260 F1 *
* in the start.gcode *
* *
*****************************************************************************************/
#define AUTOTEMP
#define AUTOTEMP_OLDWEIGHT 0.98
/*****************************************************************************************/
/***********************************************************************
************************* Wattage report ******************************
***********************************************************************
* *
* If you want the M105 heater power reported in watts, *
* define the BED_WATTS, and (shared for all hotend) HOTEND_WATTS *
* *
***********************************************************************/
//#define HOTEND_WATTS (12.0*12.0/6.7) // P=I^2/R
//#define BED_WATTS (12.0*12.0/1.1) // P=I^2/R
/***********************************************************************/
/***********************************************************************
************************* Parallel heaters ******************************
***********************************************************************
* *
* Control heater 0 and heater 1 in parallel. *
* *
***********************************************************************/
//#define HEATERS_PARALLEL
/***********************************************************************/
/***********************************************************************
********************** Redundant thermistor ***************************
***********************************************************************
* *
* This makes temp sensor 1 a redundant sensor for sensor 0. *
* If the temperatures difference between these sensors is to high *
* the print will be aborted. *
* *
***********************************************************************/
//#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 // (degC)
/***********************************************************************/
/***********************************************************************
********************* Temperature status LEDs *************************
***********************************************************************
* *
* Temperature status LEDs that display the hotend and bed *
* temperature. *
* Otherwise the RED led is on. There is 1C hysteresis. *
* *
***********************************************************************/
//#define TEMP_STAT_LEDS
/***********************************************************************/
/***********************************************************************
********************** PID Settings - HOTEND **************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* *
***********************************************************************/
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define K1 0.95 // Smoothing factor within the PID
#define MAX_OVERSHOOT_PID_AUTOTUNE 20 // Max valor for overshoot autotune
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
//#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result.
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
// If the temperature difference between the target temperature and the actual temperature
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_FUNCTIONAL_RANGE 10 // degC
#define PID_INTEGRAL_DRIVE_MAX PID_MAX // Limit for the integral term
// this adds an experimental additional term to the heating power, proportional to the extrusion speed.
// if Kc is chosen well, the additional required power due to increased melting should be compensated.
//#define PID_ADD_EXTRUSION_RATE
#define LPQ_MAX_LEN 50
// HotEnd{HE0,HE1,HE2,HE3}
#define DEFAULT_Kp {40, 40, 40, 40} // Kp for H0, H1, H2, H3
#define DEFAULT_Ki {07, 07, 07, 07} // Ki for H0, H1, H2, H3
#define DEFAULT_Kd {60, 60, 60, 60} // Kd for H0, H1, H2, H3
#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
// Enable fast PWM for cooler
//#define FAST_PWM_COOLER
//#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 ***************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* Select PID or bang-bang with PIDTEMPBED. *
* If bang-bang, BED_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 PIDTEMPBED
//#define BED_LIMIT_SWITCHING
#define BED_HYSTERESIS 2 //only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS (works only if BED_LIMIT_SWITCHING is enabled)
#define BED_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 PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
#define PID_BED_INTEGRAL_DRIVE_MAX MAX_BED_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_bedKp 10.00
#define DEFAULT_bedKi .023
#define DEFAULT_bedKd 305.4
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
//#define PID_BED_DEBUG // Sends debug data to the serial port.
/***********************************************************************/
/********************************************************************************
************************ Inverted Heater or Bed PINS ***************************
********************************************************************************
* *
* For inverted logical Heater or Bed pins *
* *
********************************************************************************/
//#define INVERTED_HEATER_PINS
//#define INVERTED_BED_PINS
/********************************************************************************
************************ Thermal runaway protection ****************************
********************************************************************************
* *
* 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/cooler on. *
* *
* The solution: Once the temperature reaches the target, start *
* observing. If the temperature stays too far below the *
* target(hysteresis) for too long, the firmware will halt *
* as a safety precaution. *
* *
* 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
#define THERMAL_PROTECTION_PERIOD 40 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius
/**
* Whenever an M104 or M109 increases the target temperature the firmware will wait for the
* WATCH TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get false positives for "Heating failed" increase WATCH TEMP PERIOD and/or decrease WATCH TEMP INCREASE
* WATCH TEMP INCREASE should not be below 2.
*/
#define WATCH_TEMP_PERIOD 20 // Seconds
#define WATCH_TEMP_INCREASE 2 // Degrees Celsius
/**
* Thermal Protection parameters for the bed are just as above for hotends.
*/
//#define THERMAL_PROTECTION_BED
#define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius
//#define THERMAL_PROTECTION_COOLER
#define THERMAL_PROTECTION_COOLER_PERIOD 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
/**
* Whenever an M140 or M190 increases the target temperature the firmware will wait for the
* WATCH BED TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH BED TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get too many "Heating failed" errors, increase WATCH BED TEMP PERIOD and/or decrease
* WATCH BED TEMP INCREASE. (WATCH BED TEMP INCREASE should not be below 2.)
*/
#define WATCH_BED_TEMP_PERIOD 60 // Seconds
#define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius
/********************************************************************************/
/**************************************************************************
**************************** Fan configuration ***************************
**************************************************************************/
......@@ -416,22 +126,6 @@
/**************************************************************************/
/**************************************************************************
**************************** MEDIAN COUNT ********************************
**************************************************************************
* *
* For Smoother temperature *
* ONLY FOR DUE *
**************************************************************************/
#define MEDIAN_COUNT 10
/**************************************************************************/
//===========================================================================
//============================= EXTRUDER FEATURES ===========================
//===========================================================================
/***********************************************************************
******************** DEFAULT NOMINAL FILAMENT DIA *********************
***********************************************************************
......@@ -1068,28 +762,6 @@
/**********************************************************************************/
/**************************************************************************
****************************** Flow sensor *******************************
**************************************************************************
* *
* Flow sensors for water circulators, usefull in case of coolers using *
* water or other liquid as heat vector *
* *
* Uncomment FLOWMETER_SENSOR to enable this feature *
* You also need to set FLOWMETER_PIN in Configurations_pins.h *
* *
**************************************************************************/
//#define FLOWMETER_SENSOR
#define FLOWMETER_MAXFLOW 6.0 // Liters per minute max
#define FLOWMETER_MAXFREQ 55 // frequency of pulses at max flow
// uncomment this to kill print job under the min flow rate, in liters/minute
//#define MINFLOW_PROTECTION 4
/**************************************************************************
*********************** Power consumption sensor *************************
**************************************************************************
......@@ -1174,6 +846,26 @@
/**************************************************************************/
/**************************************************************************
****************************** Flow sensor *******************************
**************************************************************************
* *
* Flow sensors for water circulators, usefull in case of coolers using *
* water or other liquid as heat vector *
* *
* Uncomment FLOWMETER SENSOR to enable this feature *
* You also need to set FLOWMETER PIN in Configurations_pins.h *
* *
**************************************************************************/
//#define FLOWMETER_SENSOR
#define FLOWMETER_MAXFLOW 6.0 // Liters per minute max
#define FLOWMETER_MAXFREQ 55 // frequency of pulses at max flow
// uncomment this to kill print job under the min flow rate, in liters/minute
//#define MINFLOW_PROTECTION 4
/**************************************************************************/
//===========================================================================
//============================= ADDON FEATURES ==============================
......@@ -1214,7 +906,7 @@
// as SD_DETECT_PIN in your board's pins definitions.
// This setting should be disabled unless you are using a push button, pulling the pin to ground.
// Note: This is always disabled for ULTIPANEL (except ELB_FULL_GRAPHIC_CONTROLLER).
#define SD_DETECT_INVERTED
//#define SD_DETECT_INVERTED
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers?
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place.
......@@ -1436,27 +1128,13 @@
**************************************************************************
* *
* Support for laser beam *
* Check also LASER_PWR_PIN and LASER_TTL_PIN in Configuration_pins.h *
* Check also LASER_PWR_PIN and LASER_TTL_PIN in Configuration_pins.h *
* *
**************************************************************************/
//#define LASERBEAM
/**************************************************************************/
/**************************************************************************
******************************* Laser **** *******************************
**************************************************************************
* *
* Support for laser beam *
* Check also Configuration_Laser.h *
* *
**************************************************************************/
//#define LASER
//#define LASERBEAM
/**************************************************************************/
//===========================================================================
//========================= ADVANCED MOTION FEATURES ========================
//===========================================================================
......
......@@ -4,17 +4,14 @@
//===========================================================================
//============================= Laser Settings ==============================
//===========================================================================
//
// Laser control is used by the Muve1 3D printer and the Buildlog.net laser cutter
//
//// The following define selects how to control the laser. Please choose the one that matches your setup.
// The following define selects how to control the laser.
// Please choose the one that matches your setup.
// 1 = Single pin control - LOW when off, HIGH when on, PWM to adjust intensity
// 2 = Two pin control - A firing pin for which LOW = off, HIGH = on, and a seperate intensity pin which carries a constant PWM signal and adjusts duty cycle to control intensity
// mUVe, buildlog.net and K40 chinese machines uses 2, AMRI ablative uses 1, AMRI SLS uses 2
#define LASER_CONTROL 2
#define LASER_CONTROL 1
/// The following define to use the new HakanBasted laser_pulse method to fire laser. It should be more efficient, but it's less tested.
// The following define to use the new HakanBasted laser_pulse method to fire laser. It should be more efficient, but it's less tested.
// Thanks for it to HakanBastedt that has implemented it for Marlin at https://github.com/HakanBastedt/Marlin
// Uncomment to enable it *USE AT YOUR OWN RISK*, it should work but it's *NOT WELL TESTED YET*
//#define LASER_PULSE_METHOD
......@@ -27,50 +24,32 @@
// At least some CO2-drivers need it, not sure about laserdiode drivers.
#define LASER_REMAP_INTENSITY 7
// 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
// #define HIGH_TO_FIRE
//// 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
// 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
#define LASER_FIRE_E 12 // fire the laser when the E axis moves
#define LASER_FIRE_E 12 // fire the laser when the E axis moves
//// Raster mode enables the laser to etch bitmap data at high speeds. Increases command buffer size substantially.
// Raster mode enables the laser to etch bitmap data at high speeds. Increases command buffer size substantially.
#define LASER_RASTER
#define LASER_MAX_RASTER_LINE 68 // maximum number of base64 encoded pixels per raster gcode command
#define LASER_RASTER_ASPECT_RATIO 1 // pixels aren't square on most displays, 1.33 == 4:3 aspect ratio.
#define LASER_RASTER_MM_PER_PULSE 0.2 //Can be overridden by providing an R value in M649 command : M649 S17 B2 D0 R0.1 F4000
#define LASER_MAX_RASTER_LINE 68 // Maximum number of base64 encoded pixels per raster gcode command
#define LASER_RASTER_ASPECT_RATIO 1 // pixels aren't square on most displays, 1.33 == 4:3 aspect ratio.
#define LASER_RASTER_MM_PER_PULSE 0.2 // Can be overridden by providing an R value in M649 command : M649 S17 B2 D0 R0.1 F4000
//// Uncomment the following if the laser cutter is equipped with a peripheral relay board
//// to control power to an exhaust fan, cooler pump, laser power supply, etc.
// Uncomment the following if the laser cutter is equipped with a peripheral relay board
// to control power to an exhaust fan, cooler pump, laser power supply, etc.
//#define LASER_PERIPHERALS
//#define LASER_PERIPHERALS_TIMEOUT 30000 // Number of milliseconds to wait for status signal from peripheral control board
//// Uncomment the following line to enable cubic bezier curve movement with the G5 code
// Uncomment the following line to enable cubic bezier curve movement with the G5 code
// #define G5_BEZIER
// Uncomment these options for the mUVe 1 3D printer
// #define CUSTOM_MENDEL_NAME "mUVe1 Printer"
// #define LASER_WATTS 0.05
// #define LASER_DIAMETER 0.1 // milimeters
// #define LASER_PWM 8000 // hertz
// #define MUVE_Z_PEEL // The mUVe 1 uses a special peel maneuver between each layer, it requires independent control of each Z motor
// Uncomment these options for the Buildlog.net laser cutter, and other similar models
#define CUSTOM_MENDEL_NAME "Laser Cutter"
#define LASER_WATTS 40.0
#define LASER_DIAMETER 0.1 // milimeters
#define LASER_PWM 50000 // hertz
#define LASER_FOCAL_HEIGHT 74.50 // z axis position at which the laser is focused
//Uncomment for AMRI Ablative or SLS
//#define CUSTOM_MENDEL_NAME "Laser Cutter"
//#define LASER_WATTS 40.0
//#define LASER_DIAMETER 0.1 // milimeters
//#define LASER_PWM 25000 // hertz
//#define LASER_FOCAL_HEIGHT 74.50 // z axis position at which the laser is focused
#define LASER_DIAMETER 0.1 // milimeters
#define LASER_PWM 50000 // hertz
#define LASER_FOCAL_HEIGHT 74.50 // z axis position at which the laser is focused
#endif
......@@ -64,18 +64,22 @@
#define Z_MAX_PIN ORIG_Z_MAX_PIN
// HEATER pin
#define HEATER_0_PIN ORIG_HEATER_0_PIN
#define HEATER_1_PIN ORIG_HEATER_1_PIN
#define HEATER_2_PIN ORIG_HEATER_2_PIN
#define HEATER_3_PIN ORIG_HEATER_3_PIN
#define HEATER_BED_PIN ORIG_HEATER_BED_PIN
#define HEATER_0_PIN ORIG_HEATER_0_PIN
#define HEATER_1_PIN ORIG_HEATER_1_PIN
#define HEATER_2_PIN ORIG_HEATER_2_PIN
#define HEATER_3_PIN ORIG_HEATER_3_PIN
#define HEATER_BED_PIN ORIG_HEATER_BED_PIN
#define HEATER_CHAMBER_PIN -1
#define COOLER_PIN -1
// TEMP pin
#define TEMP_0_PIN ORIG_TEMP_0_PIN
#define TEMP_1_PIN ORIG_TEMP_1_PIN
#define TEMP_2_PIN ORIG_TEMP_2_PIN
#define TEMP_3_PIN ORIG_TEMP_3_PIN
#define TEMP_BED_PIN ORIG_TEMP_BED_PIN
#define TEMP_0_PIN ORIG_TEMP_0_PIN
#define TEMP_1_PIN ORIG_TEMP_1_PIN
#define TEMP_2_PIN ORIG_TEMP_2_PIN
#define TEMP_3_PIN ORIG_TEMP_3_PIN
#define TEMP_BED_PIN ORIG_TEMP_BED_PIN
#define TEMP_CHAMBER_PIN -1
#define TEMP_COOLER_PIN -1
// FAN pin
#define FAN_PIN ORIG_FAN_PIN
......@@ -104,37 +108,14 @@
#endif
#if ENABLED(LASERBEAM)
#define LASER_PWR_PIN -1
#define LASER_TTL_PIN -1
#endif
#if ENABLED(LASER)
#if LASER_CONTROL == 1
#define LASER_FIRING_PIN 5
#define LASER_INTENSITY_PIN -1
#endif
#if LASER_CONTROL == 2
#define LASER_INTENSITY_PIN 6 // Digital pins 2, 3, 5, 6, 7, 8 are attached to timers we can use
#define LASER_FIRING_PIN 5
#endif
#if DISABLED(ORIG_TEMP_COOLER_PIN)
#define TEMP_COOLER_PIN ORIG_TEMP_0_PIN // Default to the first thermistor
#endif
#if ENABLED(LASER_POWER_DOWN)
#define LASER_POWER_PIN 9 // This is currently hard-coded to timer2 which services pins 9, 10
#endif // LASER_POWER_DOWN
#if ENABLED(LASER_PERIPHERALS)
#define LASER_PERIPHERALS_PIN 11
#define LASER_PERIPHERALS_STATUS_PIN 4
#endif // LASER_PERIPHERALS
#if ENABLED(COOLER)
#define COOLER_PIN 2 // Digital pins 2, 3, 5, 6, 7, 8 are attached to timers we can use
#endif // COOLER
#define LASER_PWR_PIN -1
#define LASER_TTL_PIN -1
#if ENABLED(LASER_PERIPHERALS)
#define LASER_PERIPHERALS_PIN -1
#define LASER_PERIPHERALS_STATUS_PIN -1
#endif
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define FILRUNOUT_PIN -1
#endif
......
#ifndef CONFIGURATION_TEMPERATURE_H
#define CONFIGURATION_TEMPERATURE_H
/*
* This configuration file contains basic settings.
*
* - Thermistor type
* - Temperature limits
* - Automatic temperature
* - Wattage report
* - Parallel heaters
* - Redundant thermistor
* - Temperature status LEDs
* - PID Settings - HOTEND
* - PID Settings - BED
* - PID Settings - CHAMBER
* - PID Settings - COOLER
* - Inverted PINS
* - Thermal runaway protection
* - Mediancount (ONLY FOR DUE)
*
*/
/*****************************************************************************************************
************************************** Thermistor type **********************************************
*****************************************************************************************************
* *
* 4.7kohm PULLUP! *
* This is a normal value, if you use a 1k pullup thermistor see below *
* Please choose the one that matches your setup and set to TEMP_SENSOR_. *
* *
* Temperature sensor settings (4.7kohm PULLUP): *
* -2 is thermocouple with MAX6675 (only for sensor 0) *
* -1 is thermocouple with AD595 or AD597 *
* 0 is not used *
* 1 is 100k thermistor - best choice for EPCOS 100k (4.7k pullup) *
* 2 is 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup) *
* 3 is Mendel-parts thermistor (4.7k pullup) *
* 4 is 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !! *
* 5 is 100K thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (4.7k pullup) *
* 6 is 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup) *
* 7 is 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup) *
* 71 is 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup) *
* 8 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) *
* 9 is 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup) *
* 10 is 100k RS thermistor 198-961 (4.7k pullup) *
* 11 is 100k beta 3950 1% thermistor (4.7k pullup) *
* 12 is 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed) *
* 13 is 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE" *
* 20 is the PT100 circuit found in the Ultimainboard V2.x *
* 40 is the 10k Carel NTC015WH01 or ELIWELL SN8T6A1502 (4.7k pullup) *
* 60 is 100k Maker's Tool Works Kapton Bed Thermistor beta=3950 *
* *
* 1kohm PULLUP! *
* This is not normal, you would have to have changed out your 4.7k for 1k *
* (but gives greater accuracy and more stable PID) *
* Please choose the one that matches your setup. *
* *
* Temperature sensor settings (1kohm PULLUP): *
* 51 is 100k thermistor - EPCOS (1k pullup) *
* 52 is 200k thermistor - ATC Semitec 204GT-2 (1k pullup) *
* 55 is 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup) *
* *
* 1047 is Pt1000 with 4k7 pullup *
* 1010 is Pt1000 with 1k pullup (non standard) *
* 147 is Pt100 with 4k7 pullup *
* 110 is Pt100 with 1k pullup (non standard) *
* 998 and 999 are Dummy Tables. ALWAYS read 25°C or DUMMY_THERMISTOR_998_VALUE temperature *
* *
*****************************************************************************************************/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
#define TEMP_SENSOR_BED 0
#define TEMP_SENSOR_CHAMBER 0 // NOT USED FOR NOW!!!
#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"
#define TEMP_SENSOR_AD595_OFFSET 0.0
#define TEMP_SENSOR_AD595_GAIN 1.0
// Use it for Testing or Development purposes. NEVER for production machine.
#define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_999_VALUE 25
//Show Temperature ADC value
//The M105 command return, besides traditional information, the ADC value read from temperature sensors.
//#define SHOW_TEMP_ADC_VALUES
/*****************************************************************************************/
/******************************************************************************************************
************************************** Temperature limits ********************************************
******************************************************************************************************/
// Hotend temperature must be close to target for this long before M109 returns success
#define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// Bed temperature must be close to target for this long before M190 returns success
#define TEMP_BED_RESIDENCY_TIME 0 // (seconds)
#define TEMP_BED_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_BED_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// Chamber temperature must be close to target for this long before M190 returns success
#define TEMP_CHAMBER_RESIDENCY_TIME 0 // (seconds)
#define TEMP_CHAMBER_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_CHAMBER_WINDOW 1 // (degC) Window around target to start the residency timer x degC early.
// Cooler temperature must be close to target for this long before M190 returns success
#define TEMP_COOLER_RESIDENCY_TIME 0 // (seconds)
#define TEMP_COOLER_HYSTERESIS 1 // (degC) range of +/- temperatures considered "close" to the target one
#define TEMP_COOLER_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)
#define HEATER_1_MAXTEMP 275 // (degC)
#define HEATER_2_MAXTEMP 275 // (degC)
#define HEATER_3_MAXTEMP 275 // (degC)
#define BED_MAXTEMP 150 // (degC)
#define CHAMBER_MAXTEMP 100 // (degC)
#define COOLER_MAXTEMP 35 // (degC)
// 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)
#define HEATER_1_MINTEMP 5 // (degC)
#define HEATER_2_MINTEMP 5 // (degC)
#define HEATER_3_MINTEMP 5 // (degC)
#define BED_MINTEMP 5 // (degC)
#define CHAMBER_MINTEMP 5 // (degC)
#define COOLER_MINTEMP 10 // (degC)
//Preheat Constants
#define PLA_PREHEAT_HOTEND_TEMP 190
#define PLA_PREHEAT_HPB_TEMP 60
#define PLA_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
#define ABS_PREHEAT_HOTEND_TEMP 240
#define ABS_PREHEAT_HPB_TEMP 100
#define ABS_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
#define GUM_PREHEAT_HOTEND_TEMP 230
#define GUM_PREHEAT_HPB_TEMP 60
#define GUM_PREHEAT_FAN_SPEED 255 // Insert Value between 0 and 255
/*****************************************************************************************/
/*****************************************************************************************
******************************** Automatic temperature **********************************
*****************************************************************************************
* *
* The hotend target temperature is calculated by all the buffered lines of gcode. *
* The maximum buffered steps/sec of the extruder motor is called "se". *
* Start autotemp mode with M109 S<mintemp> B<maxtemp> F<factor> *
* The target temperature is set to mintemp+factor*se[steps/sec] and is limited by *
* mintemp and maxtemp. Turn this off by excuting M109 without F* *
* Also, if the temperature is set to a value below mintemp, it will not be changed *
* by autotemp. *
* On an Ultimaker, some initial testing worked with M109 S215 B260 F1 *
* in the start.gcode *
* *
*****************************************************************************************/
#define AUTOTEMP
#define AUTOTEMP_OLDWEIGHT 0.98
/*****************************************************************************************/
/***********************************************************************
************************* Wattage report ******************************
***********************************************************************
* *
* If you want the M105 heater power reported in watts, *
* define the BED_WATTS, and (shared for all hotend) HOTEND_WATTS *
* *
***********************************************************************/
//#define HOTEND_WATTS (12.0*12.0/6.7) // P=I^2/R
//#define BED_WATTS (12.0*12.0/1.1) // P=I^2/R
/***********************************************************************/
/***********************************************************************
************************* Parallel heaters ******************************
***********************************************************************
* *
* Control heater 0 and heater 1 in parallel. *
* *
***********************************************************************/
//#define HEATERS_PARALLEL
/***********************************************************************/
/***********************************************************************
********************** Redundant thermistor ***************************
***********************************************************************
* *
* This makes temp sensor 1 a redundant sensor for sensor 0. *
* If the temperatures difference between these sensors is to high *
* the print will be aborted. *
* *
***********************************************************************/
//#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 // (degC)
/***********************************************************************/
/***********************************************************************
********************* Temperature status LEDs *************************
***********************************************************************
* *
* Temperature status LEDs that display the hotend and bed *
* temperature. *
* Otherwise the RED led is on. There is 1C hysteresis. *
* *
***********************************************************************/
//#define TEMP_STAT_LEDS
/***********************************************************************/
/***********************************************************************
********************** PID Settings - HOTEND **************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* *
***********************************************************************/
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define K1 0.95 // Smoothing factor within the PID
#define MAX_OVERSHOOT_PID_AUTOTUNE 20 // Max valor for overshoot autotune
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
//#define PID_AUTOTUNE_MENU // Add PID Autotune to the LCD "Temperature" menu to run M303 and apply the result.
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
// If the temperature difference between the target temperature and the actual temperature
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_FUNCTIONAL_RANGE 10 // degC
#define PID_INTEGRAL_DRIVE_MAX PID_MAX // Limit for the integral term
// this adds an experimental additional term to the heating power, proportional to the extrusion speed.
// if Kc is chosen well, the additional required power due to increased melting should be compensated.
//#define PID_ADD_EXTRUSION_RATE
#define LPQ_MAX_LEN 50
// HotEnd{HE0,HE1,HE2,HE3}
#define DEFAULT_Kp {40, 40, 40, 40} // Kp for H0, H1, H2, H3
#define DEFAULT_Ki {07, 07, 07, 07} // Ki for H0, H1, H2, H3
#define DEFAULT_Kd {60, 60, 60, 60} // Kd for H0, H1, H2, H3
#define DEFAULT_Kc {100, 100, 100, 100} // heating power = Kc * (e_speed)
/***********************************************************************/
/***********************************************************************
************************ PID Settings - BED ***************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* Select PID or bang-bang with PIDTEMPBED. *
* If bang-bang, BED_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 PIDTEMPBED
//#define BED_LIMIT_SWITCHING
#define BED_HYSTERESIS 2 //only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS (works only if BED_LIMIT_SWITCHING is enabled)
#define BED_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 PIDTEMPBED)
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
#define PID_BED_INTEGRAL_DRIVE_MAX MAX_BED_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_bedKp 10.00
#define DEFAULT_bedKi 0.1
#define DEFAULT_bedKd 300.0
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
//#define PID_BED_DEBUG // Sends debug data to the serial port.
/***********************************************************************/
/***********************************************************************
************************ PID Settings - CHAMBER ***************************
***********************************************************************
* *
* PID Tuning Guide here: http://reprap.org/wiki/PID_Tuning *
* Select PID or bang-bang with PIDTEMPCHAMBER. *
* If bang-bang, CHAMBER_LIMIT_SWITCHING will enable hysteresis *
* *
***********************************************************************/
// Uncomment this to enable PID on the chamber. 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 chamber PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
//#define PIDTEMPCHAMBER
//#define CHAMBER_LIMIT_SWITCHING
#define CHAMBER_HYSTERESIS 2 //only disable heating if T>target+CHAMBER_HYSTERESIS and enable heating if T>target-CHAMBER_HYSTERESIS (works only if CHAMBER_LIMIT_SWITCHING is enabled)
#define CHAMBER_CHECK_INTERVAL 5000 //ms between checks in bang-bang control
// This sets the max power delivered to the chamber.
// all forms of chamber control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the chamber,
// so you shouldn't use it unless you are OK with PWM on your chamber. (see the comment on enabling PIDTEMPCHAMBER)
#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber; 255=full current
#define PID_CHAMBER_INTEGRAL_DRIVE_MAX MAX_CHAMBER_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_chamberKp 10.00
#define DEFAULT_chamberKi 0.1
#define DEFAULT_chamberKd 300.0
// FIND YOUR OWN: "M303 E-2 C8 S90" to run autotune on the chamber at 90 degreesC for 8 cycles.
//#define PID_CHAMBER_DEBUG // Sends debug data to the serial port.
/***********************************************************************/
/***********************************************************************
************************ 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 cooler PID until someone else verifies your hardware works.
// If this is enabled, find your own PID constants below.
//#define PIDTEMPCOOLER
// Enable fast PWM for cooler
//#define FAST_PWM_COOLER
//#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 cooler.
// all forms of cooler control obey this (PID, bang-bang, bang-bang with hysteresis)
// setting this to anything other than 255 enables a form of PWM to the cooler,
// so you shouldn't use it unless you are OK with PWM on your cooler. (see the comment on enabling PIDTEMPCOOLER)
#define MAX_COOLER_POWER 255 // limits duty cycle to cooler; 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-3 C8 S90" to run autotune on the cooler at 90 degreesC for 8 cycles.
//#define PID_COOLER_DEBUG // Sends debug data to the serial port.
/***********************************************************************/
/********************************************************************************
**************************** Inverted PINS *************************************
********************************************************************************
* *
* For inverted logical Heater, Bed, Chamber or Cooler pins *
* *
********************************************************************************/
//#define INVERTED_HEATER_PINS
//#define INVERTED_BED_PIN
//#define INVERTED_CHAMBER_PIN
//#define INVERTED_COOLER_PIN
/********************************************************************************
************************ Thermal runaway protection ****************************
********************************************************************************
* *
* This protects your printer 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/cooler on. *
* *
* The solution: Once the temperature reaches the target, start *
* observing. If the temperature stays too far below the *
* target(hysteresis) for too long, the firmware will halt *
* as a safety precaution. *
* *
* 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 CHAMBER to enable this feature for the chamber. *
* Uncomment THERMAL PROTECTION COOLER to enable this feature for the cooler. *
* *
********************************************************************************/
//#define THERMAL_PROTECTION_HOTENDS
#define THERMAL_PROTECTION_PERIOD 40 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius
/**
* Whenever an M104 or M109 increases the target temperature the firmware will wait for the
* WATCH TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get false positives for "Heating failed" increase WATCH TEMP PERIOD and/or decrease WATCH TEMP INCREASE
* WATCH TEMP INCREASE should not be below 2.
*/
#define WATCH_TEMP_PERIOD 20 // Seconds
#define WATCH_TEMP_INCREASE 2 // Degrees Celsius
/**
* Thermal Protection parameters for the bed are just as above for hotends.
*/
//#define THERMAL_PROTECTION_BED
#define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius
/**
* Whenever an M140 or M190 increases the target temperature the firmware will wait for the
* WATCH BED TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH BED TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M140/M190,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get too many "Heating failed" errors, increase WATCH BED TEMP PERIOD and/or decrease
* WATCH BED TEMP INCREASE. (WATCH BED TEMP INCREASE should not be below 2.)
*/
#define WATCH_BED_TEMP_PERIOD 60 // Seconds
#define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius
/**
* Thermal Protection parameters for the chamber
*/
//#define THERMAL_PROTECTION_CHAMBER
#define THERMAL_PROTECTION_CHAMBER_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_CHAMBER_HYSTERESIS 2 // Degrees Celsius
/**
* Whenever an M141 or M191 increases the target temperature the firmware will wait for the
* WATCH CHAMBER TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH CHAMBER TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M141/M191,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get too many "Heating failed" errors, increase WATCH CHAMBER TEMP PERIOD and/or decrease
* WATCH CHAMBER TEMP INCREASE. (WATCH CHAMBER TEMP INCREASE should not be below 2.)
*/
#define WATCH_CHAMBER_TEMP_PERIOD 60 // Seconds
#define WATCH_CHAMBER_TEMP_INCREASE 2 // Degrees Celsius
/**
* Thermal Protection parameters for the cooler.
*/
//#define THERMAL_PROTECTION_COOLER
#define THERMAL_PROTECTION_COOLER_PERIOD 30 // Seconds
#define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degree Celsius
/**
* Whenever an M142 or M192 increases the target temperature the firmware will wait for the
* WATCH COOLER TEMP PERIOD to expire, and if the temperature hasn't increased by WATCH COOLER TEMP INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M142/M192,
* but only if the current temperature is far enough below the target for a reliable test.
*
* If you get too many "Heating failed" errors, increase WATCH COOLER TEMP PERIOD and/or decrease
* WATCH COOLER TEMP INCREASE. (WATCH COOLER TEMP INCREASE should not be below 2.)
*/
#define WATCH_TEMP_COOLER_PERIOD 60 // Seconds
#define WATCH_TEMP_COOLER_DECREASE 1 // Degree Celsius
/********************************************************************************/
/**************************************************************************
**************************** MEDIAN COUNT ********************************
**************************************************************************
* *
* For Smoother temperature *
* ONLY FOR DUE *
**************************************************************************/
#define MEDIAN_COUNT 10
/**************************************************************************/
#endif
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* MK & MK4due 3D Printer Firmware
*
* Based on Sprinter and grbl.
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -12,11 +12,11 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
......@@ -24,7 +24,7 @@
#define CONFIGURATION_VERSION_H
#define FIRMWARE_NAME "MK"
#define SHORT_BUILD_VERSION "4.2.82_dev"
#define SHORT_BUILD_VERSION "4.2.83_dev"
#define BUILD_VERSION FIRMWARE_NAME "_" SHORT_BUILD_VERSION
#define STRING_DISTRIBUTION_DATE __DATE__ " " __TIME__ // build date and time
// It might also be appropriate to define a location where additional information can be found
......
......@@ -35,14 +35,14 @@
#include "Configuration_Scara.h"
#endif
#include "Configuration_Temperature.h"
#include "Configuration_Feature.h"
#include "Configuration_Overall.h"
#if ENABLED(LASER)
#if ENABLED(LASERBEAM)
#include "Configuration_Laser.h"
#if ENABLED(LASER_RASTER)
#include "module/base64/Base64.h"
#include "module/laser/base64/base64.h"
#endif
#include "module/laser/laser.h"
#endif
......@@ -65,7 +65,7 @@
#include "module/motion/qr_solve.h"
#include "module/motion/cartesian_correction.h"
#include "module/temperature/temperature.h"
#include "module/flowmeter/flowmeter.h"
#include "module/sensor/flowmeter.h"
#include "module/temperature/thermistortables.h"
#include "module/lcd/ultralcd.h"
#include "module/lcd/buzzer.h"
......
......@@ -117,8 +117,7 @@ inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
extern void delay_ms(millis_t ms);
#if ENABLED(FAST_PWM_FAN) || ENABLED(FAST_PWM_COOLER)
void setPwmFrequency(uint8_t pin, int val);
void setPwmFrequency(uint8_t pin, uint8_t val);
#endif
extern float homing_feedrate[];
......@@ -237,10 +236,6 @@ extern int fanSpeed;
extern bool allow_lengthy_extrude_once; // for load/unload
#endif
#if ENABLED(LASERBEAM)
extern int laser_ttl_modulation;
#endif
// Print job timer
extern PrintCounter print_job_counter;
......@@ -262,12 +257,16 @@ extern uint8_t active_driver;
void print_heaterstates();
#endif
#if HAS(TEMP_CHAMBER)
void print_chamberstate();
#endif
#if HAS(TEMP_COOLER)
void print_coolerstates();
void print_coolerstate();
#endif
#if ENABLED(FLOWMETER_SENSOR)
void print_flowratestates();
void print_flowratestate();
#endif
#if ENABLED(FIRMWARE_TEST)
......
/*
* Copyright (c) 2013 Adam Rudd.
* See LICENSE for more information
*/
#ifndef _BASE64_H
#define _BASE64_H
/* b64_alphabet:
* Description: Base64 alphabet table, a mapping between integers
* and base64 digits
* Notes: This is an extern here but is defined in Base64.c
*/
extern const char b64_alphabet[];
/* base64_encode:
* Description:
* Encode a string of characters as base64
* Parameters:
* output: the output buffer for the encoding, stores the encoded string
* input: the input buffer for the encoding, stores the binary to be encoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the encoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_encode(char *output, char *input, int inputLen);
/* base64_decode:
* Description:
* Decode a base64 encoded string into bytes
* Parameters:
* output: the output buffer for the decoding,
* stores the decoded binary
* input: the input buffer for the decoding,
* stores the base64 string to be decoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the decoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_decode(unsigned char *output, char *input, int inputLen);
/* base64_enc_len:
* Description:
* Returns the length of a base64 encoded string whose decoded
* form is inputLen bytes long
* Parameters:
* inputLen: the length of the decoded string
* Return value:
* The length of a base64 encoded string whose decoded form
* is inputLen bytes long
* Requirements:
* None
*/
int base64_enc_len(int inputLen);
/* base64_dec_len:
* Description:
* Returns the length of the decoded form of a
* base64 encoded string
* Parameters:
* input: the base64 encoded string to be measured
* inputLen: the length of the base64 encoded string
* Return value:
* Returns the length of the decoded form of a
* base64 encoded string
* Requirements:
* 1. input must not be null
* 2. input must be greater than or equal to zero
*/
int base64_dec_len(char *input, int inputLen);
#endif // _BASE64_H
......@@ -605,6 +605,16 @@
#define BED_USES_THERMISTOR
#endif
#if TEMP_SENSOR_CHAMBER == -1
#define CHAMBER_USES_AD595
#elif TEMP_SENSOR_CHAMBER == 0
#undef CHAMBER_MINTEMP
#undef CHAMBER_MAXTEMP
#elif TEMP_SENSOR_CHAMBER > 0
#define THERMISTORCHAMBER TEMP_SENSOR_CHAMBER
#define CHAMBER_USES_THERMISTOR
#endif
#if TEMP_SENSOR_COOLER == -1
#define COOLER_USES_AD595
#elif TEMP_SENSOR_COOLER == 0
......@@ -615,20 +625,21 @@
#define COOLER_USES_THERMISTOR
#endif
#if !ENABLED(COOLER)
#if HASNT(COOLER)
#if ENABLED(PIDTEMPCOOLER)
#undef PIDTEMPCOOLER
#endif
#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_COOLING (ENABLED(PIDTEMPCOOLER))
#define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED))
#define HAS_PID_COOLING (ENABLED(PIDTEMPCOOLER))
/**
* ARRAY_BY_EXTRUDERS based on EXTRUDERS
*/
......@@ -677,13 +688,15 @@
#define HAS_TEMP_2 (PIN_EXISTS(TEMP_2) && TEMP_SENSOR_2 != 0)
#define HAS_TEMP_3 (PIN_EXISTS(TEMP_3) && TEMP_SENSOR_3 != 0)
#define HAS_TEMP_BED (PIN_EXISTS(TEMP_BED) && TEMP_SENSOR_BED != 0)
#define HAS_TEMP_CHAMBER (PIN_EXISTS(TEMP_CHAMBER) && TEMP_SENSOR_CHAMBER != 0)
#define HAS_TEMP_COOLER (PIN_EXISTS(TEMP_COOLER) && TEMP_SENSOR_COOLER != 0)
#define HAS_HEATER_0 (PIN_EXISTS(HEATER_0))
#define HAS_HEATER_1 (PIN_EXISTS(HEATER_1))
#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_DEV (PIN_EXISTS(COOLER))
#define HAS_HEATER_CHAMBER (PIN_EXISTS(HEATER_CHAMBER))
#define HAS_COOLER (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))
......@@ -808,14 +821,21 @@
#define WRITE_HEATER_0(v) WRITE_HEATER_0P(v)
#endif
#if HAS(HEATER_BED)
#if ENABLED(INVERTED_BED_PINS)
#if ENABLED(INVERTED_BED_PIN)
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,!v)
#else
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN,v)
#endif
#endif
#if HAS(COOLER_DEV)
#if ENABLED(INVERTED_COOLER_PINS)
#if HAS(HEATER_CHAMBER)
#if ENABLED(INVERTED_CHAMBER_PIN)
#define WRITE_HEATER_CHAMBER(v) WRITE(HEATER_CHAMBER_PIN,!v)
#else
#define WRITE_HEATER_CHAMBER(v) WRITE(HEATER_CHAMBER_PIN,v)
#endif
#endif
#if HAS(COOLER)
#if ENABLED(INVERTED_COOLER_PIN)
#define WRITE_COOLER(v) WRITE(COOLER_PIN,!v)
#else
#define WRITE_COOLER(v) WRITE(COOLER_PIN,v)
......
......@@ -198,9 +198,10 @@
#define SERIAL_PID_DEBUG_CTERM " cTerm "
#define SERIAL_INVALID_EXTRUDER_NUM " - Invalid extruder number !"
#define SERIAL_HEATER_BED "bed"
#define SERIAL_STOPPED_HEATER ", system stopped! Heater_ID: "
#define SERIAL_STOPPED_COOLER "system stopped! Cooler"
#define SERIAL_STOPPED_BED ", system stopped! Bed"
#define SERIAL_STOPPED_CHAMBER ", system stopped! Chamber"
#define SERIAL_STOPPED_COOLER ", system stopped! Cooler"
#define SERIAL_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !"
#define SERIAL_T_HEATING_FAILED "Heating failed"
#define SERIAL_T_THERMAL_RUNAWAY "Thermal Runaway"
......
#include "Base64.h"
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "base64.h"
const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
......@@ -53,7 +75,6 @@ int base64_decode(unsigned char * output, char * input, int inputLen) {
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--) {
if(*input == '=') {
break;
......
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Copyright (c) 2013 Adam Rudd.
* See LICENSE for more information
*/
#ifndef _BASE64_H
#define _BASE64_H
/* b64_alphabet:
* Description: Base64 alphabet table, a mapping between integers
* and base64 digits
* Notes: This is an extern here but is defined in Base64.c
*/
extern const char b64_alphabet[];
/* base64_encode:
* Description:
* Encode a string of characters as base64
* Parameters:
* output: the output buffer for the encoding, stores the encoded string
* input: the input buffer for the encoding, stores the binary to be encoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the encoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_encode(char *output, char *input, int inputLen);
/* base64_decode:
* Description:
* Decode a base64 encoded string into bytes
* Parameters:
* output: the output buffer for the decoding,
* stores the decoded binary
* input: the input buffer for the decoding,
* stores the base64 string to be decoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the decoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_decode(unsigned char *output, char *input, int inputLen);
/* base64_enc_len:
* Description:
* Returns the length of a base64 encoded string whose decoded
* form is inputLen bytes long
* Parameters:
* inputLen: the length of the decoded string
* Return value:
* The length of a base64 encoded string whose decoded form
* is inputLen bytes long
* Requirements:
* None
*/
int base64_enc_len(int inputLen);
/* base64_dec_len:
* Description:
* Returns the length of the decoded form of a
* base64 encoded string
* Parameters:
* input: the base64 encoded string to be measured
* inputLen: the length of the base64 encoded string
* Return value:
* Returns the length of the decoded form of a
* base64 encoded string
* Requirements:
* 1. input must not be null
* 2. input must be greater than or equal to zero
*/
int base64_dec_len(char *input, int inputLen);
#endif // _BASE64_H
/*
laser.cpp - Laser control library for Arduino using 16 bit timers- Version 1
Copyright (c) 2013 Timothy Schmidt. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* laser.cpp - Laser control library for Arduino using 16 bit timers- Version 1
* Copyright (c) 2013 Timothy Schmidt. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../base.h"
#include <avr/interrupt.h>
#include <Arduino.h>
#if ENABLED(LASER)
#if ENABLED(LASERBEAM)
laser_t laser;
laser_t laser;
#if ENABLED(LASER_PULSE_METHOD)
#define pulsebit(x) (1 << x)
#ifndef PE3 // Undef'd in fastio.h.
#define PE3 3
#endif
#endif
void timer3_init(int pin) {
#if ENABLED(LASER_PULSE_METHOD)
TCCR3A = 0; // clear control register A
TCCR3B = pulsebit(WGM33); // set mode as phase and frequency correct pwm, stop the timer
ICR3 = F_CPU / LASER_PWM / 2; // the counter runs backwards after TOP
TCCR3B &= ~(bit(CS30) | bit(CS31) | bit(CS32)); // Stop timer
TCCR3A |= pulsebit(COM3A1); // Connect pin5 to timer register
DDRE |= pulsebit(PORTE3); // Actually output on pin 5
OCR3A = 0; // Zero duty cycle = OFF
TCCR3B |= pulsebit(CS30); // No prescaler, start timer
// Use timer4 to end laser pulse
/*
Prescaler CS42 CS41 CS40 Range
1 0 0 1 0 - 4.08 msec
8 0 1 0 0 - 32.7 ms <=====
64 0 1 1 0 - 261 ms
256 1 0 0 0 - 1046 ms
1024 1 0 1 0 - 4183 ms
6000 mm/min at 508 dpi = 0.5 ms pulse
300 mm/min at 254 dpi = 20 ms pulse
For the moment a prescaler of 8 is used which
allows up to 32.7 ms pulses with a theoretical
resolution of 0.5 µs.
Waveform generation mode 4: CTC top in OCR4A
============================================
WGN43, WGM42, WGM41, WGM40 = 0, 1, 0, 0
TCCR4A
======
COM4A1, COM4A0 = 0,0 = Normal operation, OC4A disconnected
COM4B1, COM4B0 = 0,0 = Normal operation, OC4B disconnected
COM4C1, COM4C0 = 0,0 = Normal operation, OC4C disconnected
WGM41, WGM40 = 0,0 (See above)
TCCR4B
======
ICN4, IEC4 = 0,0 = Not applicable without input
WGM43, WGM42 = 0,1 (See above)
CS42, CS41, CS40 = 0,1,0 (See above)
CS42, CS41, CS40 = 0,0,0 = Clock stopped
TCCR4C
======
FOC4A, FOC4B, FOS4B = 0,0,0 = Not used
OCR4A
=====
16-bit value when timer overflows = generated interrupt
This is set in laser_pulse()
TIMSK4
======
OCIE4A = 1 = Generate interrupt when timer reach OCR4A
TIFR4
=====
OCF4A: When set, the interrupt will be executed. To clear, write 1 here
When reloading the timer in laser_pulse, an expired interrupt is cleared.
*/
// Prepare laser pulse shutdown timer
TCCR4A = 0;
TCCR4B = pulsebit(WGM42); // CTC
TIMSK4 |= pulsebit(OCIE4A); // Enable interrupt on OCR4A
#else
pinMode(pin, OUTPUT);
analogWrite(pin, 1); // let Arduino setup do it's thing to the PWM pin
TCCR3B = 0x00; // stop Timer4 clock for register updates
TCCR3A = 0x82; // Clear OC3A on match, fast PWM mode, lower WGM3x=14
ICR3 = labs(F_CPU / LASER_PWM); // clock cycles per PWM pulse
OCR3A = labs(F_CPU / LASER_PWM) - 1; // ICR3 - 1 force immediate compare on next tick
TCCR3B = 0x18 | 0x01; // upper WGM4x = 14, clock sel = prescaler, start running
noInterrupts();
TCCR3B &= 0xf8; // stop timer, OC3A may be active now
TCNT3 = labs(F_CPU / LASER_PWM); // force immediate compare on next tick
ICR3 = labs(F_CPU / LASER_PWM); // set new PWM period
TCCR3B |= 0x01; // start the timer with proper prescaler value
interrupts();
#define pulsebit(x) (1 << x)
#ifndef PE3 // Undef'd in fastio.h.
#define PE3 3
#endif
#endif
}
#if ENABLED(LASER_PULSE_METHOD)
ISR(TIMER4_COMPA_vect)
{
OCR3A = 0; // 0 Duty cycle
void timer3_init(int pin) {
#if ENABLED(LASER_PULSE_METHOD)
TCCR3A = 0; // clear control register A
TCCR3B = pulsebit(WGM33); // set mode as phase and frequency correct pwm, stop the timer
ICR3 = F_CPU / LASER_PWM / 2; // the counter runs backwards after TOP
TCCR3B &= ~(bit(CS30) | bit(CS31) | bit(CS32)); // Stop timer
TCCR3A |= pulsebit(COM3A1); // Connect pin5 to timer register
DDRE |= pulsebit(PORTE3); // Actually output on pin 5
OCR3A = 0; // Zero duty cycle = OFF
TCCR3B |= pulsebit(CS30); // No prescaler, start timer
// Use timer4 to end laser pulse
/*
Prescaler CS42 CS41 CS40 Range
1 0 0 1 0 - 4.08 msec
8 0 1 0 0 - 32.7 ms <=====
64 0 1 1 0 - 261 ms
256 1 0 0 0 - 1046 ms
1024 1 0 1 0 - 4183 ms
6000 mm/min at 508 dpi = 0.5 ms pulse
300 mm/min at 254 dpi = 20 ms pulse
For the moment a prescaler of 8 is used which
allows up to 32.7 ms pulses with a theoretical
resolution of 0.5 µs.
Waveform generation mode 4: CTC top in OCR4A
============================================
WGN43, WGM42, WGM41, WGM40 = 0, 1, 0, 0
TCCR4A
======
COM4A1, COM4A0 = 0,0 = Normal operation, OC4A disconnected
COM4B1, COM4B0 = 0,0 = Normal operation, OC4B disconnected
COM4C1, COM4C0 = 0,0 = Normal operation, OC4C disconnected
WGM41, WGM40 = 0,0 (See above)
TCCR4B
======
ICN4, IEC4 = 0,0 = Not applicable without input
WGM43, WGM42 = 0,1 (See above)
CS42, CS41, CS40 = 0,1,0 (See above)
CS42, CS41, CS40 = 0,0,0 = Clock stopped
TCCR4C
======
FOC4A, FOC4B, FOS4B = 0,0,0 = Not used
OCR4A
=====
16-bit value when timer overflows = generated interrupt
This is set in laser_pulse()
TIMSK4
======
OCIE4A = 1 = Generate interrupt when timer reach OCR4A
TIFR4
=====
OCF4A: When set, the interrupt will be executed. To clear, write 1 here
When reloading the timer in laser_pulse, an expired interrupt is cleared.
*/
// Prepare laser pulse shutdown timer
TCCR4A = 0;
TCCR4B = pulsebit(WGM42); // CTC
TIMSK4 |= pulsebit(OCIE4A); // Enable interrupt on OCR4A
#else
pinMode(pin, OUTPUT);
analogWrite(pin, 1); // let Arduino setup do it's thing to the PWM pin
TCCR3B = 0x00; // stop Timer4 clock for register updates
TCCR3A = 0x82; // Clear OC3A on match, fast PWM mode, lower WGM3x=14
ICR3 = labs(F_CPU / LASER_PWM); // clock cycles per PWM pulse
OCR3A = labs(F_CPU / LASER_PWM) - 1; // ICR3 - 1 force immediate compare on next tick
TCCR3B = 0x18 | 0x01; // upper WGM4x = 14, clock sel = prescaler, start running
noInterrupts();
TCCR3B &= 0xf8; // stop timer, OC3A may be active now
TCNT3 = labs(F_CPU / LASER_PWM); // force immediate compare on next tick
ICR3 = labs(F_CPU / LASER_PWM); // set new PWM period
TCCR3B |= 0x01; // start the timer with proper prescaler value
interrupts();
// Stop pulse shutdown timer
TCCR4B &= ~(pulsebit(CS40) | pulsebit(CS41) | pulsebit(CS42)); // Stop timer.
#endif
}
void laser_pulse(uint32_t ulValue, unsigned long usec)
{
OCR3A = ulValue; // Duty cycle of pulse
#if ENABLED(LASER_PULSE_METHOD)
ISR(TIMER4_COMPA_vect) {
OCR3A = 0; // 0 Duty cycle
// Start timer4 to end pulse
OCR4A = 2*usec; // Ticks until IRQ, "2" comes from prescaler
TCNT4 = 0; // Count from 0
TCCR4B |= pulsebit(CS41); // Start timer
TIFR4 = pulsebit(OCF4A); // Clear any pending interrupt
}
#else // LASER_PULSE_METHOD
void timer4_init(int pin) {
pinMode(pin, OUTPUT);
analogWrite(pin, 1); // let Arduino setup do it's thing to the PWM pin
TCCR4B = 0x00; // stop Timer4 clock for register updates
TCCR4A = 0x82; // Clear OC4A on match, fast PWM mode, lower WGM4x=14
ICR4 = labs(F_CPU / LASER_PWM); // clock cycles per PWM pulse
OCR4A = labs(F_CPU / LASER_PWM) - 1; // ICR4 - 1 force immediate compare on next tick
TCCR4B = 0x18 | 0x01; // upper WGM4x = 14, clock sel = prescaler, start running
noInterrupts();
TCCR4B &= 0xf8; // stop timer, OC4A may be active now
TCNT4 = labs(F_CPU / LASER_PWM); // force immediate compare on next tick
ICR4 = labs(F_CPU / LASER_PWM); // set new PWM period
TCCR4B |= 0x01; // start the timer with proper prescaler value
interrupts();
// Stop pulse shutdown timer
TCCR4B &= ~(pulsebit(CS40) | pulsebit(CS41) | pulsebit(CS42)); // Stop timer.
}
void laser_pulse(uint32_t ulValue, unsigned long usec) {
OCR3A = ulValue; // Duty cycle of pulse
// Start timer4 to end pulse
OCR4A = 2*usec; // Ticks until IRQ, "2" comes from prescaler
TCNT4 = 0; // Count from 0
TCCR4B |= pulsebit(CS41); // Start timer
TIFR4 = pulsebit(OCF4A); // Clear any pending interrupt
}
#else // LASER_PULSE_METHOD
void timer4_init(int pin) {
pinMode(pin, OUTPUT);
analogWrite(pin, 1); // let Arduino setup do it's thing to the PWM pin
TCCR4B = 0x00; // stop Timer4 clock for register updates
TCCR4A = 0x82; // Clear OC4A on match, fast PWM mode, lower WGM4x=14
ICR4 = labs(F_CPU / LASER_PWM); // clock cycles per PWM pulse
OCR4A = labs(F_CPU / LASER_PWM) - 1; // ICR4 - 1 force immediate compare on next tick
TCCR4B = 0x18 | 0x01; // upper WGM4x = 14, clock sel = prescaler, start running
noInterrupts();
TCCR4B &= 0xf8; // stop timer, OC4A may be active now
TCNT4 = labs(F_CPU / LASER_PWM); // force immediate compare on next tick
ICR4 = labs(F_CPU / LASER_PWM); // set new PWM period
TCCR4B |= 0x01; // start the timer with proper prescaler value
interrupts();
}
#endif // LASER_PULSE_METHOD
void laser_init() {
#if ENABLED(LASER_PULSE_METHOD)
// Initialize timers for laser intensity control
// ONLY laser_firing on pin 5. Can't use pin 6 for output, used by timer4.
timer3_init(LASER_PWR_PIN);
#else
// Initialize timers for laser intensity control
#if LASER_CONTROL == 1
if (LASER_PWR_PIN == 2 || LASER_PWR_PIN == 3 || LASER_PWR_PIN == 5) timer3_init(LASER_PWR_PIN);
if (LASER_PWR_PIN == 6 || LASER_PWR_PIN == 7 || LASER_PWR_PIN == 8) timer4_init(LASER_PWR_PIN);
#endif
#if LASER_CONTROL == 2
if (LASER_TTL_PIN == 2 || LASER_TTL_PIN == 3 || LASER_TTL_PIN == 5) timer3_init(LASER_TTL_PIN);
if (LASER_TTL_PIN == 6 || LASER_TTL_PIN == 7 || LASER_TTL_PIN == 8) timer4_init(LASER_TTL_PIN);
#endif
#endif // LASER_PULSE_METHOD
#if ENABLED(LASER_PERIPHERALS)
digitalWrite(LASER_PERIPHERALS_PIN, HIGH); // Laser peripherals are active LOW, so preset the pin
pinMode(LASER_PERIPHERALS_PIN, OUTPUT);
digitalWrite(LASER_PERIPHERALS_STATUS_PIN, HIGH); // Set the peripherals status pin to pull-up.
pinMode(LASER_PERIPHERALS_STATUS_PIN, INPUT);
#endif // LASER_PERIPHERALS
digitalWrite(LASER_PWR_PIN, LASER_UNARM); // Laser FIRING is active LOW, so preset the pin
pinMode(LASER_PWR_PIN, OUTPUT);
// initialize state to some sane defaults
laser.intensity = 50.0;
laser.ppm = 0.0;
laser.duration = 0;
laser.status = LASER_OFF;
laser.firing = LASER_OFF;
laser.mode = CONTINUOUS;
laser.last_firing = 0;
laser.diagnostics = false;
laser.time = 0;
#if ENABLED(LASER_RASTER)
laser.raster_aspect_ratio = LASER_RASTER_ASPECT_RATIO;
laser.raster_mm_per_pulse = LASER_RASTER_MM_PER_PULSE;
laser.raster_direction = 1;
#endif // LASER_RASTER
#if !ENABLED(LASER_PULSE_METHOD)
laser_extinguish();
#endif
}
#endif // LASER_PULSE_METHOD
void laser_init()
{
void laser_fire(float intensity = 100.0){
laser.firing = LASER_ON;
laser.last_firing = micros(); // microseconds of last laser firing
if (intensity > 100.0) intensity = 100.0; // restrict intensity between 0 and 100
if (intensity < 0) intensity = 0;
// In the case that the laserdriver need at least a certain level "LASER_REMAP_INTENSITY"
// to give anything, the intensity can be remapped to start at "LASER_REMAP_INTENSITY"
// At least some CO2-drivers need it, not sure about laserdiode drivers.
#if(ENABLED(LASER_REMAP_INTENSITY) && ENABLED(LASER_PULSE_METHOD))
#if LASER_REMAP_INTENSITY != 0
float OldRange, NewRange;
OldRange = (255.0 - 0.0);
NewRange = (intensity - LASER_REMAP_INTENSITY);
intensity = (float)(((((float)intensity - 0) * NewRange) / OldRange) + LASER_REMAP_INTENSITY);
#endif
#endif
#if ENABLED(LASER_PULSE_METHOD)
// Initialize timers for laser intensity control
// ONLY laser_firing on pin 5. Can't use pin 6 for output, used by timer4.
timer3_init(LASER_FIRING_PIN);
#if (!ENABLED(LASER_PULSE_METHOD))
pinMode(LASER_PWR_PIN, OUTPUT);
#endif
#else
// Initialize timers for laser intensity control
#if LASER_CONTROL == 1
if (LASER_FIRING_PIN == 2 || LASER_FIRING_PIN == 3 || LASER_FIRING_PIN == 5) timer3_init(LASER_FIRING_PIN);
if (LASER_FIRING_PIN == 6 || LASER_FIRING_PIN == 7 || LASER_FIRING_PIN == 8) timer4_init(LASER_FIRING_PIN);
#if ENABLED(LASER_PULSE_METHOD)
OCR3A = labs((intensity / 100.0) * (F_CPU / LASER_PWM / 2));
#else
analogWrite(LASER_PWR_PIN, labs((intensity / 100.0) * (F_CPU / LASER_PWM)));
#endif
#endif
#if LASER_CONTROL == 2
if (LASER_INTENSITY_PIN == 2 || LASER_INTENSITY_PIN == 3 || LASER_INTENSITY_PIN == 5) timer3_init(LASER_INTENSITY_PIN);
if (LASER_INTENSITY_PIN == 6 || LASER_INTENSITY_PIN == 7 || LASER_INTENSITY_PIN == 8) timer4_init(LASER_INTENSITY_PIN);
analogWrite(LASER_TTL_PIN, labs((intensity / 100.0) * (F_CPU / LASER_PWM)));
digitalWrite(LASER_PWR_PIN, LASER_ARM);
#endif
#endif // LASER_PULSE_METHOD
#ifdef LASER_PERIPHERALS
digitalWrite(LASER_PERIPHERALS_PIN, HIGH); // Laser peripherals are active LOW, so preset the pin
pinMode(LASER_PERIPHERALS_PIN, OUTPUT);
if (laser.diagnostics)
ECHO_LM(INFO, "Laser fired");
}
void laser_extinguish() {
if (laser.firing == LASER_ON) {
laser.firing = LASER_OFF;
#if ENABLED(LASER_PULSE_METHOD)
OCR3A = 0; // Zero duty cycle = OFF
#else
// Engage the pullup resistor for TTL laser controllers which don't turn off entirely without it.
digitalWrite(LASER_PWR_PIN, LASER_UNARM);
#endif
laser.time += millis() - (laser.last_firing / 1000);
if (laser.diagnostics)
ECHO_LM(INFO, "Laser extinguished");
}
}
digitalWrite(LASER_PERIPHERALS_STATUS_PIN, HIGH); // Set the peripherals status pin to pull-up.
pinMode(LASER_PERIPHERALS_STATUS_PIN, INPUT);
#endif // LASER_PERIPHERALS
void laser_set_mode(int mode) {
switch(mode) {
case 0:
laser.mode = CONTINUOUS;
return;
case 1:
laser.mode = PULSED;
return;
case 2:
laser.mode = RASTER;
return;
}
}
digitalWrite(LASER_FIRING_PIN, LASER_UNARM); // Laser FIRING is active LOW, so preset the pin
pinMode(LASER_FIRING_PIN, OUTPUT);
// initialize state to some sane defaults
laser.intensity = 50.0;
laser.ppm = 0.0;
laser.duration = 0;
laser.status = LASER_OFF;
laser.firing = LASER_OFF;
laser.mode = CONTINUOUS;
laser.last_firing = 0;
laser.diagnostics = false;
laser.time = 0;
#ifdef LASER_RASTER
laser.raster_aspect_ratio = LASER_RASTER_ASPECT_RATIO;
laser.raster_mm_per_pulse = LASER_RASTER_MM_PER_PULSE;
laser.raster_direction = 1;
#endif // LASER_RASTER
#ifdef MUVE_Z_PEEL
laser.peel_distance = 2.0;
laser.peel_speed = 2.0;
laser.peel_pause = 0.0;
#endif // MUVE_Z_PEEL
#if ENABLED(LASER_PERIPHERALS)
bool laser_peripherals_ok() { return !digitalRead(LASER_PERIPHERALS_STATUS_PIN); }
#if !ENABLED(LASER_PULSE_METHOD)
laser_extinguish();
#endif
}
void laser_fire(float intensity = 100.0){
laser.firing = LASER_ON;
laser.last_firing = micros(); // microseconds of last laser firing
if (intensity > 100.0) intensity = 100.0; // restrict intensity between 0 and 100
if (intensity < 0) intensity = 0;
// In the case that the laserdriver need at least a certain level "LASER_REMAP_INTENSITY"
// to give anything, the intensity can be remapped to start at "LASER_REMAP_INTENSITY"
// At least some CO2-drivers need it, not sure about laserdiode drivers.
#if(ENABLED(LASER_REMAP_INTENSITY) && ENABLED(LASER_PULSE_METHOD))
#if LASER_REMAP_INTENSITY != 0
float OldRange, NewRange;
OldRange = (255.0 - 0.0);
NewRange = (intensity - LASER_REMAP_INTENSITY);
intensity = (float)(((((float)intensity - 0) * NewRange) / OldRange) + LASER_REMAP_INTENSITY);
#endif
#endif
void laser_peripherals_on() {
digitalWrite(LASER_PERIPHERALS_PIN, LOW);
if (laser.diagnostics)
ECHO_LM(INFO, "Laser Peripherals Enabled");
}
#if (!ENABLED(LASER_PULSE_METHOD))
pinMode(LASER_FIRING_PIN, OUTPUT);
#endif
void laser_peripherals_off() {
if (!digitalRead(LASER_PERIPHERALS_STATUS_PIN)) {
digitalWrite(LASER_PERIPHERALS_PIN, HIGH);
if (laser.diagnostics)
ECHO_LM(INFO, "Laser Peripherals Disabled");
}
}
#if LASER_CONTROL == 1
#if ENABLED(LASER_PULSE_METHOD)
OCR3A = labs((intensity / 100.0)*(F_CPU / LASER_PWM / 2));
#else
analogWrite(LASER_FIRING_PIN, labs((intensity / 100.0)*(F_CPU / LASER_PWM)));
#endif
#endif
#if LASER_CONTROL == 2
analogWrite(LASER_INTENSITY_PIN, labs((intensity / 100.0)*(F_CPU / LASER_PWM)));
digitalWrite(LASER_FIRING_PIN, LASER_ARM);
#endif
void laser_wait_for_peripherals() {
unsigned long timeout = millis() + LASER_PERIPHERALS_TIMEOUT;
if (laser.diagnostics)
ECHO_LM(INFO, "Waiting for peripheral control board signal...");
if (laser.diagnostics) {
ECHO_LM(INFO, "Laser fired");
}
}
void laser_extinguish(){
if (laser.firing == LASER_ON) {
laser.firing = LASER_OFF;
#if ENABLED(LASER_PULSE_METHOD)
OCR3A = 0; // Zero duty cycle = OFF
#else
// Engage the pullup resistor for TTL laser controllers which don't turn off entirely without it.
digitalWrite(LASER_FIRING_PIN, LASER_UNARM);
#endif
while(!laser_peripherals_ok()) {
if (millis() > timeout) {
if (laser.diagnostics)
ECHO_LM(ER, "Peripheral control board failed to respond");
laser.time += millis() - (laser.last_firing / 1000);
if (laser.diagnostics) {
ECHO_LM(INFO, "Laser extinguished");
}
}
}
void laser_set_mode(int mode){
switch(mode){
case 0:
laser.mode = CONTINUOUS;
return;
case 1:
laser.mode = PULSED;
return;
case 2:
laser.mode = RASTER;
return;
}
}
#ifdef LASER_PERIPHERALS
bool laser_peripherals_ok(){
return !digitalRead(LASER_PERIPHERALS_STATUS_PIN);
}
void laser_peripherals_on(){
digitalWrite(LASER_PERIPHERALS_PIN, LOW);
if (laser.diagnostics) {
ECHO_LM(INFO, "Laser Peripherals Enabled");
}
}
void laser_peripherals_off(){
if (!digitalRead(LASER_PERIPHERALS_STATUS_PIN)) {
digitalWrite(LASER_PERIPHERALS_PIN, HIGH);
if (laser.diagnostics) {
ECHO_LM(INFO, "Laser Peripherals Disabled");
Stop();
break;
}
}
}
}
void laser_wait_for_peripherals() {
unsigned long timeout = millis() + LASER_PERIPHERALS_TIMEOUT;
if (laser.diagnostics) {
ECHO_LM(INFO, "Waiting for peripheral control board signal...");
}
while(!laser_peripherals_ok()) {
if (millis() > timeout) {
if (laser.diagnostics) {
ECHO_LM(ER, "Peripheral control board failed to respond");
}
Stop();
break;
}
}
}
#endif // LASER_PERIPHERALS
#endif // LASER
#endif // LASER_PERIPHERALS
#endif // LASERBEAM
/*
laser.h - Laser cutter control library for Arduino using 16 bit timers- Version 1
Copyright (c) 2013 Timothy Schmidt. All right reserved.
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* laser.cpp - Laser control library for Arduino using 16 bit timers- Version 1
* Copyright (c) 2013 Timothy Schmidt. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LASER_H
#define LASER_H
#define LASER_H
#include <inttypes.h>
#include "../../base.h"
#include <inttypes.h>
// split into planned and status
typedef struct {
int fired; // method used to ask the laser to fire - LASER_FIRE_G1, LASER_FIRE_SPINDLE, LASER_FIRE_E, etc
float intensity; // Laser firing instensity 0.0 - 100.0
float ppm; // pulses per millimeter, for pulsed firing mode
unsigned long duration; // laser firing duration in microseconds, for pulsed firing mode
unsigned long dur; // instantaneous duration
bool status; // LASER_ON / LASER_OFF - buffered
bool firing; // LASER_ON / LASER_OFF - instantaneous
uint8_t mode; // CONTINUOUS, PULSED, RASTER
unsigned long last_firing; // microseconds since last laser firing
bool diagnostics; // Verbose debugging output over serial
unsigned int time; // temporary counter to limit eeprom writes
unsigned int lifetime; // laser lifetime firing counter in minutes
#ifdef LASER_RASTER
unsigned char raster_data[LASER_MAX_RASTER_LINE];
unsigned char rasterlaserpower;
// split into planned and status
typedef struct {
int fired; // method used to ask the laser to fire - LASER_FIRE_G1, LASER_FIRE_SPINDLE, LASER_FIRE_E, etc
float intensity; // Laser firing instensity 0.0 - 100.0
float ppm; // pulses per millimeter, for pulsed firing mode
unsigned long duration; // laser firing duration in microseconds, for pulsed firing mode
unsigned long dur; // instantaneous duration
bool status; // LASER_ON / LASER_OFF - buffered
bool firing; // LASER_ON / LASER_OFF - instantaneous
uint8_t mode; // CONTINUOUS, PULSED, RASTER
unsigned long last_firing; // microseconds since last laser firing
bool diagnostics; // Verbose debugging output over serial
unsigned int time; // temporary counter to limit eeprom writes
unsigned int lifetime; // laser lifetime firing counter in minutes
#if ENABLED(LASER_RASTER)
unsigned char raster_data[LASER_MAX_RASTER_LINE];
unsigned char rasterlaserpower;
float raster_aspect_ratio;
float raster_mm_per_pulse;
int raster_raw_length;
int raster_num_pixels;
bool raster_direction;
#endif // LASER_RASTER
#ifdef MUVE_Z_PEEL
float peel_distance;
float peel_speed;
float peel_pause;
#endif // MUVE_Z_PEEL
} laser_t;
float raster_aspect_ratio;
float raster_mm_per_pulse;
int raster_raw_length;
int raster_num_pixels;
bool raster_direction;
#endif // LASER_RASTER
} laser_t;
extern laser_t laser;
extern laser_t laser;
void laser_init();
void laser_fire(float intensity);
#if ENABLED(LASER_PULSE_METHOD)
void laser_pulse(uint32_t ulValue, unsigned long usec);
#endif
void laser_extinguish();
void laser_update_lifetime();
void laser_set_mode(int mode);
#ifdef LASER_PERIPHERALS
bool laser_peripherals_ok();
void laser_peripherals_on();
void laser_peripherals_off();
void laser_wait_for_peripherals();
#endif // LASER_PERIPHERALS
void laser_init();
void laser_fire(float intensity);
#if ENABLED(LASER_PULSE_METHOD)
void laser_pulse(uint32_t ulValue, unsigned long usec);
#endif
void laser_extinguish();
void laser_update_lifetime();
void laser_set_mode(int mode);
#if ENABLED(LASER_PERIPHERALS)
bool laser_peripherals_ok();
void laser_peripherals_on();
void laser_peripherals_off();
void laser_wait_for_peripherals();
#endif // LASER_PERIPHERALS
#ifdef HIGH_TO_FIRE // Some cutters fire on high, some on low.
#define LASER_ARM HIGH
#define LASER_UNARM LOW
#else
#define LASER_ARM LOW
#define LASER_UNARM HIGH
#endif
#ifdef HIGH_TO_FIRE // Some cutters fire on high, some on low.
#define LASER_ARM HIGH
#define LASER_UNARM LOW
#else
#define LASER_ARM LOW
#define LASER_UNARM HIGH
#endif
// Laser constants
#define LASER_OFF 0
#define LASER_ON 1
// Laser constants
#define LASER_OFF 0
#define LASER_ON 1
#define CONTINUOUS 0
#define PULSED 1
#define RASTER 2
#define CONTINUOUS 0
#define PULSED 1
#define RASTER 2
#endif // LASER_H
/**
* MK & MK4due 3D Printer Firmware
*
* Based on Marlin, Sprinter and grbl
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (C) 2013 - 2016 Alberto Cotronei @MagoKimbra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#define LASERENABLE_HEIGHT 20
#define LASERENABLE_WIDTH 25
......
......@@ -21,61 +21,61 @@
*/
#ifndef MACROS_H
#define MACROS_H
#define MACROS_H
// Compiler warning on unused varable.
#define UNUSED(x) (void) (x)
// Compiler warning on unused varable.
#define UNUSED(x) (void) (x)
// Macros for bit masks
#ifndef _BV
#define _BV(b) (1<<(b))
#endif
#define TEST(n,b) (((n)&_BV(b))!=0)
#define SBI(n,b) (n |= _BV(b))
#define CBI(n,b) (n &= ~_BV(b))
#define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (_BV(b))
// Macros for bit masks
#ifndef _BV
#define _BV(b) (1<<(b))
#endif
#define TEST(n,b) (((n)&_BV(b))!=0)
#define SBI(n,b) (n |= _BV(b))
#define CBI(n,b) (n &= ~_BV(b))
#define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (_BV(b))
// Macros for maths shortcuts
#ifndef M_PI
#define M_PI 3.1415926536
#endif
#define RADIANS(d) ((d)*M_PI/180.0)
#define DEGREES(r) ((r)*180.0/M_PI)
#define SIN_60 0.8660254037844386
#define COS_60 0.5
// Macros for maths shortcuts
#ifndef M_PI
#define M_PI 3.1415926536
#endif
#define RADIANS(d) ((d)*M_PI/180.0)
#define DEGREES(r) ((r)*180.0/M_PI)
#define SIN_60 0.8660254037844386
#define COS_60 0.5
// Macros to support option testing
#define ENABLED defined
#define DISABLED !defined
// Macros to support option testing
#define ENABLED defined
#define DISABLED !defined
#define HAS(FE) (HAS_##FE)
#define HASNT(FE) (!(HAS_##FE))
#define HAS(FE) (HAS_##FE)
#define HASNT(FE) (!(HAS_##FE))
// Macros to contrain values
#define NUMERIC(a) ((a) >= '0' && '9' >= (a))
#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-')
#define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
#define NOMORE(v,n) do{ if (v > n) v = n; }while(0)
#define COUNT(a) (sizeof(a)/sizeof(*a))
// Macros to contrain values
#define NUMERIC(a) ((a) >= '0' && '9' >= (a))
#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-')
#define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
#define NOMORE(v,n) do{ if (v > n) v = n; }while(0)
#define COUNT(a) (sizeof(a)/sizeof(*a))
// Function macro
#define FORCE_INLINE __attribute__((always_inline)) inline
// Function macro
#define FORCE_INLINE __attribute__((always_inline)) inline
// Macro for debugging
#define DEBUGGING(F) (mk_debug_flags & (DEBUG_## F))
// Macro for debugging
#define DEBUGGING(F) (mk_debug_flags & (DEBUG_## F))
// Macro for String
#define STRINGIFY_(n) #n
#define STRINGIFY(n) STRINGIFY_(n)
// Macro for String
#define STRINGIFY_(n) #n
#define STRINGIFY(n) STRINGIFY_(n)
// Macro for varie
#define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
// Macro for varie
#define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
#define NOOP do{}while(0)
#define NOOP do{}while(0)
#define _AXIS(AXIS) AXIS ##_AXIS
#define _AXIS(AXIS) AXIS ##_AXIS
#endif //__MACROS_H
......@@ -21,18 +21,18 @@
*/
#ifndef MECHANICS_H
#define MECHANICS_H
#define MECHANICS_H
// Macros for mechanics type
#define MECH_UNKNOWN -1
#define MECH_CARTESIAN 0
#define MECH_COREXY 1
#define MECH_COREYX 2
#define MECH_COREXZ 8
#define MECH_COREZX 9
#define MECH_DELTA 3
#define MECH_SCARA 4
// Macros for mechanics type
#define MECH_UNKNOWN -1
#define MECH_CARTESIAN 0
#define MECH_COREXY 1
#define MECH_COREYX 2
#define MECH_COREXZ 8
#define MECH_COREZX 9
#define MECH_DELTA 3
#define MECH_SCARA 4
#define MECH(mech) (MECHANISM == MECH_##mech)
#define MECH(mech) (MECHANISM == MECH_##mech)
#endif
\ No newline at end of file
......@@ -12,11 +12,11 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
......@@ -33,11 +33,11 @@
*
* Grbl is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Grbl. If not, see <http://www.gnu.org/licenses/>.
* along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*
*
* The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis.
......@@ -417,9 +417,7 @@ void check_axes_activity() {
unsigned char tail_valve_pressure = ValvePressure,
tail_e_to_p_pressure = EtoPPressure;
#endif
#if ENABLED(LASERBEAM)
unsigned char tail_laser_ttl_modulation = laser_ttl_modulation;
#endif
block_t* block;
if (blocks_queued()) {
......@@ -430,9 +428,6 @@ void check_axes_activity() {
tail_valve_pressure = block->valve_pressure;
tail_e_to_p_pressure = block->e_to_p_pressure;
#endif
#if ENABLED(LASERBEAM)
tail_laser_ttl_modulation = block_buffer[block_index].laser_ttlmodulation;
#endif
while (block_index != block_buffer_head) {
block = &block_buffer[block_index];
......@@ -493,10 +488,6 @@ void check_axes_activity() {
#endif
#endif
// add Laser TTL Modulation(PWM) Control
#if ENABLED(LASERBEAM)
analogWrite(LASER_TTL_PIN, tail_laser_ttl_modulation);
#endif
}
float junction_deviation = 0.1;
......@@ -629,9 +620,9 @@ float junction_deviation = 0.1;
block->steps[E_AXIS] /= 100;
block->step_event_count = max(block->steps[X_AXIS], max(block->steps[Y_AXIS], max(block->steps[Z_AXIS], block->steps[E_AXIS])));
#if DISABLED(LASER)
// Bail if this is a zero-length block
if (block->step_event_count <= DROP_SEGMENTS) return;
#if DISABLED(LASERBEAM)
// Bail if this is a zero-length block
if (block->step_event_count <= DROP_SEGMENTS) return;
#endif
block->fan_speed = fanSpeed;
......@@ -647,11 +638,6 @@ float junction_deviation = 0.1;
block->mix_event_count[i] = block->steps[E_AXIS] * mixing_factor[i];
#endif
// Add update block variables for LASER BEAM control
#if ENABLED(LASERBEAM)
block->laser_ttlmodulation = laser_ttl_modulation;
#endif
// Compute direction bits for this block
uint8_t dirb = 0;
#if MECH(COREXY) || MECH(COREYX)
......@@ -882,52 +868,49 @@ float junction_deviation = 0.1;
);
}
#if ENABLED(LASER)
block->laser_intensity = laser.intensity;
block->laser_duration = laser.duration;
block->laser_status = laser.status;
block->laser_mode = laser.mode;
#if ENABLED(LASERBEAM)
block->laser_intensity = laser.intensity;
block->laser_duration = laser.duration;
block->laser_status = laser.status;
block->laser_mode = laser.mode;
// When operating in PULSED or RASTER modes, laser pulsing must operate in sync with movement.
// Calculate steps between laser firings (steps_l) and consider that when determining largest
// interval between steps for X, Y, Z, E, L to feed to the motion control code.
if (laser.mode == RASTER || laser.mode == PULSED) {
#if ENABLED(LASER_PULSE_METHOD)
// Optimizing. Move calculations here rather than in stepper isr
static const float Factor = F_CPU/(LASER_PWM*2*100.0*255.0);
block->laser_raster_intensity_factor = laser.intensity * Factor;
#endif
block->steps_l = (unsigned long)labs(block->millimeters*laser.ppm);
if (laser.mode == RASTER) {
for (int i = 0; i < LASER_MAX_RASTER_LINE; i++) {
#if (!ENABLED(LASER_PULSE_METHOD))
float OldRange, NewRange, NewValue;
OldRange = (255.0 - 0.0);
NewRange = (laser.rasterlaserpower - LASER_REMAP_INTENSITY);
NewValue = (float)(((((float)laser.raster_data[i] - 0) * NewRange) / OldRange) + LASER_REMAP_INTENSITY);
//If less than 7%, turn off the laser tube.
if(NewValue == LASER_REMAP_INTENSITY)
NewValue = 0;
block->laser_raster_data[i] = NewValue;
#else
block->laser_raster_data[i] = laser.raster_data[i];
#endif
}
}
} else {
block->steps_l = 0;
#if ENABLED(LASER_PULSE_METHOD)
// Optimizing. Move calculations here rather than in stepper isr
static const float Factor = F_CPU/(LASER_PWM*2*100.0*255.0);
block->laser_raster_intensity_factor = laser.intensity * Factor;
#endif
block->steps_l = (unsigned long)labs(block->millimeters*laser.ppm);
if (laser.mode == RASTER) {
for (int i = 0; i < LASER_MAX_RASTER_LINE; i++) {
#if (!ENABLED(LASER_PULSE_METHOD))
float OldRange, NewRange, NewValue;
OldRange = (255.0 - 0.0);
NewRange = (laser.rasterlaserpower - LASER_REMAP_INTENSITY);
NewValue = (float)(((((float)laser.raster_data[i] - 0) * NewRange) / OldRange) + LASER_REMAP_INTENSITY);
//If less than 7%, turn off the laser tube.
if(NewValue == LASER_REMAP_INTENSITY)
NewValue = 0;
block->laser_raster_data[i] = NewValue;
#else
block->laser_raster_data[i] = laser.raster_data[i];
#endif
}
}
}
else
block->steps_l = 0;
block->step_event_count = max(block->steps[X_AXIS], max(block->steps[Y_AXIS], max(block->steps[Z_AXIS], max(block->steps[E_AXIS], block->steps_l))));
if (laser.diagnostics) {
if (block->laser_status == LASER_ON) {
ECHO_LM(INFO, "Laser firing enabled");
}
}
#endif // LASER
if (laser.diagnostics && block->laser_status == LASER_ON)
ECHO_LM(INFO, "Laser firing enabled");
#endif // LASERBEAM
float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides
......
......@@ -98,8 +98,8 @@ typedef struct {
unsigned long valve_pressure;
unsigned long e_to_p_pressure;
#endif
#if ENABLED(LASER)
#if ENABLED(LASERBEAM)
uint8_t laser_mode; // CONTINUOUS, PULSED, RASTER
bool laser_status; // LASER_OFF, LASER_ON
float laser_ppm; // pulses per millimeter, for pulsed and raster firing modes
......@@ -112,10 +112,6 @@ typedef struct {
#endif
#endif
#if ENABLED(LASERBEAM)
unsigned long laser_ttlmodulation;
#endif
volatile char busy;
} block_t;
......
......@@ -68,15 +68,12 @@ block_t* current_block; // A pointer to the block currently being traced
static unsigned char last_direction_bits = 0; // The next stepping-bits to be output
static unsigned int cleaning_buffer_counter = 0;
#ifdef LASER
static long counter_L;
#endif // LASER
#ifdef LASER_RASTER
static int counter_raster;
#endif // LASER_RASTER
#if ENABLED(LASERBEAM)
static long counter_L;
#if ENABLED(LASER_RASTER)
static int counter_raster;
#endif // LASER_RASTER
#endif // LASERBEAM
#if ENABLED(Z_DUAL_ENDSTOPS)
static bool performing_homing = false,
......@@ -124,7 +121,7 @@ static unsigned short OCR1A_nominal;
static bool check_endstops = true;
volatile long count_position[NUM_AXIS] = { 0 }; // Positions of stepper motors, in step units
volatile signed char count_direction[NUM_AXIS] = { 1 };
volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
//===========================================================================
......@@ -307,11 +304,11 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
NOMORE(step_rate, MAX_STEP_FREQUENCY);
if(step_rate > (2 * DOUBLE_STEP_FREQUENCY)) { // If steprate > 2*DOUBLE_STEP_FREQUENCY >> step 4 times
step_rate = (step_rate >> 2);
step_rate >>= 2;
step_loops = 4;
}
else if(step_rate > DOUBLE_STEP_FREQUENCY) { // If steprate > DOUBLE_STEP_FREQUENCY >> step 2 times
step_rate = (step_rate >> 1);
step_rate >>= 1;
step_loops = 2;
}
else {
......@@ -429,10 +426,12 @@ ISR(TIMER1_COMPA_vect) {
return;
}
#if ENABLED(LASER) && (!ENABLED(LASER_PULSE_METHOD))
#if ENABLED(LASERBEAM) && (!ENABLED(LASER_PULSE_METHOD))
if (laser.dur != 0 && (laser.last_firing + laser.dur < micros())) {
if (laser.diagnostics) ECHO_LM(INFO,"Laser firing duration elapsed, in interrupt handler");
laser_extinguish();
if (laser.diagnostics)
ECHO_LM(INFO, "Laser firing duration elapsed, in interrupt handler");
laser_extinguish();
}
#endif
......@@ -446,7 +445,8 @@ ISR(TIMER1_COMPA_vect) {
// Initialize Bresenham counters to 1/2 the ceiling
counter_X = counter_Y = counter_Z = counter_E = -(current_block->step_event_count >> 1);
#if ENABLED(LASER)
#if ENABLED(LASERBEAM)
counter_L = counter_X;
#if !ENABLED(LASER_PULSE_METHOD)
laser.dur = current_block->laser_duration;
......@@ -463,15 +463,12 @@ ISR(TIMER1_COMPA_vect) {
#if ENABLED(Z_LATE_ENABLE)
if (current_block->steps[Z_AXIS] > 0) {
enable_z();
#if ENABLED(MUVE)
enable_e();
#endif
OCR1A = 2000; // 1ms wait
return;
}
#endif
#if ENABLED(LASER_RASTER)
#if ENABLED(LASERBEAM) && ENABLED(LASER_RASTER)
if (current_block->laser_mode == RASTER) counter_raster = 0;
#endif
......@@ -494,15 +491,15 @@ ISR(TIMER1_COMPA_vect) {
#endif
// Continuous firing of the laser during a move happens here, PPM and raster happen further down
#if ENABLED(LASER)
if (current_block->laser_mode == CONTINUOUS && current_block->laser_status == LASER_ON) {
laser_fire(current_block->laser_intensity);
}
#if ENABLED(LASERBEAM)
if (current_block->laser_mode == CONTINUOUS && current_block->laser_status == LASER_ON)
laser_fire(current_block->laser_intensity);
#if !ENABLED(LASER_PULSE_METHOD)
if (current_block->laser_status == LASER_OFF) {
if (laser.diagnostics) ECHO_LM(INFO,"Laser status set to off, in interrupt handler");
laser_extinguish();
}
if (current_block->laser_status == LASER_OFF) {
if (laser.diagnostics) ECHO_LM(INFO,"Laser status set to off, in interrupt handler");
laser_extinguish();
}
#endif
#endif
......@@ -600,14 +597,14 @@ ISR(TIMER1_COMPA_vect) {
#endif
#endif
#if ENABLED(LASER)
#if ENABLED(LASERBEAM)
counter_L += current_block->steps_l;
if (counter_L > 0) {
if (current_block->laser_mode == PULSED && current_block->laser_status == LASER_ON) { // Pulsed Firing Mode
#if ENABLED(LASER_PULSE_METHOD)
uint32_t ulValue = current_block->laser_raster_intensity_factor * 255;
laser_pulse(ulValue, current_block->laser_duration);
laser.time += current_block->laser_duration/1000;
laser.time += current_block->laser_duration / 1000;
#else
laser_fire(current_block->laser_intensity);
#endif
......@@ -652,7 +649,7 @@ ISR(TIMER1_COMPA_vect) {
laser_extinguish();
}
#endif
#endif // LASER
#endif // LASERBEAM
// safe check for erroneous calculated events count
if(current_block->step_event_count >= MAX_EVENTS_COUNT) {
......@@ -767,10 +764,9 @@ ISR(TIMER1_COMPA_vect) {
if (step_events_completed >= current_block->step_event_count) {
current_block = NULL;
plan_discard_current_block();
#if ENABLED(LASER) && ENABLED(LASER_PULSE_METHOD)
if (current_block->laser_mode == CONTINUOUS && current_block->laser_status == LASER_ON) {
#if ENABLED(LASERBEAM) && ENABLED(LASER_PULSE_METHOD)
if (current_block->laser_mode == CONTINUOUS && current_block->laser_status == LASER_ON)
laser_extinguish();
}
#endif
}
}
......
......@@ -352,12 +352,12 @@
#define COOLER_PIN -1
#endif
#ifndef LASER_FIRING_PIN
#define LASER_FIRING_PIN -1
#ifndef LASER_PWR_PIN
#define LASER_PWR_PIN -1
#endif
#ifndef LASER_INTENSITY_PIN
#define LASER_INTENSITY_PIN -1
#ifndef LASER_TTL_PIN
#define LASER_TTL_PIN -1
#endif
#ifndef FLOWMETER_PIN
......@@ -373,7 +373,7 @@
_E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS _E5_PINS \
analogInputToDigitalPin(TEMP_BED_PIN), \
analogInputToDigitalPin(TEMP_COOLER_PIN), \
COOLER_PIN, LASER_FIRING_PIN, LASER_INTENSITY_PIN, \
COOLER_PIN, LASER_PWR_PIN, LASER_TTL_PIN, \
FLOWMETER_PIN \
}
......
......@@ -82,15 +82,18 @@
#if DISABLED(TEMP_SENSOR_BED)
#error DEPENDENCY ERROR: Missing setting TEMP_SENSOR_BED
#endif
#if DISABLED(TEMP_SENSOR_CHAMBER)
#error DEPENDENCY_ERROR: Missing setting TEMP_SENSOR_CHAMBER
#endif
#if DISABLED(TEMP_SENSOR_COOLER)
#error DEPENDENCY_ERROR: Missing setting TEMP_SENSOR_COOLER
#endif
#if (THERMISTORHEATER_0 == 998) || (THERMISTORHEATER_1 == 998) || (THERMISTORHEATER_2 == 998) || (THERMISTORHEATER_3 == 998) || (THERMISTORBED == 998) || (THERMISTORCOOLER == 998) //User EXIST table
#if (THERMISTORHEATER_0 == 998) || (THERMISTORHEATER_1 == 998) || (THERMISTORHEATER_2 == 998) || (THERMISTORHEATER_3 == 998) || (THERMISTORBED == 998) || (THERMISTORCHAMBER == 998) || (THERMISTORCOOLER == 998) // User EXIST table
#if DISABLED(DUMMY_THERMISTOR_998_VALUE)
#define DUMMY_THERMISTOR_998_VALUE 25
#endif
#endif
#if (THERMISTORHEATER_0 == 999) || (THERMISTORHEATER_1 == 999) || (THERMISTORHEATER_2 == 999) || (THERMISTORHEATER_3 == 999) || (THERMISTORBED == 999) || (THERMISTORCOOLER == 999)//User EXIST table
#if (THERMISTORHEATER_0 == 999) || (THERMISTORHEATER_1 == 999) || (THERMISTORHEATER_2 == 999) || (THERMISTORHEATER_3 == 999) || (THERMISTORBED == 999) || (THERMISTORCHAMBER == 999) || (THERMISTORCOOLER == 999)// User EXIST table
#if DISABLED(DUMMY_THERMISTOR_999_VALUE)
#define DUMMY_THERMISTOR_999_VALUE 25
#endif
......@@ -148,6 +151,17 @@
#error DEPENDENCY ERROR: Missing setting BED_MINTEMP
#endif
#endif
#if TEMP_SENSOR_CHAMBER != 0
#if DISABLED(CHAMBER_MAXTEMP)
#error DEPENDENCY ERROR: Missing setting CHAMBER_MAXTEMP
#endif
#if DISABLED(CHAMBER_MINTEMP)
#error DEPENDENCY ERROR: Missing setting CHAMBER_MINTEMP
#endif
#if HASNT(HEATER_CHAMBER)
#error DEPENDENCY ERROR: Cannot enable TEMP_SENSOR_CHAMBER and not HEATER_CHAMBER_PIN
#endif
#endif
#if TEMP_SENSOR_COOLER != 0
#if DISABLED(COOLER_MAXTEMP)
#error DEPENDENCY ERROR: Missing setting COOLER_MAXTEMP
......@@ -155,8 +169,8 @@
#if DISABLED(COOLER_MINTEMP)
#error DEPENDENCY ERROR: Missing setting COOLER_MINTEMP
#endif
#if DISABLED(COOLER)
#error DEPENDENCY ERROR: Cannot enable TEMP_SENSOR_COOLER and not COOLER
#if HASNT(COOLER)
#error DEPENDENCY ERROR: Cannot enable TEMP_SENSOR_COOLER and not COOLER_PIN
#endif
#endif
#if DISABLED(PLA_PREHEAT_HOTEND_TEMP)
......@@ -201,10 +215,13 @@
#if DISABLED(MAX_BED_POWER)
#error DEPENDENCY ERROR: Missing setting MAX_BED_POWER
#endif
#if DISABLED(MAX_CHAMBER_POWER)
#error DEPENDENCY ERROR: Missing setting MAX_CHAMBER_POWER
#endif
#if DISABLED(MAX_COOLER_POWER)
#error DEPENDENCY ERROR: Missing setting MAX_COOLER_POWER
#endif
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCOOLER)
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
#if DISABLED(MAX_OVERSHOOT_PID_AUTOTUNE)
#error DEPENDENCY ERROR: Missing setting MAX_OVERSHOOT_PID_AUTOTUNE
#endif
......@@ -240,6 +257,21 @@
#error DEPENDENCY ERROR: Missing setting DEFAULT_bedKd
#endif
#endif
#if ENABLED(PIDTEMPCHAMBER)
#if DISABLED(PID_CHAMBER_INTEGRAL_DRIVE_MAX)
#error DEPENDENCY ERROR: Missing setting PID_CHAMBER_INTEGRAL_DRIVE_MAX
#endif
#if DISABLED(DEFAULT_chamberKp)
#error DEPENDENCY ERROR: Missing setting DEFAULT_chamberKp
#endif
#if DISABLED(DEFAULT_chamberKi)
#error DEPENDENCY ERROR: Missing setting DEFAULT_chamberKi
#endif
#if DISABLED(DEFAULT_chamberKd)
#error DEPENDENCY ERROR: Missing setting DEFAULT_chamberKd
#endif
#endif
#if ENABLED(PIDTEMPCOOLER)
#if DISABLED(PID_COOLER_INTEGRAL_DRIVE_MAX)
#error DEPENDENCY ERROR: Missing setting PID_COOLER_INTEGRAL_DRIVE_MAX
......@@ -253,7 +285,6 @@
#if DISABLED(DEFAULT_coolerKd)
#error DEPENDENCY ERROR: Missing setting DEFAULT_coolerKd
#endif
#endif
#if ENABLED(BED_LIMIT_SWITCHING)
#if DISABLED(BED_HYSTERESIS)
......@@ -263,6 +294,14 @@
#error DEPENDENCY ERROR: Missing setting BED_CHECK_INTERVAL
#endif
#endif
#if ENABLED(CHAMBER_LIMIT_SWITCHING)
#if DISABLED(CHAMBER_HYSTERESIS)
#error DEPENDENCY ERROR: Missing setting CHAMBER_HYSTERESIS
#endif
#if DISABLED(CHAMBER_CHECK_INTERVAL)
#error DEPENDENCY ERROR: Missing setting CHAMBER_CHECK_INTERVAL
#endif
#endif
#if ENABLED(COOLER_LIMIT_SWITCHING)
#if DISABLED(COOLER_HYSTERESIS)
#error DEPENDENCY ERROR: Missing setting COOLER_HYSTERESIS
......@@ -271,7 +310,6 @@
#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
......@@ -1820,35 +1858,26 @@
#error DEPENDENCY ERROR: You must set EXTRUDERS = 2 for DONDOLO
#endif
#if ENABLED(LASERBEAM) && (!PIN_EXISTS(LASER_PWR) || !PIN_EXISTS(LASER_TTL))
#error DEPENDENCY ERROR: You have to set LASER_PWR_PIN and LASER_TTL_PIN to a valid pin if you enable LASERBEAM
#endif
#if ENABLED(LASERBEAM) && ENABLED(LASER)
#error DEPENDENCY ERROR: You must enable only one of LASERBEAM or LASER, not both!
#endif
#if ENABLED(LASER)
#if ENABLED(LASERBEAM)
#if (!ENABLED(LASER_REMAP_INTENSITY) && ENABLED(LASER_RASTER))
#error DEPENDENCY ERROR: You have to set LASER_REMAP_INTENSITY with LASER_RASTER enabled
#endif
#if (!ENABLED(LASER_CONTROL) || ((LASER_CONTROL > 0) && (LASER_CONTROL < 2)))
#if (!ENABLED(LASER_CONTROL) || ((LASER_CONTROL != 1) && (LASER_CONTROL != 2)))
#error DEPENDENCY ERROR: You have to set LASER_CONTROL to 1 or 2
#else
#if(LASER_CONTROL == 1)
#if( !PIN_EXISTS(LASER_FIRING))
#error DEPENDENCY ERROR: You have to set LASER_FIRING_PIN
#if( !PIN_EXISTS(LASER_PWR))
#error DEPENDENCY ERROR: You have to set LASER_PWR_PIN
#endif
#else
#if( !PIN_EXISTS(LASER_FIRING) || !PIN_EXISTS(LASER_INTENSITY))
#error DEPENDENCY ERROR: You have to set LASER_FIRING_PIN and LASER_INTENSITY_PIN to a valid pin if you enable LASER
#if( !PIN_EXISTS(LASER_PWR) || !PIN_EXISTS(LASER_TTL))
#error DEPENDENCY ERROR: You have to set LASER_PWR_PIN and LASER_TTL_PIN to a valid pin if you enable LASER
#endif
#endif
#endif
#endif
#if DISABLED(LASER_HAS_FOCUS)
#error DEPENDENCY ERROR: Missing LASER_HAS_FOCUS setting
#if DISABLED(LASER_HAS_FOCUS)
#error DEPENDENCY ERROR: Missing LASER_HAS_FOCUS setting
#endif
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR) && !PIN_EXISTS(FILRUNOUT)
......@@ -1895,8 +1924,4 @@
#error DEPENDENCY ERROR: You have to set SLED_PIN to a valid pin if you enable Z_PROBE_SLED
#endif
#if ENABLED(LASERBEAM) && ENABLED(LASER)
#error DEPENDENCY ERROR: You have to select only one of LASER or LASERBEAM
#endif
#endif //SANITYCHECK_H
......@@ -51,7 +51,7 @@
#define K2 (1.0 - K1)
#endif
#if ENABLED(PIDTEMPBED) || ENABLED(PIDTEMP) || ENABLED(PIDTEMPCOOLER)
#if ENABLED(PIDTEMPBED) || ENABLED(PIDTEMP) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
#define PID_dT ((OVERSAMPLENR * 14.0)/(F_CPU / 64.0 / 256.0))
#endif
......@@ -60,11 +60,17 @@
//===========================================================================
int target_temperature[4] = { 0 };
int target_temperature_bed = 0;
int current_temperature_raw[4] = { 0 };
float current_temperature[4] = { 0.0 };
int current_temperature_bed_raw = 0;
int current_temperature_raw[4] = { 0 };
int target_temperature_bed = 0;
float current_temperature_bed = 0.0;
int current_temperature_bed_raw = 0;
int target_temperature_chamber = 0;
int current_temperature_chamber_raw = 0;
float current_temperature_chamber = 0.0;
int target_temperature_cooler = 0;
int current_temperature_cooler_raw = 0;
float current_temperature_cooler = 0.0;
......@@ -78,8 +84,14 @@ float current_temperature_cooler = 0.0;
float bedKp = DEFAULT_bedKp;
float bedKi = ((DEFAULT_bedKi) * (PID_dT));
float bedKd = ((DEFAULT_bedKd) / (PID_dT));
#endif //PIDTEMPBED
#endif
#if ENABLED(PIDTEMPCHAMBER)
float chamberKp = DEFAULT_chamberKp;
float chamberKi = ((DEFAULT_chamberKi) * (PID_dT));
float chamberKd = ((DEFAULT_chamberKd) / (PID_dT));
#endif
#if ENABLED(PIDTEMPCOOLER)
float coolerKp = DEFAULT_coolerKp;
float coolerKi = ((DEFAULT_coolerKi) * (PID_dT));
......@@ -97,14 +109,15 @@ float current_temperature_cooler = 0.0;
#endif
unsigned char soft_pwm_bed;
unsigned char soft_pwm_chamber;
unsigned char soft_pwm_cooler;
#if ENABLED(FAST_PWM_COOLER)
unsigned char fast_pwm_cooler;
unsigned char fast_pwm_cooler;
#endif
void setPwmCooler(unsigned char pwm);
#if ENABLED(BABYSTEPPING)
volatile int babystepsTodo[3] = { 0 };
#endif
......@@ -114,7 +127,7 @@ void setPwmCooler(unsigned char pwm);
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || ENABLED(THERMAL_PROTECTION_COOLER)
enum TRState { TRInactive, TRFirstRunnig, TRStable, TRRunaway };
enum TRState { TRInactive, TRFirstRunning, TRStable, TRRunaway };
void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int temp_controller_id, int period_seconds, int hysteresis_degc);
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
......@@ -172,9 +185,23 @@ static volatile bool temp_meas_ready = false;
static float pid_error_bed;
static float temp_iState_min_bed;
static float temp_iState_max_bed;
#else //PIDTEMPBED
#else // PIDTEMPBED
static millis_t next_bed_check_ms;
#endif //PIDTEMPBED
#endif // !PIDTEMPBED
#if ENABLED(PIDTEMPCHAMBER)
//static cannot be external:
static float temp_iState_chamber = { 0 };
static float temp_dState_chamber = { 0 };
static float pTerm_chamber;
static float iTerm_chamber;
static float dTerm_chamber;
//int output;
static float pid_error_chamber;
static float temp_iState_min_chamber;
static float temp_iState_max_chamber;
#else // PIDTEMPCHAMBER
static millis_t next_chamber_check_ms;
#endif // !PIDTEMPCHAMBER
#if ENABLED(PIDTEMPCOOLER)
//static cannot be external:
static float temp_iState_cooler = { 0 };
......@@ -186,9 +213,9 @@ 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
#else // PIDTEMPCOOLER
static millis_t next_cooler_check_ms;
#endif
#endif // !PIDTEMPCOOLER
static unsigned char soft_pwm[HOTENDS];
......@@ -209,7 +236,6 @@ static unsigned char soft_pwm[HOTENDS];
float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS], Kc[HOTENDS];
#endif //PIDTEMP
// Init min and max temp with extreme values to prevent false errors during startup
static int minttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP);
static int maxttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP);
......@@ -221,6 +247,12 @@ static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383);
#if ENABLED(BED_MAXTEMP)
static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
#endif
#if ENABLED(CHAMBER_MINTEMP)
static int chamber_minttemp_raw = HEATER_CHAMBER_RAW_LO_TEMP;
#endif
#if ENABLED(CHAMBER_MAXTEMP)
static int chamber_maxttemp_raw = HEATER_CHAMBER_RAW_HI_TEMP;
#endif
#if ENABLED(COOLER_MINTEMP)
static int cooler_minttemp_raw = COOLER_RAW_LO_TEMP;
#endif
......@@ -238,6 +270,7 @@ static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS1(16383);
static float analog2temp(int raw, uint8_t e);
static float analog2tempBed(int raw);
static float analog2tempChamber(int raw);
static float analog2tempCooler(int raw);
static void updateTemperaturesFromRawValues();
......@@ -246,16 +279,21 @@ static void updateTemperaturesFromRawValues();
millis_t watch_heater_next_ms[HOTENDS] = { 0 };
#endif
#if ENABLED(THERMAL_PROTECTION_COOLER)
int watch_target_temp_cooler = 0;
millis_t watch_cooler_next_ms = 0;
#endif
#if ENABLED(THERMAL_PROTECTION_BED)
int watch_target_bed_temp = 0;
millis_t watch_bed_next_ms = 0;
#endif
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
int watch_target_temp_chamber = 0;
millis_t watch_chamber_next_ms = 0;
#endif
#if ENABLED(THERMAL_PROTECTION_COOLER)
int watch_target_temp_cooler = 0;
millis_t watch_cooler_next_ms = 0;
#endif
#if DISABLED(SOFT_PWM_SCALE)
#define SOFT_PWM_SCALE 0
#endif
......@@ -272,25 +310,22 @@ static void updateTemperaturesFromRawValues();
//================================ Functions ================================
//===========================================================================
void setPwmCooler(unsigned char pwm) {
soft_pwm_cooler = pwm >> 1;
#if ENABLED(FAST_PWM_COOLER)
fast_pwm_cooler = pwm;
analogWrite(COOLER_PIN, pwm);
#endif
soft_pwm_cooler = pwm >> 1;
#if ENABLED(FAST_PWM_COOLER)
fast_pwm_cooler = pwm;
analogWrite(COOLER_PIN, pwm);
#endif
}
unsigned char getPwmCooler(bool soft=true) {
if(soft)
return soft_pwm_cooler;
#if ENABLED(FAST_PWM_COOLER)
return fast_pwm_cooler;
#else
return soft_pwm_cooler * 2;
#endif
unsigned char getPwmCooler(bool soft = true) {
if(soft)
return soft_pwm_cooler;
#if ENABLED(FAST_PWM_COOLER)
return fast_pwm_cooler;
#else
return soft_pwm_cooler * 2;
#endif
}
void autotempShutdown() {
......@@ -323,11 +358,11 @@ void autotempShutdown() {
if (temp_controller >= HOTENDS
#if HASNT(TEMP_BED) && HASNT(TEMP_COOLER)
|| temp_controller < 0
|| temp_controller < 0
#elif HASNT(TEMP_BED)
|| (temp_controller == -1 && temp_controller < -2)
|| (temp_controller == -1 && temp_controller < -3)
#elif HASNT(TEMP_COOLER)
|| temp_controller < -1
|| temp_controller < -2
#endif
) {
ECHO_LM(ER, SERIAL_PID_BAD_TEMP_CONTROLLER_NUM);
......@@ -338,21 +373,24 @@ void autotempShutdown() {
if (temp_controller == -1) {
ECHO_SM(DB, "BED");
}
else if(temp_controller < -1) {
else if(temp_controller == -2) {
ECHO_SM(DB, "CHAMBER");
}
else if(temp_controller == -3) {
ECHO_SM(DB, "COOLER");
}
else {
ECHO_SMV(DB, "Hotend: ", temp_controller);
ECHO_SMV(DB, "Hotend: ", temp_controller);
}
ECHO_MV(" Temp: ", temp);
ECHO_EMV(" Cycles: ", ncycles);
disable_all_heaters(); // switch off all heaters.
disable_all_coolers(); // switch off all coolers.
disable_all_coolers(); // switch off all coolers.
if (temp_controller == -1)
soft_pwm_bed = bias = d = MAX_BED_POWER / 2;
else if(temp_controller < -1) {
else if (temp_controller == -3) {
bias = d = MAX_COOLER_POWER / 2;
setPwmCooler(MAX_COOLER_POWER);
}
......@@ -367,10 +405,10 @@ void autotempShutdown() {
if (temp_meas_ready) { // temp sample ready
updateTemperaturesFromRawValues();
if(temp_controller == -1)
if (temp_controller == -1)
input = current_temperature_bed;
else if(temp_controller < -1)
input = current_temperature_cooler;
else if (temp_controller == -3)
input = current_temperature_cooler;
else
input = current_temperature[temp_controller];
......@@ -387,18 +425,21 @@ void autotempShutdown() {
if (running && ((input > temp && temp_controller >= -1) || (input < temp && temp_controller < -1))) {
if (ms > t2 + 5000UL) {
running = false;
if (temp_controller < -1)
if (temp_controller == -3)
setPwmCooler((bias - d));
else if (temp_controller < 0)
else if (temp_controller == -1)
soft_pwm_bed = (bias - d) >> 1;
else
soft_pwm[temp_controller] = (bias - d) >> 1;
t1 = ms;
t_high = t1 - t2;
if (temp_controller < -1)
min = temp;
else
max = temp;
if (temp_controller == -3)
min = temp;
else
max = temp;
}
}
......@@ -409,10 +450,12 @@ void autotempShutdown() {
t_low = t2 - t1;
if (cycles > 0) {
long max_pow;
if (temp_controller < -1)
max_pow = MAX_COOLER_POWER;
else
max_pow = temp_controller < 0 ? MAX_BED_POWER : PID_MAX;
if (temp_controller == -3)
max_pow = MAX_COOLER_POWER;
else
max_pow = temp_controller < 0 ? MAX_BED_POWER : PID_MAX;
bias += (d * (t_high - t_low)) / (t_low + t_high);
bias = constrain(bias, 20, max_pow - 20);
d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
......@@ -439,22 +482,27 @@ void autotempShutdown() {
ECHO_E;
}
}
#if ENABLED(PIDTEMP)
if (temp_controller >= 0)
soft_pwm[temp_controller] = (bias + d) >> 1;
if (temp_controller >= 0)
soft_pwm[temp_controller] = (bias + d) >> 1;
#endif
#if ENABLED(PIDTEMPBED)
if (temp_controller == -1)
soft_pwm_bed = (bias + d) >> 1;
#endif
#if ENABLED(PIDTEMPCOOLER)
if (temp_controller < -1)
if (temp_controller == -3)
setPwmCooler((bias + d));
#endif
cycles++;
if(temp_controller < -1)
if(temp_controller == -3)
max = temp;
else
else
min = temp;
}
}
......@@ -462,19 +510,23 @@ void autotempShutdown() {
if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE && temp_controller >= -1) {
ECHO_LM(ER, SERIAL_PID_TEMP_TOO_HIGH);
return;
}
}
else if (input < temp + MAX_OVERSHOOT_PID_AUTOTUNE && temp_controller < -1) {
ECHO_LM(ER, SERIAL_PID_TEMP_TOO_LOW);
return;
}
ECHO_LM(ER, SERIAL_PID_TEMP_TOO_LOW);
return;
}
// Every 2 seconds...
if (ELAPSED(ms, temp_ms + 2000UL)) {
#if HAS(TEMP_0) || HAS(TEMP_BED) || ENABLED(HEATER_0_USES_MAX6675)
print_heaterstates();
ECHO_E;
#endif
#if HAS(TEMP_CHAMBER)
print_chamberstate();
ECHO_E;
#endif
#if HAS(TEMP_COOLER)
print_coolerstates();
print_coolerstate();
ECHO_E;
#endif
......@@ -488,6 +540,7 @@ void autotempShutdown() {
}
if (cycles > ncycles) {
ECHO_LM(DB, SERIAL_PID_AUTOTUNE_FINISHED);
#if ENABLED(PIDTEMP)
if (temp_controller >= 0) {
ECHO_SMV(DB, SERIAL_KP, PID_PARAM(Kp, temp_controller));
......@@ -501,8 +554,9 @@ void autotempShutdown() {
}
}
#endif
#if ENABLED(PIDTEMPBED)
if(temp_controller == -1) {
if (temp_controller == -1) {
ECHO_LMV(DB, "#define DEFAULT_bedKp ", workKp);
ECHO_LMV(DB, "#define DEFAULT_bedKi ", unscalePID_i(workKi));
ECHO_LMV(DB, "#define DEFAULT_bedKd ", unscalePID_d(workKd));
......@@ -514,8 +568,9 @@ void autotempShutdown() {
}
}
#endif
#if ENABLED(PIDTEMPCOOLER)
if(temp_controller < -1) {
if (temp_controller == -3) {
ECHO_LMV(DB, "#define DEFAULT_coolerKp ", workKp);
ECHO_LMV(DB, "#define DEFAULT_coolerKi ", unscalePID_i(workKi));
ECHO_LMV(DB, "#define DEFAULT_coolerKd ", unscalePID_d(workKd));
......@@ -547,119 +602,132 @@ void updatePID() {
#if ENABLED(PIDTEMPBED)
temp_iState_max_bed = PID_BED_INTEGRAL_DRIVE_MAX / bedKi;
#endif
#if ENABLED(PIDTEMPCHAMBER)
temp_iState_max_chamber = PID_CHAMBER_INTEGRAL_DRIVE_MAX / chamberKi;
#endif
#if ENABLED(PIDTEMPCOOLER)
temp_iState_max_cooler = PID_COOLER_INTEGRAL_DRIVE_MAX / coolerKi;
#endif
}
int getHeaterPower(int heater) {
return heater < 0 ? soft_pwm_bed : soft_pwm[heater];
return soft_pwm[heater];
}
int getBedPower() {
return soft_pwm_bed;
}
int getChamberPower() {
return soft_pwm_chamber;
}
int getCoolerPower() {
#if ENABLED(FAST_PWM_COOLER)
return fast_pwm_cooler;
return fast_pwm_cooler;
#else
return soft_pwm_cooler;
return soft_pwm_cooler;
#endif
}
#if HAS(AUTO_FAN)
void setExtruderAutoFanState(int pin, bool state) {
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : EXTRUDER_AUTO_FAN_MIN_SPEED;
// this idiom allows both digital and PWM fan outputs (see M42 handling).
#if ENABLED(FAN_SOFT_PWM)
fanSpeedSoftPwm_auto = newFanSpeed;
#else
digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed);
#endif
}
void setExtruderAutoFanState(int pin, bool state) {
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : EXTRUDER_AUTO_FAN_MIN_SPEED;
// this idiom allows both digital and PWM fan outputs (see M42 handling).
#if ENABLED(FAN_SOFT_PWM)
fanSpeedSoftPwm_auto = newFanSpeed;
#else
digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed);
#endif
}
void checkExtruderAutoFans() {
uint8_t fanState = 0;
void checkExtruderAutoFans() {
uint8_t fanState = 0;
// which fan pins need to be turned on?
#if HAS(AUTO_FAN_0)
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1;
#endif
#if HAS(AUTO_FAN_1)
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
// which fan pins need to be turned on?
#if HAS(AUTO_FAN_0)
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1;
else
fanState |= 2;
}
#endif
#if HAS(AUTO_FAN_2)
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else
fanState |= 4;
}
#endif
#if HAS(AUTO_FAN_3)
if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN)
fanState |= 4;
else
fanState |= 8;
}
#endif
// update extruder auto fan states
#if HAS(AUTO_FAN_0)
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif
#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 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 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)
setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
#endif
}
#endif
#if HAS(AUTO_FAN_1)
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else
fanState |= 2;
}
#endif
#if HAS(AUTO_FAN_2)
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else
fanState |= 4;
}
#endif
#if HAS(AUTO_FAN_3)
if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) {
if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN)
fanState |= 4;
else
fanState |= 8;
}
#endif
// update extruder auto fan states
#if HAS(AUTO_FAN_0)
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif
#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 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 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)
setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
#endif
}
#endif // HAS(AUTO_FAN)
//
// Temperature Error Handlers
//
inline void _temp_error(int tc, const char* serial_msg, const char* lcd_msg) {
inline void _temp_error(int tc, const char* serial_msg, const char* lcd_msg) {
static bool killed = false;
if (IsRunning()) {
ECHO_ST(ER, serial_msg);
if (tc >= 0) {
ECHO_M(SERIAL_STOPPED_HEATER);
ECHO_EV((int)tc);
ECHO_EV((int)tc);
}
else if (tc == -1) {
ECHO_M(SERIAL_STOPPED_HEATER);
ECHO_EM(SERIAL_HEATER_BED);
ECHO_EM(SERIAL_STOPPED_BED);
}
else
ECHO_EM(SERIAL_STOPPED_COOLER);
else if (tc == -2) {
ECHO_EM(SERIAL_STOPPED_CHAMBER);
}
else
ECHO_EM(SERIAL_STOPPED_COOLER);
#if ENABLED(ULTRA_LCD)
lcd_setalertstatuspgm(lcd_msg);
#endif
}
#if DISABLED(BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE)
if (!killed) {
Running = false;
......@@ -667,8 +735,8 @@ inline void _temp_error(int tc, const char* serial_msg, const char* lcd_msg) {
kill(lcd_msg);
}
else {
disable_all_heaters(); // paranoia
disable_all_coolers();
disable_all_heaters(); // paranoia
disable_all_coolers();
}
#endif
}
......@@ -680,7 +748,7 @@ void min_temp_error(uint8_t h) {
_temp_error(h, PSTR(SERIAL_T_MINTEMP), PSTR(MSG_ERR_MINTEMP));
}
float get_pid_output(int h) {
float get_pid_output(int h) {
float pid_output;
#if ENABLED(PIDTEMP)
#if ENABLED(PID_OPENLOOP)
......@@ -805,7 +873,47 @@ float get_pid_output(int h) {
ECHO_MV(" pTerm ", pTerm_bed);
ECHO_MV(" iTerm ", iTerm_bed);
ECHO_EMV(" dTerm ", dTerm_bed);
#endif //PID_BED_DEBUG
#endif // PID_BED_DEBUG
return pid_output;
}
#endif
#if ENABLED(PIDTEMPCHAMBER)
float get_pid_output_chamber() {
float pid_output;
#if ENABLED(PID_OPENLOOP)
pid_output = constrain(target_temperature_chamber, 0, MAX_CHAMBER_POWER);
#else
pid_error_chamber = target_temperature_chamber - current_temperature_chamber;
pTerm_chamber = bedKp * pid_error_chamber;
temp_iState_chamber += pid_error_chamber;
temp_iState_chamber = constrain(temp_iState_chamber, temp_iState_min_chamber, temp_iState_max_chamber);
iTerm_chamber = chamberKi * temp_iState_chamber;
dTerm_chamber = K2 * chamberKd * (current_temperature_chamber - temp_dState_chamber) + K1 * dTerm_chamber;
temp_dState_chamber = current_temperature_chamber;
pid_output = pTerm_chamber + iTerm_chamber - dTerm_chamber;
if (pid_output > MAX_CHAMBER_POWER) {
if (pid_error_chamber > 0) temp_iState_chamber -= pid_error_chamber; // conditional un-integration
pid_output = MAX_CHAMBER_POWER;
}
else if (pid_output < 0) {
if (pid_error_chamber < 0) temp_iState_chamber -= pid_error_chamber; // conditional un-integration
pid_output = 0;
}
#endif // PID_OPENLOOP
#if ENABLED(PID_CHAMBER_DEBUG)
ECHO_SM(DB ," PID_CHAMBER_DEBUG ");
ECHO_MV(": Input ", current_temperature_chamber);
ECHO_MV(" Output ", pid_output);
ECHO_MV(" pTerm ", pTerm_chamber);
ECHO_MV(" iTerm ", iTerm_chamber);
ECHO_EMV(" dTerm ", dTerm_chamber);
#endif // PID_CHAMBER_DEBUG
return pid_output;
}
......@@ -816,12 +924,12 @@ float get_pid_output(int h) {
float pid_output;
// We need this cause 0 is lower than our current temperature probably.
if(target_temperature_cooler < COOLER_MINTEMP)
if (target_temperature_cooler < COOLER_MINTEMP)
return 0.0;
#if ENABLED(PID_OPENLOOP)
pid_output = constrain(target_temperature_cooler, 0, MAX_COOLER_POWER);
#else
#if ENABLED(PID_OPENLOOP)
pid_output = constrain(target_temperature_cooler, 0, MAX_COOLER_POWER);
#else
//pid_error_cooler = target_temperature_cooler - current_temperature_cooler;
pid_error_cooler = current_temperature_cooler - target_temperature_cooler;
pTerm_cooler = coolerKp * pid_error_cooler;
......@@ -842,7 +950,7 @@ float get_pid_output(int h) {
if (pid_error_cooler < 0) temp_iState_cooler -= pid_error_cooler; // conditional un-integration
pid_output = 0;
}
#endif // PID_OPENLOOP
#endif // PID_OPENLOOP
#if ENABLED(PID_COOLER_DEBUG)
ECHO_SM(DB ," PID_COOLER_DEBUG ");
......@@ -859,14 +967,14 @@ float get_pid_output(int h) {
#endif
/**
* Manage heating activities for extruder hot-ends and a heated bed
* Manage heating activities for hotends, bed, chamber and cooler
* - Acquire updated temperature readings
* - Invoke thermal runaway protection
* - Manage extruder auto-fan
* - Apply filament width to the extrusion rate (may move)
* - Update the heated bed PID output value
*/
void manage_temp_controller() {
void manage_temp_controller() {
if (!temp_meas_ready) return;
......@@ -878,7 +986,7 @@ void manage_temp_controller() {
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || ENABLED(THERMAL_PROTECTION_COOLER) || DISABLED(PIDTEMPBED) || DISABLED(PIDTEMPCOOLER) || HAS(AUTO_FAN)
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || ENABLED(THERMAL_PROTECTION_CHAMBER) || ENABLED(THERMAL_PROTECTION_COOLER) || DISABLED(PIDTEMPBED) || DISABLED(PIDTEMPCHAMBER) || DISABLED(PIDTEMPCOOLER) || HAS(AUTO_FAN)
millis_t ms = millis();
#endif
......@@ -958,20 +1066,24 @@ void manage_temp_controller() {
NOLESS(vm, 0.01);
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vm;
}
#endif //FILAMENT_SENSOR
#endif // FILAMENT_SENSOR
#if DISABLED(PIDTEMPBED)
#if HAS(TEMP_BED) && DISABLED(PIDTEMPBED)
if (ms < next_bed_check_ms) return;
next_bed_check_ms = ms + BED_CHECK_INTERVAL;
#endif
#if DISABLED(PIDTEMPCOOLER)
#if HAS(TEMP_CHAMBER) && DISABLED(PIDTEMPCHAMBER)
if (ms < next_chamber_check_ms) return;
next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL;
#endif
#if HAS(TEMP_COOLER) && DISABLED(PIDTEMPCOOLER)
if (ms < next_cooler_check_ms) return;
next_cooler_check_ms = ms + COOLER_CHECK_INTERVAL;
#endif
#if TEMP_SENSOR_BED != 0
#if HAS(TEMP_BED)
#if ENABLED(THERMAL_PROTECTION_BED)
thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
#endif
......@@ -1003,10 +1115,43 @@ void manage_temp_controller() {
WRITE_HEATER_BED(LOW);
}
#endif
#endif // TEMP_SENSOR_BED != 0
#endif // HAS(TEMP_BED)
#if TEMP_SENSOR_COOLER != 0
#if HAS(TEMP_CHAMBER)
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
thermal_runaway_protection(&thermal_runaway_chamber_state_machine, &thermal_runaway_chamber_timer, current_temperature_chamber, target_temperature_chamber, -1, THERMAL_PROTECTION_CHAMBER_PERIOD, THERMAL_PROTECTION_CHAMBER_HYSTERESIS);
#endif
#if ENABLED(PIDTEMPCHAMBER)
float pid_output = get_pid_output_chamber();
soft_pwm_chamber = current_temperature_chamber > CHAMBER_MINTEMP && current_temperature_chamber < CHAMBER_MAXTEMP ? (int)pid_output >> 1 : 0;
#elif ENABLED(CHAMBER_LIMIT_SWITCHING)
// Check if temperature is within the correct band
if (current_temperature_chamber > CHAMBER_MINTEMP && current_temperature_chamber < CHAMBER_MAXTEMP) {
if (current_temperature_chamber >= target_temperature_chamber + CHAMBER_HYSTERESIS)
soft_pwm_chamber = 0;
else if (current_temperature_chamber <= target_temperature_chamber - CHAMBER_HYSTERESIS)
soft_pwm_chamber = MAX_CHAMBER_POWER >> 1;
}
else {
soft_pwm_chamber = 0;
WRITE_HEATER_CHAMBER(LOW);
}
#else // !PIDTEMPCHAMBER && !CHAMBER_LIMIT_SWITCHING
// Check if temperature is within the correct range
if (current_temperature_chamber > CHAMBER_MINTEMP && current_temperature_chamber < CHAMBER_MAXTEMP) {
soft_pwm_chamber = current_temperature_chamber < target_temperature_chamber ? MAX_CHAMBER_POWER >> 1 : 0;
}
else {
soft_pwm_chamber = 0;
WRITE_HEATER_CHAMBER(LOW);
}
#endif
#endif // HAS(TEMP_CHAMBER)
#if HAS(TEMP_COOLER)
#if ENABLED(THERMAL_PROTECTION_COOLER)
thermal_runaway_protection(&thermal_runaway_cooler_state_machine, &thermal_runaway_cooler_timer, current_temperature_cooler, target_temperature_cooler, -2, THERMAL_PROTECTION_COOLER_PERIOD, THERMAL_PROTECTION_COOLER_HYSTERESIS);
#endif
......@@ -1038,8 +1183,7 @@ void manage_temp_controller() {
WRITE_COOLER(LOW);
}
#endif
#endif // TEMP_SENSOR_COOLER != 0
#endif // HAS(TEMP_COOLER)
}
#define PGM_RD_W(x) (short)pgm_read_word(&x)
......@@ -1095,7 +1239,7 @@ static float analog2temp(int raw, uint8_t h) {
// Derived from RepRap FiveD extruder::getTemperature()
// For bed temperature measurement.
static float analog2tempBed(int raw) {
static float analog2tempBed(int raw) {
#if ENABLED(BED_USES_THERMISTOR)
float celsius = 0;
byte i;
......@@ -1117,7 +1261,7 @@ static float analog2tempBed(int raw) {
#elif ENABLED(BED_USES_AD595)
#ifdef __SAM3X8E__
return ((raw * ((3.3 * 100.0) / 1024.0) / OVERSAMPLENR) * ad595_gain[h]) + ad595_offset[h];
return ((raw * ((3.3 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#else
return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#endif
......@@ -1128,6 +1272,37 @@ static float analog2tempBed(int raw) {
#endif
}
static float analog2tempChamber(int raw) {
#if ENABLED(CHAMBER_USES_THERMISTOR)
float celsius = 0;
byte i;
for (i = 1; i < CHAMBERTEMPTABLE_LEN; i++) {
if (PGM_RD_W(CHAMBERTEMPTABLE[i][0]) > raw) {
celsius = PGM_RD_W(CHAMBERTEMPTABLE[i - 1][1]) +
(raw - PGM_RD_W(CHAMBERTEMPTABLE[i - 1][0])) *
(float)(PGM_RD_W(CHAMBERTEMPTABLE[i][1]) - PGM_RD_W(CHAMBERTEMPTABLE[i - 1][1])) /
(float)(PGM_RD_W(CHAMBERTEMPTABLE[i][0]) - PGM_RD_W(CHAMBERTEMPTABLE[i - 1][0]));
break;
}
}
// Overflow: Set to last value in the table
if (i == CHAMBERTEMPTABLE_LEN) celsius = PGM_RD_W(CHAMBERTEMPTABLE[i - 1][1]);
return celsius;
#elif ENABLED(CHAMBER_USES_AD595)
#ifdef __SAM3X8E__
return ((raw * ((3.3 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#else
return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#endif
#else
UNUSED(raw);
return 0;
#endif
}
static float analog2tempCooler(int raw) {
#if ENABLED(COOLER_USES_THERMISTOR)
......@@ -1151,14 +1326,13 @@ static float analog2tempCooler(int raw) {
#elif ENABLED(COOLER_USES_AD595)
#ifdef __SAM3X8E__
return ((raw * ((3.3 * 100.0) / 1024.0) / OVERSAMPLENR) * ad595_gain[h]) + ad595_offset[h];
return ((raw * ((3.3 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#else
return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#endif
#else
UNUSED(raw);
return 0;
#endif
}
......@@ -1170,11 +1344,17 @@ static void updateTemperaturesFromRawValues() {
#if ENABLED(HEATER_0_USES_MAX6675)
current_temperature_raw[0] = read_max6675();
#endif
for (uint8_t h = 0; h < HOTENDS; h++) {
current_temperature[h] = analog2temp(current_temperature_raw[h], h);
}
current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
current_temperature_chamber = analog2tempChamber(current_temperature_chamber_raw);
current_temperature_cooler = analog2tempCooler(current_temperature_cooler_raw);
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
redundant_temperature = analog2temp(redundant_temperature_raw, 1);
#endif
......@@ -1211,7 +1391,6 @@ static void updateTemperaturesFromRawValues() {
#if ENABLED(FILAMENT_SENSOR)
// Convert raw Filament Width to millimeters
float analog2widthFil() {
return current_raw_filwidth / 16383.0 * 5.0;
......@@ -1225,7 +1404,6 @@ static void updateTemperaturesFromRawValues() {
else NOMORE(temp, MEASURED_UPPER_LIMIT);
return filament_width_nominal / temp * 100;
}
#endif
#if HAS(POWER_CONSUMPTION_SENSOR)
......@@ -1239,11 +1417,13 @@ static void updateTemperaturesFromRawValues() {
float rel_raw_power = (current_raw_powconsumption < power_zero_raw) ? (2 * power_zero_raw - current_raw_powconsumption) : (current_raw_powconsumption);
return ((5.0 * rel_raw_power) / (1023.0 * OVERSAMPLENR)) - POWER_ZERO;
}
float analog2current() {
float temp = analog2voltage() / POWER_SENSITIVITY;
temp = (((100 - POWER_ERROR) / 100) * temp) - POWER_OFFSET;
return temp > 0 ? temp : 0;
}
float analog2power() {
return (analog2current() * POWER_VOLTAGE * 100) / POWER_EFFICIENCY;
}
......@@ -1255,6 +1435,7 @@ static void updateTemperaturesFromRawValues() {
if(temp2 <= 0) return 0.0;
return ((temp2/temp1) - 1) * 100;
}
float analog2efficiency(float watt) {
return (analog2current() * POWER_VOLTAGE * 100) / watt;
}
......@@ -1264,7 +1445,7 @@ static void updateTemperaturesFromRawValues() {
* Initialize the temperature manager
* The manager is implemented by periodic calls to manage_temp_controller()
*/
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)||(TEMP_SENSOR_COOLER==-1))
// disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR = _BV(JTD);
......@@ -1279,16 +1460,23 @@ void tp_init() {
temp_iState_min[h] = 0.0;
temp_iState_max[h] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki, h);
#endif //PIDTEMP
#if ENABLED(PIDTEMPBED)
temp_iState_min_bed = 0.0;
temp_iState_max_bed = PID_BED_INTEGRAL_DRIVE_MAX / bedKi;
#endif // PIDTEMPBED
#if ENABLED(PIDTEMPCOOLER)
temp_iState_min_cooler = 0.0;
temp_iState_max_cooler = PID_COOLER_INTEGRAL_DRIVE_MAX / coolerKi;
#endif
}
#if ENABLED(PIDTEMPBED)
temp_iState_min_bed = 0.0;
temp_iState_max_bed = PID_BED_INTEGRAL_DRIVE_MAX / bedKi;
#endif // PIDTEMPBED
#if ENABLED(PIDTEMPCHAMBER)
temp_iState_min_chamber = 0.0;
temp_iState_max_chamber = PID_CHAMBER_INTEGRAL_DRIVE_MAX / chamberKi;
#endif
#if ENABLED(PIDTEMPCOOLER)
temp_iState_min_cooler = 0.0;
temp_iState_max_cooler = PID_COOLER_INTEGRAL_DRIVE_MAX / coolerKi;
#endif
#if ENABLED(PID_ADD_EXTRUSION_RATE)
for (int e = 0; e < EXTRUDERS; e++) last_position[e] = 0;
#endif
......@@ -1308,7 +1496,10 @@ void tp_init() {
#if HAS(HEATER_BED)
SET_OUTPUT(HEATER_BED_PIN);
#endif
#if HAS(COOLER_DEV)
#if HAS(HEATER_CHAMBER)
SET_OUTPUT(HEATER_CHAMBER_PIN);
#endif
#if HAS(COOLER)
SET_OUTPUT(COOLER_PIN);
#if ENABLED(FAST_PWM_COOLER)
setPwmFrequency(COOLER_PIN, 2); // No prescaling. Pwm frequency = F_CPU/256/64
......@@ -1363,6 +1554,9 @@ void tp_init() {
#if HAS(TEMP_BED)
ANALOG_SELECT(TEMP_BED_PIN);
#endif
#if HAS(TEMP_CHAMBER)
ANALOG_SELECT(TEMP_CHAMBER_PIN);
#endif
#if HAS(TEMP_COOLER)
ANALOG_SELECT(TEMP_COOLER_PIN);
#endif
......@@ -1489,6 +1683,26 @@ void tp_init() {
#endif
}
#endif // BED_MAXTEMP
#if ENABLED(CHAMBER_MINTEMP)
while(analog2tempChamber(chamber_minttemp_raw) < CHAMBER_MINTEMP) {
#if CHAMBER_RAW_LO_TEMP < HEATER_CHAMBER_RAW_HI_TEMP
chamber_minttemp_raw += OVERSAMPLENR;
#else
chamber_minttemp_raw -= OVERSAMPLENR;
#endif
}
#endif // CHAMBER_MINTEMP
#if ENABLED(CHAMBER_MAXTEMP)
while(analog2tempCooler(chamber_maxttemp_raw) > CHAMBER_MAXTEMP) {
#if CHAMBER_RAW_LO_TEMP < CHAMBER_RAW_HI_TEMP
chamber_maxttemp_raw -= OVERSAMPLENR;
#else
chamber_maxttemp_raw += OVERSAMPLENR;
#endif
}
#endif // BED_MAXTEMP
#if ENABLED(COOLER_MINTEMP)
while(analog2tempCooler(cooler_minttemp_raw) < COOLER_MINTEMP) {
#if COOLER_RAW_LO_TEMP < HEATER_COOLER_RAW_HI_TEMP
......@@ -1497,7 +1711,7 @@ void tp_init() {
cooler_minttemp_raw -= OVERSAMPLENR;
#endif
}
#endif //COOLER_MINTEMP
#endif // COOLER_MINTEMP
#if ENABLED(COOLER_MAXTEMP)
while(analog2tempCooler(cooler_maxttemp_raw) > COOLER_MAXTEMP) {
#if COOLER_RAW_LO_TEMP < COOLER_RAW_HI_TEMP
......@@ -1506,11 +1720,10 @@ void tp_init() {
cooler_maxttemp_raw += OVERSAMPLENR;
#endif
}
#endif // BED_MAXTEMP
#endif // COOLER_MAXTEMP
}
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
/**
* Start Heating Sanity Check for hotends that are below
* their target temperature by a configurable margin.
......@@ -1526,22 +1739,6 @@ void tp_init() {
}
#endif
#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() {
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
watch_cooler_next_ms = 0;
}
#endif
#if ENABLED(THERMAL_PROTECTION_BED)
/**
* Start Heating Sanity Check for bed that are below
......@@ -1558,12 +1755,42 @@ void tp_init() {
}
#endif
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
/**
* Start Cooling Sanity Check for chamber that are below
* their target temperature by a configurable margin.
* This is called when the temperature is set. (M141)
*/
void start_watching_chamber() {
if (degCooler() > degTargetCooler() - (WATCH_TEMP_CHAMBER_DECREASE - TEMP_CHAMBER_HYSTERESIS - 1)) {
watch_target_temp_chamber = degChamber() - WATCH_CHAMBER_TEMP_DECREASE;
watch_chamber_next_ms = millis() + WATCH_TEMP_CHAMBER_PERIOD * 1000UL;
}
else
watch_chamber_next_ms = 0;
}
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || ENABLED(THERMAL_PROTECTION_COOLER)
#if ENABLED(THERMAL_PROTECTION_COOLER)
/**
* Start Cooling Sanity Check for hotends that are below
* their target temperature by a configurable margin.
* This is called when the temperature is set. (M142)
*/
void start_watching_cooler() {
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
watch_cooler_next_ms = 0;
}
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || ENABLED(THERMAL_PROTECTION_CHAMBER) || ENABLED(THERMAL_PROTECTION_COOLER)
void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int temp_controller_id, int period_seconds, int hysteresis_degc) {
static float tr_target_temperature[HOTENDS + 2] = { 0.0 };
static float tr_target_temperature[HOTENDS + 3] = { 0.0 };
/*
ECHO_SM(DB, "Thermal Thermal Runaway Running. Heater ID: ");
......@@ -1575,53 +1802,57 @@ void tp_init() {
*/
int temp_controller_index;
if(temp_controller_id >= 0)
temp_controller_index = temp_controller_id;
else if(temp_controller_id == -1)
if(temp_controller_id >= 0)
temp_controller_index = temp_controller_id;
else if(temp_controller_id == -1)
temp_controller_index = HOTENDS; // BED
else:
temp_controller_index = HOTENDS + 1; // COOLER
else if(temp_controller_id == -2)
temp_controller_index = HOTENDS + 1; // CHAMBER
else
temp_controller_index = HOTENDS + 2; // COOLER
// If the target temperature changes, restart
if (tr_target_temperature[temp_controller_index] != target_temperature)
tr_target_temperature[temp_controller_index] = target_temperature;
*state = target_temperature > 0 ? TRFirstRunning : TRInactive;
*state = target_temperature > 0 ? TRFirstRunning : TRInactive;
switch (*state) {
// Inactive state waits for a target temperature to be set
case TRInactive: break;
// When first heating/cooling, wait for the temperature to be reached then go to Stable state
case TRFirstRunning:
if (temperature < tr_target_temperature[temp_controller_index] && temp_controller_index > HEATERS) break;
else if((temperature > tr_target_temperature[temp_controller_index] && temp_controller_index <= HEATERS) break;
if (temperature < tr_target_temperature[temp_controller_index] && temp_controller_index > HOTENDS) break;
else if ((temperature > tr_target_temperature[temp_controller_index] && temp_controller_index <= HOTENDS)) break;
*state = TRStable;
// While the temperature is stable watch for a bad temperature
case TRStable:
if(temp_controller_index <= HEATERS) { // HEATERS
if (temperature < tr_target_temperature[temp_controller_index] - hysteresis_degc && ELAPSED(millis(), *timer))
if (temp_controller_index <= HOTENDS) { // HOTENDS
if (temperature < tr_target_temperature[temp_controller_index] - hysteresis_degc && ELAPSED(millis(), *timer))
*state = TRRunaway;
else {
*timer = millis() + period_seconds * 1000UL;
break;
}
}
else { // COOLERS
if (temperature > tr_target_temperature[temp_controller_index] + hysteresis_degc && ELAPSED(millis(), *timer)))
*state = TRRunaway;
if (temperature > tr_target_temperature[temp_controller_index] + hysteresis_degc && ELAPSED(millis(), *timer))
*state = TRRunaway;
else {
*timer = millis() + period_seconds * 1000UL;
break;
}
}
case TRRunaway:
_temp_error(temp_controller_id, PSTR(SERIAL_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
}
}
#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED || THERMAL_PROTECTION_CHAMBER || THERMAL_PROTECTION_COOLER
#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
void disable_all_heaters() {
void disable_all_heaters() {
for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i);
setTargetBed(0);
setTargetChamber(0);
// If all heaters go down then for sure our print job has stopped
print_job_counter.stop();
......@@ -1657,26 +1888,34 @@ void disable_all_heaters() {
WRITE_HEATER_BED(LOW);
#endif
#endif
#if HAS(TEMP_CHAMBER)
target_temperature_chamber = 0;
soft_pwm_chamber = 0;
#if HAS(HEATER_CHAMBER)
WRITE_HEATER_CHAMBER(LOW);
#endif
#endif
}
void disable_all_coolers() {
setTargetCooler(0);
setTargetCooler(0);
// if cooler go down the print job is stopped
print_job_counter.stop();
// if cooler go down the print job is stopped
print_job_counter.stop();
#if ENABLED(LASER)
// No laser firing with no coolers running! (paranoia)
laser_extinguish();
#endif
#if ENABLED(LASER)
// No laser firing with no coolers running! (paranoia)
laser_extinguish();
#endif
#if HAS(TEMP_COOLER)
target_temperature_cooler = 0;
setPwmCooler(0);
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
WRITE_COOLER(LOW);
#endif
#endif
#if HAS(TEMP_COOLER)
target_temperature_cooler = 0;
setPwmCooler(0);
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
WRITE_COOLER(LOW);
#endif
#endif
}
#if ENABLED(HEATER_0_USES_MAX6675)
......@@ -1741,11 +1980,13 @@ void disable_all_coolers() {
/**
* Stages in the ISR loop
*/
enum TempState {
enum TempState {
PrepareTemp_0,
MeasureTemp_0,
PrepareTemp_BED,
MeasureTemp_BED,
PrepareTemp_CHAMBER,
MeasureTemp_CHAMBER,
PrepareTemp_COOLER,
MeasureTemp_COOLER,
PrepareTemp_1,
......@@ -1763,9 +2004,9 @@ enum TempState {
static unsigned long raw_temp_value[4] = { 0 };
static unsigned long raw_temp_bed_value = 0;
static unsigned long raw_temp_chamber_value = 0;
static unsigned long raw_temp_cooler_value = 0;
static void set_current_temp_raw() {
#if HAS(TEMP_0) && DISABLED(HEATER_0_USES_MAX6675)
current_temperature_raw[0] = raw_temp_value[0];
......@@ -1784,6 +2025,7 @@ static void set_current_temp_raw() {
#endif
#endif
current_temperature_bed_raw = raw_temp_bed_value;
current_temperature_chamber_raw = raw_temp_chamber_value;
current_temperature_cooler_raw = raw_temp_cooler_value;
#if HAS(POWER_CONSUMPTION_SENSOR)
......@@ -1799,7 +2041,7 @@ static void set_current_temp_raw() {
* - Check new temperature values for MIN/MAX errors
* - Step the babysteps value for each axis towards 0
*/
ISR(TIMER0_COMPB_vect) {
ISR(TIMER0_COMPB_vect) {
static unsigned char temp_count = 0;
static TempState temp_state = StartupDelay;
......@@ -1830,8 +2072,11 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
ISR_STATICS(BED);
#endif
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
ISR_STATICS(COOLER_DEV);
#if HAS(HEATER_CHAMBER)
ISR_STATICS(CHAMBER);
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
ISR_STATICS(COOLER);
#endif
#if HAS(FILAMENT_SENSOR)
......@@ -1866,10 +2111,17 @@ ISR(TIMER0_COMPB_vect) {
soft_pwm_BED = soft_pwm_bed;
WRITE_HEATER_BED(soft_pwm_BED > 0 ? 1 : 0);
#endif
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
soft_pwm_COOLER_DEV = soft_pwm_cooler;
WRITE_COOLER(soft_pwm_COOLER_DEV > 0 ? 1 : 0);
#if HAS(HEATER_CHAMBER)
soft_pwm_CHAMBER = soft_pwm_chamber;
WRITE_HEATER_CHAMBER(soft_pwm_CHAMBER > 0 ? 1 : 0);
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
soft_pwm_COOLER = soft_pwm_cooler;
WRITE_COOLER(soft_pwm_COOLER > 0 ? 1 : 0);
#endif
#if ENABLED(FAN_SOFT_PWM)
soft_pwm_fan = fanSpeedSoftPwm / 2;
#if HAS(CONTROLLERFAN)
......@@ -1909,8 +2161,13 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
if (soft_pwm_BED < pwm_count) WRITE_HEATER_BED(0);
#endif
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
if (soft_pwm_COOLER_DEV < pwm_count ) WRITE_COOLER(0);
#if HAS(HEATER_CHAMBER)
if (soft_pwm_CHAMBER < pwm_count) WRITE_HEATER_CHAMBER(0);
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
if (soft_pwm_COOLER < pwm_count ) WRITE_COOLER(0);
#endif
#if ENABLED(FAN_SOFT_PWM)
......@@ -1990,11 +2247,17 @@ ISR(TIMER0_COMPB_vect) {
#endif
#endif
#endif
#if HAS(HEATER_BED)
_SLOW_PWM_ROUTINE(BED, soft_pwm_bed); // BED
#endif
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
_SLOW_PWM_SOURINT(COOLER_DEV, soft_pwm_cooler); // COOLER
#if HAS(HEATER_CHAMBER)
_SLOW_PWM_ROUTINE(CHAMBER, soft_pwm_chamber); // CHAMBER
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
_SLOW_PWM_ROUTINE(COOLER, soft_pwm_cooler); // COOLER
#endif
} // slow_pwm_count == 0
......@@ -2009,11 +2272,17 @@ ISR(TIMER0_COMPB_vect) {
#endif
#endif
#endif
#if HAS(HEATER_BED)
PWM_OFF_ROUTINE(BED); // BED
#endif
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
PWM_OFF_ROUTINE(COOLER_DEV); // COOLER
#if HAS(HEATER_CHAMBER)
PWM_OFF_ROUTINE(CHAMBER); // CHAMBER
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
PWM_OFF_ROUTINE(COOLER); // COOLER
#endif
#if ENABLED(FAN_SOFT_PWM)
......@@ -2081,11 +2350,17 @@ ISR(TIMER0_COMPB_vect) {
#endif
#endif
#endif
#if HAS(HEATER_BED)
if (state_timer_heater_BED > 0) state_timer_heater_BED--;
#endif
#if HAS(COOLER_DEV) && !ENABLED(FAST_PWM_COOLER)
if(state_timer_heater_COOLER_DEV > 0) state_timer_heater_COOLER_DEV--;
#if HAS(HEATER_CHAMBER)
if (state_timer_heater_CHAMBER > 0) state_timer_heater_CHAMBER--;
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
if(state_timer_heater_COOLER > 0) state_timer_heater_COOLER--;
#endif
} // (pwm_count % 64) == 0
......@@ -2125,8 +2400,23 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(TEMP_BED)
raw_temp_bed_value += ADC;
#endif
temp_state = PrepareTemp_CHAMBER;
break;
case PrepareTemp_CHAMBER:
#if HAS(TEMP_CHAMBER)
START_ADC(TEMP_CHAMBER_PIN);
#endif
lcd_buttons_update();
temp_state = MeasureTemp_CHAMBER;
break;
case MeasureTemp_CHAMBER:
#if HAS(TEMP_CHAMBER)
raw_temp_chamber_value += ADC;
#endif
temp_state = PrepareTemp_COOLER;
break;
case PrepareTemp_COOLER:
#if HAS(TEMP_COOLER)
START_ADC(TEMP_COOLER_PIN);
......@@ -2140,6 +2430,7 @@ ISR(TIMER0_COMPB_vect) {
#endif
temp_state = PrepareTemp_1;
break;
case PrepareTemp_1:
#if HAS(TEMP_1)
START_ADC(TEMP_1_PIN);
......@@ -2291,6 +2582,17 @@ ISR(TIMER0_COMPB_vect) {
if (current_temperature_bed_raw GEBED bed_maxttemp_raw) _temp_error(-1, SERIAL_T_MAXTEMP, PSTR(MSG_ERR_MAXTEMP_BED));
if (bed_minttemp_raw GEBED current_temperature_bed_raw) _temp_error(-1, SERIAL_T_MINTEMP, PSTR(MSG_ERR_MINTEMP_BED));
#endif
#if HAS(TEMP_CHAMBER)
#if HEATER_CHAMBER_RAW_LO_TEMP > HEATER_CHAMBER_RAW_HI_TEMP
#define GECHAMBER <=
#else
#define GECHAMBER >=
#endif
if (current_temperature_chamber_raw GECHAMBER chamber_maxttemp_raw) _temp_error(-1, SERIAL_T_MAXTEMP, PSTR(MSG_ERR_MAXTEMP_CHAMBER));
if (chamber_minttemp_raw GECHAMBER current_temperature_chamber_raw) _temp_error(-1, SERIAL_T_MINTEMP, PSTR(MSG_ERR_MINTEMP_CHAMBER));
#endif
#if HAS(TEMP_COOLER)
#if COOLER_RAW_LO_TEMP > COOLER_RAW_HI_TEMP
#define GECOOLER <=
......@@ -2301,8 +2603,6 @@ ISR(TIMER0_COMPB_vect) {
if (cooler_minttemp_raw GECOOLER current_temperature_cooler_raw) _temp_error(-2, SERIAL_T_MINTEMP, PSTR(MSG_ERR_MINTEMP_COOLER));
#endif
} // temp_count >= OVERSAMPLENR
#if ENABLED(BABYSTEPPING)
......@@ -2321,10 +2621,10 @@ ISR(TIMER0_COMPB_vect) {
#endif //BABYSTEPPING
}
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCOOLER)
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
// 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; }
#endif // ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
#endif // ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
......@@ -69,15 +69,20 @@ void manage_temp_controller(); //it is critical that this is called periodically
// do not use these routines and variables outside of temperature.cpp
extern int target_temperature[4];
extern float current_temperature[4];
extern int target_temperature_bed;
extern float current_temperature_bed;
extern int target_temperature_chamber;
extern float current_temperature_chamber;
extern int target_temperature_cooler;
extern float current_temperature_cooler;
#if ENABLED(SHOW_TEMP_ADC_VALUES)
extern int current_temperature_raw[4];
extern int current_temperature_bed_raw;
extern int current_temperature_chamber_raw;
extern int current_temperature_cooler_raw;
#endif
extern int target_temperature_bed;
extern float current_temperature_bed;
extern int target_temperature_cooler;
extern float current_temperature_cooler;
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
extern float redundant_temperature;
#endif
......@@ -95,11 +100,15 @@ extern float current_temperature_cooler;
extern float bedKp, bedKi, bedKd;
#endif
#if ENABLED(PIDTEMPCHAMBER)
extern float chamberKp, chamberKi, chamberKd;
#endif
#if ENABLED(PIDTEMPCOOLER)
extern float coolerKp, coolerKi, coolerKd;
#endif
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCOOLER)
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
float scalePID_i(float i);
float scalePID_d(float d);
float unscalePID_i(float i);
......@@ -121,30 +130,37 @@ extern float current_temperature_cooler;
FORCE_INLINE float degHotend(uint8_t hotend) { return current_temperature[HOTEND_ARG]; }
FORCE_INLINE float degBed() { return current_temperature_bed; }
FORCE_INLINE float degChamber() { return current_temperature_chamber; }
FORCE_INLINE float degCooler() { return current_temperature_cooler; }
#if ENABLED(SHOW_TEMP_ADC_VALUES)
FORCE_INLINE float rawHotendTemp(uint8_t hotend) { return current_temperature_raw[HOTEND_ARG]; }
FORCE_INLINE float rawBedTemp() { return current_temperature_bed_raw; }
FORCE_INLINE float rawChamberTemp() { return current_temperature_chamber_raw; }
FORCE_INLINE float rawCoolerTemp() { return current_temperature_cooler_raw; }
#endif
FORCE_INLINE float degTargetHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG]; }
FORCE_INLINE float degTargetBed() { return target_temperature_bed; }
FORCE_INLINE float degTargetChamber() { return target_temperature_chamber; }
FORCE_INLINE float degTargetCooler() { return target_temperature_cooler; }
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
void start_watching_heater(int h = 0);
#endif
#if ENABLED(THERMAL_PROTECTION_COOLERS)
void start_watching_cooler();
#endif
#if ENABLED(THERMAL_PROTECTION_BED)
void start_watching_bed();
#endif
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
void start_watching_chamber();
#endif
#if ENABLED(THERMAL_PROTECTION_COOLER)
void start_watching_cooler();
#endif
FORCE_INLINE void setTargetHotend(const float& celsius, uint8_t hotend) {
target_temperature[HOTEND_ARG] = celsius;
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
......@@ -159,20 +175,28 @@ FORCE_INLINE void setTargetBed(const float& celsius) {
#endif
}
FORCE_INLINE void setTargetChamber(const float& celsius) {
target_temperature_chamber = celsius;
#if ENABLED(THERMAL_PROTECTION_CHAMBER)
start_watching_chamber();
#endif
}
FORCE_INLINE void setTargetCooler(const float& celsius) {
target_temperature_cooler = celsius;
#if ENABLED(THERMAL_PROTECTION_COOLER) && ENABLED(THERMAL_PROTECTION_COOLER_WATCHDOG)
#if ENABLED(THERMAL_PROTECTION_COOLER)
start_watching_cooler();
#endif
}
FORCE_INLINE bool isHeatingHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG] > current_temperature[HOTEND_ARG]; }
FORCE_INLINE bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; }
FORCE_INLINE bool isHeatingChamber() { return target_temperature_chamber > current_temperature_chamber; }
FORCE_INLINE bool isHeatingCooler() { return target_temperature_cooler > current_temperature_cooler; }
FORCE_INLINE bool isCoolingHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG] < current_temperature[HOTEND_ARG]; }
FORCE_INLINE bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; }
FORCE_INLINE bool isCoolingChamber() { return target_temperature_chamber < current_temperature_chamber; }
FORCE_INLINE bool isCoolingCooler() { return target_temperature_cooler < current_temperature_cooler; }
#define HOTEND_ROUTINES(NR) \
......@@ -199,14 +223,16 @@ HOTEND_ROUTINES(0);
#endif
int getHeaterPower(int heater);
int getBedPower();
int getChamberPower();
int getCoolerPower();
unsigned char getPwmCooler(bool soft);
void disable_all_heaters();
void disable_all_heaters();
void disable_all_coolers();
void updatePID();
#if HAS(PID_HEATING) || HAS(PID_COOLING)
#if HAS(PID_HEATING) || HAS(PID_COOLING)
void PID_autotune(float temp, int temp_controller, int ncycles, bool set_result = false);
#endif
......
......@@ -25,7 +25,7 @@
#define OVERSAMPLENR 16
#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORHEATER_3 == 1) || (THERMISTORBED == 1) || (THERMISTORCOOLER == 1) //100k bed thermistor
#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORHEATER_3 == 1) || (THERMISTORBED == 1) || (THERMISTORCHAMBER == 1) || (THERMISTORCOOLER == 1) //100k bed thermistor
const short temptable_1[][2] PROGMEM = {
{23 * OVERSAMPLENR, 300},
{25 * OVERSAMPLENR, 295},
......@@ -91,7 +91,7 @@ const short temptable_1[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORHEATER_3 == 2) || (THERMISTORBED == 2) || (THERMISTORCOOLER == 2) //200k bed thermistor
#if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORHEATER_3 == 2) || (THERMISTORBED == 2) || (THERMISTORCHAMBER == 2) || (THERMISTORCOOLER == 2) //200k bed thermistor
const short temptable_2[][2] PROGMEM = {
//200k ATC Semitec 204GT-2
//Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
......@@ -132,7 +132,7 @@ const short temptable_2[][2] PROGMEM = {
#endif
#if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORHEATER_3 == 3) || (THERMISTORBED == 3) || (THERMISTORCOOLER == 3)//mendel-parts
#if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORHEATER_3 == 3) || (THERMISTORBED == 3) || (THERMISTORCHAMBER == 3) || (THERMISTORCOOLER == 3)//mendel-parts
const short temptable_3[][2] PROGMEM = {
{1 * OVERSAMPLENR, 864},
{21 * OVERSAMPLENR, 300},
......@@ -165,7 +165,7 @@ const short temptable_3[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORHEATER_3 == 4) || (THERMISTORBED == 4) || (THERMISTORCOOLER == 4) //10k thermistor
#if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORHEATER_3 == 4) || (THERMISTORBED == 4) || (THERMISTORCHAMBER == 4) || (THERMISTORCOOLER == 4) //10k thermistor
const short temptable_4[][2] PROGMEM = {
{1 * OVERSAMPLENR, 430},
{54 * OVERSAMPLENR, 137},
......@@ -190,7 +190,7 @@ const short temptable_4[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORHEATER_3 == 5) || (THERMISTORBED == 5) || (THERMISTORCOOLER == 5)//100k ParCan thermistor (104GT-2)
#if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORHEATER_3 == 5) || (THERMISTORBED == 5) || (THERMISTORCHAMBER == 5) || (THERMISTORCOOLER == 5)//100k ParCan thermistor (104GT-2)
const short temptable_5[][2] PROGMEM = {
// ATC Semitec 104GT-2 (Used in ParCan)
// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
......@@ -230,7 +230,7 @@ const short temptable_5[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORHEATER_3 == 6) || (THERMISTORBED == 6) || (THERMISTORCOOLER == 6)// 100k Epcos thermistor
#if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORHEATER_3 == 6) || (THERMISTORBED == 6) || (THERMISTORCHAMBER == 6) || (THERMISTORCOOLER == 6)// 100k Epcos thermistor
const short temptable_6[][2] PROGMEM = {
{1 * OVERSAMPLENR, 350},
{28 * OVERSAMPLENR, 250}, //top rating 250C
......@@ -273,7 +273,7 @@ const short temptable_6[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORHEATER_3 == 7) || (THERMISTORBED == 7) || (THERMISTORCOOLER == 7)// 100k Honeywell 135-104LAG-J01
#if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORHEATER_3 == 7) || (THERMISTORBED == 7) || (THERMISTORCHAMBER == 7) || (THERMISTORCOOLER == 7)// 100k Honeywell 135-104LAG-J01
const short temptable_7[][2] PROGMEM = {
{1 * OVERSAMPLENR, 941},
{19 * OVERSAMPLENR, 362},
......@@ -336,7 +336,7 @@ const short temptable_7[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 71) || (THERMISTORHEATER_1 == 71) || (THERMISTORHEATER_2 == 71) || (THERMISTORHEATER_3 == 71) || (THERMISTORBED == 71) || (THERMISTORCOOLER == 71)// 100k Honeywell 135-104LAF-J01
#if (THERMISTORHEATER_0 == 71) || (THERMISTORHEATER_1 == 71) || (THERMISTORHEATER_2 == 71) || (THERMISTORHEATER_3 == 71) || (THERMISTORBED == 71) || (THERMISTORCHAMBER == 71) || (THERMISTORCOOLER == 71)// 100k Honeywell 135-104LAF-J01
// R0 = 100000 Ohm
// T0 = 25 °C
// Beta = 3974
......@@ -487,7 +487,7 @@ const short temptable_71[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 8) || (THERMISTORHEATER_1 == 8) || (THERMISTORHEATER_2 == 8) || (THERMISTORHEATER_3 == 8) || (THERMISTORBED == 8) || (THERMISTORCOOLER == 8)
#if (THERMISTORHEATER_0 == 8) || (THERMISTORHEATER_1 == 8) || (THERMISTORHEATER_2 == 8) || (THERMISTORHEATER_3 == 8) || (THERMISTORBED == 8) || (THERMISTORCHAMBER == 8) || (THERMISTORCOOLER == 8)
// 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
const short temptable_8[][2] PROGMEM = {
{1 * OVERSAMPLENR, 704},
......@@ -513,7 +513,7 @@ const short temptable_8[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 9) || (THERMISTORHEATER_1 == 9) || (THERMISTORHEATER_2 == 9) || (THERMISTORHEATER_3 == 9) || (THERMISTORBED == 9) || (THERMISTORCOOLER == 9)
#if (THERMISTORHEATER_0 == 9) || (THERMISTORHEATER_1 == 9) || (THERMISTORHEATER_2 == 9) || (THERMISTORHEATER_3 == 9) || (THERMISTORBED == 9) || (THERMISTORCHAMBER == 9) || (THERMISTORCOOLER == 9)
// 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
const short temptable_9[][2] PROGMEM = {
{1 * OVERSAMPLENR, 936},
......@@ -550,7 +550,7 @@ const short temptable_9[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 10) || (THERMISTORHEATER_1 == 10) || (THERMISTORHEATER_2 == 10) || (THERMISTORHEATER_3 == 10) || (THERMISTORBED == 10) || (THERMISTORCOOLER == 10)
#if (THERMISTORHEATER_0 == 10) || (THERMISTORHEATER_1 == 10) || (THERMISTORHEATER_2 == 10) || (THERMISTORHEATER_3 == 10) || (THERMISTORBED == 10) || (THERMISTORCHAMBER == 10) || (THERMISTORCOOLER == 10)
// 100k RS thermistor 198-961 (4.7k pullup)
const short temptable_10[][2] PROGMEM = {
{1 * OVERSAMPLENR, 929},
......@@ -587,7 +587,7 @@ const short temptable_10[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 11) || (THERMISTORHEATER_1 == 11) || (THERMISTORHEATER_2 == 11) || (THERMISTORHEATER_3 == 11) || (THERMISTORBED == 11) || (THERMISTORCOOLER == 11)
#if (THERMISTORHEATER_0 == 11) || (THERMISTORHEATER_1 == 11) || (THERMISTORHEATER_2 == 11) || (THERMISTORHEATER_3 == 11) || (THERMISTORBED == 11) || (THERMISTORCHAMBER == 11) || (THERMISTORCOOLER == 11)
// QU-BD silicone bed QWG-104F-3950 thermistor
const short temptable_11[][2] PROGMEM = {
{1 * OVERSAMPLENR, 938},
......@@ -643,7 +643,7 @@ const short temptable_11[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORHEATER_3 == 13) || (THERMISTORBED == 13) || (THERMISTORCOOLER == 13)
#if (THERMISTORHEATER_0 == 13) || (THERMISTORHEATER_1 == 13) || (THERMISTORHEATER_2 == 13) || (THERMISTORHEATER_3 == 13) || (THERMISTORBED == 13) || (THERMISTORCHAMBER == 13) || (THERMISTORCOOLER == 13)
// Hisens thermistor B25/50 =3950 +/-1%
const short temptable_13[][2] PROGMEM = {
{ 20.04 * OVERSAMPLENR, 300 },
......@@ -673,7 +673,7 @@ const short temptable_13[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 20) || (THERMISTORHEATER_1 == 20) || (THERMISTORHEATER_2 == 20) || (THERMISTORHEATER_3 == 20) || (THERMISTORBED == 20) || (THERMISTORCOOLER == 20) // PT100 with INA826 amp on Ultimaker v2.0 electronics
#if (THERMISTORHEATER_0 == 20) || (THERMISTORHEATER_1 == 20) || (THERMISTORHEATER_2 == 20) || (THERMISTORHEATER_3 == 20) || (THERMISTORBED == 20) || (THERMISTORCHAMBER == 20) || (THERMISTORCOOLER == 20) // PT100 with INA826 amp on Ultimaker v2.0 electronics
/* The PT100 in the Ultimaker v2.0 electronics has a high sample value for a high temperature.
This does not match the normal thermistor behaviour so we need to set the following defines */
#if (THERMISTORHEATER_0 == 20)
......@@ -753,7 +753,7 @@ const short temptable_20[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 40) || (THERMISTORHEATER_1 == 40) || (THERMISTORHEATER_2 == 40) || (THERMISTORHEATER_3 == 40) || (THERMISTORBED == 40) || (THERMISTORCOOLER == 40)
#if (THERMISTORHEATER_0 == 40) || (THERMISTORHEATER_1 == 40) || (THERMISTORHEATER_2 == 40) || (THERMISTORHEATER_3 == 40) || (THERMISTORBED == 40) || (THERMISTORCHAMBER == 40) || (THERMISTORCOOLER == 40)
// 10k Carel NTC015WH01 or ELIWELL SN8T6A1502 (4.7k pullup)
// roughly calculated using datasheet ( 10k at 25 celsius ), my body temp ( 35.9 celsius, 6.66k ) and my freezer ( -21 celsius, 56k )
// Unbelivable, seems to be pretty precise.
......@@ -796,7 +796,7 @@ const short temptable_40[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 51) || (THERMISTORHEATER_1 == 51) || (THERMISTORHEATER_2 == 51) || (THERMISTORHEATER_3 == 51) || (THERMISTORBED == 51) || (THERMISTORCOOLER == 51)
#if (THERMISTORHEATER_0 == 51) || (THERMISTORHEATER_1 == 51) || (THERMISTORHEATER_2 == 51) || (THERMISTORHEATER_3 == 51) || (THERMISTORBED == 51) || (THERMISTORCHAMBER == 51) || (THERMISTORCOOLER == 51)
// 100k EPCOS (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee.
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
......@@ -858,7 +858,7 @@ const short temptable_51[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 52) || (THERMISTORHEATER_1 == 52) || (THERMISTORHEATER_2 == 52) || (THERMISTORHEATER_3 == 52) || (THERMISTORBED == 52) || (THERMISTORCOOLER == 52)
#if (THERMISTORHEATER_0 == 52) || (THERMISTORHEATER_1 == 52) || (THERMISTORHEATER_2 == 52) || (THERMISTORHEATER_3 == 52) || (THERMISTORBED == 52) || (THERMISTORCHAMBER == 52) || (THERMISTORCOOLER == 52)
// 200k ATC Semitec 204GT-2 (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
......@@ -899,7 +899,7 @@ const short temptable_52[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 55) || (THERMISTORHEATER_1 == 55) || (THERMISTORHEATER_2 == 55) || (THERMISTORHEATER_3 == 55) || (THERMISTORBED == 55) || (THERMISTORCOOLER == 55)
#if (THERMISTORHEATER_0 == 55) || (THERMISTORHEATER_1 == 55) || (THERMISTORHEATER_2 == 55) || (THERMISTORHEATER_3 == 55) || (THERMISTORBED == 55) || (THERMISTORCHAMBER == 55) || (THERMISTORCOOLER == 55)
// 100k ATC Semitec 104GT-2 (Used on ParCan) (WITH 1kohm RESISTOR FOR PULLUP, R9 ON SANGUINOLOLU! NOT FOR 4.7kohm PULLUP! THIS IS NOT NORMAL!)
// Verified by linagee. Source: http://shop.arcol.hu/static/datasheets/thermistors.pdf
// Calculated using 1kohm pullup, voltage divider math, and manufacturer provided temp/resistance
......@@ -940,7 +940,7 @@ const short temptable_55[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 60) || (THERMISTORHEATER_1 == 60) || (THERMISTORHEATER_2 == 60) || (THERMISTORHEATER_3 == 60) || (THERMISTORBED == 60) || (THERMISTORCOOLER == 60) // Maker's Tool Works Kapton Bed Thermister
#if (THERMISTORHEATER_0 == 60) || (THERMISTORHEATER_1 == 60) || (THERMISTORHEATER_2 == 60) || (THERMISTORHEATER_3 == 60) || (THERMISTORBED == 60) || (THERMISTORCHAMBER == 60) || (THERMISTORCOOLER == 60) // Maker's Tool Works Kapton Bed Thermister
// ./createTemperatureLookup.py --r0=100000 --t0=25 --r1=0 --r2=4700 --beta=3950
// r0: 100000
// t0: 25
......@@ -1025,7 +1025,7 @@ const short temptable_60[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 12) || (THERMISTORHEATER_1 == 12) || (THERMISTORHEATER_2 == 12) || (THERMISTORHEATER_3 == 12) || (THERMISTORBED == 12) || (THERMISTORCOOLER == 12)
#if (THERMISTORHEATER_0 == 12) || (THERMISTORHEATER_1 == 12) || (THERMISTORHEATER_2 == 12) || (THERMISTORHEATER_3 == 12) || (THERMISTORBED == 12) || (THERMISTORCHAMBER == 12) || (THERMISTORCOOLER == 12)
//100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
const short temptable_12[][2] PROGMEM = {
{35 * OVERSAMPLENR, 180}, //top rating 180C
......@@ -1072,7 +1072,7 @@ const short temptable_12[][2] PROGMEM = {
#define PtAdVal(T,R0,Rup) (short)(1024/(Rup/PtRt(T,R0)+1))
#define PtLine(T,R0,Rup) { PtAdVal(T,R0,Rup)*OVERSAMPLENR, T },
#if (THERMISTORHEATER_0 == 110) || (THERMISTORHEATER_1 == 110) || (THERMISTORHEATER_2 == 110) || (THERMISTORHEATER_3 == 110) || (THERMISTORBED == 110) || (THERMISTORCOOLER == 110)// Pt100 with 1k0 pullup
#if (THERMISTORHEATER_0 == 110) || (THERMISTORHEATER_1 == 110) || (THERMISTORHEATER_2 == 110) || (THERMISTORHEATER_3 == 110) || (THERMISTORBED == 110) || (THERMISTORCHAMBER == 110) || (THERMISTORCOOLER == 110)// Pt100 with 1k0 pullup
const short temptable_110[][2] PROGMEM = {
// only few values are needed as the curve is very flat
PtLine(0, 100, 1000)
......@@ -1085,7 +1085,7 @@ const short temptable_110[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 147) || (THERMISTORHEATER_1 == 147) || (THERMISTORHEATER_2 == 147) || (THERMISTORHEATER_3 == 147) || (THERMISTORBED == 147) || (THERMISTORCOOLER == 147) // Pt100 with 4k7 pullup
#if (THERMISTORHEATER_0 == 147) || (THERMISTORHEATER_1 == 147) || (THERMISTORHEATER_2 == 147) || (THERMISTORHEATER_3 == 147) || (THERMISTORBED == 147) || (THERMISTORCHAMBER == 147) || (THERMISTORCOOLER == 147) // Pt100 with 4k7 pullup
const short temptable_147[][2] PROGMEM = {
// only few values are needed as the curve is very flat
PtLine(0, 100, 4700)
......@@ -1098,7 +1098,7 @@ const short temptable_147[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 1010) || (THERMISTORHEATER_1 == 1010) || (THERMISTORHEATER_2 == 1010) || (THERMISTORHEATER_3 == 1010) || (THERMISTORBED == 1010) || (THERMISTORCOOLER == 1010) // Pt1000 with 1k0 pullup
#if (THERMISTORHEATER_0 == 1010) || (THERMISTORHEATER_1 == 1010) || (THERMISTORHEATER_2 == 1010) || (THERMISTORHEATER_3 == 1010) || (THERMISTORBED == 1010) || (THERMISTORCHAMBER == 1010) || (THERMISTORCOOLER == 1010) // Pt1000 with 1k0 pullup
const short temptable_1010[][2] PROGMEM = {
PtLine(0, 1000, 1000)
PtLine(25, 1000, 1000)
......@@ -1116,7 +1116,7 @@ const short temptable_1010[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 1047) || (THERMISTORHEATER_1 == 1047) || (THERMISTORHEATER_2 == 1047) || (THERMISTORHEATER_3 == 1047) || (THERMISTORBED == 1047) || (THERMISTORCOOLER == 1047) // Pt1000 with 4k7 pullup
#if (THERMISTORHEATER_0 == 1047) || (THERMISTORHEATER_1 == 1047) || (THERMISTORHEATER_2 == 1047) || (THERMISTORHEATER_3 == 1047) || (THERMISTORBED == 1047) || (THERMISTORCHAMBER == 1047) || (THERMISTORCOOLER == 1047) // Pt1000 with 4k7 pullup
const short temptable_1047[][2] PROGMEM = {
// only few values are needed as the curve is very flat
PtLine(0, 1000, 4700)
......@@ -1129,7 +1129,7 @@ const short temptable_1047[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 999) || (THERMISTORHEATER_1 == 999) || (THERMISTORHEATER_2 == 999) || (THERMISTORHEATER_3 == 999) || (THERMISTORBED == 999) || (THERMISTORCOOLER == 999)//User defined table
#if (THERMISTORHEATER_0 == 999) || (THERMISTORHEATER_1 == 999) || (THERMISTORHEATER_2 == 999) || (THERMISTORHEATER_3 == 999) || (THERMISTORBED == 999) || (THERMISTORCHAMBER == 999) || (THERMISTORCOOLER == 999)//User defined table
// Dummy Thermistor table.. It will ALWAYS read a fixed value.
#ifndef DUMMY_THERMISTOR_999_VALUE
#define DUMMY_THERMISTOR_999_VALUE 25
......@@ -1140,7 +1140,7 @@ const short temptable_1047[][2] PROGMEM = {
};
#endif
#if (THERMISTORHEATER_0 == 998) || (THERMISTORHEATER_1 == 998) || (THERMISTORHEATER_2 == 998) || (THERMISTORHEATER_3 == 998) || (THERMISTORBED == 998) || (THERMISTORCOOLER == 998)//User defined table
#if (THERMISTORHEATER_0 == 998) || (THERMISTORHEATER_1 == 998) || (THERMISTORHEATER_2 == 998) || (THERMISTORHEATER_3 == 998) || (THERMISTORBED == 998) || (THERMISTORCHAMBER == 998) || (THERMISTORCOOLER == 998)//User defined table
// Dummy Thermistor table.. It will ALWAYS read a fixed value.
#ifndef DUMMY_THERMISTOR_998_VALUE
#define DUMMY_THERMISTOR_998_VALUE 25
......@@ -1256,16 +1256,6 @@ 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
......@@ -1277,6 +1267,34 @@ const short temptable_1047[][2] PROGMEM = {
#endif
#endif
#ifdef THERMISTORCHAMBER
#define CHAMBERTEMPTABLE TT_NAME(THERMISTORCHAMBER)
#define CHAMBERTEMPTABLE_LEN COUNT(CHAMBERTEMPTABLE)
#else
#ifdef CHAMBER_USES_THERMISTOR
#error No chamber thermistor table specified
#endif // CHAMBER_USES_THERMISTOR
#endif
#ifndef HEATER_CHAMBER_RAW_HI_TEMP
#ifdef CHAMBER_USES_THERMISTOR //In case of a thermistor the highest temperature results in the lowest ADC value
#define HEATER_CHAMBER_RAW_HI_TEMP 0
#define HEATER_CHAMBER_RAW_LO_TEMP 16383
#else //In case of an thermocouple the highest temperature results in the highest ADC value
#define HEATER_CHAMBER_RAW_HI_TEMP 16383
#define HEATER_CHAMBER_RAW_LO_TEMP 0
#endif
#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
#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
......@@ -1287,5 +1305,4 @@ const short temptable_1047[][2] PROGMEM = {
#endif
#endif
#endif //THERMISTORTABLES_H_
#endif // THERMISTORTABLES_H_
......@@ -46,6 +46,8 @@ Added total filament printed writed in SD CARD.
Added anti extruder idle oozing system.
Added Hysteresis and Z-Wobble correction (only cartesian printers).
Added support reader TAG width MFRC522
Added Cooler and Hot Chamber
Added Laser beam and raster base64
## Credits
......
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