Commit 184769cb authored by MagoKimbra's avatar MagoKimbra

Update 4.2.83

Add Cooler and Hot Chamber
Add Laser PWM and raster base 64
parent 3fdffbe0
......@@ -7,9 +7,10 @@
* G2 - CW ARC
* G3 - CCW ARC
* G4 - Dwell S[seconds] or P[milliseconds], delay in Second or Millisecond
* G7 - Laser raster base64
* G10 - retract filament according to settings of M207
* G11 - retract recover filament according to settings of M208
* G28 - X0 Y0 Z0 Home all Axis. G28 M for bed manual setting with LCD.
* G28 - X Y Z Home all Axis. M for bed manual setting with LCD. B return to back point
* G29 - Detailed Z-Probe, probes the bed at 3 points or grid. You must be at the home position for this to work correctly.
G29 Fyyy Lxxx Rxxx Byyy for customer grid.
* G30 - Single Z Probe, probes bed at current XY location. Bed Probe and Delta geometry Autocalibration G30 A
......@@ -45,7 +46,8 @@
* M32 - Make directory
* M35 - Upload Firmware to Nextion from SD
* M42 - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
* M49 - Z probe repetability test
* M48 - Measure Z_Probe repeatability. M48 [P # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel]
* M70 - Power consumption sensor calibration
* M80 - Turn on Power Supply
* M81 - Turn off Power, including Power Supply, if possible
* M82 - Set E codes absolute (default)
......@@ -58,26 +60,29 @@
* M98 - Print Hysteresis value
* M99 - Set Hysteresis parameter M99 X<in mm> Y<in mm> Z<in mm> E<in mm>
* M100 - Watch Free Memory (For Debugging Only)
* M104 - Set extruder target temp
* M104 - Set hotend target temp
* M105 - Read current temp
* M106 - Fan on
* M107 - Fan off
* M109 - S[xxx] Wait for extruder current temp to reach target temp. Waits only when heating
- R[xxx] Wait for extruder current temp to reach target temp. Waits when heating and cooling
* M111 - Debug Dryrun Repetier
* M109 - S[xxx] Wait for hotend current temp to reach target temp. Waits only when heating
- R[xxx] Wait for hotend current temp to reach target temp. Waits when heating and cooling
* M110 - Set the current line number
* M111 - Set debug flags with S<mask>.
* M112 - Emergency stop
* M114 - Output current position to serial port, (V)erbose for user
* M114 - Output current position to serial port
* M115 - Capabilities string
* M117 - display message
* M117 - Display a message on the controller screen
* M119 - Output Endstop status to serial port
* M120 - Disable Endstop
* M121 - Enable Endstop
* M120 - Enable endstop detection
* M121 - Disable endstop detection
* M122 - S<1=true/0=false> Enable or disable check software endstop
* M126 - Solenoid Air Valve Open (BariCUDA support by jmil)
* M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil)
* M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil)
* M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil)
* M140 - Set bed target temp
* M140 - Set hot bed target temp
* M141 - Set hot chamber target temp
* M142 - Set cooler target temp
* M145 - Set the heatup state H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
* M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work.
* M163 - Set a single proportion for a mixing extruder. Requires COLOR_MIXING_EXTRUDER.
......@@ -85,6 +90,10 @@
* M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. Requires COLOR_MIXING_EXTRUDER.
* M190 - S[xxx] Wait for bed current temp to reach target temp. Waits only when heating
- R[xxx] Wait for bed current temp to reach target temp. Waits when heating and cooling
* M191 - Sxxx Wait for chamber current temp to reach target temp. Waits only when heating
* Rxxx Wait for chamber current temp to reach target temp. Waits when heating and cooling
* M192 - Sxxx Wait for cooler current temp to reach target temp. Waits only when heating
* Rxxx Wait for cooler current temp to reach target temp. Waits when heating and cooling
* M200 - D[millimeters]- set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).
* M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000 Z1000 E0 S1000 E1 S1000 E2 S1000 E3 S1000) in mm/sec^2
* M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E0 S1000 E1 S1000 E2 S1000 E3 S1000) in mm/sec
......@@ -104,7 +113,9 @@
* M301 - Set PID parameters P I and D
* M302 - Allow cold extrudes
* M303 - PID relay autotune S<temperature> sets the target temperature (default target temperature = 150C). H<hotend> C<cycles> U<Apply result>
* M304 - Set bed PID parameters P I and D
* M304 - Set hot bed PID parameters P I and D
* M305 - Set hot chamber PID parameters P I and D
* M306 - Set cooler PID parameters P I and D
* M350 - Set microstepping mode.
* M351 - Toggle MS1 MS2 pins directly.
* M400 - Finish all moves
......@@ -131,4 +142,5 @@
* M907 - Set digital trimpot motor current using axis codes.
* M908 - Control digital trimpot directly.
* M928 - Start SD logging (M928 filename.g) - ended by M29
* M997 - NPR2 Color rotate
* M999 - Restart after being stopped by error
### Version 4.2.83
* Add Cooler and Hot Chamber
* Add Laser Beam PWM and raster base64 ONLY ARDUINO MEGA
### Version 4.2.82
* Add DONDOLO_DUAL_MOTOR for DONDOLO bowden and dual extruder
* Add reader TAG width MFRC522
......
......@@ -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"
*/
......@@ -127,118 +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
//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.
// When temperature exceeds max temp, your heater will be switched off.
// 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)
// The minimal temperature defines the temperature below which the heater will not be enabled It is used
// 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)
//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
......@@ -239,7 +239,7 @@
/*****************************************************************************************
************************************** MBL or ABL ***************************************
/*****************************************************************************************
*****************************************************************************************
* *
* Manual Bed Leveling (MBL) or Auto Bed Leveling (ABL) settings *
* Set the rectangle in which to probe in MBL or ABL. *
......@@ -456,4 +456,4 @@
#define HOTEND_OFFSET_Z {0.0, 0.0, 0.0, 0.0} // (in mm) for each hotend, offset of the hotend on the Z axis
/*****************************************************************************************/
#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,227 +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 - 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 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 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. *
* *
********************************************************************************/
//#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
/********************************************************************************/
/**************************************************************************
**************************** Fan configuration ***************************
**************************************************************************/
......@@ -354,22 +126,6 @@
/**************************************************************************/
/**************************************************************************
**************************** MEDIAN COUNT ********************************
**************************************************************************
* *
* For Smoother temperature *
* ONLY FOR DUE *
**************************************************************************/
#define MEDIAN_COUNT 10
/**************************************************************************/
//===========================================================================
//============================= EXTRUDER FEATURES ===========================
//===========================================================================
/***********************************************************************
******************** DEFAULT NOMINAL FILAMENT DIA *********************
***********************************************************************
......@@ -1090,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 ==============================
......@@ -1352,8 +1128,7 @@
**************************************************************************
* *
* 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 *
* Check also Configuration_Laser.h *
* *
**************************************************************************/
//#define LASERBEAM
......
#ifndef CONFIGURATION_LASER
#define CONFIGURATION_LASER
//===========================================================================
//============================= Laser Settings ==============================
//===========================================================================
// 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
#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.
// 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
// If your machine has laser focuser, set this to true and it will use Z axis for focus or disable it.
#define LASER_HAS_FOCUS false
//// 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.
#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
// 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
// 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
// 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
// #define G5_BEZIER
// Uncomment these options for the Buildlog.net laser cutter, and other similar models
#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
#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,8 +108,12 @@
#endif
#if ENABLED(LASERBEAM)
#define LASER_PWR_PIN -1
#define LASER_TTL_PIN -1
#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)
......@@ -116,6 +124,10 @@
#define FILWIDTH_PIN -1
#endif
#if ENABLED(FLOWMETER_SENSOR)
#define FLOWMETER_PIN -1
#endif
#if ENABLED(POWER_CONSUMPTION)
#define POWER_CONSUMPTION_PIN -1
#endif
......
......@@ -95,6 +95,10 @@
*
* PIDTEMPBED:
* M304 PID bedKp, bedKi, bedKd
* PIDTEMPCHAMBER
* M305 PID chamberKp, chamberKi, chamberKd
* PIDTEMPCOOLER
* M306 PID coolerKp, coolerKi, coolerKd
*
* DOGLCD:
* M250 C lcd_contrast
......@@ -232,6 +236,18 @@ void Config_StoreSettings() {
EEPROM_WRITE_VAR(i, bedKd);
#endif
#if ENABLED(PIDTEMPCHAMBER)
EEPROM_WRITE_VAR(i, chamberKp);
EEPROM_WRITE_VAR(i, chamberKi);
EEPROM_WRITE_VAR(i, chamberKd);
#endif
#if ENABLED(PIDTEMPCOOLER)
EEPROM_WRITE_VAR(i, coolerKp);
EEPROM_WRITE_VAR(i, coolerKi);
EEPROM_WRITE_VAR(i, coolerKd);
#endif
#if HASNT(LCD_CONTRAST)
const int lcd_contrast = 32;
#endif
......@@ -381,6 +397,18 @@ void Config_RetrieveSettings() {
EEPROM_READ_VAR(i, bedKd);
#endif
#if ENABLED(PIDTEMPCHAMBER)
EEPROM_READ_VAR(i, chamberKp);
EEPROM_READ_VAR(i, chamberKi);
EEPROM_READ_VAR(i, chamberKd);
#endif
#if ENABLED(PIDTEMPCOOLER)
EEPROM_READ_VAR(i, coolerKp);
EEPROM_READ_VAR(i, coolerKi);
EEPROM_READ_VAR(i, coolerKd);
#endif
#if HASNT(LCD_CONTRAST)
int lcd_contrast;
#endif
......@@ -575,6 +603,18 @@ void Config_ResetDefault() {
bedKd = scalePID_d(DEFAULT_bedKd);
#endif
#if ENABLED(PIDTEMPCHAMBER)
chamberKp = DEFAULT_chamberKp;
chamberKi = scalePID_i(DEFAULT_chamberKi);
chamberKd = scalePID_d(DEFAULT_chamberKd);
#endif
#if ENABLED(PIDTEMPCOOLER)
coolerKp = DEFAULT_coolerKp;
coolerKi = scalePID_i(DEFAULT_coolerKi);
coolerKd = scalePID_d(DEFAULT_coolerKd);
#endif
#if ENABLED(FWRETRACT)
autoretract_enabled = false;
retract_length = RETRACT_LENGTH;
......@@ -777,7 +817,7 @@ void Config_ResetDefault() {
ECHO_EM(" (Material GUM)");
#endif // ULTIPANEL
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
if (!forReplay) {
ECHO_LM(CFG, "PID settings:");
}
......@@ -797,10 +837,21 @@ void Config_ResetDefault() {
#endif
#endif
#if ENABLED(PIDTEMPBED)
ECHO_SMV(CFG, " M304 P", bedKp); // for compatibility with hosts, only echos values for E0
ECHO_SMV(CFG, " M304 P", bedKp);
ECHO_MV(" I", unscalePID_i(bedKi));
ECHO_EMV(" D", unscalePID_d(bedKd));
#endif
#if ENABLED(PIDTEMPCHAMBER)
ECHO_SMV(CFG, " M305 P", chamberKp);
ECHO_MV(" I", unscalePID_i(chamberKi));
ECHO_EMV(" D", unscalePID_d(chamberKd));
#endif
#if ENABLED(PIDTEMPCOOLER)
ECHO_SMV(CFG, " M306 P", coolerKp);
ECHO_MV(" I", unscalePID_i(coolerKi));
ECHO_EMV(" D", unscalePID_d(coolerKd));
#endif
#endif
#if ENABLED(FWRETRACT)
......
#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,13 +35,14 @@
* "G" Codes
*
* G0 -> G1
* G1 - Coordinated Movement X Y Z E
* G1 - Coordinated Movement X Y Z E F(feedrate) P(Purge)
* G2 - CW ARC
* G3 - CCW ARC
* G4 - Dwell S<seconds> or P<milliseconds>
* G4 - Dwell S[seconds] or P[milliseconds], delay in Second or Millisecond
* G7 - Laser raster base64
* G10 - retract filament according to settings of M207
* G11 - retract recover filament according to settings of M208
* G28 - Home one or more axes
* G28 - X Y Z Home all Axis. M for bed manual setting with LCD. B return to back point
* G29 - Detailed Z-Probe, probes the bed at 3 or more points. Will fail if you haven't homed yet.
* G30 - Single Z Probe, probes bed at current XY location. - Bed Probe and Delta geometry Autocalibration
* G31 - Dock sled (Z_PROBE_SLED only)
......@@ -96,15 +97,15 @@
* M98 - Print Hysteresis value
* M99 - Set Hysteresis parameter M99 X<in mm> Y<in mm> Z<in mm> E<in mm>
* M100 - Watch Free Memory (For Debugging Only)
* M104 - Set extruder target temp
* M104 - Set hotend target temp
* M105 - Read current temp
* M106 - Fan on
* M107 - Fan off
* M109 - Sxxx Wait for extruder current temp to reach target temp. Waits only when heating
* Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling
* M109 - Sxxx Wait for hotend current temp to reach target temp. Waits only when heating
* Rxxx Wait for hotend current temp to reach target temp. Waits when heating and cooling
* IF AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
* M110 - Set the current line number
* M111 - Set debug flags with S<mask>. See flag bits defined in Marlin.h.
* M111 - Set debug flags with S<mask>.
* M112 - Emergency stop
* M114 - Output current position to serial port
* M115 - Capabilities string
......@@ -117,7 +118,9 @@
* M127 - Solenoid Air Valve Closed (BariCUDA vent to atmospheric pressure by jmil)
* M128 - EtoP Open (BariCUDA EtoP = electricity to air pressure transducer by jmil)
* M129 - EtoP Closed (BariCUDA EtoP = electricity to air pressure transducer by jmil)
* M140 - Set bed target temp
* M140 - Set hot bed target temp
* M141 - Set hot chamber target temp
* M142 - Set cooler target temp
* M145 - Set the heatup state H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
* M150 - Set BlinkM Color Output R: Red<0-255> U(!): Green<0-255> B: Blue<0-255> over i2c, G for green does not work.
* M163 - Set a single proportion for a mixing extruder. Requires COLOR_MIXING_EXTRUDER.
......@@ -125,6 +128,10 @@
* M165 - Set the proportions for a mixing extruder. Use parameters ABCDHI to set the mixing factors. Requires COLOR_MIXING_EXTRUDER.
* M190 - Sxxx Wait for bed current temp to reach target temp. Waits only when heating
* Rxxx Wait for bed current temp to reach target temp. Waits when heating and cooling
* M191 - Sxxx Wait for chamber current temp to reach target temp. Waits only when heating
* Rxxx Wait for chamber current temp to reach target temp. Waits when heating and cooling
* M192 - Sxxx Wait for cooler current temp to reach target temp. Waits only when heating
* Rxxx Wait for cooler current temp to reach target temp. Waits when heating and cooling
* M200 - set filament diameter and set E axis units to cubic millimeters (use S0 to set back to millimeters).:D<millimeters>-
* M201 - Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
* M202 - Set max acceleration in units/s^2 for travel moves (M202 X1000 Y1000) Unused in Marlin!!
......@@ -137,8 +144,8 @@
* M209 - S<1=true/0=false> enable automatic retract detect if the slicer did not support G10/11: every normal extrude-only move will be classified as retract depending on the direction.
* M218 - Set hotend offset (in mm): T<extruder_number> X<offset_on_X> Y<offset_on_Y>
* M220 - Set speed factor override percentage: S<factor in percent>
* M221 - Set extrude factor override percentage: S<factor in percent>
* M222 - Set density extrusion percentage for purge: S<factor in percent>
* M221 - T<extruder> S<factor in percent> - set extrude factor override percentage
* M222 - T<extruder> S<factor in percent> - set density extrude factor percentage for purge
* M226 - Wait until the specified pin reaches the state required: P<pin number> S<pin state>
* M240 - Trigger a camera to take a photograph
* M250 - Set LCD contrast C<contrast value> (value 0..63)
......@@ -147,7 +154,9 @@
* M301 - Set PID parameters P I D and C
* M302 - Allow cold extrudes, or set the minimum extrude S<temperature>.
* M303 - PID relay autotune S<temperature> sets the target temperature (default target temperature = 150C). H<hotend> C<cycles> U<Apply result>
* M304 - Set bed PID parameters P I and D
* M304 - Set hot bed PID parameters P I and D
* M305 - Set hot chamber PID parameters P I and D
* M306 - Set cooler PID parameters P I and D
* M350 - Set microstepping mode.
* M351 - Toggle MS1 MS2 pins directly.
* M380 - Activate solenoid on active extruder
......
......@@ -35,9 +35,18 @@
#include "Configuration_Scara.h"
#endif
#include "Configuration_Temperature.h"
#include "Configuration_Feature.h"
#include "Configuration_Overall.h"
#if ENABLED(LASERBEAM)
#include "Configuration_Laser.h"
#if ENABLED(LASER_RASTER)
#include "module/laser/base64/base64.h"
#endif
#include "module/laser/laser.h"
#endif
#include "module/conditionals.h"
#include "module/sanitycheck.h"
#include "module/HAL/HAL.h"
......@@ -56,6 +65,7 @@
#include "module/motion/qr_solve.h"
#include "module/motion/cartesian_correction.h"
#include "module/temperature/temperature.h"
#include "module/sensor/flowmeter.h"
#include "module/temperature/thermistortables.h"
#include "module/lcd/ultralcd.h"
#include "module/lcd/buzzer.h"
......
......@@ -32,11 +32,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/>.
*
*
* Description: *** HAL for Arduino ***
......@@ -92,16 +92,16 @@
inline void protect() {
cli();
}
inline void unprotect() {
SREG = sreg;
}
inline InterruptProtectedBlock(bool later = false) {
sreg = SREG;
if (!later) cli();
}
inline ~InterruptProtectedBlock() {
SREG = sreg;
}
......
/*
HardwareSerial.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. 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 2.1 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
Modified 28 September 2010 by Mark Sproul
*/
/**
* 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/>.
*
*/
/**
* HardwareSerial.h - Hardware serial library for Wiring
* Copyright (c) 2006 Nicholas Zambetti. 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 2.1 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
*
* Modified 28 September 2010 by Mark Sproul
* Modified 3 March 2015 by MagoKimbra
*/
#ifndef HardwareSerial_H
#define HardwareSerial_H
......
......@@ -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/>.
*
*/
......
......@@ -42,6 +42,10 @@
CardReader card;
#endif
#if ENABLED(FLOWMETER_SENSOR) && ENABLED(MINFLOW_PROTECTION)
bool flow_firstread = false;
#endif
bool Running = true;
bool Printing = false;
......@@ -99,6 +103,7 @@ const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
static bool relative_mode = false;
bool cancel_heatup = false;
bool cancel_cooldown = false;
static int serial_count = 0;
......@@ -285,10 +290,6 @@ bool software_endstops = true;
unsigned long stoppower = 0;
#endif
#if ENABLED(LASERBEAM)
int laser_ttl_modulation = 0;
#endif
#if ENABLED(NPR2)
static float color_position[] = COLOR_STEP;
static float color_step_moltiplicator = (DRIVER_MICROSTEP / MOTOR_ANGLE) * CARTER_MOLTIPLICATOR;
......@@ -530,13 +531,6 @@ bool enqueue_and_echo_command(const char* cmd, bool say_ok/*=false*/) {
}
#endif
#if ENABLED(LASERBEAM)
void setup_laserbeampin() {
OUT_WRITE(LASER_PWR_PIN, LOW);
OUT_WRITE(LASER_TTL_PIN, LOW);
}
#endif
#if HAS(POWER_SWITCH)
void setup_powerhold() {
#if HAS(SUICIDE)
......@@ -649,7 +643,7 @@ bool enqueue_and_echo_command(const char* cmd, bool say_ok/*=false*/) {
* • watchdog
* • stepper
* • photo pin
* • laserbeam
* • laserbeam, laser and laser_raster
* • servos
* • LCD controller
* • Digipot I2C
......@@ -710,10 +704,6 @@ void setup() {
setup_photpin();
#endif
#if ENABLED(LASERBEAM)
setup_laserbeampin();
#endif
#if HAS(SERVOS)
servo_init();
#endif
......@@ -738,6 +728,17 @@ void setup() {
setup_statled();
#endif
#if ENABLED(LASERBEAM)
laser_init();
#endif
#if ENABLED(FLOWMETER_SENSOR)
#if ENABLED(MINFLOW_PROTECTION)
flow_firstread = false;
#endif
flow_init();
#endif
#if ENABLED(COLOR_MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1
// Initialize mixing to 100% color 1
for (uint8_t i = 0; i < DRIVER_EXTRUDERS; i++) {
......@@ -1637,6 +1638,10 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
#endif
home_dir(axis);
#if ENABLED(LASERBEAM) && (LASER_HAS_FOCUS == false)
if (axis == Z_AXIS) goto AvoidLaserFocus;
#endif
// Set the axis position as setup for the move
current_position[axis] = 0;
sync_plan_position();
......@@ -1761,6 +1766,11 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
#endif
}
}
#if ENABLED(LASERBEAM) && (LASER_HAS_FOCUS == false)
AvoidLaserFocus:
#endif
if (DEBUGGING(INFO)) {
ECHO_SMV(INFO, "<<< homeaxis(", (unsigned long)axis);
ECHO_EM(")");
......@@ -2889,9 +2899,9 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
#if HAS(TEMP_BED)
ECHO_M(SERIAL_BAT);
#if ENABLED(BED_WATTS)
ECHO_VM(((BED_WATTS) * getHeaterPower(-1)) / 127, "W");
ECHO_VM(((BED_WATTS) * getBedPower()) / 127, "W");
#else
ECHO_V(getHeaterPower(-1));
ECHO_V(getBedPower());
#endif
#endif
ECHO_M(SERIAL_AT ":");
......@@ -2926,6 +2936,56 @@ inline void do_blocking_move_to_z(float z) { do_blocking_move_to(current_positio
}
#endif
#if HAS(TEMP_CHAMBER)
void print_chamberstate() {
ECHO_M(" CHAMBER: ");
ECHO_MV(SERIAL_C, degChamber(), 1);
ECHO_MV(" /", degTargetChamber(), 1);
ECHO_M(SERIAL_CAT);
#if ENABLED(CHAMBER_WATTS)
ECHO_VM(((CHAMBER_WATTS) * getChamberPower()) / 127, "W");
#else
ECHO_V(getChamberPower());
#endif
#if ENABLED(SHOW_TEMP_ADC_VALUES)
ECHO_MV(" ADC C:", degChamber(), 1);
ECHO_MV("C->", rawChamberTemp() / OVERSAMPLENR, 0);
#endif
}
#endif // HAS(TEMP_CHAMBER)
#if HAS(TEMP_COOLER)
void print_coolerstate() {
ECHO_M(" COOL: ");
ECHO_MV(SERIAL_C, degCooler(), 1);
ECHO_MV(" /", degTargetCooler(), 1);
ECHO_M(SERIAL_CAT);
#if ENABLED(COOLER_WATTS)
ECHO_VM(((COOLER_WATTS) * getCoolerPower()) / 127, "W");
#else
ECHO_V(getCoolerPower());
#endif
#if ENABLED(SHOW_TEMP_ADC_VALUES)
ECHO_MV(" ADC C:", degCooler(), 1);
ECHO_MV("C->", rawCoolerTemp() / OVERSAMPLENR, 0);
#endif
}
#endif // HAS(TEMP_COOLER)
#if ENABLED(FLOWMETER_SENSOR)
void print_flowratestate() {
float readval = get_flowrate();
#if ENABLED(MINFLOW_PROTECTION)
if(readval > MINFLOW_PROTECTION)
flow_firstread = true;
#endif
ECHO_MV(" FLOW: ", readval);
ECHO_M(" l/min ");
}
#endif
inline void wait_heater(bool no_wait_for_cooling = true) {
#if ENABLED(TEMP_RESIDENCY_TIME)
......@@ -3072,6 +3132,152 @@ inline void wait_bed(bool no_wait_for_cooling = true) {
KEEPALIVE_STATE(IN_HANDLER);
}
#if HAS(TEMP_CHAMBER)
inline void wait_chamber(bool no_wait_for_heating = true) {
#if TEMP_CHAMBER_RESIDENCY_TIME > 0
millis_t residency_start_ms = 0;
// Loop until the temperature has stabilized
#define TEMP_CHAMBER_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_CHAMBER_RESIDENCY_TIME) * 1000UL))
#else
// Loop until the temperature is very close target
#define TEMP_CHAMBER_CONDITIONS (wants_to_heat ? isHeatingChamber() : isCoolingChamber())
#endif
float theTarget = -1;
bool wants_to_heat;
cancel_cooldown = false;
millis_t now, next_temp_ms = 0;
KEEPALIVE_STATE(NOT_BUSY);
// Wait for temperature to come close enough
do {
now = millis();
if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up.
next_temp_ms = now + 1000UL;
print_chamberstate();
#if TEMP_CHAMBER_RESIDENCY_TIME > 0
ECHO_M(SERIAL_W);
if (residency_start_ms) {
long rem = (((TEMP_CHAMBER_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL;
ECHO_EV(rem);
}
else {
ECHO_EM("?");
}
#else
ECHO_E;
#endif
}
// Target temperature might be changed during the loop
if (theTarget != degTargetChamber()) {
wants_to_heat = isHeatingChamber();
theTarget = degTargetChamber();
// Exit if S<higher>, continue if S<lower>, R<higher>, or R<lower>
if (no_wait_for_heating && wants_to_heat) break;
// Prevent a wait-forever situation if R is misused i.e. M190 C R50
// Simply don't wait to heat a chamber over 25C
if (wants_to_heat && theTarget > 25) break;
}
idle();
refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out
#if TEMP_CHAMBER_RESIDENCY_TIME > 0
float temp_diff = fabs(degTargetBed() - theTarget);
if (!residency_start_ms) {
// Start the TEMP_CHAMBER_RESIDENCY_TIME timer when we reach target temp for the first time.
if (temp_diff < TEMP_CHAMBER_WINDOW) residency_start_ms = millis();
}
else if (temp_diff > TEMP_CHAMBER_HYSTERESIS) {
// Restart the timer whenever the temperature falls outside the hysteresis.
residency_start_ms = millis();
}
#endif //TEMP_CHAMBER_RESIDENCY_TIME > 0
} while (!cancel_cooldown && TEMP_CHAMBER_CONDITIONS);
LCD_MESSAGEPGM(MSG_CHAMBER_DONE);
KEEPALIVE_STATE(IN_HANDLER);
}
#endif
#if HAS(TEMP_COOLER)
inline void wait_cooler(bool no_wait_for_heating = true) {
#if TEMP_COOLER_RESIDENCY_TIME > 0
millis_t residency_start_ms = 0;
// Loop until the temperature has stabilized
#define TEMP_COOLER_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_COOLER_RESIDENCY_TIME) * 1000UL))
#else
// Loop until the temperature is very close target
#define TEMP_COOLER_CONDITIONS (wants_to_heat ? isHeatingCooler() : isCoolingCooler())
#endif
float theTarget = -1;
bool wants_to_heat;
cancel_cooldown = false;
millis_t now, next_temp_ms = 0;
KEEPALIVE_STATE(NOT_BUSY);
// Wait for temperature to come close enough
do {
now = millis();
if (ELAPSED(now, next_temp_ms)) { //Print Temp Reading every 1 second while heating up.
next_temp_ms = now + 1000UL;
print_coolerstate();
#if TEMP_COOLER_RESIDENCY_TIME > 0
ECHO_M(SERIAL_W);
if (residency_start_ms) {
long rem = (((TEMP_COOLER_RESIDENCY_TIME) * 1000UL) - (now - residency_start_ms)) / 1000UL;
ECHO_EV(rem);
}
else {
ECHO_EM("?");
}
#else
ECHO_E;
#endif
}
// Target temperature might be changed during the loop
if (theTarget != degTargetCooler()) {
wants_to_heat = isHeatingCooler();
theTarget = degTargetCooler();
// Exit if S<higher>, continue if S<lower>, R<higher>, or R<lower>
if (no_wait_for_heating && wants_to_heat) break;
// Prevent a wait-forever situation if R is misused i.e. M190 C R50
// Simply don't wait to heat a cooler over 25C
if (wants_to_heat && theTarget > 25) break;
}
idle();
refresh_cmd_timeout(); // to prevent stepper_inactive_time from running out
#if TEMP_COOLER_RESIDENCY_TIME > 0
float temp_diff = fabs(degTargetBed() - theTarget);
if (!residency_start_ms) {
// Start the TEMP_COOLER_RESIDENCY_TIME timer when we reach target temp for the first time.
if (temp_diff < TEMP_COOLER_WINDOW) residency_start_ms = millis();
}
else if (temp_diff > TEMP_COOLER_HYSTERESIS) {
// Restart the timer whenever the temperature falls outside the hysteresis.
residency_start_ms = millis();
}
#endif //TEMP_COOLER_RESIDENCY_TIME > 0
} while (!cancel_cooldown && TEMP_COOLER_CONDITIONS);
LCD_MESSAGEPGM(MSG_COOLER_DONE);
KEEPALIVE_STATE(IN_HANDLER);
}
#endif
/******************************************************************************
***************************** G-Code Functions ********************************
......@@ -3176,7 +3382,7 @@ void unknown_command_error() {
/**
* G0, G1: Coordinated movement of X Y Z E axes
*/
inline void gcode_G0_G1() {
inline void gcode_G0_G1(bool lfire) {
if (IsRunning()) {
gcode_get_destination(); // For X Y Z E F
......@@ -3191,9 +3397,27 @@ inline void gcode_G0_G1() {
return;
}
}
#endif //FWRETRACT
#endif // FWRETRACT
#if ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_G1)
if(lfire) {
if (code_seen('S') && IsRunning()) laser.intensity = (float) code_value();
if (code_seen('L') && IsRunning()) laser.duration = (unsigned long) labs(code_value());
if (code_seen('P') && IsRunning()) laser.ppm = (float) code_value();
if (code_seen('D') && IsRunning()) laser.diagnostics = (bool) code_value();
if (code_seen('B') && IsRunning()) laser_set_mode((int) code_value());
laser.status = LASER_ON;
laser.fired = LASER_FIRE_G1;
}
#endif
prepare_move();
#if ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_G1)
if(lfire) laser.status = LASER_OFF;
#endif
}
}
......@@ -3211,6 +3435,17 @@ inline void gcode_G2_G3(bool clockwise) {
gcode_get_destination();
#if ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_G1)
if (code_seen('S') && IsRunning()) laser.intensity = (float) code_value();
if (code_seen('L') && IsRunning()) laser.duration = (unsigned long) labs(code_value());
if (code_seen('P') && IsRunning()) laser.ppm = (float) code_value();
if (code_seen('D') && IsRunning()) laser.diagnostics = (bool) code_value();
if (code_seen('B') && IsRunning()) laser_set_mode((int) code_value());
laser.status = LASER_ON;
laser.fired = LASER_FIRE_G1;
#endif
#if ENABLED(SF_ARC_FIX)
relative_mode = relative_mode_backup;
#endif
......@@ -3225,6 +3460,11 @@ inline void gcode_G2_G3(bool clockwise) {
plan_arc(destination, arc_offset, clockwise);
refresh_cmd_timeout();
#if ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_G1)
laser.status = LASER_OFF;
#endif
}
}
......@@ -3267,6 +3507,152 @@ inline void gcode_G4() {
#endif //FWRETRACT
#if ENABLED(G5_BEZIER)
inline void gcode_G5() {
float p[4][2] = {{0.0,0.0},{0.0,0.0},{0.0,0.0},{0.0,0.0}};
int steps = 10;
float stepsPerUnit = 1;
float f[2]={0,0};
float fd[2]={0,0};
float fdd[2]={0,0};
float fddd[2]={0,0};
float fdd_per_2[2]={0,0};
float fddd_per_2[2]={0,0};
float fddd_per_6[2]={0,0};
float t = (1.0);
float temp;
// get coordinates
//---------------------------------------
// start point
p[0][0] = current_position[0];
p[0][1] = current_position[1];
// control point 1
if(code_seen('I')) p[1][0] = (float)code_value() + (axis_relative_modes[0] || relative_mode)*current_position[0];
if(code_seen('J')) p[1][1] = (float)code_value() + (axis_relative_modes[1] || relative_mode)*current_position[1];
// control point 2
if(code_seen('K')) p[2][0] = (float)code_value() + (axis_relative_modes[0] || relative_mode)*current_position[0];
if(code_seen('L')) p[2][1] = (float)code_value() + (axis_relative_modes[1] || relative_mode)*current_position[1];
// end point
if(code_seen(axis_codes[0])) p[3][0] = (float)code_value() + (axis_relative_modes[0] || relative_mode)*current_position[0];
if(code_seen(axis_codes[1])) p[3][1] = (float)code_value() + (axis_relative_modes[1] || relative_mode)*current_position[1];
#ifdef DEBUG
log_float("CX", p[0][0]);
log_float("CY", p[0][1]);
log_float("I", p[1][0]);
log_float("J", p[1][1]);
log_float("K", p[2][0]);
log_float("L", p[2][1]);
log_float("X", p[3][0]);
log_float("Y", p[3][1]);
#endif
// calc num steps
float maxD = 0, sqrD = 0;
for (int i=1; i<4; i++) {
sqrD = (p[i][0] - p[i-1][0])*(p[i][0] - p[i-1][0]) + (p[i][1] - p[i-1][1])*(p[i][1] - p[i-1][1]);
if (sqrD > maxD) {maxD = sqrD; };
}
maxD = sqrt(maxD);
if (maxD > 0)
steps = round((3 * maxD * stepsPerUnit));
if (steps < 1)
steps = 1;
if (steps > 200)
steps = 200;
#ifdef DEBUG
log_float("maxD",maxD);
log_int("steps", steps);
#endif
// init Forward Differencing algo
//---------------------------------------
t = 1.0 / steps;
temp = t*t;
for (int i = 0; i < 2; i++) {
f[i] = p[0][i];
fd[i] = 3 * (p[1][i] - p[0][i]) * t;
fdd_per_2[i] = 3 * (p[0][i] - 2 * p[1][i] + p[2][i]) * temp;
fddd_per_2[i] = 3 * (3 * (p[1][i] - p[2][i]) + p[3][i] - p[0][i]) * temp * t;
fddd[i] = fddd_per_2[i] + fddd_per_2[i];
fdd[i] = fdd_per_2[i] + fdd_per_2[i];
fddd_per_6[i] = (fddd_per_2[i] * (1.0 / 3));
}
// prep destination
for(int i = 0; i < NUM_AXIS; i++) {
destination[i] = current_position[i];
}
// iterate through curve
//---------------------------------------
for (int loop = 0; loop < steps; loop++) {
destination[0] = f[0];
destination[1] = f[1];
#ifdef DEBUG
log_float("X",f[0]);
log_float("Y",f[1]);
#endif
prepare_move();
previous_millis_cmd = millis();
// update f
for (int i=0; i<2; i++) {
f[i] = f[i] + fd[i] + fdd_per_2[i] + fddd_per_6[i];
fd[i] = fd[i] + fdd[i] + fddd_per_2[i];
fdd[i] = fdd[i] + fddd[i];
fdd_per_2[i] = fdd_per_2[i] + fddd_per_2[i];
}
}
// Move to final position
destination[0] = p[3][0];
destination[1] = p[3][1];
prepare_move();
previous_millis_cmd = millis();
}
#endif
#if ENABLED(LASERBEAM) && ENABLED(LASER_RASTER)
inline void gcode_G7() {
if (code_seen('L')) laser.raster_raw_length = int(code_value());
if (code_seen('$')) {
laser.raster_direction = (bool)code_value();
destination[Y_AXIS] = current_position[Y_AXIS] + (laser.raster_mm_per_pulse * laser.raster_aspect_ratio); // increment Y axis
}
if (code_seen('D')) laser.raster_num_pixels = base64_decode(laser.raster_data, seen_pointer+1, laser.raster_raw_length);
if (!laser.raster_direction) {
destination[X_AXIS] = current_position[X_AXIS] - (laser.raster_mm_per_pulse * laser.raster_num_pixels);
if (laser.diagnostics)
ECHO_LM(INFO, "Negative Raster Line");
}
else {
destination[X_AXIS] = current_position[X_AXIS] + (laser.raster_mm_per_pulse * laser.raster_num_pixels);
if (laser.diagnostics)
ECHO_LM(INFO, "Positive Raster Line");
}
laser.ppm = 1 / laser.raster_mm_per_pulse; // number of pulses per millimetre
laser.duration = (1000000 / ( feedrate / 60)) / laser.ppm; // (1 second in microseconds / (time to move 1mm in microseconds)) / (pulses per mm) = Duration of pulse, taking into account feedrate as speed and ppm
laser.mode = RASTER;
laser.status = LASER_ON;
laser.fired = RASTER;
prepare_move();
}
#endif
/**
* G28: Home all axes according to settings
*
......@@ -4478,7 +4864,12 @@ inline void gcode_G92() {
current_position[i] = v;
if (i != E_AXIS) {
if (i == E_AXIS) {
#if DISABLED(MUVE_Z_PEEL)
plan_set_e_position(v);
#endif
}
else {
position_shift[i] += v - p; // Offset the coordinate space
update_software_endstops((AxisEnum)i);
didXYZ = true;
......@@ -4549,35 +4940,43 @@ inline void gcode_G92() {
}
#endif //ULTIPANEL
#if ENABLED(LASERBEAM)
#if (ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_SPINDLE))
/**
* M3: S - Setting laser beam
* M3: S - Setting laser beam or fire laser
*/
inline void gcode_M3() {
if (code_seen('S')) {
laser_ttl_modulation = constrain(code_value(), 0, 255);
}
else {
laser_ttl_modulation = 0;
}
}
inline void gcode_M3_M4() {
if (code_seen('S') && IsRunning()) laser.intensity = (float) code_value();
if (code_seen('L') && IsRunning()) laser.duration = (unsigned long) labs(code_value());
if (code_seen('P') && IsRunning()) laser.ppm = (float) code_value();
if (code_seen('D') && IsRunning()) laser.diagnostics = (bool) code_value();
if (code_seen('B') && IsRunning()) laser_set_mode((int) code_value());
/**
* M4: Turn on laser beam
*/
inline void gcode_M4() {
WRITE(LASER_PWR_PIN, HIGH);
laser_ttl_modulation = 0;
laser.status = LASER_ON;
laser.fired = LASER_FIRE_SPINDLE;
lcd_update();
prepare_move();
}
/**
* M5: Turn off laser beam
*/
inline void gcode_M5() {
WRITE(LASER_PWR_PIN, LOW);
laser_ttl_modulation = 0;
if (laser.status != LASER_OFF) {
laser.status = LASER_OFF;
laser.mode = CONTINUOUS;
laser.duration = 0;
lcd_update();
prepare_move();
if (laser.diagnostics)
ECHO_LM(INFO, "Laser M5 called and laser OFF");
}
}
#endif //LASERBEAM
#endif // LASERBEAM
/**
* M11: Start/Stop printing serial mode
......@@ -5079,6 +5478,11 @@ inline void gcode_M78() {
LCD_MESSAGEPGM(WELCOME_MSG);
lcd_update();
#endif
#if ENABLED(LASERBEAM) && ENABLED(LASER_PERIPHERALS)
laser_peripherals_on();
laser_wait_for_peripherals();
#endif
}
#endif // HAS(POWER_SWITCH)
......@@ -5089,14 +5493,21 @@ inline void gcode_M78() {
*/
inline void gcode_M81() {
disable_all_heaters();
disable_all_coolers();
st_synchronize();
disable_e();
finishAndDisableSteppers();
fanSpeed = 0;
#if ENABLED(LASERBEAM)
laser_ttl_modulation = 0;
laser_extinguish();
#if ENABLED(LASER_PERIPHERALS)
laser_peripherals_off();
#endif
#endif
delay_ms(1000); // Wait 1 second before switching off
#if HAS(SUICIDE)
st_synchronize();
suicide();
......@@ -5104,6 +5515,7 @@ inline void gcode_M81() {
OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
powersupply = false;
#endif
#if ENABLED(ULTIPANEL)
LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF ".");
lcd_update();
......@@ -5441,9 +5853,20 @@ inline void gcode_M104() {
inline void gcode_M105() {
if (get_target_extruder_from_command(105)) return;
#if HAS(TEMP_0) || HAS(TEMP_BED) || ENABLED(HEATER_0_USES_MAX6675)
#if HAS(TEMP_0) || HAS(TEMP_BED) || ENABLED(HEATER_0_USES_MAX6675) || HAS(TEMP_COOLER) || ENABLED(FLOWMETER_SENSOR)
ECHO_S(OK);
print_heaterstates();
#if HAS(TEMP_0) || HAS(TEMP_BED) || ENABLED(HEATER_0_USES_MAX6675)
print_heaterstates();
#endif
#if HAS(TEMP_CHAMBER)
print_chamberstate();
#endif
#if HAS(TEMP_COOLER)
print_coolerstate();
#endif
#if ENABLED(FLOWMETER_SENSOR)
print_flowratestate();
#endif
#else // HASNT(TEMP_0) && HASNT(TEMP_BED)
ECHO_LM(ER, SERIAL_ERR_NO_THERMISTORS);
#endif
......@@ -5465,8 +5888,8 @@ inline void gcode_M105() {
#endif // HAS(FAN)
/**
* M109: Sxxx Wait for extruder(s) to reach temperature. Waits only when heating.
* Rxxx Wait for extruder(s) to reach temperature. Waits when heating and cooling.
* M109: Sxxx Wait for hotend(s) to reach temperature. Waits only when heating.
* Rxxx Wait for hotend(s) to reach temperature. Waits when heating and cooling.
*/
inline void gcode_M109() {
if (get_target_extruder_from_command(109)) return;
......@@ -5637,13 +6060,35 @@ inline void gcode_M122() {
#endif
#endif //BARICUDA
/**
* M140: Set bed temperature
*/
inline void gcode_M140() {
if (DEBUGGING(DRYRUN)) return;
if (code_seen('S')) setTargetBed(code_value());
}
#if HAS(TEMP_BED)
/**
* M140: Set Bed temperature
*/
inline void gcode_M140() {
if (DEBUGGING(DRYRUN)) return;
if (code_seen('S')) setTargetBed(code_value());
}
#endif
#if HAS(TEMP_CHAMBER)
/**
* M141: Set Chamber temperature
*/
inline void gcode_M141() {
if (DEBUGGING(DRYRUN)) return;
if (code_seen('S')) setTargetChamber(code_value());
}
#endif
#if HAS(TEMP_COOLER)
/**
* M142: Set Cooler temperature
*/
inline void gcode_M142() {
if (DEBUGGING(DRYRUN)) return;
if (code_seen('S')) setTargetCooler(code_value());
}
#endif
#if ENABLED(ULTIPANEL) && TEMP_SENSOR_0 != 0
/**
......@@ -5805,6 +6250,38 @@ inline void gcode_M140() {
}
#endif // HAS(TEMP_BED)
#if HAS(TEMP_CHAMBER)
/**
* M191: Sxxx Wait for chamber current temp to reach target temp. Waits only when heating
* Rxxx Wait for chamber current temp to reach target temp. Waits when heating and cooling
*/
inline void gcode_M191() {
if (DEBUGGING(DRYRUN)) return;
LCD_MESSAGEPGM(MSG_CHAMBER_HEATING);
bool no_wait_for_cooling = code_seen('S');
if (no_wait_for_cooling || code_seen('R')) setTargetChamber(code_value());
wait_chamber(no_wait_for_cooling);
}
#endif // HAS(TEMP_CHAMBER)
#if HAS(TEMP_COOLER)
/**
* M192: Sxxx Wait for cooler current temp to reach target temp. Waits only when heating
* Rxxx Wait for cooler current temp to reach target temp. Waits when heating and cooling
*/
inline void gcode_M192() {
if (DEBUGGING(DRYRUN)) return;
LCD_MESSAGEPGM(MSG_COOLER_COOLING);
bool no_wait_for_heating = code_seen('S');
if (no_wait_for_heating || code_seen('R')) setTargetCooler(code_value());
wait_cooler(no_wait_for_heating);
}
#endif
/**
* M200: Set filament diameter and set E axis units to cubic millimetres
*
......@@ -5865,7 +6342,6 @@ inline void gcode_M201() {
}
#endif
/**
* M203: Set maximum feedrate that your machine can sustain in mm/sec
*
......@@ -6263,11 +6739,11 @@ inline void gcode_M226() {
}
#endif // PREVENT_DANGEROUS_EXTRUDE
#if HAS(PID_HEATING)
#if HAS(PID_HEATING) || HAS(PID_COOLING)
/**
* M303: PID relay autotune
* S<temperature> sets the target temperature. (default target temperature = 150C)
* H<hotend> (-1 for the bed) (default 0)
* H<hotend> (-1 for the bed, -2 for chamber, -3 for cooler) (default 0)
* C<cycles>
* U<bool> with a non-zero value will apply the result to current settings
*/
......@@ -6283,7 +6759,7 @@ inline void gcode_M226() {
KEEPALIVE_STATE(NOT_BUSY); // don't send "busy: processing" messages during autotune output
PID_autotune(temp, h, c, u);
KEEPALIVE_STATE(IN_HANDLER);
}
#endif
......@@ -6296,12 +6772,40 @@ inline void gcode_M226() {
if (code_seen('D')) bedKd = scalePID_d(code_value());
updatePID();
ECHO_SMV(DB, "p:", bedKp);
ECHO_SMV(OK, "p:", bedKp);
ECHO_MV(" i:", unscalePID_i(bedKi));
ECHO_EMV(" d:", unscalePID_d(bedKd));
}
#endif // PIDTEMPBED
#if ENABLED(PIDTEMPCHAMBER)
// M305: Set chamber PID parameters P I and D
inline void gcode_M305() {
if (code_seen('P')) chamberKp = code_value();
if (code_seen('I')) chamberKi = scalePID_i(code_value());
if (code_seen('D')) chamberKd = scalePID_d(code_value());
updatePID();
ECHO_SMV(OK, "p:", chamberKp);
ECHO_MV(" i:", unscalePID_i(chamberKi));
ECHO_EMV(" d:", unscalePID_d(chamberKd));
}
#endif // PIDTEMPCHAMBER
#if ENABLED(PIDTEMPCOOLER)
// M306: Set cooler PID parameters P I and D
inline void gcode_M306() {
if (code_seen('P')) coolerKp = code_value();
if (code_seen('I')) coolerKi = scalePID_i(code_value());
if (code_seen('D')) coolerKd = scalePID_d(code_value());
updatePID();
ECHO_SMV(OK, "p:", coolerKp);
ECHO_MV(" i:", unscalePID_i(coolerKi));
ECHO_EMV(" d:", unscalePID_d(coolerKd));
}
#endif // PIDTEMPCOOLER
#if HAS(MICROSTEPS)
// M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
inline void gcode_M350() {
......@@ -7044,6 +7548,7 @@ inline void gcode_M503() {
if ((millis() - last_set > 60000) && cnt <= FILAMENT_CHANGE_PRINTER_OFF) beep = true;
if (cnt >= FILAMENT_CHANGE_PRINTER_OFF && !sleep) {
disable_all_heaters();
disable_all_coolers();
sleep = true;
lcd_reset_alert_level();
LCD_ALERTMESSAGEPGM("Zzzz Zzzz Zzzz");
......@@ -7175,6 +7680,32 @@ inline void gcode_M503() {
}
#endif // DUAL_X_CARRIAGE
#if ENABLED(LASERBEAM)
// M649 set laser options
inline void gcode_M649() {
// do this at the start so we can debug if needed!
if (code_seen('D') && IsRunning()) laser.diagnostics = (bool) code_value();
// Wait for the rest
//st_synchronize();
if (code_seen('S') && IsRunning()) {
laser.intensity = (float) code_value();
laser.rasterlaserpower = laser.intensity;
}
if (code_seen('L') && IsRunning()) laser.duration = (unsigned long) labs(code_value());
if (code_seen('P') && IsRunning()) laser.ppm = (float) code_value();
if (code_seen('B') && IsRunning()) laser_set_mode((int) code_value());
if (code_seen('R') && IsRunning()) laser.raster_mm_per_pulse = ((float) code_value());
if (code_seen('F')) {
float next_feedrate = code_value();
if(next_feedrate > 0.0) feedrate = next_feedrate;
}
}
#endif // LASERBEAM
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
//M666: Set Z probe offset
inline void gcode_M666() {
......@@ -7747,7 +8278,7 @@ void process_next_command() {
// G0 -> G1
case 0:
case 1:
gcode_G0_G1(); break;
gcode_G0_G1(codenum == 1); break;
// G2, G3
#if !MECH(SCARA)
......@@ -7760,6 +8291,18 @@ void process_next_command() {
case 4:
gcode_G4(); break;
#if ENABLED(LASERBEAM)
#if ENABLED(G5_BEZIER)
case 5: // G5: Bezier curve - from http://forums.reprap.org/read.php?147,93577
gcode_G5(); break;
#endif
#if ENABLED(LASER_RASTER)
case 7: // G7: Execute laser raster line
gcode_G7(); break;
#endif
#endif
#if ENABLED(FWRETRACT)
case 10: // G10: retract
case 11: // G11: retract_recover
......@@ -7810,14 +8353,13 @@ void process_next_command() {
gcode_M0_M1(); break;
#endif //ULTIPANEL
#if ENABLED(LASERBEAM)
#if ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_SPINDLE)
case 3: // M03 S - Setting laser beam
gcode_M3(); break;
case 4: // M04 - Turn on laser beam
gcode_M4(); break;
gcode_M3_M4(); break;
case 5: // M05 - Turn off laser beam
gcode_M5(); break;
#endif //LASERBEAM
#endif // LASERBEAM
case 11: // M11 - Start/Stop printing serial mode
gcode_M11(); break;
......@@ -7989,8 +8531,20 @@ void process_next_command() {
#endif // HAS(HEATER_2)
#endif // BARICUDA
case 140: // M140 Set bed temp
gcode_M140(); break;
#if HAS(TEMP_BED)
case 140: // M140 - Set bed temp
gcode_M140(); break;
#endif
#if HAS(TEMP_CHAMBER)
case 141: // M141 - Set chamber temp
gcode_M141(); break;
#endif
#if HAS(TEMP_COOLER)
case 142: // M142 - Set cooler temp
gcode_M142(); break;
#endif
#if ENABLED(BLINKM)
case 150: // M150
......@@ -8011,7 +8565,17 @@ void process_next_command() {
#if HAS(TEMP_BED)
case 190: // M190 - Wait for bed heater to reach target.
gcode_M190(); break;
#endif //TEMP_BED_PIN
#endif // TEMP_BED
#if HAS(TEMP_CHAMBER)
case 191: // M191 - Wait for chamber heater to reach target.
gcode_M191(); break;
#endif
#if HAS(TEMP_COOLER)
case 192: // M192 - Wait for chamber heater to reach target.
gcode_M192(); break;
#endif
case 200: // M200 D<millimetres> set filament diameter and set E axis units to cubic millimetres (use S0 to set back to millimeters).
gcode_M200(); break;
......@@ -8087,10 +8651,20 @@ void process_next_command() {
#endif
#if ENABLED(PIDTEMPBED)
case 304: // M304
case 304: // M304 - Set Bed PID
gcode_M304(); break;
#endif // PIDTEMPBED
#if ENABLED(PIDTEMPCHAMBER)
case 305: // M305 - Set Chamber PID
gcode_M305(); break;
#endif // PIDTEMPCHAMBER
#if ENABLED(PIDTEMPCOOLER)
case 306: // M306 - Set Cooler PID
gcode_M306(); break;
#endif // PIDTEMPCOOLER
#if HAS(MICROSTEPS)
case 350: // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
gcode_M350(); break;
......@@ -8179,6 +8753,11 @@ void process_next_command() {
gcode_M605(); break;
#endif
#if ENABLED(LASERBEAM)
case 649: // M649 set laser options
gcode_M649(); break;
#endif
#if ENABLED(AUTO_BED_LEVELING_FEATURE) || MECH(DELTA)
case 666: // M666 Set Z probe offset or set delta endstop and geometry adjustment
gcode_M666(); break;
......@@ -8258,23 +8837,26 @@ void clamp_to_software_endstops(float target[3]) {
if (SOFTWARE_MIN_ENDSTOPS && software_endstops) {
NOLESS(target[X_AXIS], sw_endstop_min[X_AXIS]);
NOLESS(target[Y_AXIS], sw_endstop_min[Y_AXIS]);
float negative_z_offset = 0;
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
if (zprobe_zoffset < 0) negative_z_offset += zprobe_zoffset;
if (home_offset[Z_AXIS] < 0) {
if (DEBUGGING(INFO))
ECHO_LMV(INFO, "> clamp_to_software_endstops > Add home_offset[Z_AXIS]:", home_offset[Z_AXIS]);
negative_z_offset += home_offset[Z_AXIS];
}
#if !ENABLED(LASERBEAM)
float negative_z_offset = 0;
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
if (zprobe_zoffset < 0) negative_z_offset += zprobe_zoffset;
if (home_offset[Z_AXIS] < 0) {
if (DEBUGGING(INFO))
ECHO_LMV(INFO, "> clamp_to_software_endstops > Add home_offset[Z_AXIS]:", home_offset[Z_AXIS]);
negative_z_offset += home_offset[Z_AXIS];
}
#endif
NOLESS(target[Z_AXIS], sw_endstop_min[Z_AXIS] + negative_z_offset);
#endif
NOLESS(target[Z_AXIS], sw_endstop_min[Z_AXIS] + negative_z_offset);
}
if (SOFTWARE_MAX_ENDSTOPS && software_endstops) {
NOMORE(target[X_AXIS], sw_endstop_max[X_AXIS]);
NOMORE(target[Y_AXIS], sw_endstop_max[Y_AXIS]);
NOMORE(target[Z_AXIS], sw_endstop_max[Z_AXIS]);
#if !ENABLED(LASERBEAM)
NOMORE(target[Z_AXIS], sw_endstop_max[Z_AXIS]);
#endif
}
}
......@@ -8441,13 +9023,21 @@ static void report_current_position() {
#if MECH(CARTESIAN) || MECH(COREXY) || MECH(COREYX) || MECH(COREXZ) || MECH(COREZX)
inline bool prepare_move_cartesian() {
#if ENABLED(LASERBEAM) && ENABLED(LASER_FIRE_E)
if (current_position[E_AXIS] != destination[E_AXIS] && ((current_position[X_AXIS] != destination [X_AXIS]) || (current_position[Y_AXIS] != destination [Y_AXIS]))){
laser.status = LASER_ON;
laser.fired = LASER_FIRE_E;
}
if (current_position[E_AXIS] == destination[E_AXIS] && laser.fired == LASER_FIRE_E)
laser.status = LASER_OFF;
#endif
// Do not use feedrate_multiplier for E or Z only moves
if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) {
if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS])
line_to_destination();
}
else {
else
line_to_destination(feedrate * feedrate_multiplier / 100.0);
}
return true;
}
......@@ -8773,7 +9363,10 @@ void idle(
bool no_stepper_sleep/*=false*/
#endif
) {
manage_heater();
manage_temp_controller();
#if ENABLED(FLOWMETER_SENSOR)
flowrate_manage();
#endif
manage_inactivity(
#if ENABLED(FILAMENT_CHANGE_FEATURE)
no_stepper_sleep
......@@ -8811,6 +9404,12 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
if (max_inactive_time && ELAPSED(ms, previous_cmd_ms + max_inactive_time)) kill(PSTR(MSG_KILLED));
#if ENABLED(FLOWMETER_SENSOR) && ENABLED(MINFLOW_PROTECTION)
if (flow_firstread && Printing && (get_flowrate() < (float)MINFLOW_PROTECTION)) {
flow_firstread = false;
kill(PSTR(MSG_KILLED));
}
#endif
if (stepper_inactive_time && ELAPSED(ms, previous_cmd_ms + stepper_inactive_time)
&& !ignore_stepper_queue && !blocks_queued()) {
#if DISABLE_X == true
......@@ -8825,6 +9424,17 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
#if DISABLE_E == true
disable_e();
#endif
#if ENABLED(LASERBEAM)
if (laser.time / 60000 > 0) {
laser.lifetime += laser.time / 60000; // convert to minutes
laser.time = 0;
Config_StoreSettings();
}
laser_init();
#if ENABLED(LASER_PERIPHERALS)
laser_peripherals_off();
#endif
#endif
}
#if HAS(CHDK) // Check if pin should be set to LOW after M240 set it to HIGH
......@@ -9008,6 +9618,9 @@ void kill(const char* lcd_msg) {
#if ENABLED(KILL_METHOD) && KILL_METHOD == 1
HAL::resetHardware();
#endif
#if ENABLED(FLOWMETER_SENSOR) && ENABLED(MINFLOW_PROTECTION)
flow_firstread = false;
#endif
#if ENABLED(ULTRA_LCD)
lcd_setalertstatuspgm(lcd_msg);
......@@ -9015,8 +9628,16 @@ void kill(const char* lcd_msg) {
cli(); // Stop interrupts
disable_all_heaters();
disable_all_coolers();
disable_all_steppers();
#if ENABLED(LASERBEAM)
laser_init();
#if ENABLED(LASER_PERIPHERALS)
laser_peripherals_off();
#endif
#endif
#if HAS(POWER_SWITCH)
SET_INPUT(PS_ON_PIN);
#endif
......@@ -9043,7 +9664,7 @@ void kill(const char* lcd_msg) {
}
#endif
#if ENABLED(FAST_PWM_FAN)
#if ENABLED(FAST_PWM_FAN) || ENABLED(FAST_PWM_COOLER)
void setPwmFrequency(uint8_t pin, int val) {
val &= 0x07;
......@@ -9112,7 +9733,21 @@ void kill(const char* lcd_msg) {
#endif // FAST_PWM_FAN
void stop() {
#if ENABLED(FLOWMETER_SENSOR) && ENABLED(MINFLOW_PROTECTION)
flow_firstread=false;
#endif
disable_all_heaters();
disable_all_coolers();
#if ENABLED(LASERBEAM)
if (laser.diagnostics) ECHO_LM(INFO, "Laser set to off, stop() called");
laser_extinguish();
#if ENABLED(LASER_PERIPHERALS)
laser_peripherals_off();
#endif
#endif
if (IsRunning()) {
Running = false;
ECHO_LM(ER, SERIAL_ERR_STOPPED);
......
......@@ -116,7 +116,7 @@ inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
extern void delay_ms(millis_t ms);
#if ENABLED(FAST_PWM_FAN)
#if ENABLED(FAST_PWM_FAN) || ENABLED(FAST_PWM_COOLER)
void setPwmFrequency(uint8_t pin, uint8_t val);
#endif
......@@ -236,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;
......@@ -261,6 +257,18 @@ extern uint8_t active_driver;
void print_heaterstates();
#endif
#if HAS(TEMP_CHAMBER)
void print_chamberstate();
#endif
#if HAS(TEMP_COOLER)
void print_coolerstate();
#endif
#if ENABLED(FLOWMETER_SENSOR)
void print_flowratestate();
#endif
#if ENABLED(FIRMWARE_TEST)
void FirmwareTest();
#endif
......
......@@ -13,7 +13,9 @@
#if MB(RAMPS_FD_V1)
#define RAMPS_FD_V1
#define INVERTED_HEATER_PINS
#define INVERTED_BED_PINS
#define INVERTED_BED_PIN
#define INVERTED_CHAMBER_PIN
#define INVERTED_COOLER_PIN
// No EEPROM
// Use 4k7 thermistor tables
#else
......
......@@ -13,7 +13,9 @@
#if MB(RAMPS_FD_V1)
#define RAMPS_FD_V1
#define INVERTED_HEATER_PINS
#define INVERTED_BED_PINS
#define INVERTED_BED_PIN
#define INVERTED_CHAMBER_PIN
#define INVERTED_COOLER_PIN
// No EEPROM
// Use 4k7 thermistor tables
#else
......
......@@ -605,6 +605,32 @@
#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
#undef COOLER_MINTEMP
#undef COOLER_MAXTEMP
#elif TEMP_SENSOR_COOLER > 0
#define THERMISTORCOOLER TEMP_SENSOR_COOLER
#define COOLER_USES_THERMISTOR
#endif
#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))
/**
......@@ -612,6 +638,7 @@
*/
#define HAS_PID_HEATING (ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED))
#define HAS_PID_FOR_BOTH (ENABLED(PIDTEMP) && ENABLED(PIDTEMPBED))
#define HAS_PID_COOLING (ENABLED(PIDTEMPCOOLER))
/**
* ARRAY_BY_EXTRUDERS based on EXTRUDERS
......@@ -661,11 +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_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))
......@@ -790,12 +821,26 @@
#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(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)
#endif
#endif
#if HAS(FAN)
#if ENABLED(INVERTED_HEATER_PINS)
#define WRITE_FAN(v) WRITE(FAN_PIN, !v)
......
......@@ -94,7 +94,6 @@
#define SERIAL_INVALID_HOTEND "Invalid hotend"
#define SERIAL_INVALID_SOLENOID "Invalid solenoid"
#define SERIAL_ERR_NO_THERMISTORS "No thermistors - no temperature"
#define SERIAL_COUNT_X " Count X: "
#define SERIAL_ERR_KILLED "Printer halted. kill() called!"
#define SERIAL_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
#define SERIAL_BUSY_PROCESSING "processing"
......@@ -168,8 +167,9 @@
#define SERIAL_PID_AUTOTUNE "PID Autotune"
#define SERIAL_PID_AUTOTUNE_START SERIAL_PID_AUTOTUNE " start"
#define SERIAL_PID_AUTOTUNE_FAILED SERIAL_PID_AUTOTUNE " failed!"
#define SERIAL_PID_BAD_EXTRUDER_NUM SERIAL_PID_AUTOTUNE_FAILED " Bad extruder number"
#define SERIAL_PID_BAD_TEMP_CONTROLLER_NUM SERIAL_PID_AUTOTUNE_FAILED " Bad temperature controller number"
#define SERIAL_PID_TEMP_TOO_HIGH SERIAL_PID_AUTOTUNE_FAILED " Temperature too high"
#define SERIAL_PID_TEMP_TOO_LOW SERIAL_PID_AUTOTUNE_FAILED " Temperature too low"
#define SERIAL_PID_TIMEOUT SERIAL_PID_AUTOTUNE_FAILED " timeout"
#define SERIAL_BIAS " bias: "
#define SERIAL_D " d: "
......@@ -182,9 +182,11 @@
#define SERIAL_KI " Ki: "
#define SERIAL_KD " Kd: "
#define SERIAL_T " T:"
#define SERIAL_C " C:"
#define SERIAL_B " B:"
#define SERIAL_AT " @"
#define SERIAL_BAT " B@:"
#define SERIAL_CAT " C@:"
#define SERIAL_W " W:"
#define SERIAL_PID_AUTOTUNE_FINISHED SERIAL_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from above into Configuration.h or send command M500 for save in EEPROM the new value!"
#define SERIAL_PID_DEBUG " PID_DEBUG "
......@@ -196,8 +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_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"
......@@ -228,6 +232,8 @@
#define SERIAL_BED_LEVELLING_Y " Y: "
#define SERIAL_BED_LEVELLING_Z " Z: "
#define MSG_COOLER "Cooler"
// LCD Menu Messages
#define LANGUAGE_INCL_(M) STRINGIFY_(language_##M.h)
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -218,6 +220,9 @@
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
#define MSG_CONFIG "Configuration"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "часа"
#define MSG_END_MINUTE "минути"
......@@ -218,6 +220,9 @@
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
#define MSG_CONFIG "Configuration"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -218,6 +220,9 @@
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
#define MSG_CONFIG "Configuration"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -218,6 +220,10 @@
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
#define MSG_CONFIG "Configuration"
......
......@@ -183,6 +183,8 @@
#define MSG_ERR_MINTEMP "Chyba: NIZKA TEPLOTA"
#define MSG_ERR_MAXTEMP_BED "Chyba: VYSOKA TEPLOTA PODL."
#define MSG_ERR_MINTEMP_BED "Chyba: NIZKA TEPLOTA PODL."
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hod"
#define MSG_END_MINUTE "min"
......@@ -220,6 +222,9 @@
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
#define MSG_CONFIG "Configuration"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "timer"
#define MSG_END_MINUTE "minutter"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Opvarmet"
#define MSG_BED_HEATING "Opvarmer plade"
#define MSG_BED_DONE "Plade opvarmet"
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "tage"
#define MSG_END_HOUR "uur"
#define MSG_END_MINUTE "minuten"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -184,6 +184,10 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_CHAMBER "MAXTEMP CHAMBER ERROR"
#define MSG_ERR_MINTEMP_CHAMBER "MINTEMP CHAMBER ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -244,6 +248,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "heures"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -155,12 +155,17 @@
#define MSG_ERR_MINTEMP "Err: temp. min."
#define MSG_ERR_MAXTEMP_BED "Err: MAXTEMP BED"
#define MSG_ERR_MINTEMP_BED "Err: MINTEMP BED"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_HOUR "horas"
#define MSG_END_MINUTE "minutos"
#define MSG_HEATING "Quentando..."
#define MSG_HEATING_COMPLETE "Xa esta quente"
#define MSG_BED_HEATING "Quentando cama"
#define MSG_BED_DONE "Cama esta quente"
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
#define MSG_DELTA_CALIBRATE "Calibracion Delta"
#define MSG_DELTA_CALIBRATE_X "Calibrar X"
......
......@@ -181,6 +181,10 @@
#define MSG_ERR_MINTEMP "Err: TEMP MINIMA"
#define MSG_ERR_MAXTEMP_BED "Err: TEMP MASSIMA PIATTO"
#define MSG_ERR_MINTEMP_BED "Err: TEMP MINIMA PIATTO"
#define MSG_ERR_MAXTEMP_CHAMBER "MAXTEMP CHAMBER ERROR"
#define MSG_ERR_MINTEMP_CHAMBER "MINTEMP CHAMBER ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "giorni"
#define MSG_END_HOUR "ore"
#define MSG_END_MINUTE "minuti"
......@@ -241,6 +245,8 @@
#define MSG_HEATING_COMPLETE "Riscaldamento finito."
#define MSG_BED_HEATING "Riscaldamento piatto."
#define MSG_BED_DONE "Piatto riscaldato."
#define MSG_COOLER_COOLING "Raffreddamento..."
#define MSG_COOLER_DONE "Raffreddamento finito."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -183,6 +183,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -219,6 +221,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -186,6 +186,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -222,6 +224,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -157,12 +157,17 @@
#define MSG_ERR_MINTEMP "Err: T Mínima"
#define MSG_ERR_MAXTEMP_BED "Err: T Base Máxima"
#define MSG_ERR_MINTEMP_BED "Err: T Base Mínima"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_HOUR "Horas"
#define MSG_END_MINUTE "Minutos"
#define MSG_HEATING "Aquecendo..."
#define MSG_HEATING_COMPLETE "Aquecida."
#define MSG_BED_HEATING "Aquecendo base.."
#define MSG_BED_DONE "Base aquecida."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
#define MSG_DELTA_CALIBRATE "Calibrar Delta"
#define MSG_DELTA_CALIBRATE_X "Calibrar X"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
......@@ -161,12 +161,17 @@
#define MSG_ERR_MINTEMP "Err: T Mínima"
#define MSG_ERR_MAXTEMP_BED "Err: T Base Máxima"
#define MSG_ERR_MINTEMP_BED "Err: T Base Mínima"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_HOUR "horas"
#define MSG_END_MINUTE "minutos"
#define MSG_HEATING "Aquecendo..."
#define MSG_HEATING_COMPLETE "Aquecida."
#define MSG_BED_HEATING "Aquecendo base.."
#define MSG_BED_DONE "Base aquecida."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
#define MSG_DELTA_CALIBRATE "Calibração Delta"
#define MSG_DELTA_CALIBRATE_X "Calibrar X"
......
......@@ -181,6 +181,8 @@
#define MSG_ERR_MINTEMP "MINTEMP ERROR"
#define MSG_ERR_MAXTEMP_BED "MAXTEMP BED ERROR"
#define MSG_ERR_MINTEMP_BED "MINTEMP BED ERROR"
#define MSG_ERR_MAXTEMP_COOLER "MAXTEMP COOLER ERROR"
#define MSG_ERR_MINTEMP_COOLER "MINTEMP COOLER ERROR"
#define MSG_END_DAY "days"
#define MSG_END_HOUR "hours"
#define MSG_END_MINUTE "minutes"
......@@ -217,6 +219,9 @@
#define MSG_HEATING_COMPLETE "Heating done."
#define MSG_BED_HEATING "Bed Heating."
#define MSG_BED_DONE "Bed done."
#define MSG_COOLER_COOLING "Cooling..."
#define MSG_COOLER_DONE "Cooling done."
// Extra
#define MSG_LASER "Laser Preset"
......
/**
* 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"
"0123456789+/";
/* 'Private' declarations */
inline void a3_to_a4(unsigned char * a4, unsigned char * a3);
inline void a4_to_a3(unsigned char * a3, unsigned char * a4);
inline unsigned char b64_lookup(char c);
int base64_encode(char *output, char *input, int inputLen) {
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while(inputLen--) {
a3[i++] = *(input++);
if(i == 3) {
a3_to_a4(a4, a3);
for(i = 0; i < 4; i++) {
output[encLen++] = b64_alphabet[a4[i]];
}
i = 0;
}
}
if(i) {
for(j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for(j = 0; j < i + 1; j++) {
output[encLen++] = b64_alphabet[a4[j]];
}
while((i++ < 3)) {
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
int base64_decode(unsigned char * output, char * input, int inputLen) {
int i = 0, j = 0;
int decLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--) {
if(*input == '=') {
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
for (i = 0; i < 3; i++) {
output[decLen++] = a3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
a4[j] = '\0';
}
for (j = 0; j <4; j++) {
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
for (j = 0; j < i - 1; j++) {
output[decLen++] = a3[j];
}
}
output[decLen] = '\0';
return decLen;
}
int base64_enc_len(int plainLen) {
int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
int base64_dec_len(char * input, int inputLen) {
int i = 0;
int numEq = 0;
for(i = inputLen - 1; input[i] == '='; i--) {
numEq++;
}
return ((6 * inputLen) / 8) - numEq;
}
inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
inline unsigned char b64_lookup(char c) {
if(c >='A' && c <='Z') return c - 'A';
if(c >='a' && c <='z') return c - 71;
if(c >='0' && c <='9') return c + 4;
if(c == '+') return 62;
if(c == '/') return 63;
return -1;
}
/**
* 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
/**
* 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(LASERBEAM)
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();
#endif
}
#if ENABLED(LASER_PULSE_METHOD)
ISR(TIMER4_COMPA_vect) {
OCR3A = 0; // 0 Duty cycle
// 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
}
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))
pinMode(LASER_PWR_PIN, OUTPUT);
#endif
#if LASER_CONTROL == 1
#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
analogWrite(LASER_TTL_PIN, labs((intensity / 100.0) * (F_CPU / LASER_PWM)));
digitalWrite(LASER_PWR_PIN, LASER_ARM);
#endif
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");
}
}
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;
}
}
#if ENABLED(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");
}
}
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 // LASERBEAM
/**
* 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
*/
#ifndef LASER_H
#define LASER_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
#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
} laser_t;
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);
#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
// Laser constants
#define LASER_OFF 0
#define LASER_ON 1
#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
#define LASERENABLE_BYTEWIDTH 4
const unsigned char laserenable_bmp[] PROGMEM = {
0x00, 0x1c, 0x00, 0x00,
0x00, 0x3e, 0x00, 0x00,
0x00, 0x77, 0x00, 0x00,
0x00, 0x63, 0x00, 0x00,
0x00, 0xc1, 0x80, 0x00,
0x01, 0xc1, 0xc0, 0x00,
0x01, 0x88, 0xc0, 0x00,
0x03, 0x08, 0x60, 0x00,
0x07, 0x41, 0x70, 0x00,
0x06, 0x2a, 0x30, 0x00,
0x0c, 0x1c, 0x18, 0x00,
0x1d, 0xbf, 0xfc, 0x00,
0x18, 0x1c, 0x0c, 0x00,
0x30, 0x2a, 0x06, 0x00,
0x70, 0x41, 0x07, 0x00,
0x60, 0x88, 0x83, 0x00,
0xc0, 0x08, 0x01, 0x80,
0xc0, 0x00, 0x01, 0x80,
0xff, 0xff, 0xff, 0x80,
0x7f, 0xff, 0xff, 0x00
};
#define ICON_HEIGHT 13
#define ICON_WIDTH 12
#define ICON_BYTEWIDTH 2
const unsigned char laseron_bmp[] PROGMEM = {
0xff, 0xf0,
0x8f, 0x10,
0x8f, 0x10,
0x9f, 0x90,
0x9f, 0x90,
0x80, 0x10,
0x86, 0x10,
0x86, 0x10,
0xc6, 0x30,
0xa6, 0x50,
0x96, 0x90,
0xaf, 0x50,
0xff, 0xf0
};
const unsigned char laseroff_bmp[] PROGMEM = {
0xff, 0xf0,
0x8f, 0x10,
0x8f, 0x10,
0x9f, 0x90,
0x9f, 0x90,
0x80, 0x10,
0x80, 0x10,
0x80, 0x10,
0x80, 0x10,
0x80, 0x10,
0x80, 0x10,
0x80, 0x10,
0xff, 0xf0
};
const unsigned char lockicon_bmp[] PROGMEM = {
0x0f, 0x00,
0x19, 0x80,
0x30, 0xc0,
0x20, 0x40,
0x20, 0x40,
0x20, 0x40,
0x3f, 0xc0,
0x20, 0x40,
0x26, 0x40,
0x26, 0x40,
0x2f, 0x40,
0x20, 0x40,
0x3f, 0xc0
};
const unsigned char vacicon_bmp[] PROGMEM = {
0x06, 0x00,
0x06, 0x00,
0x06, 0x00,
0x0f, 0x00,
0x0f, 0x00,
0x1f, 0x80,
0x3f, 0xc0,
0xff, 0xf0,
0xff, 0xf0,
0xc0, 0x30,
0x16, 0x80,
0x29, 0x40,
0x50, 0xa0
};
const unsigned char airicon_bmp[] PROGMEM = {
0x32, 0xc0,
0x30, 0xc0,
0x34, 0xc0,
0x30, 0xc0,
0x32, 0xc0,
0x30, 0xc0,
0x34, 0xc0,
0x19, 0x80,
0x02, 0x00,
0x00, 0x00,
0x04, 0x00,
0x09, 0x00,
0x22, 0x40
};
const unsigned char watericon_bmp[] PROGMEM = {
0x02, 0x00,
0x07, 0x00,
0x05, 0x00,
0x0d, 0x80,
0x08, 0x80,
0x18, 0xc0,
0x10, 0x40,
0x30, 0x60,
0x38, 0x20,
0x3c, 0x60,
0x3f, 0xe0,
0x1f, 0xc0,
0x0f, 0x80
};
......@@ -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
......@@ -162,6 +162,7 @@ void Endstops::report_state() {
card.closeFile();
quickStop();
disable_all_heaters(); // switch off all heaters.
disable_all_coolers();
}
#endif
}
......
......@@ -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,8 +620,10 @@ 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])));
// 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;
......@@ -645,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)
......@@ -879,6 +867,51 @@ float junction_deviation = 0.1;
#endif
);
}
#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;
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 && 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
// Calculate speed in mm/second for each axis. No divide by zero due to previous checks.
......
......@@ -100,14 +100,25 @@ typedef struct {
#endif
#if ENABLED(LASERBEAM)
unsigned long laser_ttlmodulation;
#endif
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
unsigned long laser_duration; // laser firing duration in microseconds, for pulsed and raster firing modes
unsigned long steps_l; // step count between firings of the laser, for pulsed firing mode
float laser_intensity; // Laser firing instensity in clock cycles for the PWM timer
#if ENABLED(LASER_RASTER)
unsigned char laser_raster_data[LASER_MAX_RASTER_LINE];
float laser_raster_intensity_factor;
#endif
#endif
volatile char busy;
} block_t;
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
#define MAX_EVENTS_COUNT 2147483648 // max for a signed 32 bit number
// Initialize the motion plan subsystem
void plan_init();
......
......@@ -68,6 +68,13 @@ 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;
#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,
locked_z_motor = false,
......@@ -114,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 };
//===========================================================================
......@@ -419,6 +426,15 @@ ISR(TIMER1_COMPA_vect) {
return;
}
#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();
}
#endif
// If there is no current block, attempt to pop one from the buffer
if (!current_block) {
// Anything in the buffer?
......@@ -430,6 +446,13 @@ 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(LASERBEAM)
counter_L = counter_X;
#if !ENABLED(LASER_PULSE_METHOD)
laser.dur = current_block->laser_duration;
#endif
#endif
#if ENABLED(COLOR_MIXING_EXTRUDER)
for (uint8_t i = 0; i < DRIVER_EXTRUDERS; i++)
counter_m[i] = -(current_block->step_event_count >> 1);
......@@ -445,6 +468,10 @@ ISR(TIMER1_COMPA_vect) {
}
#endif
#if ENABLED(LASERBEAM) && ENABLED(LASER_RASTER)
if (current_block->laser_mode == RASTER) counter_raster = 0;
#endif
// #if ENABLED(ADVANCE)
// e_steps[current_block->active_driver] = 0;
// #endif
......@@ -463,6 +490,19 @@ ISR(TIMER1_COMPA_vect) {
if (endstops.enabled) endstops.update();
#endif
// Continuous firing of the laser during a move happens here, PPM and raster happen further down
#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();
}
#endif
#endif
// Take multiple steps per interrupt (For high speed moves)
for (uint8_t i = 0; i < step_loops; i++) {
......@@ -557,6 +597,66 @@ ISR(TIMER1_COMPA_vect) {
#endif
#endif
#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;
#else
laser_fire(current_block->laser_intensity);
#endif
if (laser.diagnostics) {
ECHO_MV("X: ", counter_X);
ECHO_MV("Y: ", counter_Y);
ECHO_MV("L: ", counter_L);
}
}
#if ENABLED(LASER_RASTER)
if (current_block->laser_mode == RASTER && current_block->laser_status == LASER_ON) { // Raster Firing Mode
#if ENABLED(LASER_PULSE_METHOD)
uint32_t ulValue = current_block->laser_raster_intensity_factor *
current_block->laser_raster_data[counter_raster];
laser_pulse(ulValue, current_block->laser_duration);
counter_raster++;
laser.time += current_block->laser_duration/1000;
#else
// For some reason, when comparing raster power to ppm line burns the rasters were around 2% more powerful
// going from darkened paper to burning through paper.
laser_fire(current_block->laser_raster_data[counter_raster]);
#endif
if (laser.diagnostics) ECHO_EMV("Pixel: ", (float)current_block->laser_raster_data[counter_raster]);
counter_raster++;
}
#endif // LASER_RASTER
counter_L -= current_block->step_event_count;
}
#if !ENABLED(LASER_PULSE_METHOD)
if (current_block->laser_duration != 0 && (laser.last_firing + current_block->laser_duration < micros())) {
if (laser.diagnostics) {
ECHO_MV("X: ", counter_X);
ECHO_MV(", Y: ", counter_Y);
ECHO_MV(", L: ", counter_L);
ECHO_MV(", Z: ", counter_L);
ECHO_MV(", E: ", counter_E);
ECHO_MV(", steps done: ",step_events_completed);
ECHO_MV(", event count: ", current_block->step_event_count);
ECHO_EM(", <--------------------");
ECHO_LM(INFO, "Laser firing duration elapsed, in interrupt fast loop ");
}
laser_extinguish();
}
#endif
#endif // LASERBEAM
// safe check for erroneous calculated events count
if(current_block->step_event_count >= MAX_EVENTS_COUNT) {
kill_current_block();
break;
}
step_events_completed++;
if (step_events_completed >= current_block->step_event_count) break;
}
......@@ -664,6 +764,10 @@ ISR(TIMER1_COMPA_vect) {
if (step_events_completed >= current_block->step_event_count) {
current_block = NULL;
plan_discard_current_block();
#if ENABLED(LASERBEAM) && ENABLED(LASER_PULSE_METHOD)
if (current_block->laser_mode == CONTINUOUS && current_block->laser_status == LASER_ON)
laser_extinguish();
#endif
}
}
}
......
......@@ -65,7 +65,7 @@ bool recvRetNumber(uint32_t *number, uint32_t timeout)
&& temp[7] == 0xFF
)
{
*number = (temp[4] << 24) | (temp[3] << 16) | (temp[2] << 8) | (temp[1]);
*number = ((uint32_t)temp[4] << 24) | ((uint32_t)temp[3] << 16) | ((uint32_t)temp[2] << 8) | ((uint32_t)temp[1]);
ret = true;
}
......
......@@ -344,6 +344,26 @@
#define _E5_PINS
#endif
#ifndef TEMP_COOLER_PIN
#define TEMP_COOLER_PIN -1
#endif
#ifndef COOLER_PIN
#define COOLER_PIN -1
#endif
#ifndef LASER_PWR_PIN
#define LASER_PWR_PIN -1
#endif
#ifndef LASER_TTL_PIN
#define LASER_TTL_PIN -1
#endif
#ifndef FLOWMETER_PIN
#define FLOWMETER_PIN -1
#endif
#define SENSITIVE_PINS { 0, 1, \
X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, \
Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, \
......@@ -351,7 +371,10 @@
PS_ON_PIN, HEATER_BED_PIN, FAN_PIN, \
_H0_PINS _H1_PINS _H2_PINS _H3_PINS \
_E0_PINS _E1_PINS _E2_PINS _E3_PINS _E4_PINS _E5_PINS \
analogInputToDigitalPin(TEMP_BED_PIN) \
analogInputToDigitalPin(TEMP_BED_PIN), \
analogInputToDigitalPin(TEMP_COOLER_PIN), \
COOLER_PIN, LASER_PWR_PIN, LASER_TTL_PIN, \
FLOWMETER_PIN \
}
#endif //__PINS_H
......@@ -82,12 +82,18 @@
#if DISABLED(TEMP_SENSOR_BED)
#error DEPENDENCY ERROR: Missing setting TEMP_SENSOR_BED
#endif
#if (THERMISTORHEATER_0 == 998) || (THERMISTORHEATER_1 == 998) || (THERMISTORHEATER_2 == 998) || (THERMISTORHEATER_3 == 998) || (THERMISTORBED == 998) //User EXIST table
#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) || (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) //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
......@@ -145,6 +151,28 @@
#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
#endif
#if DISABLED(COOLER_MINTEMP)
#error DEPENDENCY ERROR: Missing setting COOLER_MINTEMP
#endif
#if HASNT(COOLER)
#error DEPENDENCY ERROR: Cannot enable TEMP_SENSOR_COOLER and not COOLER_PIN
#endif
#endif
#if DISABLED(PLA_PREHEAT_HOTEND_TEMP)
#error DEPENDENCY ERROR: Missing setting PLA_PREHEAT_HOTEND_TEMP
#endif
......@@ -187,7 +215,13 @@
#if DISABLED(MAX_BED_POWER)
#error DEPENDENCY ERROR: Missing setting MAX_BED_POWER
#endif
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
#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(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
#if DISABLED(MAX_OVERSHOOT_PID_AUTOTUNE)
#error DEPENDENCY ERROR: Missing setting MAX_OVERSHOOT_PID_AUTOTUNE
#endif
......@@ -223,6 +257,35 @@
#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
#endif
#if DISABLED(DEFAULT_coolerKp)
#error DEPENDENCY ERROR: Missing setting DEFAULT_coolerKp
#endif
#if DISABLED(DEFAULT_coolerKi)
#error DEPENDENCY ERROR: Missing setting DEFAULT_coolerKi
#endif
#if DISABLED(DEFAULT_coolerKd)
#error DEPENDENCY ERROR: Missing setting DEFAULT_coolerKd
#endif
#endif
#if ENABLED(BED_LIMIT_SWITCHING)
#if DISABLED(BED_HYSTERESIS)
#error DEPENDENCY ERROR: Missing setting BED_HYSTERESIS
......@@ -231,6 +294,22 @@
#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
#endif
#if DISABLED(COOLER_CHECK_INTERVAL)
#error DEPENDENCY ERROR: Missing setting COOLER_CHECK_INTERVAL
#endif
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
#if DISABLED(THERMAL_PROTECTION_PERIOD)
#error DEPENDENCY ERROR: Missing setting THERMAL_PROTECTION_PERIOD
......@@ -253,6 +332,23 @@
#error DEPENDENCY ERROR: Missing setting THERMAL_PROTECTION_BED_HYSTERESIS
#endif
#endif
#if ENABLED(THERMAL_PROTECTION_COOLER)
#if DISANLED(THERMAL_PROTECTION_COOLER_PERIOD)
#error DEPENDENCY ERROR: Missing setting THERMAL_PROTECTION_COOLER_PERIOD
#endif
#if DISABLED(THERMAL_PROTECTION_COOLER_HYSTERESIS)
#error DEPENDENCY ERROR: Missing setting THERMAL_PROTECTION_COOLER_HYSTERESIS
#endif
#if ENABLED(THERMAL_PROTECTION_COOLER_WATCHDOG)
#if DISABLED(WATCH_TEMP_COOLER_PERIOD)
#error DEPENDENCY ERROR: Missing setting WATCH_TEMP_COOLER_PERIOD
#endif
#if DISABLED(WATCH_TEMP_COOLER_DECREASE)
#error DEPENDENCY ERROR: Missing setting WATCH_TEMP_COOLER_DECREASE
#endif
#endif
#endif
// Fan
#if DISABLED(SOFT_PWM_SCALE)
......@@ -1762,8 +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
#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 != 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_PWR))
#error DEPENDENCY ERROR: You have to set LASER_PWR_PIN
#endif
#else
#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
#if DISABLED(LASER_HAS_FOCUS)
#error DEPENDENCY ERROR: Missing LASER_HAS_FOCUS setting
#endif
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR) && !PIN_EXISTS(FILRUNOUT)
......@@ -1774,6 +1888,10 @@
#error DEPENDENCY ERROR: You have to set FILWIDTH_PIN to a valid pin if you enable FILAMENT_SENSOR
#endif
#if ENABLED(FILAMENT_SENSOR) && !PIN_EXISTS(FLOWMETER)
#error DEPENDENCY ERROR: You have to set FLOWMETER_PIN to a valid pin if you enable FLOWMETER_SENSOR
#endif
#if ENABLED(POWER_CONSUMPTION) && !PIN_EXISTS(POWER_CONSUMPTION)
#error DEPENDENCY ERROR: You have to set POWER_CONSUMPTION_PIN to a valid pin if you enable POWER_CONSUMPTION
#endif
......
/**
* 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/>.
*
*/
/**
* flowmeter.h - Flowmeter control library for Arduino - Version 1
* Copyright (c) 2016 Franco (nextime) Lanza. 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 <Arduino.h>
#if ENABLED(FLOWMETER_SENSOR)
volatile int flowrate_pulsecount;
float flowrate;
static millis_t flowmeter_timer = 0;
static millis_t lastflow = 0;
void flowrate_pulsecounter();
void flow_init() {
flowrate = 0;
flowrate_pulsecount = 0;
pinMode(FLOWMETER_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN), flowrate_pulsecounter, FALLING);
}
void flowrate_manage() {
millis_t now;
now = millis();
if(ELAPSED(now, flowmeter_timer)) {
detachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN));
flowrate = (float)(((1000.0 / (float)((float)now - (float)lastflow)) * (float)flowrate_pulsecount) / (float)FLOWMETER_CALIBRATION);
#if ENABLED(FLOWMETER_DEBUG)
ECHO_M(" FLOWMETER DEBUG ");
ECHO_MV(" flowrate:", flowrate);
ECHO_MV(" flowrate_pulsecount:", flowrate_pulsecount);
ECHO_EMV(" CALIBRATION:", FLOWMETER_CALIBRATION);
#endif
flowmeter_timer = now + 1000UL;
lastflow = now;
flowrate_pulsecount = 0;
attachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN), flowrate_pulsecounter, FALLING);
}
}
float get_flowrate() {
return flowrate;
}
void flowrate_pulsecounter() {
// Increment the pulse counter
flowrate_pulsecount++;
}
#endif // FLOWMETER_SENSOR
/**
* 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/>.
*
*/
/**
* flowmeter.h - Flowmeter control library for Arduino - Version 1
* Copyright (c) 2016 Franco (nextime) Lanza. 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 FLOWMETER_H
#define FLOWMETER_H
#define FLOWMETER_CALIBRATION (FLOWMETER_MAXFREQ / FLOWMETER_MAXFLOW)
#if ENABLED(FLOWMETER_SENSOR)
void flowrate_manage();
void flow_init();
float get_flowrate();
#endif
#endif // FLOWMETER_H
......@@ -51,7 +51,7 @@
#define K2 (1.0 - K1)
#endif
#if ENABLED(PIDTEMPBED) || ENABLED(PIDTEMP)
#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,21 @@
//===========================================================================
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;
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
int redundant_temperature_raw = 0;
float redundant_temperature = 0.0;
......@@ -74,8 +84,20 @@ float current_temperature_bed = 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));
float coolerKd = ((DEFAULT_coolerKd) / (PID_dT));
#endif
#if ENABLED(FAN_SOFT_PWM)
unsigned char fanSpeedSoftPwm = 0;
#if HAS(AUTO_FAN)
......@@ -87,6 +109,14 @@ float current_temperature_bed = 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;
#endif
void setPwmCooler(unsigned char pwm);
#if ENABLED(BABYSTEPPING)
volatile int babystepsTodo[3] = { 0 };
......@@ -96,9 +126,10 @@ unsigned char soft_pwm_bed;
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED)
enum TRState { TRInactive, TRFirstHeating, TRStable, TRRunaway };
void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || ENABLED(THERMAL_PROTECTION_COOLER)
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)
static TRState thermal_runaway_state_machine[HOTENDS] = { TRInactive };
static millis_t thermal_runaway_timer[HOTENDS] = { 0 };
......@@ -107,6 +138,10 @@ unsigned char soft_pwm_bed;
static TRState thermal_runaway_bed_state_machine = TRInactive;
static millis_t thermal_runaway_bed_timer;
#endif
#if ENABLED(THERMAL_PROTECTION_COOLER) && TEMP_SENSOR_COOLER != 0
static TRState thermal_runaway_cooler_state_machine = TRReset;
static millis_t thermal_runaway_cooler_timer;
#endif
#endif
#if HAS(POWER_CONSUMPTION_SENSOR)
......@@ -150,9 +185,38 @@ 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 };
static float temp_dState_cooler = { 0 };
static float pTerm_cooler;
static float iTerm_cooler;
static float dTerm_cooler;
//int output;
static float pid_error_cooler;
static float temp_iState_min_cooler;
static float temp_iState_max_cooler;
#else // PIDTEMPCOOLER
static millis_t next_cooler_check_ms;
#endif // !PIDTEMPCOOLER
static unsigned char soft_pwm[HOTENDS];
#if ENABLED(FAN_SOFT_PWM)
......@@ -183,6 +247,18 @@ 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
#if ENABLED(COOLER_MAXTEMP)
static int cooler_maxttemp_raw = COOLER_RAW_HI_TEMP;
#endif
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
static void* heater_ttbl_map[2] = {(void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE };
......@@ -194,6 +270,8 @@ 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();
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
......@@ -206,6 +284,16 @@ static void updateTemperaturesFromRawValues();
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
......@@ -222,6 +310,24 @@ 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
}
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() {
#if ENABLED(AUTOTEMP)
if (autotemp_enabled) {
......@@ -232,11 +338,11 @@ void autotempShutdown() {
#endif
}
#if HAS(PID_HEATING)
void PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) {
#if HAS(PID_HEATING) || HAS(PID_COOLING)
void PID_autotune(float temp, int temp_controller, int ncycles, bool set_result/*=false*/) {
float input = 0.0;
int cycles = 0;
bool heating = true;
bool running = true;
millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms;
long t_high = 0, t_low = 0;
......@@ -250,31 +356,46 @@ void autotempShutdown() {
millis_t next_auto_fan_check_ms = temp_ms + 2500;
#endif
if (hotend >= HOTENDS
#if HASNT(TEMP_BED)
|| hotend < 0
if (temp_controller >= HOTENDS
#if HASNT(TEMP_BED) && HASNT(TEMP_COOLER)
|| temp_controller < 0
#elif HASNT(TEMP_BED)
|| (temp_controller == -1 && temp_controller < -3)
#elif HASNT(TEMP_COOLER)
|| temp_controller < -2
#endif
) {
ECHO_LM(ER, SERIAL_PID_BAD_EXTRUDER_NUM);
ECHO_LM(ER, SERIAL_PID_BAD_TEMP_CONTROLLER_NUM);
return;
}
ECHO_LM(DB, SERIAL_PID_AUTOTUNE_START);
if (hotend < 0) {
if (temp_controller == -1) {
ECHO_SM(DB, "BED");
}
else if(temp_controller == -2) {
ECHO_SM(DB, "CHAMBER");
}
else if(temp_controller == -3) {
ECHO_SM(DB, "COOLER");
}
else {
ECHO_SMV(DB, "Hotend: ", hotend);
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.
if (hotend < 0)
if (temp_controller == -1)
soft_pwm_bed = bias = d = MAX_BED_POWER / 2;
else if (temp_controller == -3) {
bias = d = MAX_COOLER_POWER / 2;
setPwmCooler(MAX_COOLER_POWER);
}
else
soft_pwm[hotend] = bias = d = PID_MAX / 2;
soft_pwm[temp_controller] = bias = d = PID_MAX / 2;
// PID Tuning loop
for (;;) {
......@@ -284,7 +405,12 @@ void autotempShutdown() {
if (temp_meas_ready) { // temp sample ready
updateTemperaturesFromRawValues();
input = (hotend < 0) ? current_temperature_bed:current_temperature[hotend];
if (temp_controller == -1)
input = current_temperature_bed;
else if (temp_controller == -3)
input = current_temperature_cooler;
else
input = current_temperature[temp_controller];
max = max(max, input);
min = min(min, input);
......@@ -296,26 +422,40 @@ void autotempShutdown() {
}
#endif
if (heating && input > temp) {
if (running && ((input > temp && temp_controller >= -1) || (input < temp && temp_controller < -1))) {
if (ms > t2 + 5000UL) {
heating = false;
if (hotend < 0)
running = false;
if (temp_controller == -3)
setPwmCooler((bias - d));
else if (temp_controller == -1)
soft_pwm_bed = (bias - d) >> 1;
else
soft_pwm[hotend] = (bias - d) >> 1;
soft_pwm[temp_controller] = (bias - d) >> 1;
t1 = ms;
t_high = t1 - t2;
max = temp;
if (temp_controller == -3)
min = temp;
else
max = temp;
}
}
if (!heating && input < temp) {
if (!running && ((input < temp && temp_controller >= -1) || (input > temp && temp_controller < -1))) {
if (ms > t1 + 5000UL) {
heating = true;
running = true;
t2 = ms;
t_low = t2 - t1;
if (cycles > 0) {
long max_pow = hotend < 0 ? MAX_BED_POWER : PID_MAX;
long max_pow;
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;
......@@ -342,32 +482,53 @@ void autotempShutdown() {
ECHO_E;
}
}
#if HAS(PID_FOR_BOTH)
if (hotend < 0)
#if ENABLED(PIDTEMP)
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;
else
soft_pwm[hotend] = (bias + d) >> 1;
#elif ENABLED(PIDTEMP)
soft_pwm[hotend] = (bias + d) >> 1;
#else
soft_pwm_bed = (bias + d) >> 1;
#endif
#if ENABLED(PIDTEMPCOOLER)
if (temp_controller == -3)
setPwmCooler((bias + d));
#endif
cycles++;
min = temp;
if(temp_controller == -3)
max = temp;
else
min = temp;
}
}
}
if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) {
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;
}
// 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_coolerstate();
ECHO_E;
#endif
temp_ms = ms;
} // every 2 seconds
......@@ -379,19 +540,23 @@ void autotempShutdown() {
}
if (cycles > ncycles) {
ECHO_LM(DB, SERIAL_PID_AUTOTUNE_FINISHED);
#if HAS(PID_FOR_BOTH)
if (hotend >= 0) {
ECHO_SMV(DB, SERIAL_KP, PID_PARAM(Kp, hotend));
ECHO_MV(SERIAL_KI, unscalePID_i(PID_PARAM(Ki, hotend)));
ECHO_EMV(SERIAL_KD, unscalePID_d(PID_PARAM(Kd, hotend)));
#if ENABLED(PIDTEMP)
if (temp_controller >= 0) {
ECHO_SMV(DB, SERIAL_KP, PID_PARAM(Kp, temp_controller));
ECHO_MV(SERIAL_KI, unscalePID_i(PID_PARAM(Ki, temp_controller)));
ECHO_EMV(SERIAL_KD, unscalePID_d(PID_PARAM(Kd, temp_controller)));
if (set_result) {
PID_PARAM(Kp, hotend) = workKp;
PID_PARAM(Ki, hotend) = scalePID_i(workKi);
PID_PARAM(Kd, hotend) = scalePID_d(workKd);
PID_PARAM(Kp, temp_controller) = workKp;
PID_PARAM(Ki, temp_controller) = scalePID_i(workKi);
PID_PARAM(Kd, temp_controller) = scalePID_d(workKd);
updatePID();
}
}
else {
#endif
#if ENABLED(PIDTEMPBED)
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));
......@@ -402,25 +567,19 @@ void autotempShutdown() {
updatePID();
}
}
#elif ENABLED(PIDTEMP)
ECHO_SMV(DB, SERIAL_KP, PID_PARAM(Kp, hotend));
ECHO_MV(SERIAL_KI, unscalePID_i(PID_PARAM(Ki, hotend)));
ECHO_EMV(SERIAL_KD, unscalePID_d(PID_PARAM(Kd, hotend)));
if (set_result) {
PID_PARAM(Kp, hotend) = workKp;
PID_PARAM(Ki, hotend) = scalePID_i(workKi);
PID_PARAM(Kd, hotend) = scalePID_d(workKd);
updatePID();
}
#else
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));
if (set_result) {
bedKp = workKp;
bedKi = scalePID_i(workKi);
bedKd = scalePID_d(workKd);
updatePID();
#endif
#if ENABLED(PIDTEMPCOOLER)
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));
if (set_result) {
coolerKp = workKp;
coolerKi = scalePID_i(workKi);
coolerKd = scalePID_d(workKd);
updatePID();
}
}
#endif
......@@ -443,108 +602,142 @@ 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];
}
#if HAS(AUTO_FAN)
int getBedPower() {
return soft_pwm_bed;
}
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;
int getChamberPower() {
return soft_pwm_chamber;
}
int getCoolerPower() {
#if ENABLED(FAST_PWM_COOLER)
return fast_pwm_cooler;
#else
digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed);
return soft_pwm_cooler;
#endif
}
void checkExtruderAutoFans() {
uint8_t fanState = 0;
#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
}
// 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)
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
void checkExtruderAutoFans() {
uint8_t fanState = 0;
// 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
}
// 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)
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 h, 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);
ECHO_M(SERIAL_STOPPED_HEATER);
if (h >= 0) ECHO_EV((int)h); else ECHO_EM(SERIAL_HEATER_BED);
if (tc >= 0) {
ECHO_M(SERIAL_STOPPED_HEATER);
ECHO_EV((int)tc);
}
else if (tc == -1) {
ECHO_EM(SERIAL_STOPPED_BED);
}
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;
killed = true;
kill(lcd_msg);
}
else
else {
disable_all_heaters(); // paranoia
disable_all_coolers();
}
#endif
}
......@@ -649,6 +842,7 @@ float get_pid_output(int h) {
#if ENABLED(PIDTEMPBED)
float get_pid_output_bed() {
float pid_output;
#if ENABLED(PID_OPENLOOP)
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#else
......@@ -679,21 +873,108 @@ 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;
}
#endif
#if ENABLED(PIDTEMPCOOLER)
float get_pid_output_cooler() {
float pid_output;
// We need this cause 0 is lower than our current temperature probably.
if (target_temperature_cooler < COOLER_MINTEMP)
return 0.0;
#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;
temp_iState_cooler += pid_error_cooler;
temp_iState_cooler = constrain(temp_iState_cooler, temp_iState_min_cooler, temp_iState_max_cooler);
iTerm_cooler = coolerKi * temp_iState_cooler;
//dTerm_cooler = K2 * coolerKd * (current_temperature_cooler - temp_dState_cooler) + K1 * dTerm_cooler;
dTerm_cooler = K2 * coolerKd * (temp_dState_cooler - current_temperature_cooler) + K1 * dTerm_cooler;
temp_dState_cooler = current_temperature_cooler;
pid_output = pTerm_cooler + iTerm_cooler - dTerm_cooler;
if (pid_output > MAX_COOLER_POWER) {
if (pid_error_cooler > 0) temp_iState_cooler -= pid_error_cooler; // conditional un-integration
pid_output = MAX_COOLER_POWER;
}
else if (pid_output < 0) {
if (pid_error_cooler < 0) temp_iState_cooler -= pid_error_cooler; // conditional un-integration
pid_output = 0;
}
#endif // PID_OPENLOOP
#if ENABLED(PID_COOLER_DEBUG)
ECHO_SM(DB ," PID_COOLER_DEBUG ");
ECHO_MV(": Input ", current_temperature_cooler);
ECHO_MV(" Output ", pid_output);
ECHO_MV(" pTerm ", pTerm_cooler);
ECHO_MV(" iTerm ", iTerm_cooler);
ECHO_EMV(" dTerm ", dTerm_cooler);
#endif //PID_COOLER_DEBUG
return pid_output;
}
#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_heater() {
void manage_temp_controller() {
if (!temp_meas_ready) return;
......@@ -705,7 +986,7 @@ void manage_heater() {
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED) || DISABLED(PIDTEMPBED) || 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
......@@ -785,15 +1066,24 @@ void manage_heater() {
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 TEMP_SENSOR_BED != 0
#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 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
......@@ -825,7 +1115,75 @@ void manage_heater() {
WRITE_HEATER_BED(LOW);
}
#endif
#endif // TEMP_SENSOR_BED != 0
#endif // HAS(TEMP_BED)
#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
#if ENABLED(PIDTEMPCOOLER)
float pid_output = get_pid_output_cooler();
setPwmCooler(current_temperature_cooler > COOLER_MINTEMP && current_temperature_cooler < COOLER_MAXTEMP ? (int)pid_output : 0);
#elif ENABLED(COOLER_LIMIT_SWITCHING)
// Check if temperature is within the correct band
if (current_temperature_cooler > COOLER_MINTEMP && current_temperature_cooler < COOLER_MAXTEMP) {
if (current_temperature_cooler >= target_temperature_cooler + COOLER_HYSTERESIS)
setPwmCooler(MAX_COOLER_POWER);
else if (current_temperature_cooler <= target_temperature_cooler - COOLER_HYSTERESIS)
setPwmCooler(0);
}
else {
setPwmCooler(0);
WRITE_COOLER(LOW);
}
#else // COOLER_LIMIT_SWITCHING
// Check if temperature is within the correct range
if (current_temperature_cooler > COOLER_MINTEMP && current_temperature_cooler < COOLER_MAXTEMP) {
setPwmCooler(current_temperature_cooler > target_temperature_cooler ? MAX_COOLER_POWER : 0);
}
else {
setPwmCooler(0);
WRITE_COOLER(LOW);
}
#endif
#endif // HAS(TEMP_COOLER)
}
#define PGM_RD_W(x) (short)pgm_read_word(&x)
......@@ -903,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
......@@ -914,6 +1272,71 @@ 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)
float celsius = 0;
byte i;
for (i = 1; i < COOLERTEMPTABLE_LEN; i++) {
if (PGM_RD_W(COOLERTEMPTABLE[i][0]) > raw) {
celsius = PGM_RD_W(COOLERTEMPTABLE[i - 1][1]) +
(raw - PGM_RD_W(COOLERTEMPTABLE[i - 1][0])) *
(float)(PGM_RD_W(COOLERTEMPTABLE[i][1]) - PGM_RD_W(COOLERTEMPTABLE[i - 1][1])) /
(float)(PGM_RD_W(COOLERTEMPTABLE[i][0]) - PGM_RD_W(COOLERTEMPTABLE[i - 1][0]));
break;
}
}
// Overflow: Set to last value in the table
if (i == COOLERTEMPTABLE_LEN) celsius = PGM_RD_W(COOLERTEMPTABLE[i - 1][1]);
return celsius;
#elif ENABLED(COOLER_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
}
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
static void updateTemperaturesFromRawValues() {
......@@ -921,10 +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
......@@ -961,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;
......@@ -975,7 +1404,6 @@ static void updateTemperaturesFromRawValues() {
else NOMORE(temp, MEASURED_UPPER_LIMIT);
return filament_width_nominal / temp * 100;
}
#endif
#if HAS(POWER_CONSUMPTION_SENSOR)
......@@ -989,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;
}
......@@ -1005,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;
}
......@@ -1012,10 +1443,10 @@ static void updateTemperaturesFromRawValues() {
/**
* Initialize the temperature manager
* The manager is implemented by periodic calls to manage_heater()
* The manager is implemented by periodic calls to manage_temp_controller()
*/
void tp_init() {
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1)||(TEMP_SENSOR_COOLER==-1))
// disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR = _BV(JTD);
MCUCR = _BV(JTD);
......@@ -1029,12 +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(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
......@@ -1054,6 +1496,15 @@ void tp_init() {
#if HAS(HEATER_BED)
SET_OUTPUT(HEATER_BED_PIN);
#endif
#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
#endif
#endif
#if HAS(FAN)
SET_OUTPUT(FAN_PIN);
#if ENABLED(FAST_PWM_FAN)
......@@ -1103,6 +1554,12 @@ 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
#if HAS(FILAMENT_SENSOR)
ANALOG_SELECT(FILWIDTH_PIN);
#endif
......@@ -1226,6 +1683,44 @@ 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
cooler_minttemp_raw += OVERSAMPLENR;
#else
cooler_minttemp_raw -= OVERSAMPLENR;
#endif
}
#endif // COOLER_MINTEMP
#if ENABLED(COOLER_MAXTEMP)
while(analog2tempCooler(cooler_maxttemp_raw) > COOLER_MAXTEMP) {
#if COOLER_RAW_LO_TEMP < COOLER_RAW_HI_TEMP
cooler_maxttemp_raw -= OVERSAMPLENR;
#else
cooler_maxttemp_raw += OVERSAMPLENR;
#endif
}
#endif // COOLER_MAXTEMP
}
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
......@@ -1260,11 +1755,42 @@ void tp_init() {
}
#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) || ENABLED(THERMAL_PROTECTION_BED)
#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_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
void thermal_runaway_protection(TRState* state, millis_t* timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
#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 + 1] = { 0.0 };
static float tr_target_temperature[HOTENDS + 3] = { 0.0 };
/*
ECHO_SM(DB, "Thermal Thermal Runaway Running. Heater ID: ");
......@@ -1274,40 +1800,59 @@ void tp_init() {
ECHO_MV(" ; Temperature:", temperature);
ECHO_EMV(" ; Target Temp:", target_temperature);
*/
int heater_index = heater_id >= 0 ? heater_id : HOTENDS;
int temp_controller_index;
if(temp_controller_id >= 0)
temp_controller_index = temp_controller_id;
else if(temp_controller_id == -1)
temp_controller_index = HOTENDS; // BED
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[heater_index] != target_temperature) {
tr_target_temperature[heater_index] = target_temperature;
*state = target_temperature > 0 ? TRFirstHeating : TRInactive;
}
if (tr_target_temperature[temp_controller_index] != target_temperature)
tr_target_temperature[temp_controller_index] = target_temperature;
*state = target_temperature > 0 ? TRFirstRunning : TRInactive;
switch (*state) {
// Inactive state waits for a target temperature to be set
case TRInactive: break;
// When first heating, wait for the temperature to be reached then go to Stable state
case TRFirstHeating:
if (temperature < tr_target_temperature[heater_index]) 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 > 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 (temperature < tr_target_temperature[heater_index] - hysteresis_degc && ELAPSED(millis(), *timer))
*state = TRRunaway;
else {
*timer = millis() + period_seconds * 1000UL;
break;
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;
else {
*timer = millis() + period_seconds * 1000UL;
break;
}
}
case TRRunaway:
_temp_error(heater_id, PSTR(SERIAL_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
_temp_error(temp_controller_id, PSTR(SERIAL_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
}
}
#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
#endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED || THERMAL_PROTECTION_CHAMBER || THERMAL_PROTECTION_COOLER
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();
......@@ -1343,6 +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);
// 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 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)
......@@ -1412,6 +1985,10 @@ enum TempState {
MeasureTemp_0,
PrepareTemp_BED,
MeasureTemp_BED,
PrepareTemp_CHAMBER,
MeasureTemp_CHAMBER,
PrepareTemp_COOLER,
MeasureTemp_COOLER,
PrepareTemp_1,
MeasureTemp_1,
PrepareTemp_2,
......@@ -1427,6 +2004,8 @@ 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)
......@@ -1446,6 +2025,8 @@ 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)
current_raw_powconsumption = raw_powconsumption_value;
......@@ -1455,7 +2036,7 @@ static void set_current_temp_raw() {
/**
* Timer 0 is shared with millies
* - Manage PWM to all the heaters and fan
* - Manage PWM to all the heaters, coolers and fan
* - Update the raw temperature values
* - Check new temperature values for MIN/MAX errors
* - Step the babysteps value for each axis towards 0
......@@ -1491,6 +2072,12 @@ ISR(TIMER0_COMPB_vect) {
#if HAS(HEATER_BED)
ISR_STATICS(BED);
#endif
#if HAS(HEATER_CHAMBER)
ISR_STATICS(CHAMBER);
#endif
#if HAS(COOLER) && !ENABLED(FAST_PWM_COOLER)
ISR_STATICS(COOLER);
#endif
#if HAS(FILAMENT_SENSOR)
static unsigned long raw_filwidth_value = 0;
......@@ -1524,6 +2111,17 @@ ISR(TIMER0_COMPB_vect) {
soft_pwm_BED = soft_pwm_bed;
WRITE_HEATER_BED(soft_pwm_BED > 0 ? 1 : 0);
#endif
#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)
......@@ -1564,6 +2162,14 @@ ISR(TIMER0_COMPB_vect) {
if (soft_pwm_BED < pwm_count) WRITE_HEATER_BED(0);
#endif
#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)
if (soft_pwm_fan < pwm_count) WRITE_FAN(0);
#if HAS(CONTROLLERFAN)
......@@ -1641,10 +2247,19 @@ ISR(TIMER0_COMPB_vect) {
#endif
#endif
#endif
#if HAS(HEATER_BED)
_SLOW_PWM_ROUTINE(BED, soft_pwm_bed); // BED
#endif
#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
PWM_OFF_ROUTINE(0); // HOTEND 0
......@@ -1657,10 +2272,19 @@ ISR(TIMER0_COMPB_vect) {
#endif
#endif
#endif
#if HAS(HEATER_BED)
PWM_OFF_ROUTINE(BED); // BED
#endif
#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)
if (pwm_count == 0) {
soft_pwm_fan = fanSpeedSoftPwm / 2;
......@@ -1726,9 +2350,18 @@ ISR(TIMER0_COMPB_vect) {
#endif
#endif
#endif
#if HAS(HEATER_BED)
if (state_timer_heater_BED > 0) state_timer_heater_BED--;
#endif
#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
#endif // SLOW_PWM_HEATERS
......@@ -1767,6 +2400,34 @@ 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);
#endif
lcd_buttons_update();
temp_state = MeasureTemp_COOLER;
break;
case MeasureTemp_COOLER:
#if HAS(TEMP_COOLER)
raw_temp_cooler_value += ADC;
#endif
temp_state = PrepareTemp_1;
break;
......@@ -1866,6 +2527,7 @@ ISR(TIMER0_COMPB_vect) {
temp_count = 0;
for (int i = 0; i < 4; i++) raw_temp_value[i] = 0;
raw_temp_bed_value = 0;
raw_temp_cooler_value = 0;
#if HAS(POWER_CONSUMPTION_SENSOR)
raw_powconsumption_value = 0;
......@@ -1917,8 +2579,28 @@ ISR(TIMER0_COMPB_vect) {
#else
#define GEBED >=
#endif
if (current_temperature_bed_raw GEBED bed_maxttemp_raw) _temp_error(-1, PSTR(SERIAL_T_MAXTEMP), PSTR(MSG_ERR_MAXTEMP_BED));
if (bed_minttemp_raw GEBED current_temperature_bed_raw) _temp_error(-1, PSTR(SERIAL_T_MINTEMP), PSTR(MSG_ERR_MINTEMP_BED));
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 <=
#else
#define GECOOLER >=
#endif
if (current_temperature_cooler_raw GECOOLER cooler_maxttemp_raw) _temp_error(-2, SERIAL_T_MAXTEMP, PSTR(MSG_ERR_MAXTEMP_COOLER));
if (cooler_minttemp_raw GECOOLER current_temperature_cooler_raw) _temp_error(-2, SERIAL_T_MINTEMP, PSTR(MSG_ERR_MINTEMP_COOLER));
#endif
} // temp_count >= OVERSAMPLENR
......@@ -1939,10 +2621,10 @@ ISR(TIMER0_COMPB_vect) {
#endif //BABYSTEPPING
}
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
#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)
......@@ -45,7 +45,7 @@
// public functions
void tp_init(); //initialize the heating
void manage_heater(); //it is critical that this is called periodically.
void manage_temp_controller(); //it is critical that this is called periodically.
#if ENABLED(FILAMENT_SENSOR)
// For converting raw Filament Width to milimeters
......@@ -69,12 +69,20 @@ void manage_heater(); //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;
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
extern float redundant_temperature;
#endif
......@@ -92,7 +100,15 @@ extern float current_temperature_bed;
extern float bedKp, bedKi, bedKd;
#endif
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED)
#if ENABLED(PIDTEMPCHAMBER)
extern float chamberKp, chamberKi, chamberKd;
#endif
#if ENABLED(PIDTEMPCOOLER)
extern float coolerKp, coolerKi, coolerKd;
#endif
#if ENABLED(PIDTEMP) || ENABLED(PIDTEMPBED) || ENABLED(PIDTEMPCHAMBER) || ENABLED(PIDTEMPCOOLER)
float scalePID_i(float i);
float scalePID_d(float d);
float unscalePID_i(float i);
......@@ -114,14 +130,20 @@ extern float current_temperature_bed;
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);
......@@ -131,6 +153,14 @@ FORCE_INLINE float degTargetBed() { return target_temperature_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)
......@@ -145,11 +175,29 @@ 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)
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) \
FORCE_INLINE float degHotend##NR() { return degHotend(NR); } \
......@@ -175,11 +223,17 @@ 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_coolers();
void updatePID();
#if HAS(PID_HEATING)
void PID_autotune(float temp, int hotend, int ncycles, bool set_result = false);
#if HAS(PID_HEATING) || HAS(PID_COOLING)
void PID_autotune(float temp, int temp_controller, int ncycles, bool set_result = false);
#endif
void setExtruderAutoFanState(int pin, bool state);
......
......@@ -25,7 +25,7 @@
#define OVERSAMPLENR 16
#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORHEATER_3 == 1) || (THERMISTORBED == 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) //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) //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) //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) //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) // 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) // 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) // 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)
#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)
#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)
#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)
#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)
#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) // 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)
......@@ -696,6 +696,10 @@ This does not match the normal thermistor behaviour so we need to set the follow
#define HEATER_BED_RAW_HI_TEMP 16383
#define HEATER_BED_RAW_LO_TEMP 0
#endif
#if (THERMISTORCOOLER == 20)
#define COOLER_RAW_HI_TEMP 16383
#define COOLER_RAW_LO_TEMP 0
#endif
const short temptable_20[][2] PROGMEM = {
{0 * OVERSAMPLENR, 0},
{227 * OVERSAMPLENR, 1},
......@@ -749,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)
#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.
......@@ -792,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)
#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
......@@ -854,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)
#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
......@@ -895,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)
#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
......@@ -936,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) // 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
......@@ -1021,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)
#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
......@@ -1068,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) // 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)
......@@ -1081,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) // 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)
......@@ -1094,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) // 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)
......@@ -1112,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) // 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)
......@@ -1125,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) //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
......@@ -1136,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) //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
......@@ -1263,4 +1267,42 @@ const short temptable_1047[][2] PROGMEM = {
#endif
#endif
#endif //THERMISTORTABLES_H_
#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
#define COOLER_RAW_LO_TEMP 16383
#else //In case of an thermocouple the highest temperature results in the highest ADC value
#define COOLER_RAW_HI_TEMP 16383
#define COOLER_RAW_LO_TEMP 0
#endif
#endif
#endif // THERMISTORTABLES_H_
......@@ -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, raset
## 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