From: Erik van der Zalm Date: Sat, 5 Nov 2011 19:03:38 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/Marlin_v1' into Marlin_v1 X-Git-Tag: iwj-success-2012-07-29~262 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=04d3b5537f7c23adf7ea362a8492d21114aa6a2e;p=marlin.git Merge remote-tracking branch 'origin/Marlin_v1' into Marlin_v1 Conflicts: Marlin/Configuration.h Marlin/EEPROMwrite.h Marlin/Marlin.h Marlin/Marlin.pde Marlin/temperature.cpp Marlin/temperature.h Marlin/thermistortables.h --- 04d3b5537f7c23adf7ea362a8492d21114aa6a2e diff --cc Marlin/Configuration.h index dd5fe41,0df1ba6..ed258c7 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@@ -1,222 -1,243 +1,245 @@@ -#ifndef CONFIGURATION_H -#define CONFIGURATION_H - -//#define DEBUG_STEPS - -// BASIC SETTINGS: select your board type, thermistor type, axis scaling, and endstop configuration - -//// The following define selects which electronics board you have. Please choose the one that matches your setup -// MEGA/RAMPS up to 1.2 = 3, -// RAMPS 1.3 = 33 -// Gen6 = 5, -// Sanguinololu 1.2 and above = 62 -// Ultimaker = 7, -#define MOTHERBOARD 7 -//#define MOTHERBOARD 5 - - -//// Thermistor settings: -// 1 is 100k thermistor -// 2 is 200k thermistor -// 3 is mendel-parts thermistor -// 4 is 10k thermistor -// 5 is ParCan supplied 104GT-2 100K -// 6 is EPCOS 100k -// 7 is 100k Honeywell thermistor 135-104LAG-J01 -#define THERMISTORHEATER_1 3 -#define THERMISTORHEATER_2 3 -#define THERMISTORBED 3 - -//#define HEATER_1_USES_THERMISTOR -//#define HEATER_2_USES_THERMISTOR -#define HEATER_1_USES_AD595 -//#define HEATER_2_USES_AD595 - -// Select one of these only to define how the bed temp is read. -//#define BED_USES_THERMISTOR -//#define BED_USES_AD595 - -#define HEATER_CHECK_INTERVAL 50 -#define BED_CHECK_INTERVAL 5000 - - -//// Endstop Settings -#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors -// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins. -const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. -// For optos H21LOB set to true, for Mendel-Parts newer optos TCST2103 set to false - -// This determines the communication speed of the printer -//#define BAUDRATE 250000 -#define BAUDRATE 115200 -//#define BAUDRATE 230400 - -// Comment out (using // at the start of the line) to disable SD support: - -// #define ULTRA_LCD //any lcd - - -#define ULTIPANEL -#ifdef ULTIPANEL - //#define NEWPANEL //enable this if you have a click-encoder panel - #define SDSUPPORT - #define ULTRA_LCD - #define LCD_WIDTH 20 -#define LCD_HEIGHT 4 -#else //no panel but just lcd - #ifdef ULTRA_LCD - #define LCD_WIDTH 16 - #define LCD_HEIGHT 2 - #endif -#endif - - -//#define SDSUPPORT // Enable SD Card Support in Hardware Console - - - -const int dropsegments=5; //everything with this number of steps will be ignored as move - -//// ADVANCED SETTINGS - to tweak parameters - -#include "thermistortables.h" - -// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 -#define X_ENABLE_ON 0 -#define Y_ENABLE_ON 0 -#define Z_ENABLE_ON 0 -#define E_ENABLE_ON 0 - -// Disables axis when it's not being used. -#define DISABLE_X false -#define DISABLE_Y false -#define DISABLE_Z false -#define DISABLE_E false - -// Inverting axis direction -#define INVERT_X_DIR true // for Mendel set to false, for Orca set to true -#define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false -#define INVERT_Z_DIR true // for Mendel set to false, for Orca set to true -#define INVERT_E_DIR false // for direct drive extruder v9 set to true, for geared extruder set to false - -//// ENDSTOP SETTINGS: -// Sets direction of endstops when homing; 1=MAX, -1=MIN -#define X_HOME_DIR -1 -#define Y_HOME_DIR -1 -#define Z_HOME_DIR -1 - -#define min_software_endstops false //If true, axis won't move to coordinates less than zero. -#define max_software_endstops false //If true, axis won't move to coordinates greater than the defined lengths below. -#define X_MAX_LENGTH 210 -#define Y_MAX_LENGTH 210 -#define Z_MAX_LENGTH 210 - -//// MOVEMENT SETTINGS -#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E -//note: on bernhards ultimaker 200 200 12 are working well. -#define HOMING_FEEDRATE {50*60, 50*60, 12*60, 0} // set the homing speeds -//the followint checks if an extrusion is existent in the move. if _not_, the speed of the move is set to the maximum speed. -//!!!!!!Use only if you know that your printer works at the maximum declared speeds. -// works around the skeinforge cool-bug. There all moves are slowed to have a minimum layer time. However slow travel moves= ooze -#define TRAVELING_AT_MAXSPEED -#define AXIS_RELATIVE_MODES {false, false, false, false} - -#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) - -// default settings - -#define DEFAULT_AXIS_STEPS_PER_UNIT {79.87220447,79.87220447,200*8/3,14} // default steps per unit for ultimaker -#define DEFAULT_MAX_FEEDRATE {160*60, 160*60, 10*60, 500000} -#define DEFAULT_MAX_ACCELERATION {9000,9000,150,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot. - -#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves -#define DEFAULT_RETRACT_ACCELERATION 7000 // X, Y, Z and E max acceleration in mm/s^2 for r retracts - -#define DEFAULT_MINIMUMFEEDRATE 10 // minimum feedrate -#define DEFAULT_MINTRAVELFEEDRATE 10 - -// minimum time in microseconds that a movement needs to take if the buffer is emptied. Increase this number if you see blobs while printing high speed & high detail. It will slowdown on the detailed stuff. -#define DEFAULT_MINSEGMENTTIME 20000 -#define DEFAULT_XYJERK 30.0*60 -#define DEFAULT_ZJERK 10.0*60 - - -// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature -//this enables the watchdog interrupt. -#define USE_WATCHDOG -//you cannot reboot on a mega2560 due to a bug in he bootloader. Hence, you have to reset manually, and this is done hereby: -#define RESET_MANUAL - -#define WATCHDOG_TIMEOUT 4 - - - -//// Experimental watchdog and minimal temp -// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature -// If the temperature has not increased at the end of that period, the target temperature is set to zero. It can be reset with another M104/M109 -//#define WATCHPERIOD 5000 //5 seconds - -// Actual temperature must be close to target for this long before M109 returns success -//#define TEMP_RESIDENCY_TIME 20 // (seconds) -//#define TEMP_HYSTERESIS 5 // (C°) range of +/- temperatures considered "close" to the target one - -//// The minimal temperature defines the temperature below which the heater will not be enabled -#define MINTEMP 5 -#define BED_MINTEMP 5 - - -// 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 MAXTEMP 275 -#define BED_MAXTEMP 150 - - - - - - - -#define PIDTEMP -#ifdef PIDTEMP - /// PID settings: - // Uncomment the following line to enable PID support. - //#define SMOOTHING - //#define SMOOTHFACTOR 5.0 - //float current_raw_average=0; - #define K1 0.95 //smoothing of the PID - //#define PID_DEBUG // Sends debug data to the serial port. - //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in % - #define PID_MAX 255 // limits current to nozzle - #define PID_INTEGRAL_DRIVE_MAX 255 - #define PID_dT 0.1 - //machine with red silicon: 1950:45 second ; with fan fully blowin 3000:47 - - #define PID_CRITIAL_GAIN 3000 - #define PID_SWING_AT_CRITIAL 45 //seconds - #define PIDIADD 5 - /* - //PID according to Ziegler-Nichols method - float Kp = 0.6*PID_CRITIAL_GAIN; - float Ki =PIDIADD+2*Kp/PID_SWING_AT_CRITIAL*PID_dT; - float Kd = Kp*PID_SWING_AT_CRITIAL/8./PID_dT; - */ - //PI according to Ziegler-Nichols method - #define DEFAULT_Kp (PID_CRITIAL_GAIN/2.2) - #define DEFAULT_Ki (1.2*Kp/PID_SWING_AT_CRITIAL*PID_dT) - #define DEFAULT_Kd (0) - - #define PID_ADD_EXTRUSION_RATE - #ifdef PID_ADD_EXTRUSION_RATE - #define DEFAULT_Kc (5) //heatingpower=Kc*(e_speed) - #endif -#endif // PIDTEMP - -// extruder advance constant (s2/mm3) -// -// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2 -// -// hooke's law says: force = k * distance -// bernoulli's priniciple says: v ^ 2 / 2 + g . h + pressure / density = constant -// so: v ^ 2 is proportional to number of steps we advance the extruder -//#define ADVANCE - -#ifdef ADVANCE -#define EXTRUDER_ADVANCE_K .3 - -#define D_FILAMENT 1.7 -#define STEPS_MM_E 65 -#define EXTRUTION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159) -#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUTION_AREA) - -#endif // ADVANCE - -// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, e.g. 8,16,32 -#if defined SDSUPPORT -// The number of linear motions that can be in the plan at any give time. - #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller -#else - #define BLOCK_BUFFER_SIZE 16 // maximize block buffer -#endif - - -#endif +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +//#define DEBUG_STEPS + +// BASIC SETTINGS: select your board type, thermistor type, axis scaling, and endstop configuration + +//// The following define selects which electronics board you have. Please choose the one that matches your setup +// MEGA/RAMPS up to 1.2 = 3, +// RAMPS 1.3 = 33 +// Gen6 = 5, +// Sanguinololu 1.2 and above = 62 +// Ultimaker = 7, +#define MOTHERBOARD 7 +//#define MOTHERBOARD 5 + + +//// Thermistor settings: +// 1 is 100k thermistor +// 2 is 200k thermistor +// 3 is mendel-parts thermistor +// 4 is 10k thermistor +// 5 is ParCan supplied 104GT-2 100K +// 6 is EPCOS 100k +// 7 is 100k Honeywell thermistor 135-104LAG-J01 +#define THERMISTORHEATER_1 3 +#define THERMISTORHEATER_2 3 +#define THERMISTORBED 3 + +//#define HEATER_0_USES_THERMISTOR +//#define HEATER_1_USES_THERMISTOR +#define HEATER_0_USES_AD595 +//#define HEATER_1_USES_AD595 + +// Select one of these only to define how the bed temp is read. +//#define BED_USES_THERMISTOR +//#define BED_USES_AD595 + +#define HEATER_CHECK_INTERVAL 50 +#define BED_CHECK_INTERVAL 5000 + + +//// Endstop Settings +#define ENDSTOPPULLUPS // Comment this out (using // at the start of the line) to disable the endstop pullup resistors +// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins. +const bool ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. +// For optos H21LOB set to true, for Mendel-Parts newer optos TCST2103 set to false + +// This determines the communication speed of the printer +#define BAUDRATE 250000 +//#define BAUDRATE 115200 +//#define BAUDRATE 230400 + +// Comment out (using // at the start of the line) to disable SD support: + +// #define ULTRA_LCD //any lcd - #define LCD_WIDTH 16 - #define LCD_HEIGHT 2 + ++#define ULTIPANEL +#define ULTIPANEL +#ifdef ULTIPANEL + //#define NEWPANEL //enable this if you have a click-encoder panel + #define SDSUPPORT + #define ULTRA_LCD + #define LCD_WIDTH 20 +#define LCD_HEIGHT 4 ++#else //no panel but just lcd ++ #ifdef ULTRA_LCD ++ #define LCD_WIDTH 16 ++ #define LCD_HEIGHT 2 ++ #endif +#endif + + +//#define SDSUPPORT // Enable SD Card Support in Hardware Console + + + +const int dropsegments=5; //everything with this number of steps will be ignored as move + +//// ADVANCED SETTINGS - to tweak parameters + +#include "thermistortables.h" + +// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1 +#define X_ENABLE_ON 0 +#define Y_ENABLE_ON 0 +#define Z_ENABLE_ON 0 +#define E_ENABLE_ON 0 + +// Disables axis when it's not being used. +#define DISABLE_X false +#define DISABLE_Y false +#define DISABLE_Z false +#define DISABLE_E false + +// Inverting axis direction +#define INVERT_X_DIR true // for Mendel set to false, for Orca set to true +#define INVERT_Y_DIR false // for Mendel set to true, for Orca set to false +#define INVERT_Z_DIR true // for Mendel set to false, for Orca set to true +#define INVERT_E_DIR false // for direct drive extruder v9 set to true, for geared extruder set to false + +//// ENDSTOP SETTINGS: +// Sets direction of endstops when homing; 1=MAX, -1=MIN +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR -1 + +#define min_software_endstops false //If true, axis won't move to coordinates less than zero. +#define max_software_endstops false //If true, axis won't move to coordinates greater than the defined lengths below. +#define X_MAX_LENGTH 210 +#define Y_MAX_LENGTH 210 +#define Z_MAX_LENGTH 210 + +//// MOVEMENT SETTINGS +#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E +//note: on bernhards ultimaker 200 200 12 are working well. +#define HOMING_FEEDRATE {50*60, 50*60, 12*60, 0} // set the homing speeds +//the followint checks if an extrusion is existent in the move. if _not_, the speed of the move is set to the maximum speed. +//!!!!!!Use only if you know that your printer works at the maximum declared speeds. +// works around the skeinforge cool-bug. There all moves are slowed to have a minimum layer time. However slow travel moves= ooze +#define TRAVELING_AT_MAXSPEED +#define AXIS_RELATIVE_MODES {false, false, false, false} + +#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step) + +// default settings + +#define DEFAULT_AXIS_STEPS_PER_UNIT {79.87220447,79.87220447,200*8/3,14} // default steps per unit for ultimaker +#define DEFAULT_MAX_FEEDRATE {160*60, 160*60, 10*60, 500000} +#define DEFAULT_MAX_ACCELERATION {9000,9000,150,10000} // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot. + +#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E max acceleration in mm/s^2 for printing moves +#define DEFAULT_RETRACT_ACCELERATION 7000 // X, Y, Z and E max acceleration in mm/s^2 for r retracts + +#define DEFAULT_MINIMUMFEEDRATE 10 // minimum feedrate +#define DEFAULT_MINTRAVELFEEDRATE 10 + +// minimum time in microseconds that a movement needs to take if the buffer is emptied. Increase this number if you see blobs while printing high speed & high detail. It will slowdown on the detailed stuff. +#define DEFAULT_MINSEGMENTTIME 20000 +#define DEFAULT_XYJERK 30.0*60 +#define DEFAULT_ZJERK 10.0*60 + + +// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature +//this enables the watchdog interrupt. +#define USE_WATCHDOG +//you cannot reboot on a mega2560 due to a bug in he bootloader. Hence, you have to reset manually, and this is done hereby: +#define RESET_MANUAL + +#define WATCHDOG_TIMEOUT 4 + + + +//// Experimental watchdog and minimal temp +// The watchdog waits for the watchperiod in milliseconds whenever an M104 or M109 increases the target temperature +// If the temperature has not increased at the end of that period, the target temperature is set to zero. It can be reset with another M104/M109 +//#define WATCHPERIOD 5000 //5 seconds + +// Actual temperature must be close to target for this long before M109 returns success +//#define TEMP_RESIDENCY_TIME 20 // (seconds) +//#define TEMP_HYSTERESIS 5 // (C°) range of +/- temperatures considered "close" to the target one + +//// The minimal temperature defines the temperature below which the heater will not be enabled +#define HEATER_0_MINTEMP 5 +//#define HEATER_1_MINTEMP 5 +//#define BED_MINTEMP 5 + + +// 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 +//#define_HEATER_1_MAXTEMP 275 +//#define BED_MAXTEMP 150 + - /// PID settings: - // Uncomment the following line to enable PID support. - //#define SMOOTHING - //#define SMOOTHFACTOR 5.0 - //float current_raw_average=0; ++ ++ ++ ++ ++ + +#define PIDTEMP +#ifdef PIDTEMP - //#define PID_DEBUG // Sends debug data to the serial port. - //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in % - #define PID_MAX 255 // limits current to nozzle - #define PID_INTEGRAL_DRIVE_MAX 255 - #define PID_dT 0.10 // 100ms sample time - #define DEFAULT_Kp 20.0 - #define DEFAULT_Ki 1.5*PID_dT - #define DEFAULT_Kd 80/PID_dT - #define DEFAULT_Kc 0 ++ /// PID settings: ++ // Uncomment the following line to enable PID support. ++ //#define SMOOTHING ++ //#define SMOOTHFACTOR 5.0 ++ //float current_raw_average=0; ++ #define K1 0.95 //smoothing of the PID ++ //#define PID_DEBUG // Sends debug data to the serial port. ++ //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in % ++ #define PID_MAX 255 // limits current to nozzle ++ #define PID_INTEGRAL_DRIVE_MAX 255 ++ #define PID_dT 0.1 ++ //machine with red silicon: 1950:45 second ; with fan fully blowin 3000:47 ++ ++ #define PID_CRITIAL_GAIN 3000 ++ #define PID_SWING_AT_CRITIAL 45 //seconds ++ #define PIDIADD 5 ++ /* ++ //PID according to Ziegler-Nichols method ++ float Kp = 0.6*PID_CRITIAL_GAIN; ++ float Ki =PIDIADD+2*Kp/PID_SWING_AT_CRITIAL*PID_dT; ++ float Kd = Kp*PID_SWING_AT_CRITIAL/8./PID_dT; ++ */ ++ //PI according to Ziegler-Nichols method ++ #define DEFAULT_Kp (PID_CRITIAL_GAIN/2.2) ++ #define DEFAULT_Ki (1.2*Kp/PID_SWING_AT_CRITIAL*PID_dT) ++ #define DEFAULT_Kd (0) ++ ++ #define PID_ADD_EXTRUSION_RATE ++ #ifdef PID_ADD_EXTRUSION_RATE ++ #define DEFAULT_Kc (5) //heatingpower=Kc*(e_speed) ++ #endif +#endif // PIDTEMP + - +// extruder advance constant (s2/mm3) +// +// advance (steps) = STEPS_PER_CUBIC_MM_E * EXTUDER_ADVANCE_K * cubic mm per second ^ 2 +// +// hooke's law says: force = k * distance +// bernoulli's priniciple says: v ^ 2 / 2 + g . h + pressure / density = constant +// so: v ^ 2 is proportional to number of steps we advance the extruder +//#define ADVANCE + +#ifdef ADVANCE +#define EXTRUDER_ADVANCE_K .3 + +#define D_FILAMENT 1.7 +#define STEPS_MM_E 65 +#define EXTRUTION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159) +#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUTION_AREA) + +#endif // ADVANCE + ++// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, e.g. 8,16,32 +#if defined SDSUPPORT +// The number of linear motions that can be in the plan at any give time. + #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller +#else + #define BLOCK_BUFFER_SIZE 16 // maximize block buffer +#endif + - #ifdef SIMPLE_LCD - #define BLOCK_BUFFER_SIZE 16 // A little less buffer for just a simple LCD - #endif + +#endif diff --cc Marlin/EEPROMwrite.h index 0390d94,2247e2f..ea84334 --- a/Marlin/EEPROMwrite.h +++ b/Marlin/EEPROMwrite.h @@@ -1,123 -1,129 +1,129 @@@ - -#ifndef __EEPROMH -#define __EEPROMH -#include "planner.h" -#include "temperature.h" -#include -#include "Marlin.h" -#include "streaming.h" - -//====================================================================================== -template int EEPROM_writeAnything(int &ee, const T& value) -{ - const byte* p = (const byte*)(const void*)&value; - int i; - for (i = 0; i < (int)sizeof(value); i++) - EEPROM.write(ee++, *p++); - return i; -} -//====================================================================================== -template int EEPROM_readAnything(int &ee, T& value) -{ - byte* p = (byte*)(void*)&value; - int i; - for (i = 0; i < (int)sizeof(value); i++) - *p++ = EEPROM.read(ee++); - return i; -} -//====================================================================================== - -#define EEPROM_OFFSET 100 - -#define EEPROM_VERSION "V04" // IMPORTANT: Whenever there are changes made to the variables stored in EEPROM - // in the functions below, also increment the version number. This makes sure that - // the default values are used whenever there is a change to the data, to prevent - // wrong data being written to the variables. - // ALSO: always make sure the variables in the Store and retrieve sections are in the same order. -void StoreSettings() { - char ver[4]= "000"; - int i=EEPROM_OFFSET; - EEPROM_writeAnything(i,ver); // invalidate data first - EEPROM_writeAnything(i,axis_steps_per_unit); - EEPROM_writeAnything(i,max_feedrate); - EEPROM_writeAnything(i,max_acceleration_units_per_sq_second); - EEPROM_writeAnything(i,acceleration); - EEPROM_writeAnything(i,retract_acceleration); - EEPROM_writeAnything(i,minimumfeedrate); - EEPROM_writeAnything(i,mintravelfeedrate); - EEPROM_writeAnything(i,minsegmenttime); - EEPROM_writeAnything(i,max_xy_jerk); - EEPROM_writeAnything(i,max_z_jerk); - #ifdef PIDTEMP - EEPROM_writeAnything(i,Kp); - EEPROM_writeAnything(i,Ki); - EEPROM_writeAnything(i,Kd); -#else - EEPROM_writeAnything(i,3000); - EEPROM_writeAnything(i,0); - EEPROM_writeAnything(i,0); -#endif - char ver2[4]=EEPROM_VERSION; - i=EEPROM_OFFSET; - EEPROM_writeAnything(i,ver2); // validate data - ECHOLN("Settings Stored"); - -} - -void RetrieveSettings(bool def=false){ // if def=true, the default values will be used - int i=EEPROM_OFFSET; - char stored_ver[4]; - char ver[4]=EEPROM_VERSION; - EEPROM_readAnything(i,stored_ver); //read stored version -// ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]"); - if ((!def)&&(strncmp(ver,stored_ver,3)==0)) { // version number match - EEPROM_readAnything(i,axis_steps_per_unit); - EEPROM_readAnything(i,max_feedrate); - EEPROM_readAnything(i,max_acceleration_units_per_sq_second); - EEPROM_readAnything(i,acceleration); - EEPROM_readAnything(i,retract_acceleration); - EEPROM_readAnything(i,minimumfeedrate); - EEPROM_readAnything(i,mintravelfeedrate); - EEPROM_readAnything(i,minsegmenttime); - EEPROM_readAnything(i,max_xy_jerk); - EEPROM_readAnything(i,max_z_jerk); -#ifndef PIDTEMP - float Kp,Ki,Kd; -#endif - EEPROM_readAnything(i,Kp); - EEPROM_readAnything(i,Ki); - EEPROM_readAnything(i,Kd); - - ECHOLN("Stored settings retreived:"); - } - else { - float tmp1[]=DEFAULT_AXIS_STEPS_PER_UNIT; - float tmp2[]=DEFAULT_MAX_FEEDRATE; - long tmp3[]=DEFAULT_MAX_ACCELERATION; - for (int i=0;i<4;i++) { - axis_steps_per_unit[i]=tmp1[i]; - max_feedrate[i]=tmp2[i]; - max_acceleration_units_per_sq_second[i]=tmp3[i]; - } - acceleration=DEFAULT_ACCELERATION; - retract_acceleration=DEFAULT_RETRACT_ACCELERATION; - minimumfeedrate=DEFAULT_MINIMUMFEEDRATE; - minsegmenttime=DEFAULT_MINSEGMENTTIME; - mintravelfeedrate=DEFAULT_MINTRAVELFEEDRATE; - max_xy_jerk=DEFAULT_XYJERK; - max_z_jerk=DEFAULT_ZJERK; - ECHOLN("Using Default settings:"); - } - ECHOLN("Steps per unit:"); - ECHOLN(" M92 X" <<_FLOAT(axis_steps_per_unit[0],3) << " Y" << _FLOAT(axis_steps_per_unit[1],3) << " Z" << _FLOAT(axis_steps_per_unit[2],3) << " E" << _FLOAT(axis_steps_per_unit[3],3)); - ECHOLN("Maximum feedrates (mm/s):"); - ECHOLN(" M203 X" <<_FLOAT(max_feedrate[0]/60,2)<<" Y" << _FLOAT(max_feedrate[1]/60,2) << " Z" << _FLOAT(max_feedrate[2]/60,2) << " E" << _FLOAT(max_feedrate[3]/60,2)); - ECHOLN("Maximum Acceleration (mm/s2):"); - ECHOLN(" M201 X" <<_FLOAT(max_acceleration_units_per_sq_second[0],0) << " Y" << _FLOAT(max_acceleration_units_per_sq_second[1],0) << " Z" << _FLOAT(max_acceleration_units_per_sq_second[2],0) << " E" << _FLOAT(max_acceleration_units_per_sq_second[3],0)); - ECHOLN("Acceleration: S=acceleration, T=retract acceleration"); - ECHOLN(" M204 S" <<_FLOAT(acceleration,2) << " T" << _FLOAT(retract_acceleration,2)); - ECHOLN("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s), Z=maximum Z jerk (mm/s)"); - ECHOLN(" M205 S" <<_FLOAT(minimumfeedrate/60,2) << " T" << _FLOAT(mintravelfeedrate/60,2) << " B" << _FLOAT(minsegmenttime,2) << " X" << _FLOAT(max_xy_jerk/60,2) << " Z" << _FLOAT(max_z_jerk/60,2)); -#ifdef PIDTEMP - ECHOLN("PID settings:"); - ECHOLN(" M301 P" << _FLOAT(Kp,3) << " I" << _FLOAT(Ki,3) << " D" << _FLOAT(Kd,3)); -#endif - -} - -#endif - - ++#ifndef __EEPROMH ++#define __EEPROMH +#include "planner.h" +#include "temperature.h" ++#include ++#include "Marlin.h" ++#include "streaming.h" + +//====================================================================================== +template int EEPROM_writeAnything(int &ee, const T& value) +{ + const byte* p = (const byte*)(const void*)&value; + int i; - for (i = 0; i < sizeof(value); i++) ++ for (i = 0; i < (int)sizeof(value); i++) + EEPROM.write(ee++, *p++); + return i; +} +//====================================================================================== +template int EEPROM_readAnything(int &ee, T& value) +{ + byte* p = (byte*)(void*)&value; + int i; - for (i = 0; i < sizeof(value); i++) ++ for (i = 0; i < (int)sizeof(value); i++) + *p++ = EEPROM.read(ee++); + return i; +} +//====================================================================================== + +#define EEPROM_OFFSET 100 + +#define EEPROM_VERSION "V04" // IMPORTANT: Whenever there are changes made to the variables stored in EEPROM + // in the functions below, also increment the version number. This makes sure that + // the default values are used whenever there is a change to the data, to prevent + // wrong data being written to the variables. + // ALSO: always make sure the variables in the Store and retrieve sections are in the same order. +void StoreSettings() { + char ver[4]= "000"; + int i=EEPROM_OFFSET; + EEPROM_writeAnything(i,ver); // invalidate data first + EEPROM_writeAnything(i,axis_steps_per_unit); + EEPROM_writeAnything(i,max_feedrate); + EEPROM_writeAnything(i,max_acceleration_units_per_sq_second); + EEPROM_writeAnything(i,acceleration); + EEPROM_writeAnything(i,retract_acceleration); + EEPROM_writeAnything(i,minimumfeedrate); + EEPROM_writeAnything(i,mintravelfeedrate); + EEPROM_writeAnything(i,minsegmenttime); + EEPROM_writeAnything(i,max_xy_jerk); + EEPROM_writeAnything(i,max_z_jerk); + #ifdef PIDTEMP + EEPROM_writeAnything(i,Kp); + EEPROM_writeAnything(i,Ki); + EEPROM_writeAnything(i,Kd); +#else + EEPROM_writeAnything(i,3000); + EEPROM_writeAnything(i,0); + EEPROM_writeAnything(i,0); +#endif + char ver2[4]=EEPROM_VERSION; + i=EEPROM_OFFSET; + EEPROM_writeAnything(i,ver2); // validate data + ECHOLN("Settings Stored"); + +} + +void RetrieveSettings(bool def=false){ // if def=true, the default values will be used + int i=EEPROM_OFFSET; + char stored_ver[4]; + char ver[4]=EEPROM_VERSION; + EEPROM_readAnything(i,stored_ver); //read stored version +// ECHOLN("Version: [" << ver << "] Stored version: [" << stored_ver << "]"); + if ((!def)&&(strncmp(ver,stored_ver,3)==0)) { // version number match + EEPROM_readAnything(i,axis_steps_per_unit); + EEPROM_readAnything(i,max_feedrate); + EEPROM_readAnything(i,max_acceleration_units_per_sq_second); + EEPROM_readAnything(i,acceleration); + EEPROM_readAnything(i,retract_acceleration); + EEPROM_readAnything(i,minimumfeedrate); + EEPROM_readAnything(i,mintravelfeedrate); + EEPROM_readAnything(i,minsegmenttime); + EEPROM_readAnything(i,max_xy_jerk); + EEPROM_readAnything(i,max_z_jerk); +#ifndef PIDTEMP + float Kp,Ki,Kd; +#endif + EEPROM_readAnything(i,Kp); + EEPROM_readAnything(i,Ki); + EEPROM_readAnything(i,Kd); + + ECHOLN("Stored settings retreived:"); + } + else { + float tmp1[]=DEFAULT_AXIS_STEPS_PER_UNIT; + float tmp2[]=DEFAULT_MAX_FEEDRATE; + long tmp3[]=DEFAULT_MAX_ACCELERATION; + for (int i=0;i<4;i++) { + axis_steps_per_unit[i]=tmp1[i]; + max_feedrate[i]=tmp2[i]; + max_acceleration_units_per_sq_second[i]=tmp3[i]; + } + acceleration=DEFAULT_ACCELERATION; + retract_acceleration=DEFAULT_RETRACT_ACCELERATION; + minimumfeedrate=DEFAULT_MINIMUMFEEDRATE; + minsegmenttime=DEFAULT_MINSEGMENTTIME; + mintravelfeedrate=DEFAULT_MINTRAVELFEEDRATE; + max_xy_jerk=DEFAULT_XYJERK; + max_z_jerk=DEFAULT_ZJERK; + ECHOLN("Using Default settings:"); + } + ECHOLN("Steps per unit:"); + ECHOLN(" M92 X" <<_FLOAT(axis_steps_per_unit[0],3) << " Y" << _FLOAT(axis_steps_per_unit[1],3) << " Z" << _FLOAT(axis_steps_per_unit[2],3) << " E" << _FLOAT(axis_steps_per_unit[3],3)); + ECHOLN("Maximum feedrates (mm/s):"); + ECHOLN(" M203 X" <<_FLOAT(max_feedrate[0]/60,2)<<" Y" << _FLOAT(max_feedrate[1]/60,2) << " Z" << _FLOAT(max_feedrate[2]/60,2) << " E" << _FLOAT(max_feedrate[3]/60,2)); + ECHOLN("Maximum Acceleration (mm/s2):"); + ECHOLN(" M201 X" <<_FLOAT(max_acceleration_units_per_sq_second[0],0) << " Y" << _FLOAT(max_acceleration_units_per_sq_second[1],0) << " Z" << _FLOAT(max_acceleration_units_per_sq_second[2],0) << " E" << _FLOAT(max_acceleration_units_per_sq_second[3],0)); + ECHOLN("Acceleration: S=acceleration, T=retract acceleration"); + ECHOLN(" M204 S" <<_FLOAT(acceleration,2) << " T" << _FLOAT(retract_acceleration,2)); + ECHOLN("Advanced variables: S=Min feedrate (mm/s), T=Min travel feedrate (mm/s), B=minimum segment time (ms), X=maximum xY jerk (mm/s), Z=maximum Z jerk (mm/s)"); + ECHOLN(" M205 S" <<_FLOAT(minimumfeedrate/60,2) << " T" << _FLOAT(mintravelfeedrate/60,2) << " B" << _FLOAT(minsegmenttime,2) << " X" << _FLOAT(max_xy_jerk/60,2) << " Z" << _FLOAT(max_z_jerk/60,2)); +#ifdef PIDTEMP + ECHOLN("PID settings:"); + ECHOLN(" M301 P" << _FLOAT(Kp,3) << " I" << _FLOAT(Ki,3) << " D" << _FLOAT(Kd,3)); +#endif + +} + ++#endif ++ + diff --cc Marlin/Marlin.h index 130cd86,f85dad3..15e6570 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@@ -1,83 -1,82 +1,82 @@@ -#ifndef __MARLINH -#define __MARLINH - -// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. -// Licence: GPL -#include -#include "fastio.h" - - -#define ECHO(x) Serial << "echo: " << x; -#define ECHOLN(x) Serial << "echo: "< -1 -#define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON) -#define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON) -#else -#define enable_x() ; -#define disable_x() ; -#endif -#if Y_ENABLE_PIN > -1 -#define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) -#define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON) -#else -#define enable_y() ; -#define disable_y() ; -#endif -#if Z_ENABLE_PIN > -1 -#define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) -#define disable_z() WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON) -#else -#define enable_z() ; -#define disable_z() ; -#endif - -#if E_ENABLE_PIN > -1 - - #define enable_e() WRITE(E_ENABLE_PIN, E_ENABLE_ON) - #define disable_e() WRITE(E_ENABLE_PIN,!E_ENABLE_ON) - -#else -#define enable_e() ; -#define disable_e() ; -#endif - -#define X_AXIS 0 -#define Y_AXIS 1 -#define Z_AXIS 2 -#define E_AXIS 3 - -void FlushSerialRequestResend(); -void ClearToSend(); - -void get_coordinates(); -void prepare_move(); -void kill(); - -//void check_axes_activity(); -//void plan_init(); -//void st_init(); -//void tp_init(); -//void plan_buffer_line(float x, float y, float z, float e, float feed_rate); -//void plan_set_position(float x, float y, float z, float e); -//void st_wake_up(); -//void st_synchronize(); -void enquecommand(const char *cmd); - - -#ifndef CRITICAL_SECTION_START -#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); -#define CRITICAL_SECTION_END SREG = _sreg; -#endif //CRITICAL_SECTION_START - -extern float homing_feedrate[]; -extern bool axis_relative_modes[]; - -void wd_reset() ; -#endif +#ifndef __MARLINH +#define __MARLINH + +// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. +// Licence: GPL +#include +#include "fastio.h" + + +#define ECHO(x) Serial << "echo: " << x; +#define ECHOLN(x) Serial << "echo: "< -1 +#define enable_x() WRITE(X_ENABLE_PIN, X_ENABLE_ON) +#define disable_x() WRITE(X_ENABLE_PIN,!X_ENABLE_ON) +#else +#define enable_x() ; +#define disable_x() ; +#endif +#if Y_ENABLE_PIN > -1 +#define enable_y() WRITE(Y_ENABLE_PIN, Y_ENABLE_ON) +#define disable_y() WRITE(Y_ENABLE_PIN,!Y_ENABLE_ON) +#else +#define enable_y() ; +#define disable_y() ; +#endif +#if Z_ENABLE_PIN > -1 +#define enable_z() WRITE(Z_ENABLE_PIN, Z_ENABLE_ON) +#define disable_z() WRITE(Z_ENABLE_PIN,!Z_ENABLE_ON) +#else +#define enable_z() ; +#define disable_z() ; +#endif + +#if E_ENABLE_PIN > -1 + + #define enable_e() WRITE(E_ENABLE_PIN, E_ENABLE_ON) + #define disable_e() WRITE(E_ENABLE_PIN,!E_ENABLE_ON) + +#else +#define enable_e() ; +#define disable_e() ; +#endif + +#define X_AXIS 0 +#define Y_AXIS 1 +#define Z_AXIS 2 +#define E_AXIS 3 + +void FlushSerialRequestResend(); +void ClearToSend(); + +void get_coordinates(); +void prepare_move(); +void kill(); + +//void check_axes_activity(); +//void plan_init(); +//void st_init(); +//void tp_init(); +//void plan_buffer_line(float x, float y, float z, float e, float feed_rate); +//void plan_set_position(float x, float y, float z, float e); +//void st_wake_up(); +//void st_synchronize(); +void enquecommand(const char *cmd); - void wd_reset(); ++ + +#ifndef CRITICAL_SECTION_START +#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli(); +#define CRITICAL_SECTION_END SREG = _sreg; +#endif //CRITICAL_SECTION_START + +extern float homing_feedrate[]; +extern bool axis_relative_modes[]; + - void manage_inactivity(byte debug); - ++void wd_reset() ; +#endif diff --cc Marlin/Marlin.pde index a95ae1f,3cf8d3b..f1dbc5c --- a/Marlin/Marlin.pde +++ b/Marlin/Marlin.pde @@@ -1,1235 -1,1233 +1,1235 @@@ -/* - Reprap firmware based on Sprinter and grbl. - Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm - - 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 . - */ - -/* - This firmware is a mashup between Sprinter and grbl. - (https://github.com/kliment/Sprinter) - (https://github.com/simen/grbl/tree) - - It has preliminary support for Matthew Roberts advance algorithm - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html - */ - -#include "EEPROMwrite.h" -#include "fastio.h" -#include "Configuration.h" -#include "pins.h" -#include "Marlin.h" -#include "ultralcd.h" -#include "streaming.h" -#include "planner.h" -#include "stepper.h" -#include "temperature.h" - -#ifdef SIMPLE_LCD - #include "Simplelcd.h" -#endif - -char version_string[] = "1.0.0 Alpha 1"; - -#ifdef SDSUPPORT -#include "SdFat.h" -#endif //SDSUPPORT - - -// look here for descriptions of gcodes: http://linuxcnc.org/handbook/gcode/g-code.html -// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes - -//Implemented Codes -//------------------- -// G0 -> G1 -// G1 - Coordinated Movement X Y Z E -// G4 - Dwell S or P -// G28 - Home all Axis -// G90 - Use Absolute Coordinates -// G91 - Use Relative Coordinates -// G92 - Set current position to cordinates given - -//RepRap M Codes -// M104 - Set extruder target temp -// M105 - Read current temp -// M106 - Fan on -// M107 - Fan off -// M109 - Wait for extruder current temp to reach target temp. -// M114 - Display current position - -//Custom M Codes -// M20 - List SD card -// M21 - Init SD card -// M22 - Release SD card -// M23 - Select SD file (M23 filename.g) -// M24 - Start/resume SD print -// M25 - Pause SD print -// M26 - Set SD position in bytes (M26 S12345) -// M27 - Report SD print status -// M28 - Start SD write (M28 filename.g) -// M29 - Stop SD write -// M42 - Change pin status via gcode -// M80 - Turn on Power Supply -// M81 - Turn off Power Supply -// M82 - Set E codes absolute (default) -// M83 - Set E codes relative while in Absolute Coordinates (G90) mode -// M84 - Disable steppers until next move, -// or use S to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. -// M85 - Set inactivity shutdown timer with parameter S. To disable set zero (default) -// M92 - Set axis_steps_per_unit - same syntax as G92 -// M115 - Capabilities string -// M140 - Set bed target temp -// M190 - Wait for bed current temp to reach target temp. -// M200 - Set filament diameter -// 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!! -// M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec -// M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate -// M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk -// M220 - set speed factor override percentage S:factor in percent -// M301 - Set PID parameters P I and D -// M500 - stores paramters in EEPROM -// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). D -// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. - -//Stepper Movement Variables - -char axis_codes[NUM_AXIS] = { - 'X', 'Y', 'Z', 'E'}; -float destination[NUM_AXIS] = { - 0.0, 0.0, 0.0, 0.0}; -float current_position[NUM_AXIS] = { - 0.0, 0.0, 0.0, 0.0}; -bool home_all_axis = true; -float feedrate = 1500.0, next_feedrate, saved_feedrate; -long gcode_N, gcode_LastN; - -float homing_feedrate[] = HOMING_FEEDRATE; -bool axis_relative_modes[] = AXIS_RELATIVE_MODES; - -bool relative_mode = false; //Determines Absolute or Relative Coordinates -bool relative_mode_e = false; //Determines Absolute or Relative E Codes while in Absolute Coordinates mode. E is always relative in Relative Coordinates mode. - -uint8_t fanpwm=0; - -volatile int feedmultiply=100; //100->1 200->2 -int saved_feedmultiply; -volatile bool feedmultiplychanged=false; -// comm variables -#define MAX_CMD_SIZE 96 -#define BUFSIZE 4 -char cmdbuffer[BUFSIZE][MAX_CMD_SIZE]; -bool fromsd[BUFSIZE]; -int bufindr = 0; -int bufindw = 0; -int buflen = 0; -int i = 0; -char serial_char; -int serial_count = 0; -boolean comment_mode = false; -char *strchr_pointer; // just a pointer to find chars in the cmd string like X, Y, Z, E, etc -extern float HeaterPower; - -#include "EEPROM.h" - -const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42 - -float tt = 0, bt = 0; -#ifdef WATCHPERIOD -int watch_raw = -1000; -unsigned long watchmillis = 0; -#endif //WATCHPERIOD - -//Inactivity shutdown variables -unsigned long previous_millis_cmd = 0; -unsigned long max_inactive_time = 0; -unsigned long stepper_inactive_time = 0; - -unsigned long starttime=0; -unsigned long stoptime=0; -#ifdef SDSUPPORT -Sd2Card card; -SdVolume volume; -SdFile root; -SdFile file; -uint32_t filesize = 0; -uint32_t sdpos = 0; -bool sdmode = false; -bool sdactive = false; -bool savetosd = false; -int16_t n; -unsigned long autostart_atmillis=0; - -void initsd(){ - sdactive = false; -#if SDSS >- 1 - if(root.isOpen()) - root.close(); - if (!card.init(SPI_FULL_SPEED,SDSS)){ - //if (!card.init(SPI_HALF_SPEED,SDSS)) - Serial.println("SD init fail"); - } - else if (!volume.init(&card)) - Serial.println("volume.init failed"); - else if (!root.openRoot(&volume)) - Serial.println("openRoot failed"); - else - { - sdactive = true; - Serial.println("SD card ok"); - } -#endif //SDSS -} - -void quickinitsd(){ - sdactive=false; - autostart_atmillis=millis()+5000; -} - -inline void write_command(char *buf){ - char* begin = buf; - char* npos = 0; - char* end = buf + strlen(buf) - 1; - - file.writeError = false; - if((npos = strchr(buf, 'N')) != NULL){ - begin = strchr(npos, ' ') + 1; - end = strchr(npos, '*') - 1; - } - end[1] = '\r'; - end[2] = '\n'; - end[3] = '\0'; - //Serial.println(begin); - file.write(begin); - if (file.writeError){ - Serial.println("error writing to file"); - } -} -#endif //SDSUPPORT - - -///adds an command to the main command buffer -void enquecommand(const char *cmd) -{ - if(buflen < BUFSIZE) - { - //this is dangerous if a mixing of serial and this happsens - strcpy(&(cmdbuffer[bufindw][0]),cmd); - Serial.print("en:");Serial.println(cmdbuffer[bufindw]); - bufindw= (bufindw + 1)%BUFSIZE; - buflen += 1; - } -} - -void setup() -{ - - Serial.begin(BAUDRATE); - ECHOLN("Marlin "< -1 - SET_OUTPUT(SDPOWER); - WRITE(SDPOWER,HIGH); -#endif //SDPOWER - quickinitsd(); - -#endif //SDSUPPORT - plan_init(); // Initialize planner; - st_init(); // Initialize stepper; - tp_init(); // Initialize temperature loop - //checkautostart(); -} - -#ifdef SDSUPPORT -bool autostart_stilltocheck=true; - - -void checkautostart(bool force) -{ - //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset - if(!force) - { - if(!autostart_stilltocheck) - return; - if(autostart_atmillis 0) - { - for(int i=0;i<(int)strlen((char*)p.name);i++) - p.name[i]=tolower(p.name[i]); - //Serial.print((char*)p.name); - //Serial.print(" "); - //Serial.println(autoname); - if(p.name[9]!='~') //skip safety copies - if(strncmp((char*)p.name,autoname,5)==0) - { - char cmd[30]; - - sprintf(cmd,"M23 %s",autoname); - //sprintf(cmd,"M115"); - //enquecommand("G92 Z0"); - //enquecommand("G1 Z10 F2000"); - //enquecommand("G28 X-105 Y-105"); - enquecommand(cmd); - enquecommand("M24"); - found=true; - - } - } - if(!found) - lastnr=-1; - else - lastnr++; - -} -#else - -inline void checkautostart(bool x) -{ -} -#endif - - -void loop() -{ - if(buflen<3) - get_command(); - checkautostart(false); - if(buflen) - { -#ifdef SDSUPPORT - if(savetosd){ - if(strstr(cmdbuffer[bufindr],"M29") == NULL){ - write_command(cmdbuffer[bufindr]); - Serial.println("ok"); - } - else{ - file.sync(); - file.close(); - savetosd = false; - Serial.println("Done saving file."); - } - } - else{ - process_commands(); - } -#else - process_commands(); -#endif //SDSUPPORT - buflen = (buflen-1); - bufindr = (bufindr + 1)%BUFSIZE; - } - //check heater every n milliseconds - manage_heater(); - manage_inactivity(1); - LCD_STATUS; -} - - -inline void get_command() -{ - while( Serial.available() > 0 && buflen < BUFSIZE) { - serial_char = Serial.read(); - if(serial_char == '\n' || serial_char == '\r' || serial_char == ':' || serial_count >= (MAX_CMD_SIZE - 1) ) - { - if(!serial_count) return; //if empty line - cmdbuffer[bufindw][serial_count] = 0; //terminate string - if(!comment_mode){ - fromsd[bufindw] = false; - if(strstr(cmdbuffer[bufindw], "N") != NULL) - { - strchr_pointer = strchr(cmdbuffer[bufindw], 'N'); - gcode_N = (strtol(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL, 10)); - if(gcode_N != gcode_LastN+1 && (strstr(cmdbuffer[bufindw], "M110") == NULL) ) { - Serial.print("Serial Error: Line Number is not Last Line Number+1, Last Line:"); - Serial.println(gcode_LastN); - //Serial.println(gcode_N); - FlushSerialRequestResend(); - serial_count = 0; - return; - } - - if(strstr(cmdbuffer[bufindw], "*") != NULL) - { - byte checksum = 0; - byte count = 0; - while(cmdbuffer[bufindw][count] != '*') checksum = checksum^cmdbuffer[bufindw][count++]; - strchr_pointer = strchr(cmdbuffer[bufindw], '*'); - - if( (int)(strtod(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL)) != checksum) { - Serial.print("Error: checksum mismatch, Last Line:"); - Serial.println(gcode_LastN); - FlushSerialRequestResend(); - serial_count = 0; - return; - } - //if no errors, continue parsing - } - else - { - Serial.print("Error: No Checksum with line number, Last Line:"); - Serial.println(gcode_LastN); - FlushSerialRequestResend(); - serial_count = 0; - return; - } - - gcode_LastN = gcode_N; - //if no errors, continue parsing - } - else // if we don't receive 'N' but still see '*' - { - if((strstr(cmdbuffer[bufindw], "*") != NULL)) - { - Serial.print("Error: No Line Number with checksum, Last Line:"); - Serial.println(gcode_LastN); - serial_count = 0; - return; - } - } - if((strstr(cmdbuffer[bufindw], "G") != NULL)){ - strchr_pointer = strchr(cmdbuffer[bufindw], 'G'); - switch((int)((strtod(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL)))){ - case 0: - case 1: -#ifdef SDSUPPORT - if(savetosd) - break; -#endif //SDSUPPORT - Serial.println("ok"); - break; - default: - break; - } - - } - bufindw = (bufindw + 1)%BUFSIZE; - buflen += 1; - - } - comment_mode = false; //for new command - serial_count = 0; //clear buffer - } - else - { - if(serial_char == ';') comment_mode = true; - if(!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char; - } - } -#ifdef SDSUPPORT - if(!sdmode || serial_count!=0){ - return; - } - while( filesize > sdpos && buflen < BUFSIZE) { - n = file.read(); - serial_char = (char)n; - if(serial_char == '\n' || serial_char == '\r' || serial_char == ':' || serial_count >= (MAX_CMD_SIZE - 1) || n == -1) - { - sdpos = file.curPosition(); - if(sdpos >= filesize){ - sdmode = false; - Serial.println("Done printing file"); - stoptime=millis(); - char time[30]; - unsigned long t=(stoptime-starttime)/1000; - int sec,min; - min=t/60; - sec=t%60; - sprintf(time,"%i min, %i sec",min,sec); - Serial.println(time); - LCD_MESSAGE(time); - checkautostart(true); - } - if(!serial_count) return; //if empty line - cmdbuffer[bufindw][serial_count] = 0; //terminate string - if(!comment_mode){ - fromsd[bufindw] = true; - buflen += 1; - bufindw = (bufindw + 1)%BUFSIZE; - } - comment_mode = false; //for new command - serial_count = 0; //clear buffer - } - else - { - if(serial_char == ';') comment_mode = true; - if(!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char; - } - } -#endif //SDSUPPORT - -} - - -inline float code_value() { - return (strtod(&cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], NULL)); -} -inline long code_value_long() { - return (strtol(&cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], NULL, 10)); -} -inline bool code_seen(char code_string[]) { - return (strstr(cmdbuffer[bufindr], code_string) != NULL); -} //Return True if the string was found - -inline bool code_seen(char code) -{ - strchr_pointer = strchr(cmdbuffer[bufindr], code); - return (strchr_pointer != NULL); //Return True if a character was found -} - -inline void process_commands() -{ - unsigned long codenum; //throw away variable - char *starpos = NULL; - - if(code_seen('G')) - { - switch((int)code_value()) - { - case 0: // G0 -> G1 - case 1: // G1 - get_coordinates(); // For X Y Z E F - prepare_move(); - previous_millis_cmd = millis(); - //ClearToSend(); - return; - //break; - case 4: // G4 dwell - codenum = 0; - if(code_seen('P')) codenum = code_value(); // milliseconds to wait - if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait - codenum += millis(); // keep track of when we started waiting - while(millis() < codenum ){ - manage_heater(); - } - break; - case 28: //G28 Home all Axis one at a time - saved_feedrate = feedrate; - saved_feedmultiply = feedmultiply; - feedmultiply = 100; - - for(int i=0; i < NUM_AXIS; i++) { - destination[i] = current_position[i]; - } - feedrate = 0.0; - - home_all_axis = !((code_seen(axis_codes[0])) || (code_seen(axis_codes[1])) || (code_seen(axis_codes[2]))); - - if((home_all_axis) || (code_seen(axis_codes[X_AXIS]))) { - if ((X_MIN_PIN > -1 && X_HOME_DIR==-1) || (X_MAX_PIN > -1 && X_HOME_DIR==1)){ -// st_synchronize(); - current_position[X_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[X_AXIS] = 1.5 * X_MAX_LENGTH * X_HOME_DIR; - feedrate = homing_feedrate[X_AXIS]; - prepare_move(); - -// st_synchronize(); - current_position[X_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[X_AXIS] = -5 * X_HOME_DIR; - prepare_move(); - -// st_synchronize(); - destination[X_AXIS] = 10 * X_HOME_DIR; - feedrate = homing_feedrate[X_AXIS]/2 ; - prepare_move(); - -// st_synchronize(); - current_position[X_AXIS] = (X_HOME_DIR == -1) ? 0 : X_MAX_LENGTH; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[X_AXIS] = current_position[X_AXIS]; - feedrate = 0.0; - } - } - - if((home_all_axis) || (code_seen(axis_codes[Y_AXIS]))) { - if ((Y_MIN_PIN > -1 && Y_HOME_DIR==-1) || (Y_MAX_PIN > -1 && Y_HOME_DIR==1)){ - current_position[Y_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[Y_AXIS] = 1.5 * Y_MAX_LENGTH * Y_HOME_DIR; - feedrate = homing_feedrate[Y_AXIS]; - prepare_move(); -// st_synchronize(); - - current_position[Y_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[Y_AXIS] = -5 * Y_HOME_DIR; - prepare_move(); -// st_synchronize(); - - destination[Y_AXIS] = 10 * Y_HOME_DIR; - feedrate = homing_feedrate[Y_AXIS]/2; - prepare_move(); -// st_synchronize(); - - current_position[Y_AXIS] = (Y_HOME_DIR == -1) ? 0 : Y_MAX_LENGTH; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[Y_AXIS] = current_position[Y_AXIS]; - feedrate = 0.0; - } - } - - if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { - if ((Z_MIN_PIN > -1 && Z_HOME_DIR==-1) || (Z_MAX_PIN > -1 && Z_HOME_DIR==1)){ - current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[Z_AXIS] = 1.5 * Z_MAX_LENGTH * Z_HOME_DIR; - feedrate = homing_feedrate[Z_AXIS]; - prepare_move(); -// st_synchronize(); - - current_position[Z_AXIS] = 0; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[Z_AXIS] = -2 * Z_HOME_DIR; - prepare_move(); -// st_synchronize(); - - destination[Z_AXIS] = 3 * Z_HOME_DIR; - feedrate = homing_feedrate[Z_AXIS]/2; - prepare_move(); -// st_synchronize(); - - current_position[Z_AXIS] = (Z_HOME_DIR == -1) ? 0 : Z_MAX_LENGTH; - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - destination[Z_AXIS] = current_position[Z_AXIS]; - feedrate = 0.0; - } - } - feedrate = saved_feedrate; - feedmultiply = saved_feedmultiply; - previous_millis_cmd = millis(); - break; - case 90: // G90 - relative_mode = false; - break; - case 91: // G91 - relative_mode = true; - break; - case 92: // G92 - if(!code_seen(axis_codes[E_AXIS])) - st_synchronize(); - for(int i=0; i < NUM_AXIS; i++) { - if(code_seen(axis_codes[i])) current_position[i] = code_value(); - } - plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); - break; - } - } - - else if(code_seen('M')) - { - - switch( (int)code_value() ) - { -#ifdef SDSUPPORT - - case 20: // M20 - list SD card - Serial.println("Begin file list"); - root.ls(); - Serial.println("End file list"); - break; - case 21: // M21 - init SD card - sdmode = false; - initsd(); - break; - case 22: //M22 - release SD card - sdmode = false; - sdactive = false; - break; - case 23: //M23 - Select file - if(sdactive){ - sdmode = false; - file.close(); - starpos = (strchr(strchr_pointer + 4,'*')); - if(starpos!=NULL) - *(starpos-1)='\0'; - if (file.open(&root, strchr_pointer + 4, O_READ)) { - Serial.print("File opened:"); - Serial.print(strchr_pointer + 4); - Serial.print(" Size:"); - Serial.println(file.fileSize()); - sdpos = 0; - filesize = file.fileSize(); - Serial.println("File selected"); - } - else{ - Serial.println("file.open failed"); - } - } - break; - case 24: //M24 - Start SD print - if(sdactive){ - sdmode = true; - starttime=millis(); - } - break; - case 25: //M25 - Pause SD print - if(sdmode){ - sdmode = false; - } - break; - case 26: //M26 - Set SD index - if(sdactive && code_seen('S')){ - sdpos = code_value_long(); - file.seekSet(sdpos); - } - break; - case 27: //M27 - Get SD status - if(sdactive){ - Serial.print("SD printing byte "); - Serial.print(sdpos); - Serial.print("/"); - Serial.println(filesize); - } - else{ - Serial.println("Not SD printing"); - } - break; - case 28: //M28 - Start SD write - if(sdactive){ - char* npos = 0; - file.close(); - sdmode = false; - starpos = (strchr(strchr_pointer + 4,'*')); - if(starpos != NULL){ - npos = strchr(cmdbuffer[bufindr], 'N'); - strchr_pointer = strchr(npos,' ') + 1; - *(starpos-1) = '\0'; - } - if (!file.open(&root, strchr_pointer+4, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) - { - Serial.print("open failed, File: "); - Serial.print(strchr_pointer + 4); - Serial.print("."); - } - else{ - savetosd = true; - Serial.print("Writing to file: "); - Serial.println(strchr_pointer + 4); - } - } - break; - case 29: //M29 - Stop SD write - //processed in write to file routine above - //savetosd = false; - break; - case 30: - { - stoptime=millis(); - char time[30]; - unsigned long t=(stoptime-starttime)/1000; - int sec,min; - min=t/60; - sec=t%60; - sprintf(time,"%i min, %i sec",min,sec); - Serial.println(time); - LCD_MESSAGE(time); - } - break; -#endif //SDSUPPORT - case 42: //M42 -Change pin status via gcode - if (code_seen('S')) - { - int pin_status = code_value(); - if (code_seen('P') && pin_status >= 0 && pin_status <= 255) - { - int pin_number = code_value(); - for(int i = 0; i < (int)sizeof(sensitive_pins); i++) - { - if (sensitive_pins[i] == pin_number) - { - pin_number = -1; - break; - } - } - - if (pin_number > -1) - { - pinMode(pin_number, OUTPUT); - digitalWrite(pin_number, pin_status); - analogWrite(pin_number, pin_status); - } - } - } - break; - case 104: // M104 - if (code_seen('S')) target_raw[TEMPSENSOR_HOTEND] = temp2analog(code_value()); -#ifdef PIDTEMP - pid_setpoint = code_value(); -#endif //PIDTEM - #ifdef WATCHPERIOD - if(target_raw[TEMPSENSOR_HOTEND] > current_raw[TEMPSENSOR_HOTEND]){ - watchmillis = max(1,millis()); - watch_raw[TEMPSENSOR_HOTEND] = current_raw[TEMPSENSOR_HOTEND]; - }else{ - watchmillis = 0; - } - #endif - break; - case 140: // M140 set bed temp - if (code_seen('S')) target_raw[TEMPSENSOR_BED] = temp2analogBed(code_value()); - break; - case 105: // M105 - #if (TEMP_0_PIN > -1) || defined (HEATER_USES_AD595) - tt = analog2temp(current_raw[TEMPSENSOR_HOTEND]); - #endif - #if TEMP_1_PIN > -1 - bt = analog2tempBed(current_raw[TEMPSENSOR_BED]); - #endif - #if (TEMP_0_PIN > -1) || defined (HEATER_USES_AD595) - Serial.print("ok T:"); - Serial.print(tt); -// Serial.print(", raw:"); -// Serial.print(current_raw); - #if TEMP_1_PIN > -1 -#ifdef PIDTEMP - Serial.print(" B:"); - #if TEMP_1_PIN > -1 - Serial.println(bt); - #else - Serial.println(HeaterPower); - #endif -#else - Serial.println(); -#endif - #else - Serial.println(); - #endif - #else - Serial.println("No thermistors - no temp"); - #endif - return; - //break; - case 109: {// M109 - Wait for extruder heater to reach target. - LCD_MESSAGE("Heating..."); - if (code_seen('S')) target_raw[TEMPSENSOR_HOTEND] = temp2analog(code_value()); - #ifdef PIDTEMP - pid_setpoint = code_value(); - #endif //PIDTEM - #ifdef WATCHPERIOD - if(target_raw[TEMPSENSOR_HOTEND]>current_raw[TEMPSENSOR_HOTEND]){ - watchmillis = max(1,millis()); - watch_raw[TEMPSENSOR_HOTEND] = current_raw[TEMPSENSOR_HOTEND]; - } else { - watchmillis = 0; - } - #endif //WATCHPERIOD - codenum = millis(); - - /* See if we are heating up or cooling down */ - bool target_direction = (current_raw[0] < target_raw[0]); // true if heating, false if cooling - - #ifdef TEMP_RESIDENCY_TIME - long residencyStart; - residencyStart = -1; - /* continue to loop until we have reached the target temp - _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */ - while((target_direction ? (current_raw[0] < target_raw[0]) : (current_raw[0] > target_raw[0])) || - (residencyStart > -1 && (millis() - residencyStart) < TEMP_RESIDENCY_TIME*1000) ) { - #else - while ( target_direction ? (current_raw[0] < target_raw[0]) : (current_raw[0] > target_raw[0]) ) { - #endif //TEMP_RESIDENCY_TIME - if( (millis() - codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up/cooling down - Serial.print("T:"); - Serial.println( analog2temp(current_raw[TEMPSENSOR_HOTEND]) ); - codenum = millis(); - } - manage_heater(); - LCD_STATUS; - #ifdef TEMP_RESIDENCY_TIME - /* start/restart the TEMP_RESIDENCY_TIME timer whenever we reach target temp for the first time - or when current temp falls outside the hysteresis after target temp was reached */ - if ((residencyStart == -1 && target_direction && current_raw[0] >= target_raw[0]) || - (residencyStart == -1 && !target_direction && current_raw[0] <= target_raw[0]) || - (residencyStart > -1 && labs(analog2temp(current_raw[0]) - analog2temp(target_raw[0])) > TEMP_HYSTERESIS) ) { - residencyStart = millis(); - } - #endif //TEMP_RESIDENCY_TIME - } - LCD_MESSAGE("Marlin ready."); - } - break; - case 190: // M190 - Wait bed for heater to reach target. - #if TEMP_1_PIN > -1 - if (code_seen('S')) target_raw[TEMPSENSOR_BED] = temp2analog(code_value()); - codenum = millis(); - while(current_raw[TEMPSENSOR_BED] < target_raw[TEMPSENSOR_BED]) - { - if( (millis()-codenum) > 1000 ) //Print Temp Reading every 1 second while heating up. - { - float tt=analog2temp(current_raw[TEMPSENSOR_HOTEND]); - Serial.print("T:"); - Serial.println( tt ); - Serial.print("ok T:"); - Serial.print( tt ); - Serial.print(" B:"); - Serial.println( analog2temp(current_raw[TEMPSENSOR_BED]) ); - codenum = millis(); - } - manage_heater(); - } - #endif - break; -#if FAN_PIN > -1 - case 106: //M106 Fan On - if (code_seen('S')){ - WRITE(FAN_PIN,HIGH); - fanpwm=constrain(code_value(),0,255); - analogWrite(FAN_PIN, fanpwm); - } - else { - WRITE(FAN_PIN,HIGH); - fanpwm=255; - analogWrite(FAN_PIN, fanpwm); - } - break; - case 107: //M107 Fan Off - WRITE(FAN_PIN,LOW); - analogWrite(FAN_PIN, 0); - break; -#endif -#if (PS_ON_PIN > -1) - case 80: // M80 - ATX Power On - SET_OUTPUT(PS_ON_PIN); //GND - break; - case 81: // M81 - ATX Power Off - SET_INPUT(PS_ON_PIN); //Floating - break; -#endif - case 82: - axis_relative_modes[3] = false; - break; - case 83: - axis_relative_modes[3] = true; - break; - case 18: - case 84: - if(code_seen('S')){ - stepper_inactive_time = code_value() * 1000; - } - else{ - st_synchronize(); - disable_x(); - disable_y(); - disable_z(); - disable_e(); - } - break; - case 85: // M85 - code_seen('S'); - max_inactive_time = code_value() * 1000; - break; - case 92: // M92 - for(int i=0; i < NUM_AXIS; i++) { - if(code_seen(axis_codes[i])) axis_steps_per_unit[i] = code_value(); - } - - break; - case 115: // M115 - Serial.println("FIRMWARE_NAME:Sprinter/grbl mashup for gen6 FIRMWARE_URL:http://www.mendel-parts.com PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1"); - break; - case 114: // M114 - Serial.print("X:"); - Serial.print(current_position[X_AXIS]); - Serial.print("Y:"); - Serial.print(current_position[Y_AXIS]); - Serial.print("Z:"); - Serial.print(current_position[Z_AXIS]); - Serial.print("E:"); - Serial.print(current_position[E_AXIS]); - #ifdef DEBUG_STEPS - Serial.print(" Count X:"); - Serial.print(float(count_position[X_AXIS])/axis_steps_per_unit[X_AXIS]); - Serial.print("Y:"); - Serial.print(float(count_position[Y_AXIS])/axis_steps_per_unit[Y_AXIS]); - Serial.print("Z:"); - Serial.println(float(count_position[Z_AXIS])/axis_steps_per_unit[Z_AXIS]); - #endif - Serial.println(""); - break; - case 119: // M119 -#if (X_MIN_PIN > -1) - Serial.print("x_min:"); - Serial.print((READ(X_MIN_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); -#endif -#if (X_MAX_PIN > -1) - Serial.print("x_max:"); - Serial.print((READ(X_MAX_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); -#endif -#if (Y_MIN_PIN > -1) - Serial.print("y_min:"); - Serial.print((READ(Y_MIN_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); -#endif -#if (Y_MAX_PIN > -1) - Serial.print("y_max:"); - Serial.print((READ(Y_MAX_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); -#endif -#if (Z_MIN_PIN > -1) - Serial.print("z_min:"); - Serial.print((READ(Z_MIN_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); -#endif -#if (Z_MAX_PIN > -1) - Serial.print("z_max:"); - Serial.print((READ(Z_MAX_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); -#endif - Serial.println(""); - break; - //TODO: update for all axis, use for loop - case 201: // M201 - for(int i=0; i < NUM_AXIS; i++) { - if(code_seen(axis_codes[i])) axis_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i]; - } - break; -#if 0 // Not used for Sprinter/grbl gen6 - case 202: // M202 - for(int i=0; i < NUM_AXIS; i++) { - if(code_seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i]; - } - break; -#endif - case 203: // M203 max feedrate mm/sec - for(int i=0; i < NUM_AXIS; i++) { - if(code_seen(axis_codes[i])) max_feedrate[i] = code_value()*60 ; - } - break; - case 204: // M204 acclereration S normal moves T filmanent only moves - { - if(code_seen('S')) acceleration = code_value() ; - if(code_seen('T')) retract_acceleration = code_value() ; - } - break; - case 205: //M205 advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk - { - if(code_seen('S')) minimumfeedrate = code_value()*60 ; - if(code_seen('T')) mintravelfeedrate = code_value()*60 ; - if(code_seen('B')) minsegmenttime = code_value() ; - if(code_seen('X')) max_xy_jerk = code_value()*60 ; - if(code_seen('Z')) max_z_jerk = code_value()*60 ; - } - break; - case 220: // M220 S- set speed factor override percentage - { - if(code_seen('S')) - { - feedmultiply = code_value() ; - feedmultiplychanged=true; - } - } - break; -#ifdef PIDTEMP - case 301: // M301 - if(code_seen('P')) Kp = code_value(); - if(code_seen('I')) Ki = code_value()*PID_dT; - if(code_seen('D')) Kd = code_value()/PID_dT; -// ECHOLN("Kp "<<_FLOAT(Kp,2)); -// ECHOLN("Ki "<<_FLOAT(Ki/PID_dT,2)); -// ECHOLN("Kd "<<_FLOAT(Kd*PID_dT,2)); - -// temp_iState_min = 0.0; -// if (Ki!=0) { -// temp_iState_max = PID_INTEGRAL_DRIVE_MAX / (Ki/100.0); -// } -// else temp_iState_max = 1.0e10; - break; -#endif //PIDTEMP - case 500: // Store settings in EEPROM - { - StoreSettings(); - } - break; - case 501: // Read settings from EEPROM - { - RetrieveSettings(); - } - break; - case 502: // Revert to default settings - { - RetrieveSettings(true); - } - break; - - } - } - else{ - Serial.println("Unknown command:"); - Serial.println(cmdbuffer[bufindr]); - } - - ClearToSend(); -} - -void FlushSerialRequestResend() -{ - //char cmdbuffer[bufindr][100]="Resend:"; - Serial.flush(); - Serial.print("Resend:"); - Serial.println(gcode_LastN + 1); - ClearToSend(); -} - -void ClearToSend() -{ - previous_millis_cmd = millis(); -#ifdef SDSUPPORT - if(fromsd[bufindr]) - return; -#endif //SDSUPPORT - Serial.println("ok"); -} - -inline void get_coordinates() -{ - for(int i=0; i < NUM_AXIS; i++) { - if(code_seen(axis_codes[i])) destination[i] = (float)code_value() + (axis_relative_modes[i] || relative_mode)*current_position[i]; - else destination[i] = current_position[i]; //Are these else lines really needed? - } - if(code_seen('F')) { - next_feedrate = code_value(); - if(next_feedrate > 0.0) feedrate = next_feedrate; - } -} - -void prepare_move() -{ - plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60.0/100.0); - for(int i=0; i < NUM_AXIS; i++) { - current_position[i] = destination[i]; - } -} - - - -#ifdef USE_WATCHDOG - -#include -#include - -volatile uint8_t timeout_seconds=0; - -void(* ctrlaltdelete) (void) = 0; - -ISR(WDT_vect) { //Watchdog timer interrupt, called if main program blocks >1sec - if(timeout_seconds++ >= WATCHDOG_TIMEOUT) - { - kill(); -#ifdef RESET_MANUAL - LCD_MESSAGE("Please Reset!"); - ECHOLN("echo_: Something is wrong, please turn off the printer."); -#else - LCD_MESSAGE("Timeout, resetting!"); -#endif - //disable watchdog, it will survife reboot. - WDTCSR |= (1< -1 - target_raw[0]=0; - #if HEATER_0_PIN > -1 - WRITE(HEATER_0_PIN,LOW); - #endif - #endif - #if TEMP_1_PIN > -1 - target_raw[1]=0; - #if HEATER_1_PIN > -1 - WRITE(HEATER_1_PIN,LOW); - #endif - #endif - #if TEMP_2_PIN > -1 - target_raw[2]=0; - #if HEATER_2_PIN > -1 - WRITE(HEATER_2_PIN,LOW); - #endif - #endif - disable_x(); - disable_y(); - disable_z(); - disable_e(); - - if(PS_ON_PIN > -1) pinMode(PS_ON_PIN,INPUT); - Serial.println("!! Printer halted. kill() called!!"); - while(1); // Wait for reset -} - -void manage_inactivity(byte debug) { - if( (millis()-previous_millis_cmd) > max_inactive_time ) if(max_inactive_time) kill(); - if( (millis()-previous_millis_cmd) > stepper_inactive_time ) if(stepper_inactive_time) { - disable_x(); - disable_y(); - disable_z(); - disable_e(); - } - check_axes_activity(); -} +/* + Reprap firmware based on Sprinter and grbl. + Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + + 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 . + */ + +/* + This firmware is a mashup between Sprinter and grbl. + (https://github.com/kliment/Sprinter) + (https://github.com/simen/grbl/tree) + + It has preliminary support for Matthew Roberts advance algorithm + http://reprap.org/pipermail/reprap-dev/2011-May/003323.html + */ + - #include ++#include "EEPROMwrite.h" +#include "fastio.h" +#include "Configuration.h" +#include "pins.h" +#include "Marlin.h" +#include "ultralcd.h" +#include "streaming.h" +#include "planner.h" +#include "stepper.h" +#include "temperature.h" + +#ifdef SIMPLE_LCD + #include "Simplelcd.h" +#endif + +char version_string[] = "1.0.0 Alpha 1"; + +#ifdef SDSUPPORT +#include "SdFat.h" +#endif //SDSUPPORT + + +// look here for descriptions of gcodes: http://linuxcnc.org/handbook/gcode/g-code.html +// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes + +//Implemented Codes +//------------------- +// G0 -> G1 +// G1 - Coordinated Movement X Y Z E +// G2 - CW ARC +// G3 - CCW ARC +// G4 - Dwell S or P +// G28 - Home all Axis +// G90 - Use Absolute Coordinates +// G91 - Use Relative Coordinates +// G92 - Set current position to cordinates given + +//RepRap M Codes +// M104 - Set extruder target temp +// M105 - Read current temp +// M106 - Fan on +// M107 - Fan off +// M109 - Wait for extruder current temp to reach target temp. +// M114 - Display current position + +//Custom M Codes +// M20 - List SD card +// M21 - Init SD card +// M22 - Release SD card +// M23 - Select SD file (M23 filename.g) +// M24 - Start/resume SD print +// M25 - Pause SD print +// M26 - Set SD position in bytes (M26 S12345) +// M27 - Report SD print status +// M28 - Start SD write (M28 filename.g) +// M29 - Stop SD write +// M42 - Change pin status via gcode +// M80 - Turn on Power Supply +// M81 - Turn off Power Supply +// M82 - Set E codes absolute (default) +// M83 - Set E codes relative while in Absolute Coordinates (G90) mode +// M84 - Disable steppers until next move, +// or use S to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout. +// M85 - Set inactivity shutdown timer with parameter S. To disable set zero (default) +// M92 - Set axis_steps_per_unit - same syntax as G92 +// M115 - Capabilities string +// M140 - Set bed target temp +// M190 - Wait for bed current temp to reach target temp. +// M200 - Set filament diameter +// 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!! +// M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec +// M204 - Set default acceleration: S normal moves T filament only moves (M204 S3000 T7000) im mm/sec^2 also sets minimum segment time in ms (B20000) to prevent buffer underruns and M20 minimum feedrate +// M205 - advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk +// M220 - set speed factor override percentage S:factor in percent +// M301 - Set PID parameters P I and D +// M500 - stores paramters in EEPROM +// M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily). D +// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. + +//Stepper Movement Variables + +char axis_codes[NUM_AXIS] = { + 'X', 'Y', 'Z', 'E'}; +float destination[NUM_AXIS] = { + 0.0, 0.0, 0.0, 0.0}; +float current_position[NUM_AXIS] = { + 0.0, 0.0, 0.0, 0.0}; +bool home_all_axis = true; +float feedrate = 1500.0, next_feedrate, saved_feedrate; +long gcode_N, gcode_LastN; + +float homing_feedrate[] = HOMING_FEEDRATE; +bool axis_relative_modes[] = AXIS_RELATIVE_MODES; + +bool relative_mode = false; //Determines Absolute or Relative Coordinates +bool relative_mode_e = false; //Determines Absolute or Relative E Codes while in Absolute Coordinates mode. E is always relative in Relative Coordinates mode. + +uint8_t fanpwm=0; + +volatile int feedmultiply=100; //100->1 200->2 +int saved_feedmultiply; +volatile bool feedmultiplychanged=false; +// comm variables +#define MAX_CMD_SIZE 96 +#define BUFSIZE 4 +char cmdbuffer[BUFSIZE][MAX_CMD_SIZE]; +bool fromsd[BUFSIZE]; +int bufindr = 0; +int bufindw = 0; +int buflen = 0; +int i = 0; +char serial_char; +int serial_count = 0; +boolean comment_mode = false; +char *strchr_pointer; // just a pointer to find chars in the cmd string like X, Y, Z, E, etc +extern float HeaterPower; + +#include "EEPROM.h" + +const int sensitive_pins[] = SENSITIVE_PINS; // Sensitive pin list for M42 + +float tt = 0, bt = 0; +#ifdef WATCHPERIOD +int watch_raw = -1000; +unsigned long watchmillis = 0; +#endif //WATCHPERIOD + +//Inactivity shutdown variables +unsigned long previous_millis_cmd = 0; +unsigned long max_inactive_time = 0; +unsigned long stepper_inactive_time = 0; + +unsigned long starttime=0; +unsigned long stoptime=0; +#ifdef SDSUPPORT +Sd2Card card; +SdVolume volume; +SdFile root; +SdFile file; +uint32_t filesize = 0; +uint32_t sdpos = 0; +bool sdmode = false; +bool sdactive = false; +bool savetosd = false; +int16_t n; - long autostart_atmillis=0; ++unsigned long autostart_atmillis=0; + +void initsd(){ + sdactive = false; +#if SDSS >- 1 + if(root.isOpen()) + root.close(); + if (!card.init(SPI_FULL_SPEED,SDSS)){ + //if (!card.init(SPI_HALF_SPEED,SDSS)) + Serial.println("SD init fail"); + } + else if (!volume.init(&card)) + Serial.println("volume.init failed"); + else if (!root.openRoot(&volume)) + Serial.println("openRoot failed"); + else + { + sdactive = true; + Serial.println("SD card ok"); + } +#endif //SDSS +} + +void quickinitsd(){ + sdactive=false; + autostart_atmillis=millis()+5000; +} + +inline void write_command(char *buf){ + char* begin = buf; + char* npos = 0; + char* end = buf + strlen(buf) - 1; + + file.writeError = false; + if((npos = strchr(buf, 'N')) != NULL){ + begin = strchr(npos, ' ') + 1; + end = strchr(npos, '*') - 1; + } + end[1] = '\r'; + end[2] = '\n'; + end[3] = '\0'; + //Serial.println(begin); + file.write(begin); + if (file.writeError){ + Serial.println("error writing to file"); + } +} +#endif //SDSUPPORT + + +///adds an command to the main command buffer +void enquecommand(const char *cmd) +{ + if(buflen < BUFSIZE) + { + //this is dangerous if a mixing of serial and this happsens + strcpy(&(cmdbuffer[bufindw][0]),cmd); + Serial.print("en:");Serial.println(cmdbuffer[bufindw]); + bufindw= (bufindw + 1)%BUFSIZE; + buflen += 1; + } +} + +void setup() +{ + + Serial.begin(BAUDRATE); + ECHOLN("Marlin "< -1 + SET_OUTPUT(SDPOWER); + WRITE(SDPOWER,HIGH); +#endif //SDPOWER + quickinitsd(); + +#endif //SDSUPPORT + plan_init(); // Initialize planner; + st_init(); // Initialize stepper; + tp_init(); // Initialize temperature loop + //checkautostart(); +} + +#ifdef SDSUPPORT +bool autostart_stilltocheck=true; + + +void checkautostart(bool force) +{ + //this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset + if(!force) + { + if(!autostart_stilltocheck) + return; + if(autostart_atmillis 0) - { - for(int i=0;i 0) ++ { ++ for(int i=0;i<(int)strlen((char*)p.name);i++) ++ p.name[i]=tolower(p.name[i]); ++ //Serial.print((char*)p.name); ++ //Serial.print(" "); + //Serial.println(autoname); + if(p.name[9]!='~') //skip safety copies + if(strncmp((char*)p.name,autoname,5)==0) + { + char cmd[30]; + + sprintf(cmd,"M23 %s",autoname); + //sprintf(cmd,"M115"); + //enquecommand("G92 Z0"); + //enquecommand("G1 Z10 F2000"); + //enquecommand("G28 X-105 Y-105"); + enquecommand(cmd); + enquecommand("M24"); + found=true; + + } + } + if(!found) + lastnr=-1; + else + lastnr++; + +} +#else + +inline void checkautostart(bool x) +{ +} +#endif + + +void loop() +{ + if(buflen<3) + get_command(); + checkautostart(false); + if(buflen) + { +#ifdef SDSUPPORT + if(savetosd){ + if(strstr(cmdbuffer[bufindr],"M29") == NULL){ + write_command(cmdbuffer[bufindr]); + Serial.println("ok"); + } + else{ + file.sync(); + file.close(); + savetosd = false; + Serial.println("Done saving file."); + } + } + else{ + process_commands(); + } +#else + process_commands(); +#endif //SDSUPPORT + buflen = (buflen-1); + bufindr = (bufindr + 1)%BUFSIZE; + } + //check heater every n milliseconds + manage_heater(); + manage_inactivity(1); + LCD_STATUS; +} + + +inline void get_command() +{ + while( Serial.available() > 0 && buflen < BUFSIZE) { + serial_char = Serial.read(); + if(serial_char == '\n' || serial_char == '\r' || serial_char == ':' || serial_count >= (MAX_CMD_SIZE - 1) ) + { + if(!serial_count) return; //if empty line + cmdbuffer[bufindw][serial_count] = 0; //terminate string + if(!comment_mode){ + fromsd[bufindw] = false; + if(strstr(cmdbuffer[bufindw], "N") != NULL) + { + strchr_pointer = strchr(cmdbuffer[bufindw], 'N'); + gcode_N = (strtol(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL, 10)); + if(gcode_N != gcode_LastN+1 && (strstr(cmdbuffer[bufindw], "M110") == NULL) ) { + Serial.print("Serial Error: Line Number is not Last Line Number+1, Last Line:"); + Serial.println(gcode_LastN); + //Serial.println(gcode_N); + FlushSerialRequestResend(); + serial_count = 0; + return; + } + + if(strstr(cmdbuffer[bufindw], "*") != NULL) + { + byte checksum = 0; + byte count = 0; + while(cmdbuffer[bufindw][count] != '*') checksum = checksum^cmdbuffer[bufindw][count++]; + strchr_pointer = strchr(cmdbuffer[bufindw], '*'); + + if( (int)(strtod(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL)) != checksum) { + Serial.print("Error: checksum mismatch, Last Line:"); + Serial.println(gcode_LastN); + FlushSerialRequestResend(); + serial_count = 0; + return; + } + //if no errors, continue parsing + } + else + { + Serial.print("Error: No Checksum with line number, Last Line:"); + Serial.println(gcode_LastN); + FlushSerialRequestResend(); + serial_count = 0; + return; + } + + gcode_LastN = gcode_N; + //if no errors, continue parsing + } + else // if we don't receive 'N' but still see '*' + { + if((strstr(cmdbuffer[bufindw], "*") != NULL)) + { + Serial.print("Error: No Line Number with checksum, Last Line:"); + Serial.println(gcode_LastN); + serial_count = 0; + return; + } + } + if((strstr(cmdbuffer[bufindw], "G") != NULL)){ + strchr_pointer = strchr(cmdbuffer[bufindw], 'G'); + switch((int)((strtod(&cmdbuffer[bufindw][strchr_pointer - cmdbuffer[bufindw] + 1], NULL)))){ + case 0: + case 1: +#ifdef SDSUPPORT + if(savetosd) + break; +#endif //SDSUPPORT + Serial.println("ok"); + break; + default: + break; + } + + } + bufindw = (bufindw + 1)%BUFSIZE; + buflen += 1; + + } + comment_mode = false; //for new command + serial_count = 0; //clear buffer + } + else + { + if(serial_char == ';') comment_mode = true; + if(!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char; + } + } +#ifdef SDSUPPORT + if(!sdmode || serial_count!=0){ + return; + } + while( filesize > sdpos && buflen < BUFSIZE) { + n = file.read(); + serial_char = (char)n; + if(serial_char == '\n' || serial_char == '\r' || serial_char == ':' || serial_count >= (MAX_CMD_SIZE - 1) || n == -1) + { + sdpos = file.curPosition(); + if(sdpos >= filesize){ + sdmode = false; + Serial.println("Done printing file"); + stoptime=millis(); + char time[30]; + unsigned long t=(stoptime-starttime)/1000; + int sec,min; + min=t/60; + sec=t%60; + sprintf(time,"%i min, %i sec",min,sec); + Serial.println(time); + LCD_MESSAGE(time); + checkautostart(true); + } + if(!serial_count) return; //if empty line + cmdbuffer[bufindw][serial_count] = 0; //terminate string + if(!comment_mode){ + fromsd[bufindw] = true; + buflen += 1; + bufindw = (bufindw + 1)%BUFSIZE; + } + comment_mode = false; //for new command + serial_count = 0; //clear buffer + } + else + { + if(serial_char == ';') comment_mode = true; + if(!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char; + } + } +#endif //SDSUPPORT + +} + + +inline float code_value() { + return (strtod(&cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], NULL)); +} +inline long code_value_long() { + return (strtol(&cmdbuffer[bufindr][strchr_pointer - cmdbuffer[bufindr] + 1], NULL, 10)); +} +inline bool code_seen(char code_string[]) { + return (strstr(cmdbuffer[bufindr], code_string) != NULL); +} //Return True if the string was found + +inline bool code_seen(char code) +{ + strchr_pointer = strchr(cmdbuffer[bufindr], code); + return (strchr_pointer != NULL); //Return True if a character was found +} + +inline void process_commands() +{ + unsigned long codenum; //throw away variable + char *starpos = NULL; + + if(code_seen('G')) + { + switch((int)code_value()) + { + case 0: // G0 -> G1 + case 1: // G1 + get_coordinates(); // For X Y Z E F + prepare_move(); + previous_millis_cmd = millis(); + //ClearToSend(); + return; + //break; + case 4: // G4 dwell + codenum = 0; + if(code_seen('P')) codenum = code_value(); // milliseconds to wait + if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait + codenum += millis(); // keep track of when we started waiting + while(millis() < codenum ){ + manage_heater(); + } + break; + case 28: //G28 Home all Axis one at a time + saved_feedrate = feedrate; + saved_feedmultiply = feedmultiply; + feedmultiply = 100; + + for(int i=0; i < NUM_AXIS; i++) { + destination[i] = current_position[i]; + } + feedrate = 0.0; + + home_all_axis = !((code_seen(axis_codes[0])) || (code_seen(axis_codes[1])) || (code_seen(axis_codes[2]))); + + if((home_all_axis) || (code_seen(axis_codes[X_AXIS]))) { + if ((X_MIN_PIN > -1 && X_HOME_DIR==-1) || (X_MAX_PIN > -1 && X_HOME_DIR==1)){ +// st_synchronize(); + current_position[X_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[X_AXIS] = 1.5 * X_MAX_LENGTH * X_HOME_DIR; + feedrate = homing_feedrate[X_AXIS]; + prepare_move(); + +// st_synchronize(); + current_position[X_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[X_AXIS] = -5 * X_HOME_DIR; + prepare_move(); + +// st_synchronize(); + destination[X_AXIS] = 10 * X_HOME_DIR; + feedrate = homing_feedrate[X_AXIS]/2 ; + prepare_move(); + +// st_synchronize(); + current_position[X_AXIS] = (X_HOME_DIR == -1) ? 0 : X_MAX_LENGTH; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[X_AXIS] = current_position[X_AXIS]; + feedrate = 0.0; + } + } + + if((home_all_axis) || (code_seen(axis_codes[Y_AXIS]))) { + if ((Y_MIN_PIN > -1 && Y_HOME_DIR==-1) || (Y_MAX_PIN > -1 && Y_HOME_DIR==1)){ + current_position[Y_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Y_AXIS] = 1.5 * Y_MAX_LENGTH * Y_HOME_DIR; + feedrate = homing_feedrate[Y_AXIS]; + prepare_move(); +// st_synchronize(); + + current_position[Y_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Y_AXIS] = -5 * Y_HOME_DIR; + prepare_move(); +// st_synchronize(); + + destination[Y_AXIS] = 10 * Y_HOME_DIR; + feedrate = homing_feedrate[Y_AXIS]/2; + prepare_move(); +// st_synchronize(); + + current_position[Y_AXIS] = (Y_HOME_DIR == -1) ? 0 : Y_MAX_LENGTH; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Y_AXIS] = current_position[Y_AXIS]; + feedrate = 0.0; + } + } + + if((home_all_axis) || (code_seen(axis_codes[Z_AXIS]))) { + if ((Z_MIN_PIN > -1 && Z_HOME_DIR==-1) || (Z_MAX_PIN > -1 && Z_HOME_DIR==1)){ + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Z_AXIS] = 1.5 * Z_MAX_LENGTH * Z_HOME_DIR; + feedrate = homing_feedrate[Z_AXIS]; + prepare_move(); +// st_synchronize(); + + current_position[Z_AXIS] = 0; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Z_AXIS] = -2 * Z_HOME_DIR; + prepare_move(); +// st_synchronize(); + + destination[Z_AXIS] = 3 * Z_HOME_DIR; + feedrate = homing_feedrate[Z_AXIS]/2; + prepare_move(); +// st_synchronize(); + + current_position[Z_AXIS] = (Z_HOME_DIR == -1) ? 0 : Z_MAX_LENGTH; + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + destination[Z_AXIS] = current_position[Z_AXIS]; + feedrate = 0.0; + } + } + feedrate = saved_feedrate; + feedmultiply = saved_feedmultiply; + previous_millis_cmd = millis(); + break; + case 90: // G90 + relative_mode = false; + break; + case 91: // G91 + relative_mode = true; + break; + case 92: // G92 + if(!code_seen(axis_codes[E_AXIS])) + st_synchronize(); + for(int i=0; i < NUM_AXIS; i++) { + if(code_seen(axis_codes[i])) current_position[i] = code_value(); + } + plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); + break; + } + } + + else if(code_seen('M')) + { + + switch( (int)code_value() ) + { +#ifdef SDSUPPORT + + case 20: // M20 - list SD card + Serial.println("Begin file list"); + root.ls(); + Serial.println("End file list"); + break; + case 21: // M21 - init SD card + sdmode = false; + initsd(); + break; + case 22: //M22 - release SD card + sdmode = false; + sdactive = false; + break; + case 23: //M23 - Select file + if(sdactive){ + sdmode = false; + file.close(); + starpos = (strchr(strchr_pointer + 4,'*')); + if(starpos!=NULL) + *(starpos-1)='\0'; + if (file.open(&root, strchr_pointer + 4, O_READ)) { + Serial.print("File opened:"); + Serial.print(strchr_pointer + 4); + Serial.print(" Size:"); + Serial.println(file.fileSize()); + sdpos = 0; + filesize = file.fileSize(); + Serial.println("File selected"); + } + else{ + Serial.println("file.open failed"); + } + } + break; + case 24: //M24 - Start SD print + if(sdactive){ + sdmode = true; + starttime=millis(); + } + break; + case 25: //M25 - Pause SD print + if(sdmode){ + sdmode = false; + } + break; + case 26: //M26 - Set SD index + if(sdactive && code_seen('S')){ + sdpos = code_value_long(); + file.seekSet(sdpos); + } + break; + case 27: //M27 - Get SD status + if(sdactive){ + Serial.print("SD printing byte "); + Serial.print(sdpos); + Serial.print("/"); + Serial.println(filesize); + } + else{ + Serial.println("Not SD printing"); + } + break; + case 28: //M28 - Start SD write + if(sdactive){ + char* npos = 0; + file.close(); + sdmode = false; + starpos = (strchr(strchr_pointer + 4,'*')); + if(starpos != NULL){ + npos = strchr(cmdbuffer[bufindr], 'N'); + strchr_pointer = strchr(npos,' ') + 1; + *(starpos-1) = '\0'; + } + if (!file.open(&root, strchr_pointer+4, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) + { + Serial.print("open failed, File: "); + Serial.print(strchr_pointer + 4); + Serial.print("."); + } + else{ + savetosd = true; + Serial.print("Writing to file: "); + Serial.println(strchr_pointer + 4); + } + } + break; + case 29: //M29 - Stop SD write + //processed in write to file routine above + //savetosd = false; + break; + case 30: + { + stoptime=millis(); + char time[30]; + unsigned long t=(stoptime-starttime)/1000; + int sec,min; + min=t/60; + sec=t%60; + sprintf(time,"%i min, %i sec",min,sec); + Serial.println(time); + LCD_MESSAGE(time); - } - break; ++ } ++ break; +#endif //SDSUPPORT + case 42: //M42 -Change pin status via gcode + if (code_seen('S')) + { + int pin_status = code_value(); + if (code_seen('P') && pin_status >= 0 && pin_status <= 255) + { + int pin_number = code_value(); - for(int i = 0; i < sizeof(sensitive_pins); i++) ++ for(int i = 0; i < (int)sizeof(sensitive_pins); i++) + { + if (sensitive_pins[i] == pin_number) + { + pin_number = -1; + break; + } + } + + if (pin_number > -1) + { + pinMode(pin_number, OUTPUT); + digitalWrite(pin_number, pin_status); + analogWrite(pin_number, pin_status); + } + } + } + break; + case 104: // M104 - if (code_seen('S')) target_raw[0] = temp2analog(code_value()); ++ if (code_seen('S')) target_raw[TEMPSENSOR_HOTEND] = temp2analog(code_value()); +#ifdef PIDTEMP + pid_setpoint = code_value(); +#endif //PIDTEM + #ifdef WATCHPERIOD - if(target_raw[0] > current_raw[0]){ ++ if(target_raw[TEMPSENSOR_HOTEND] > current_raw[TEMPSENSOR_HOTEND]){ + watchmillis = max(1,millis()); - watch_raw = current_raw[0]; ++ watch_raw[TEMPSENSOR_HOTEND] = current_raw[TEMPSENSOR_HOTEND]; + }else{ + watchmillis = 0; + } + #endif + break; + case 140: // M140 set bed temp - if (code_seen('S')) target_raw[1] = temp2analogBed(code_value()); ++ if (code_seen('S')) target_raw[TEMPSENSOR_BED] = temp2analogBed(code_value()); + break; + case 105: // M105 + #if (TEMP_0_PIN > -1) || defined (HEATER_USES_AD595) - tt = analog2temp(current_raw[0]); ++ tt = analog2temp(current_raw[TEMPSENSOR_HOTEND]); + #endif + #if TEMP_1_PIN > -1 - bt = analog2tempBed(current_raw[1]); ++ bt = analog2tempBed(current_raw[TEMPSENSOR_BED]); + #endif + #if (TEMP_0_PIN > -1) || defined (HEATER_USES_AD595) + Serial.print("ok T:"); + Serial.print(tt); +// Serial.print(", raw:"); +// Serial.print(current_raw); + #if TEMP_1_PIN > -1 +#ifdef PIDTEMP + Serial.print(" B:"); + #if TEMP_1_PIN > -1 + Serial.println(bt); + #else + Serial.println(HeaterPower); + #endif +#else + Serial.println(); +#endif + #else + Serial.println(); + #endif + #else + Serial.println("No thermistors - no temp"); + #endif + return; + //break; + case 109: {// M109 - Wait for extruder heater to reach target. + LCD_MESSAGE("Heating..."); - if (code_seen('S')) target_raw[0] = temp2analog(code_value()); ++ if (code_seen('S')) target_raw[TEMPSENSOR_HOTEND] = temp2analog(code_value()); + #ifdef PIDTEMP + pid_setpoint = code_value(); + #endif //PIDTEM + #ifdef WATCHPERIOD - if(target_raw[0]>current_raw[0]) { ++ if(target_raw[TEMPSENSOR_HOTEND]>current_raw[TEMPSENSOR_HOTEND]){ + watchmillis = max(1,millis()); - watch_raw = current_raw[0]; ++ watch_raw[TEMPSENSOR_HOTEND] = current_raw[TEMPSENSOR_HOTEND]; + } else { + watchmillis = 0; + } + #endif //WATCHPERIOD + codenum = millis(); + + /* See if we are heating up or cooling down */ + bool target_direction = (current_raw[0] < target_raw[0]); // true if heating, false if cooling + + #ifdef TEMP_RESIDENCY_TIME + long residencyStart; + residencyStart = -1; + /* continue to loop until we have reached the target temp + _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */ + while((target_direction ? (current_raw[0] < target_raw[0]) : (current_raw[0] > target_raw[0])) || + (residencyStart > -1 && (millis() - residencyStart) < TEMP_RESIDENCY_TIME*1000) ) { + #else + while ( target_direction ? (current_raw[0] < target_raw[0]) : (current_raw[0] > target_raw[0]) ) { + #endif //TEMP_RESIDENCY_TIME + if( (millis() - codenum) > 1000 ) { //Print Temp Reading every 1 second while heating up/cooling down + Serial.print("T:"); - Serial.println( analog2temp(current_raw[0]) ); ++ Serial.println( analog2temp(current_raw[TEMPSENSOR_HOTEND]) ); + codenum = millis(); + } + manage_heater(); + LCD_STATUS; + #ifdef TEMP_RESIDENCY_TIME + /* start/restart the TEMP_RESIDENCY_TIME timer whenever we reach target temp for the first time + or when current temp falls outside the hysteresis after target temp was reached */ + if ((residencyStart == -1 && target_direction && current_raw[0] >= target_raw[0]) || + (residencyStart == -1 && !target_direction && current_raw[0] <= target_raw[0]) || + (residencyStart > -1 && labs(analog2temp(current_raw[0]) - analog2temp(target_raw[0])) > TEMP_HYSTERESIS) ) { + residencyStart = millis(); + } + #endif //TEMP_RESIDENCY_TIME - } ++ } + LCD_MESSAGE("Marlin ready."); + } + break; + case 190: // M190 - Wait bed for heater to reach target. + #if TEMP_1_PIN > -1 - if (code_seen('S')) target_raw[1] = temp2analog(code_value()); ++ if (code_seen('S')) target_raw[TEMPSENSOR_BED] = temp2analog(code_value()); + codenum = millis(); - while(current_raw[1] < target_raw[1]) ++ while(current_raw[TEMPSENSOR_BED] < target_raw[TEMPSENSOR_BED]) + { + if( (millis()-codenum) > 1000 ) //Print Temp Reading every 1 second while heating up. + { - float tt=analog2temp(current_raw[0]); ++ float tt=analog2temp(current_raw[TEMPSENSOR_HOTEND]); + Serial.print("T:"); + Serial.println( tt ); + Serial.print("ok T:"); + Serial.print( tt ); + Serial.print(" B:"); - Serial.println( analog2temp(current_raw[1]) ); ++ Serial.println( analog2temp(current_raw[TEMPSENSOR_BED]) ); + codenum = millis(); + } + manage_heater(); + } + #endif + break; +#if FAN_PIN > -1 + case 106: //M106 Fan On + if (code_seen('S')){ + WRITE(FAN_PIN,HIGH); + fanpwm=constrain(code_value(),0,255); + analogWrite(FAN_PIN, fanpwm); + } + else { + WRITE(FAN_PIN,HIGH); + fanpwm=255; + analogWrite(FAN_PIN, fanpwm); + } + break; + case 107: //M107 Fan Off + WRITE(FAN_PIN,LOW); + analogWrite(FAN_PIN, 0); + break; +#endif +#if (PS_ON_PIN > -1) + case 80: // M80 - ATX Power On + SET_OUTPUT(PS_ON_PIN); //GND + break; + case 81: // M81 - ATX Power Off + SET_INPUT(PS_ON_PIN); //Floating + break; +#endif + case 82: + axis_relative_modes[3] = false; + break; + case 83: + axis_relative_modes[3] = true; + break; + case 18: + case 84: + if(code_seen('S')){ + stepper_inactive_time = code_value() * 1000; + } + else{ + st_synchronize(); + disable_x(); + disable_y(); + disable_z(); + disable_e(); + } + break; + case 85: // M85 + code_seen('S'); + max_inactive_time = code_value() * 1000; + break; + case 92: // M92 + for(int i=0; i < NUM_AXIS; i++) { + if(code_seen(axis_codes[i])) axis_steps_per_unit[i] = code_value(); + } + + break; + case 115: // M115 + Serial.println("FIRMWARE_NAME:Sprinter/grbl mashup for gen6 FIRMWARE_URL:http://www.mendel-parts.com PROTOCOL_VERSION:1.0 MACHINE_TYPE:Mendel EXTRUDER_COUNT:1"); + break; + case 114: // M114 + Serial.print("X:"); + Serial.print(current_position[X_AXIS]); + Serial.print("Y:"); + Serial.print(current_position[Y_AXIS]); + Serial.print("Z:"); + Serial.print(current_position[Z_AXIS]); + Serial.print("E:"); + Serial.print(current_position[E_AXIS]); + #ifdef DEBUG_STEPS + Serial.print(" Count X:"); + Serial.print(float(count_position[X_AXIS])/axis_steps_per_unit[X_AXIS]); + Serial.print("Y:"); + Serial.print(float(count_position[Y_AXIS])/axis_steps_per_unit[Y_AXIS]); + Serial.print("Z:"); + Serial.println(float(count_position[Z_AXIS])/axis_steps_per_unit[Z_AXIS]); + #endif + Serial.println(""); + break; + case 119: // M119 +#if (X_MIN_PIN > -1) + Serial.print("x_min:"); + Serial.print((READ(X_MIN_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); +#endif +#if (X_MAX_PIN > -1) + Serial.print("x_max:"); + Serial.print((READ(X_MAX_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); +#endif +#if (Y_MIN_PIN > -1) + Serial.print("y_min:"); + Serial.print((READ(Y_MIN_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); +#endif +#if (Y_MAX_PIN > -1) + Serial.print("y_max:"); + Serial.print((READ(Y_MAX_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); +#endif +#if (Z_MIN_PIN > -1) + Serial.print("z_min:"); + Serial.print((READ(Z_MIN_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); +#endif +#if (Z_MAX_PIN > -1) + Serial.print("z_max:"); + Serial.print((READ(Z_MAX_PIN)^ENDSTOPS_INVERTING)?"H ":"L "); +#endif + Serial.println(""); + break; + //TODO: update for all axis, use for loop + case 201: // M201 + for(int i=0; i < NUM_AXIS; i++) { + if(code_seen(axis_codes[i])) axis_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i]; + } + break; +#if 0 // Not used for Sprinter/grbl gen6 + case 202: // M202 + for(int i=0; i < NUM_AXIS; i++) { + if(code_seen(axis_codes[i])) axis_travel_steps_per_sqr_second[i] = code_value() * axis_steps_per_unit[i]; + } + break; +#endif + case 203: // M203 max feedrate mm/sec + for(int i=0; i < NUM_AXIS; i++) { + if(code_seen(axis_codes[i])) max_feedrate[i] = code_value()*60 ; + } + break; + case 204: // M204 acclereration S normal moves T filmanent only moves + { + if(code_seen('S')) acceleration = code_value() ; + if(code_seen('T')) retract_acceleration = code_value() ; + } + break; + case 205: //M205 advanced settings: minimum travel speed S=while printing T=travel only, B=minimum segment time X= maximum xy jerk, Z=maximum Z jerk + { + if(code_seen('S')) minimumfeedrate = code_value()*60 ; + if(code_seen('T')) mintravelfeedrate = code_value()*60 ; + if(code_seen('B')) minsegmenttime = code_value() ; + if(code_seen('X')) max_xy_jerk = code_value()*60 ; + if(code_seen('Z')) max_z_jerk = code_value()*60 ; + } + break; + case 220: // M220 S- set speed factor override percentage + { + if(code_seen('S')) + { + feedmultiply = code_value() ; + feedmultiplychanged=true; + } + } + break; +#ifdef PIDTEMP + case 301: // M301 + if(code_seen('P')) Kp = code_value(); + if(code_seen('I')) Ki = code_value()*PID_dT; + if(code_seen('D')) Kd = code_value()/PID_dT; +// ECHOLN("Kp "<<_FLOAT(Kp,2)); +// ECHOLN("Ki "<<_FLOAT(Ki/PID_dT,2)); +// ECHOLN("Kd "<<_FLOAT(Kd*PID_dT,2)); + +// temp_iState_min = 0.0; +// if (Ki!=0) { +// temp_iState_max = PID_INTEGRAL_DRIVE_MAX / (Ki/100.0); +// } +// else temp_iState_max = 1.0e10; + break; +#endif //PIDTEMP + case 500: // Store settings in EEPROM + { + StoreSettings(); + } + break; + case 501: // Read settings from EEPROM + { + RetrieveSettings(); + } + break; + case 502: // Revert to default settings + { + RetrieveSettings(true); + } + break; + + } + } + else{ + Serial.println("Unknown command:"); + Serial.println(cmdbuffer[bufindr]); + } + + ClearToSend(); +} + +void FlushSerialRequestResend() +{ + //char cmdbuffer[bufindr][100]="Resend:"; + Serial.flush(); + Serial.print("Resend:"); + Serial.println(gcode_LastN + 1); + ClearToSend(); +} + +void ClearToSend() +{ + previous_millis_cmd = millis(); +#ifdef SDSUPPORT + if(fromsd[bufindr]) + return; +#endif //SDSUPPORT + Serial.println("ok"); +} + +inline void get_coordinates() +{ + for(int i=0; i < NUM_AXIS; i++) { + if(code_seen(axis_codes[i])) destination[i] = (float)code_value() + (axis_relative_modes[i] || relative_mode)*current_position[i]; + else destination[i] = current_position[i]; //Are these else lines really needed? + } + if(code_seen('F')) { + next_feedrate = code_value(); + if(next_feedrate > 0.0) feedrate = next_feedrate; + } +} + +void prepare_move() +{ + plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60.0/100.0); + for(int i=0; i < NUM_AXIS; i++) { + current_position[i] = destination[i]; + } +} + + + +#ifdef USE_WATCHDOG + +#include +#include + +volatile uint8_t timeout_seconds=0; + +void(* ctrlaltdelete) (void) = 0; + +ISR(WDT_vect) { //Watchdog timer interrupt, called if main program blocks >1sec + if(timeout_seconds++ >= WATCHDOG_TIMEOUT) + { + kill(); +#ifdef RESET_MANUAL + LCD_MESSAGE("Please Reset!"); + ECHOLN("echo_: Something is wrong, please turn off the printer."); +#else + LCD_MESSAGE("Timeout, resetting!"); +#endif + //disable watchdog, it will survife reboot. + WDTCSR |= (1< -1 + target_raw[0]=0; + #if HEATER_0_PIN > -1 + WRITE(HEATER_0_PIN,LOW); + #endif + #endif + #if TEMP_1_PIN > -1 + target_raw[1]=0; + #if HEATER_1_PIN > -1 + WRITE(HEATER_1_PIN,LOW); + #endif + #endif + #if TEMP_2_PIN > -1 + target_raw[2]=0; + #if HEATER_2_PIN > -1 + WRITE(HEATER_2_PIN,LOW); + #endif + #endif + disable_x(); + disable_y(); + disable_z(); + disable_e(); + + if(PS_ON_PIN > -1) pinMode(PS_ON_PIN,INPUT); + Serial.println("!! Printer halted. kill() called!!"); + while(1); // Wait for reset +} + +void manage_inactivity(byte debug) { + if( (millis()-previous_millis_cmd) > max_inactive_time ) if(max_inactive_time) kill(); + if( (millis()-previous_millis_cmd) > stepper_inactive_time ) if(stepper_inactive_time) { + disable_x(); + disable_y(); + disable_z(); + disable_e(); + } + check_axes_activity(); +} diff --cc Marlin/temperature.cpp index 4406e94,25df2f7..430e87f --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@@ -1,496 -1,486 +1,501 @@@ -/* - temperature.c - temperature control - Part of Marlin - - Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm - - 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 . - */ - -/* - This firmware is a mashup between Sprinter and grbl. - (https://github.com/kliment/Sprinter) - (https://github.com/simen/grbl/tree) - - It has preliminary support for Matthew Roberts advance algorithm - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html - - This firmware is optimized for gen6 electronics. - */ - -#include "fastio.h" -#include "Configuration.h" -#include "pins.h" -#include "Marlin.h" -#include "ultralcd.h" -#include "streaming.h" -#include "temperature.h" - -int target_bed_raw = 0; -int current_bed_raw = 0; - -int target_raw[3] = {0, 0, 0}; -int current_raw[3] = {0, 0, 0}; -unsigned char temp_meas_ready = false; - -unsigned long previous_millis_heater, previous_millis_bed_heater; - -#ifdef PIDTEMP - double temp_iState = 0; - double temp_dState = 0; - double pTerm; - double iTerm; - double dTerm; - //int output; - double pid_error; - double temp_iState_min; - double temp_iState_max; - double pid_setpoint = 0.0; - double pid_input; - double pid_output; - bool pid_reset; - float HeaterPower; - - float Kp=DEFAULT_Kp; - float Ki=DEFAULT_Ki; - float Kd=DEFAULT_Kd; - float Kc=DEFAULT_Kc; -#endif //PIDTEMP - -#ifdef MINTEMP -int minttemp = temp2analog(MINTEMP); -#endif //MINTEMP -#ifdef MAXTEMP -int maxttemp = temp2analog(MAXTEMP); -#endif //MAXTEMP - -#ifdef BED_MINTEMP -int bed_minttemp = temp2analog(BED_MINTEMP); -#endif //BED_MINTEMP -#ifdef BED_MAXTEMP -int bed_maxttemp = temp2analog(BED_MAXTEMP); -#endif //BED_MAXTEMP - -void manage_heater() -{ -#ifdef USE_WATCHDOG - wd_reset(); -#endif - - float pid_input; - float pid_output; - if(temp_meas_ready != true) //better readability - return; - -CRITICAL_SECTION_START; - temp_meas_ready = false; -CRITICAL_SECTION_END; - -#ifdef PIDTEMP - pid_input = analog2temp(current_raw[TEMPSENSOR_HOTEND]); - -#ifndef PID_OPENLOOP - pid_error = pid_setpoint - pid_input; - if(pid_error > 10){ - pid_output = PID_MAX; - pid_reset = true; - } - else if(pid_error < -10) { - pid_output = 0; - pid_reset = true; - } - else { - if(pid_reset == true) { - temp_iState = 0.0; - pid_reset = false; - } - pTerm = Kp * pid_error; - temp_iState += pid_error; - temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max); - iTerm = Ki * temp_iState; - //K1 defined in Configuration.h in the PID settings - #define K2 (1.0-K1) - dTerm = (Kd * (pid_input - temp_dState))*K2 + (K1 * dTerm); - temp_dState = pid_input; - #ifdef PID_ADD_EXTRUSION_RATE - pTerm+=Kc*current_block->speed_e; //additional heating if extrusion speed is high - #endif - pid_output = constrain(pTerm + iTerm - dTerm, 0, PID_MAX); - } -#endif //PID_OPENLOOP -#ifdef PID_DEBUG - Serial.print(" Input "); - Serial.print(pid_input); - Serial.print(" Output "); - Serial.print(pid_output); - Serial.print(" pTerm "); - Serial.print(pTerm); - Serial.print(" iTerm "); - Serial.print(iTerm); - Serial.print(" dTerm "); - Serial.print(dTerm); - Serial.println(); -#endif //PID_DEBUG - analogWrite(HEATER_0_PIN, pid_output); -#endif //PIDTEMP - -#ifndef PIDTEMP - if(current_raw[0] >= target_raw[0]) - { - WRITE(HEATER_0_PIN,LOW); - } - else - { - WRITE(HEATER_0_PIN,HIGH); - } -#endif - - if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) - return; - previous_millis_bed_heater = millis(); - - #if TEMP_1_PIN > -1 - if(current_raw[TEMPSENSOR_BED] >= target_raw[TEMPSENSOR_BED]) - { - WRITE(HEATER_1_PIN,LOW); - } - else - { - WRITE(HEATER_1_PIN,HIGH); - } - #endif - } - -// Takes hot end temperature value as input and returns corresponding raw value. -// For a thermistor, it uses the RepRap thermistor temp table. -// This is needed because PID in hydra firmware hovers around a given analog value, not a temp value. -// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware. -float temp2analog(int celsius) { - #ifdef HEATER_USES_THERMISTOR_1 - int raw = 0; - byte i; - - for (i=1; i raw) - { - celsius = temptable_1[i-1][1] + - (raw - temptable_1[i-1][0]) * - (temptable_1[i][1] - temptable_1[i-1][1]) / - (temptable_1[i][0] - temptable_1[i-1][0]); - - break; - } - } - - // Overflow: Set to last value in the table - if (i == NUMTEMPS_HEATER_1) celsius = temptable_1[i-1][1]; - - return celsius; - #elif defined HEATER_1_USES_AD595 - return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; - #endif -} - -// Derived from RepRap FiveD extruder::getTemperature() -// For bed temperature measurement. -float analog2tempBed(int raw) { - #ifdef BED_USES_THERMISTOR - int celsius = 0; - byte i; - - raw = (1023 * OVERSAMPLENR) - raw; - - for (i=1; i raw) - { - celsius = bedtemptable[i-1][1] + - (raw - bedtemptable[i-1][0]) * - (bedtemptable[i][1] - bedtemptable[i-1][1]) / - (bedtemptable[i][0] - bedtemptable[i-1][0]); - - break; - } - } - - // Overflow: Set to last value in the table - if (i == BNUMTEMPS) celsius = bedtemptable[i-1][1]; - - return celsius; - - #elif defined BED_USES_AD595 - return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; - #endif -} - -void tp_init() -{ -#if (HEATER_0_PIN > -1) - SET_OUTPUT(HEATER_0_PIN); -#endif -#if (HEATER_1_PIN > -1) - SET_OUTPUT(HEATER_1_PIN); -#endif -#if (HEATER_2_PIN > -1) - SET_OUTPUT(HEATER_2_PIN); -#endif - -#ifdef PIDTEMP - temp_iState_min = 0.0; - temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki; -#endif //PIDTEMP - -// Set analog inputs - ADCSRA = 1< -1) - #if TEMP_0_PIN < 8 - DIDR0 = 1 << TEMP_0_PIN; - #else - DIDR2 = 1<<(TEMP_0_PIN - 8); - ADCSRB = 1< -1) - raw_temp_0_value += ADC; - #endif - temp_state = 2; - break; - case 2: // Prepare TEMP_1 - #if (TEMP_1_PIN > -1) - #if TEMP_1_PIN < 7 - DIDR0 = 1< -1) - raw_temp_1_value += ADC; - #endif - temp_state = 4; - break; - case 4: // Prepare TEMP_2 - #if (TEMP_2_PIN > -1) - #if TEMP_2_PIN < 7 - DIDR0 = 1 << TEMP_2_PIN; - #else - DIDR2 = 1<<(TEMP_2_PIN - 8); - ADCSRB = 1< -1) - raw_temp_2_value += ADC; - #endif - temp_state = 0; - temp_count++; - break; - default: - Serial.println("!! Temp measurement error !!"); - break; - } - - if(temp_count >= 16) // 6 ms * 16 = 96ms. - { - #ifdef HEATER_1_USES_AD595 - current_raw[0] = raw_temp_0_value; - #else - current_raw[0] = 16383 - raw_temp_0_value; - #endif - - #ifdef HEATER_2_USES_AD595 - current_raw[2] = raw_temp_2_value; - #else - current_raw[2] = 16383 - raw_temp_2_value; - #endif - - #ifdef BED_USES_AD595 - current_raw[1] = raw_temp_1_value; - #else - current_raw[1] = 16383 - raw_temp_1_value; - #endif - - temp_meas_ready = true; - temp_count = 0; - raw_temp_0_value = 0; - raw_temp_1_value = 0; - raw_temp_2_value = 0; -#ifdef MAXTEMP - #if (HEATER_0_PIN > -1) - if(current_raw[TEMPSENSOR_HOTEND] >= maxttemp) { - target_raw[TEMPSENSOR_HOTEND] = 0; - analogWrite(HEATER_0_PIN, 0); - Serial.println("!! Temperature extruder 0 switched off. MAXTEMP triggered !!"); - } - #endif - #if (HEATER_2_PIN > -1) - if(current_raw[TEMPSENSOR_AUX] >= maxttemp) { - target_raw[TEMPSENSOR_AUX] = 0; - analogWrite(HEATER_2_PIN, 0); - Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!"); - } - #endif -#endif //MAXTEMP -#ifdef MINTEMP - #if (HEATER_0_PIN > -1) - if(current_raw[TEMPSENSOR_HOTEND] <= minttemp) { - target_raw[TEMPSENSOR_HOTEND] = 0; - analogWrite(HEATER_0_PIN, 0); - Serial.println("!! Temperature extruder 0 switched off. MINTEMP triggered !!"); - } - #endif - #if (HEATER_2_PIN > -1) - if(current_raw[TEMPSENSOR_AUX] <= minttemp) { - target_raw[TEMPSENSOR_AUX] = 0; - analogWrite(HEATER_2_PIN, 0); - Serial.println("!! Temperature extruder 1 switched off. MINTEMP triggered !!"); - } - #endif -#endif //MAXTEMP -#ifdef BED_MINTEMP - #if (HEATER_1_PIN > -1) - if(current_raw[1] <= bed_minttemp) { - target_raw[1] = 0; - WRITE(HEATER_1_PIN, 0); - Serial.println("!! Temperatur heated bed switched off. MINTEMP triggered !!"); - } - #endif -#endif -#ifdef BED_MAXTEMP - #if (HEATER_1_PIN > -1) - if(current_raw[1] >= bed_maxttemp) { - target_raw[1] = 0; - WRITE(HEATER_1_PIN, 0); - Serial.println("!! Temperature heated bed switched off. MAXTEMP triggered !!"); - } - #endif -#endif - } -} +/* + temperature.c - temperature control + Part of Marlin + + Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + + 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 . + */ + +/* + This firmware is a mashup between Sprinter and grbl. + (https://github.com/kliment/Sprinter) + (https://github.com/simen/grbl/tree) + + It has preliminary support for Matthew Roberts advance algorithm + http://reprap.org/pipermail/reprap-dev/2011-May/003323.html + + This firmware is optimized for gen6 electronics. + */ + +#include "fastio.h" +#include "Configuration.h" +#include "pins.h" +#include "Marlin.h" +#include "ultralcd.h" +#include "streaming.h" +#include "temperature.h" + +int target_bed_raw = 0; +int current_bed_raw = 0; + +int target_raw[3] = {0, 0, 0}; +int current_raw[3] = {0, 0, 0}; +unsigned char temp_meas_ready = false; + +unsigned long previous_millis_heater, previous_millis_bed_heater; + +#ifdef PIDTEMP + double temp_iState = 0; + double temp_dState = 0; + double pTerm; + double iTerm; + double dTerm; + //int output; + double pid_error; + double temp_iState_min; + double temp_iState_max; + double pid_setpoint = 0.0; + double pid_input; + double pid_output; + bool pid_reset; + float HeaterPower; + + float Kp=DEFAULT_Kp; + float Ki=DEFAULT_Ki; + float Kd=DEFAULT_Kd; + float Kc=DEFAULT_Kc; +#endif //PIDTEMP + +#ifdef HEATER_0_MINTEMP +int minttemp_0 = temp2analog(HEATER_0_MINTEMP); +#endif //MINTEMP +#ifdef HEATER_0_MAXTEMP +int maxttemp_0 = temp2analog(HEATER_0_MAXTEMP); +#endif //MAXTEMP + +#ifdef HEATER_1_MINTEMP +int minttemp_1 = temp2analog(HEATER_1_MINTEMP); +#endif //MINTEMP +#ifdef HEATER_1_MAXTEMP +int maxttemp_1 = temp2analog(HEATER_1_MAXTEMP); +#endif //MAXTEMP + +#ifdef BED_MINTEMP +int bed_minttemp = temp2analog(BED_MINTEMP); +#endif //BED_MINTEMP +#ifdef BED_MAXTEMP +int bed_maxttemp = temp2analog(BED_MAXTEMP); +#endif //BED_MAXTEMP + +void manage_heater() +{ +#ifdef USE_WATCHDOG + wd_reset(); +#endif + + float pid_input; + float pid_output; - if(temp_meas_ready == true) { ++ if(temp_meas_ready != true) //better readability ++ return; + +CRITICAL_SECTION_START; + temp_meas_ready = false; +CRITICAL_SECTION_END; + +#ifdef PIDTEMP - pid_input = analog2temp(current_raw[0]); ++ pid_input = analog2temp(current_raw[TEMPSENSOR_HOTEND]); + +#ifndef PID_OPENLOOP + pid_error = pid_setpoint - pid_input; + if(pid_error > 10){ + pid_output = PID_MAX; + pid_reset = true; + } + else if(pid_error < -10) { + pid_output = 0; + pid_reset = true; + } + else { + if(pid_reset == true) { + temp_iState = 0.0; + pid_reset = false; + } + pTerm = Kp * pid_error; + temp_iState += pid_error; + temp_iState = constrain(temp_iState, temp_iState_min, temp_iState_max); + iTerm = Ki * temp_iState; - #define K1 0.95 ++ //K1 defined in Configuration.h in the PID settings + #define K2 (1.0-K1) + dTerm = (Kd * (pid_input - temp_dState))*K2 + (K1 * dTerm); + temp_dState = pid_input; ++ #ifdef PID_ADD_EXTRUSION_RATE ++ pTerm+=Kc*current_block->speed_e; //additional heating if extrusion speed is high ++ #endif + pid_output = constrain(pTerm + iTerm - dTerm, 0, PID_MAX); + } +#endif //PID_OPENLOOP +#ifdef PID_DEBUG + Serial.print(" Input "); + Serial.print(pid_input); + Serial.print(" Output "); + Serial.print(pid_output); + Serial.print(" pTerm "); + Serial.print(pTerm); + Serial.print(" iTerm "); + Serial.print(iTerm); + Serial.print(" dTerm "); + Serial.print(dTerm); + Serial.println(); +#endif //PID_DEBUG + analogWrite(HEATER_0_PIN, pid_output); +#endif //PIDTEMP + +#ifndef PIDTEMP + if(current_raw[0] >= target_raw[0]) + { + WRITE(HEATER_0_PIN,LOW); + } + else + { + WRITE(HEATER_0_PIN,HIGH); + } +#endif + + if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) + return; + previous_millis_bed_heater = millis(); + + #if TEMP_1_PIN > -1 - if(current_raw[1] >= target_raw[1]) ++ if(current_raw[TEMPSENSOR_BED] >= target_raw[TEMPSENSOR_BED]) + { + WRITE(HEATER_1_PIN,LOW); + } + else + { + WRITE(HEATER_1_PIN,HIGH); + } + #endif + } - } + +// Takes hot end temperature value as input and returns corresponding raw value. +// For a thermistor, it uses the RepRap thermistor temp table. +// This is needed because PID in hydra firmware hovers around a given analog value, not a temp value. +// This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware. +int temp2analog(int celsius) { + #ifdef HEATER_0_USES_THERMISTOR + int raw = 0; + byte i; + + for (i=1; i raw) + { + celsius = heater_0_temptable[i-1][1] + + (raw - heater_0_temptable[i-1][0]) * + (float)(heater_0_temptable[i][1] - heater_0_temptable[i-1][1]) / + (float)(heater_0_temptable[i][0] - heater_0_temptable[i-1][0]); + + break; + } + } + + // Overflow: Set to last value in the table + if (i == NUMTEMPS_HEATER_0) celsius = heater_0_temptable[i-1][1]; + + return celsius; + #elif defined HEATER_0_USES_AD595 + return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; + #endif +} + +// Derived from RepRap FiveD extruder::getTemperature() +// For bed temperature measurement. +float analog2tempBed(int raw) { + #ifdef BED_USES_THERMISTOR + int celsius = 0; + byte i; + + raw = (1023 * OVERSAMPLENR) - raw; + + for (i=1; i raw) + { + celsius = bedtemptable[i-1][1] + + (raw - bedtemptable[i-1][0]) * + (bedtemptable[i][1] - bedtemptable[i-1][1]) / + (bedtemptable[i][0] - bedtemptable[i-1][0]); + + break; + } + } + + // Overflow: Set to last value in the table + if (i == BNUMTEMPS) celsius = bedtemptable[i-1][1]; + + return celsius; + + #elif defined BED_USES_AD595 + return raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR; + #endif +} + +void tp_init() +{ +#if (HEATER_0_PIN > -1) + SET_OUTPUT(HEATER_0_PIN); +#endif +#if (HEATER_1_PIN > -1) + SET_OUTPUT(HEATER_1_PIN); +#endif +#if (HEATER_2_PIN > -1) + SET_OUTPUT(HEATER_2_PIN); +#endif + +#ifdef PIDTEMP + temp_iState_min = 0.0; + temp_iState_max = PID_INTEGRAL_DRIVE_MAX / Ki; +#endif //PIDTEMP + +// Set analog inputs + ADCSRA = 1< -1) + #if TEMP_0_PIN < 8 + DIDR0 = 1 << TEMP_0_PIN; + #else + DIDR2 = 1<<(TEMP_0_PIN - 8); + ADCSRB = 1< -1) + raw_temp_0_value += ADC; + #endif + temp_state = 2; + break; + case 2: // Prepare TEMP_1 + #if (TEMP_1_PIN > -1) + #if TEMP_1_PIN < 7 + DIDR0 = 1< -1) + raw_temp_1_value += ADC; + #endif + temp_state = 4; + break; + case 4: // Prepare TEMP_2 + #if (TEMP_2_PIN > -1) + #if TEMP_2_PIN < 7 + DIDR0 = 1 << TEMP_2_PIN; + #else + DIDR2 = 1<<(TEMP_2_PIN - 8); + ADCSRB = 1< -1) + raw_temp_2_value += ADC; + #endif + temp_state = 0; + temp_count++; + break; + default: + Serial.println("!! Temp measurement error !!"); + break; + } + + if(temp_count >= 16) // 6 ms * 16 = 96ms. + { + #ifdef HEATER_0_USES_AD595 + current_raw[0] = raw_temp_0_value; + #else + current_raw[0] = 16383 - raw_temp_0_value; + #endif + + #ifdef HEATER_1_USES_AD595 + current_raw[2] = raw_temp_2_value; + #else + current_raw[2] = 16383 - raw_temp_2_value; + #endif + + #ifdef BED_USES_AD595 + current_raw[1] = raw_temp_1_value; + #else + current_raw[1] = 16383 - raw_temp_1_value; + #endif + + temp_meas_ready = true; + temp_count = 0; + raw_temp_0_value = 0; + raw_temp_1_value = 0; + raw_temp_2_value = 0; +#ifdef HEATER_0_MAXTEMP + #if (HEATER_0_PIN > -1) - if(current_raw[0] >= maxttemp_0) { - target_raw[0] = 0; ++ if(current_raw[TEMPSENSOR_HOTEND] >= maxttemp) { ++ target_raw[TEMPSENSOR_HOTEND] = 0; + analogWrite(HEATER_0_PIN, 0); + Serial.println("!! Temperature extruder 0 switched off. MAXTEMP triggered !!"); + kill(); + } + #endif +#endif - #ifdef HEATER_1_MAXTEMP - #if (HEATER_1_PIN > -1) ++ if(current_raw[TEMPSENSOR_AUX] >= maxttemp) { ++ target_raw[TEMPSENSOR_AUX] = 0; + if(current_raw[2] >= maxttemp_1) { - target_raw[2] = 0; + analogWrite(HEATER_2_PIN, 0); + Serial.println("!! Temperature extruder 1 switched off. MAXTEMP triggered !!"); + kill() + } + #endif +#endif //MAXTEMP +#ifdef HEATER_0_MINTEMP + #if (HEATER_0_PIN > -1) - if(current_raw[0] <= minttemp_0) { - target_raw[0] = 0; ++ if(current_raw[TEMPSENSOR_HOTEND] <= minttemp) { ++ target_raw[TEMPSENSOR_HOTEND] = 0; + analogWrite(HEATER_0_PIN, 0); + Serial.println("!! Temperature extruder 0 switched off. MINTEMP triggered !!"); + kill(); + } + #endif +#endif +#ifdef HEATER_1_MINTEMP + #if (HEATER_2_PIN > -1) - if(current_raw[2] <= minttemp_1) { - target_raw[2] = 0; ++ if(current_raw[TEMPSENSOR_AUX] <= minttemp) { ++ target_raw[TEMPSENSOR_AUX] = 0; + analogWrite(HEATER_2_PIN, 0); + Serial.println("!! Temperature extruder 1 switched off. MINTEMP triggered !!"); + kill(); + } + #endif +#endif //MAXTEMP +#ifdef BED_MINTEMP + #if (HEATER_1_PIN > -1) + if(current_raw[1] <= bed_minttemp) { + target_raw[1] = 0; + WRITE(HEATER_1_PIN, 0); + Serial.println("!! Temperatur heated bed switched off. MINTEMP triggered !!"); + kill(); + } + #endif +#endif +#ifdef BED_MAXTEMP + #if (HEATER_1_PIN > -1) + if(current_raw[1] >= bed_maxttemp) { + target_raw[1] = 0; + WRITE(HEATER_1_PIN, 0); + Serial.println("!! Temperature heated bed switched off. MAXTEMP triggered !!"); + kill(); + } + #endif +#endif + } +} diff --cc Marlin/temperature.h index 7d9b792,e2e6c45..b787979 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@@ -1,55 -1,58 +1,58 @@@ -/* - temperature.h - temperature controller - Part of Marlin - - Copyright (c) 2011 Erik van der Zalm - - Grbl 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. - - Grbl is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Grbl. If not, see . -*/ - -#ifndef temperature_h -#define temperature_h - -#include "Marlin.h" -#ifdef PID_ADD_EXTRUSION_RATE - #include "stepper.h" -#endif -void tp_init(); -void manage_heater(); -//int temp2analogu(int celsius, const short table[][2], int numtemps); -//float analog2tempu(int raw, const short table[][2], int numtemps); -float temp2analog(int celsius); -float temp2analogBed(int celsius); -float analog2temp(int raw); -float analog2tempBed(int raw); - -#ifdef HEATER_USES_THERMISTOR - #define HEATERSOURCE 1 -#endif -#ifdef BED_USES_THERMISTOR - #define BEDSOURCE 1 -#endif - -//#define temp2analogh( c ) temp2analogu((c),temptable,NUMTEMPS) -//#define analog2temp( c ) analog2tempu((c),temptable,NUMTEMPS - - -extern float Kp; -extern float Ki; -extern float Kd; -extern float Kc; - -enum {TEMPSENSOR_HOTEND=0,TEMPSENSOR_BED=1, TEMPSENSOR_AUX=2}; -extern int target_raw[3]; -extern int current_raw[3]; -extern double pid_setpoint; - -#endif +/* + temperature.h - temperature controller + Part of Marlin + + Copyright (c) 2011 Erik van der Zalm + + Grbl 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. + + Grbl is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . +*/ + +#ifndef temperature_h +#define temperature_h + - void manage_inactivity(byte debug); - ++#include "Marlin.h" ++#ifdef PID_ADD_EXTRUSION_RATE ++ #include "stepper.h" ++#endif +void tp_init(); +void manage_heater(); +//int temp2analogu(int celsius, const short table[][2], int numtemps); +//float analog2tempu(int raw, const short table[][2], int numtemps); +int temp2analog(int celsius); +int temp2analogBed(int celsius); +float analog2temp(int raw); +float analog2tempBed(int raw); + +#ifdef HEATER_USES_THERMISTOR + #define HEATERSOURCE 1 +#endif +#ifdef BED_USES_THERMISTOR + #define BEDSOURCE 1 +#endif + +//#define temp2analogh( c ) temp2analogu((c),temptable,NUMTEMPS) +//#define analog2temp( c ) analog2tempu((c),temptable,NUMTEMPS + + +extern float Kp; +extern float Ki; +extern float Kd; +extern float Kc; + ++enum {TEMPSENSOR_HOTEND=0,TEMPSENSOR_BED=1, TEMPSENSOR_AUX=2}; +extern int target_raw[3]; +extern int current_raw[3]; +extern double pid_setpoint; + +#endif diff --cc Marlin/thermistortables.h index 9e3af6c,fcefa55..fbd2ef1 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@@ -1,410 -1,410 +1,410 @@@ -#ifndef THERMISTORTABLES_H_ -#define THERMISTORTABLES_H_ - -#define OVERSAMPLENR 16 - -#if (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor - -#define NUMTEMPS_1 61 -const short temptable_1[NUMTEMPS_1][2] = { -{ 23*OVERSAMPLENR , 300 }, -{ 25*OVERSAMPLENR , 295 }, -{ 27*OVERSAMPLENR , 290 }, -{ 28*OVERSAMPLENR , 285 }, -{ 31*OVERSAMPLENR , 280 }, -{ 33*OVERSAMPLENR , 275 }, -{ 35*OVERSAMPLENR , 270 }, -{ 38*OVERSAMPLENR , 265 }, -{ 41*OVERSAMPLENR , 260 }, -{ 44*OVERSAMPLENR , 255 }, -{ 48*OVERSAMPLENR , 250 }, -{ 52*OVERSAMPLENR , 245 }, -{ 56*OVERSAMPLENR , 240 }, -{ 61*OVERSAMPLENR , 235 }, -{ 66*OVERSAMPLENR , 230 }, -{ 71*OVERSAMPLENR , 225 }, -{ 78*OVERSAMPLENR , 220 }, -{ 84*OVERSAMPLENR , 215 }, -{ 92*OVERSAMPLENR , 210 }, -{ 100*OVERSAMPLENR , 205 }, -{ 109*OVERSAMPLENR , 200 }, -{ 120*OVERSAMPLENR , 195 }, -{ 131*OVERSAMPLENR , 190 }, -{ 143*OVERSAMPLENR , 185 }, -{ 156*OVERSAMPLENR , 180 }, -{ 171*OVERSAMPLENR , 175 }, -{ 187*OVERSAMPLENR , 170 }, -{ 205*OVERSAMPLENR , 165 }, -{ 224*OVERSAMPLENR , 160 }, -{ 245*OVERSAMPLENR , 155 }, -{ 268*OVERSAMPLENR , 150 }, -{ 293*OVERSAMPLENR , 145 }, -{ 320*OVERSAMPLENR , 140 }, -{ 348*OVERSAMPLENR , 135 }, -{ 379*OVERSAMPLENR , 130 }, -{ 411*OVERSAMPLENR , 125 }, -{ 445*OVERSAMPLENR , 120 }, -{ 480*OVERSAMPLENR , 115 }, -{ 516*OVERSAMPLENR , 110 }, -{ 553*OVERSAMPLENR , 105 }, -{ 591*OVERSAMPLENR , 100 }, -{ 628*OVERSAMPLENR , 95 }, -{ 665*OVERSAMPLENR , 90 }, -{ 702*OVERSAMPLENR , 85 }, -{ 737*OVERSAMPLENR , 80 }, -{ 770*OVERSAMPLENR , 75 }, -{ 801*OVERSAMPLENR , 70 }, -{ 830*OVERSAMPLENR , 65 }, -{ 857*OVERSAMPLENR , 60 }, -{ 881*OVERSAMPLENR , 55 }, -{ 903*OVERSAMPLENR , 50 }, -{ 922*OVERSAMPLENR , 45 }, -{ 939*OVERSAMPLENR , 40 }, -{ 954*OVERSAMPLENR , 35 }, -{ 966*OVERSAMPLENR , 30 }, -{ 977*OVERSAMPLENR , 25 }, -{ 985*OVERSAMPLENR , 20 }, -{ 993*OVERSAMPLENR , 15 }, -{ 999*OVERSAMPLENR , 10 }, -{ 1004*OVERSAMPLENR , 5 }, -{ 1008*OVERSAMPLENR , 0 } //safety -}; -#endif -#if (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor -#define NUMTEMPS_2 21 -const short temptable_2[NUMTEMPS_2][2] = { - {1*OVERSAMPLENR, 848}, - {54*OVERSAMPLENR, 275}, - {107*OVERSAMPLENR, 228}, - {160*OVERSAMPLENR, 202}, - {213*OVERSAMPLENR, 185}, - {266*OVERSAMPLENR, 171}, - {319*OVERSAMPLENR, 160}, - {372*OVERSAMPLENR, 150}, - {425*OVERSAMPLENR, 141}, - {478*OVERSAMPLENR, 133}, - {531*OVERSAMPLENR, 125}, - {584*OVERSAMPLENR, 118}, - {637*OVERSAMPLENR, 110}, - {690*OVERSAMPLENR, 103}, - {743*OVERSAMPLENR, 95}, - {796*OVERSAMPLENR, 86}, - {849*OVERSAMPLENR, 77}, - {902*OVERSAMPLENR, 65}, - {955*OVERSAMPLENR, 49}, - {1008*OVERSAMPLENR, 17}, - {1020*OVERSAMPLENR, 0} //safety -}; - -#endif -#if (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORBED == 3) //mendel-parts -#define NUMTEMPS_3 28 -const short temptable_3[NUMTEMPS_3][2] = { - {1*OVERSAMPLENR,864}, - {21*OVERSAMPLENR,300}, - {25*OVERSAMPLENR,290}, - {29*OVERSAMPLENR,280}, - {33*OVERSAMPLENR,270}, - {39*OVERSAMPLENR,260}, - {46*OVERSAMPLENR,250}, - {54*OVERSAMPLENR,240}, - {64*OVERSAMPLENR,230}, - {75*OVERSAMPLENR,220}, - {90*OVERSAMPLENR,210}, - {107*OVERSAMPLENR,200}, - {128*OVERSAMPLENR,190}, - {154*OVERSAMPLENR,180}, - {184*OVERSAMPLENR,170}, - {221*OVERSAMPLENR,160}, - {265*OVERSAMPLENR,150}, - {316*OVERSAMPLENR,140}, - {375*OVERSAMPLENR,130}, - {441*OVERSAMPLENR,120}, - {513*OVERSAMPLENR,110}, - {588*OVERSAMPLENR,100}, - {734*OVERSAMPLENR,80}, - {856*OVERSAMPLENR,60}, - {938*OVERSAMPLENR,40}, - {986*OVERSAMPLENR,20}, - {1008*OVERSAMPLENR,0}, - {1018*OVERSAMPLENR,-20} - }; - -#endif -#if (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor - -#define NUMTEMPS_4 20 -short temptable_4[NUMTEMPS_4][2] = { - {1*OVERSAMPLENR, 430}, - {54*OVERSAMPLENR, 137}, - {107*OVERSAMPLENR, 107}, - {160*OVERSAMPLENR, 91}, - {213*OVERSAMPLENR, 80}, - {266*OVERSAMPLENR, 71}, - {319*OVERSAMPLENR, 64}, - {372*OVERSAMPLENR, 57}, - {425*OVERSAMPLENR, 51}, - {478*OVERSAMPLENR, 46}, - {531*OVERSAMPLENR, 41}, - {584*OVERSAMPLENR, 35}, - {637*OVERSAMPLENR, 30}, - {690*OVERSAMPLENR, 25}, - {743*OVERSAMPLENR, 20}, - {796*OVERSAMPLENR, 14}, - {849*OVERSAMPLENR, 7}, - {902*OVERSAMPLENR, 0}, - {955*OVERSAMPLENR, -11}, - {1008*OVERSAMPLENR, -35} -}; -#endif - -#if (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2) - -#define NUMTEMPS_5 61 -const short temptable_5[NUMTEMPS_5][2] = { -{1*OVERSAMPLENR, 713}, -{18*OVERSAMPLENR, 316}, -{35*OVERSAMPLENR, 266}, -{52*OVERSAMPLENR, 239}, -{69*OVERSAMPLENR, 221}, -{86*OVERSAMPLENR, 208}, -{103*OVERSAMPLENR, 197}, -{120*OVERSAMPLENR, 188}, -{137*OVERSAMPLENR, 181}, -{154*OVERSAMPLENR, 174}, -{171*OVERSAMPLENR, 169}, -{188*OVERSAMPLENR, 163}, -{205*OVERSAMPLENR, 159}, -{222*OVERSAMPLENR, 154}, -{239*OVERSAMPLENR, 150}, -{256*OVERSAMPLENR, 147}, -{273*OVERSAMPLENR, 143}, -{290*OVERSAMPLENR, 140}, -{307*OVERSAMPLENR, 136}, -{324*OVERSAMPLENR, 133}, -{341*OVERSAMPLENR, 130}, -{358*OVERSAMPLENR, 128}, -{375*OVERSAMPLENR, 125}, -{392*OVERSAMPLENR, 122}, -{409*OVERSAMPLENR, 120}, -{426*OVERSAMPLENR, 117}, -{443*OVERSAMPLENR, 115}, -{460*OVERSAMPLENR, 112}, -{477*OVERSAMPLENR, 110}, -{494*OVERSAMPLENR, 108}, -{511*OVERSAMPLENR, 106}, -{528*OVERSAMPLENR, 103}, -{545*OVERSAMPLENR, 101}, -{562*OVERSAMPLENR, 99}, -{579*OVERSAMPLENR, 97}, -{596*OVERSAMPLENR, 95}, -{613*OVERSAMPLENR, 92}, -{630*OVERSAMPLENR, 90}, -{647*OVERSAMPLENR, 88}, -{664*OVERSAMPLENR, 86}, -{681*OVERSAMPLENR, 84}, -{698*OVERSAMPLENR, 81}, -{715*OVERSAMPLENR, 79}, -{732*OVERSAMPLENR, 77}, -{749*OVERSAMPLENR, 75}, -{766*OVERSAMPLENR, 72}, -{783*OVERSAMPLENR, 70}, -{800*OVERSAMPLENR, 67}, -{817*OVERSAMPLENR, 64}, -{834*OVERSAMPLENR, 61}, -{851*OVERSAMPLENR, 58}, -{868*OVERSAMPLENR, 55}, -{885*OVERSAMPLENR, 52}, -{902*OVERSAMPLENR, 48}, -{919*OVERSAMPLENR, 44}, -{936*OVERSAMPLENR, 40}, -{953*OVERSAMPLENR, 34}, -{970*OVERSAMPLENR, 28}, -{987*OVERSAMPLENR, 20}, -{1004*OVERSAMPLENR, 8}, -{1021*OVERSAMPLENR, 0} -}; -#endif - -#if (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor -#define NUMTEMPS_6 36 -const short temptable_6[NUMTEMPS_6][2] = { - {28*OVERSAMPLENR, 250}, - {31*OVERSAMPLENR, 245}, - {35*OVERSAMPLENR, 240}, - {39*OVERSAMPLENR, 235}, - {42*OVERSAMPLENR, 230}, - {44*OVERSAMPLENR, 225}, - {49*OVERSAMPLENR, 220}, - {53*OVERSAMPLENR, 215}, - {62*OVERSAMPLENR, 210}, - {73*OVERSAMPLENR, 205}, - {72*OVERSAMPLENR, 200}, - {94*OVERSAMPLENR, 190}, - {102*OVERSAMPLENR, 185}, - {116*OVERSAMPLENR, 170}, - {143*OVERSAMPLENR, 160}, - {183*OVERSAMPLENR, 150}, - {223*OVERSAMPLENR, 140}, - {270*OVERSAMPLENR, 130}, - {318*OVERSAMPLENR, 120}, - {383*OVERSAMPLENR, 110}, - {413*OVERSAMPLENR, 105}, - {439*OVERSAMPLENR, 100}, - {484*OVERSAMPLENR, 95}, - {513*OVERSAMPLENR, 90}, - {607*OVERSAMPLENR, 80}, - {664*OVERSAMPLENR, 70}, - {781*OVERSAMPLENR, 60}, - {810*OVERSAMPLENR, 55}, - {849*OVERSAMPLENR, 50}, - {914*OVERSAMPLENR, 45}, - {914*OVERSAMPLENR, 40}, - {935*OVERSAMPLENR, 35}, - {954*OVERSAMPLENR, 30}, - {970*OVERSAMPLENR, 25}, - {978*OVERSAMPLENR, 22}, - {1008*OVERSAMPLENR, 3} -}; -#endif - -#if (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01 -#define NUMTEMPS_7 54 -const short temptable_7[NUMTEMPS_7][2] = { - {46*OVERSAMPLENR, 270}, - {50*OVERSAMPLENR, 265}, - {54*OVERSAMPLENR, 260}, - {58*OVERSAMPLENR, 255}, - {62*OVERSAMPLENR, 250}, - {67*OVERSAMPLENR, 245}, - {72*OVERSAMPLENR, 240}, - {79*OVERSAMPLENR, 235}, - {85*OVERSAMPLENR, 230}, - {91*OVERSAMPLENR, 225}, - {99*OVERSAMPLENR, 220}, - {107*OVERSAMPLENR, 215}, - {116*OVERSAMPLENR, 210}, - {126*OVERSAMPLENR, 205}, - {136*OVERSAMPLENR, 200}, - {149*OVERSAMPLENR, 195}, - {160*OVERSAMPLENR, 190}, - {175*OVERSAMPLENR, 185}, - {191*OVERSAMPLENR, 180}, - {209*OVERSAMPLENR, 175}, - {224*OVERSAMPLENR, 170}, - {246*OVERSAMPLENR, 165}, - {267*OVERSAMPLENR, 160}, - {293*OVERSAMPLENR, 155}, - {316*OVERSAMPLENR, 150}, - {340*OVERSAMPLENR, 145}, - {364*OVERSAMPLENR, 140}, - {396*OVERSAMPLENR, 135}, - {425*OVERSAMPLENR, 130}, - {460*OVERSAMPLENR, 125}, - {489*OVERSAMPLENR, 120}, - {526*OVERSAMPLENR, 115}, - {558*OVERSAMPLENR, 110}, - {591*OVERSAMPLENR, 105}, - {628*OVERSAMPLENR, 100}, - {660*OVERSAMPLENR, 95}, - {696*OVERSAMPLENR, 90}, - {733*OVERSAMPLENR, 85}, - {761*OVERSAMPLENR, 80}, - {794*OVERSAMPLENR, 75}, - {819*OVERSAMPLENR, 70}, - {847*OVERSAMPLENR, 65}, - {870*OVERSAMPLENR, 60}, - {892*OVERSAMPLENR, 55}, - {911*OVERSAMPLENR, 50}, - {929*OVERSAMPLENR, 45}, - {944*OVERSAMPLENR, 40}, - {959*OVERSAMPLENR, 35}, - {971*OVERSAMPLENR, 30}, - {981*OVERSAMPLENR, 25}, - {989*OVERSAMPLENR, 20}, - {994*OVERSAMPLENR, 15}, - {1001*OVERSAMPLENR, 10}, - {1005*OVERSAMPLENR, 5} -}; -#endif - - - -#if THERMISTORHEATER_1 == 1 -#define NUMTEMPS_HEATER_1 NUMTEMPS_1 -#define temptable_1 temptable_1 -#elif THERMISTORHEATER_1 == 2 -#define NUMTEMPS_HEATER_1 NUMTEMPS_2 -#define temptable_1 temptable_2 -#elif THERMISTORHEATER_1 == 3 -#define NUMTEMPS_HEATER_1 NUMTEMPS_3 -#define temptable_1 temptable_3 -#elif THERMISTORHEATER_1 == 4 -#define NUMTEMPS_HEATER_1 NUMTEMPS_4 -#define temptable_1 temptable_4 -#elif THERMISTORHEATER_1 == 5 -#define NUMTEMPS_HEATER_1 NUMTEMPS_5 -#define temptable_1 temptable_5 -#elif THERMISTORHEATER_1 == 6 -#define NUMTEMPS_HEATER_1 NUMTEMPS_6 -#define temptable_1 temptable_6 -#elif THERMISTORHEATER_1 == 7 -#define NUMTEMPS_HEATER_1 NUMTEMPS_7 -#define temptable_1 temptable_7 -#elif defined HEATER_1_USES_THERMISTOR -#error No heater 1 thermistor table specified -#endif - -#if THERMISTORHEATER_2 == 1 -#define NUMTEMPS_HEATER_2 NUMTEMPS_1 -#define temptable_2 temptable_1 -#elif THERMISTORHEATER_2 == 2 -#define NUMTEMPS_HEATER_2 NUMTEMPS_2 -#define temptable_2 temptable_2 -#elif THERMISTORHEATER_2 == 3 -#define NUMTEMPS_HEATER_2 NUMTEMPS_3 -#define temptable_2 temptable_3 -#elif THERMISTORHEATER_2 == 4 -#define NUMTEMPS_HEATER_2 NUMTEMPS_4 -#define temptable_2 temptable_4 -#elif THERMISTORHEATER_2 == 5 -#define NUMTEMPS_HEATER_2 NUMTEMPS_5 -#define temptable_2 temptable_5 -#elif THERMISTORHEATER_2 == 6 -#define NUMTEMPS_HEATER_2 NUMTEMPS_6 -#define temptable_2 temptable_6 -#elif THERMISTORHEATER_2 == 7 -#define NUMTEMPS_HEATER22 NUMTEMPS_7 -#define temptable_2 temptable_7 -#elif defined HEATER_2_USES_THERMISTOR -#error No heater 2 thermistor table specified -#endif - - -#if THERMISTORBED == 1 -#define BNUMTEMPS NUMTEMPS_1 -#define bedtemptable temptable_1 -#elif THERMISTORBED == 2 -#define BNUMTEMPS NUMTEMPS_2 -#define bedtemptable temptable_2 -#elif THERMISTORBED == 3 -#define BNUMTEMPS NUMTEMPS_3 -#define bedtemptable temptable_3 -#elif THERMISTORBED == 4 -#define BNUMTEMPS NUMTEMPS_4 -#define bedtemptable temptable_4 -#elif THERMISTORBED == 5 -#define BNUMTEMPS NUMTEMPS_5 -#define bedtemptable temptable_5 -#elif THERMISTORBED == 6 -#define BNUMTEMPS NUMTEMPS_6 -#define bedtemptable temptable_6 -#elif THERMISTORBED == 7 -#define BNUMTEMPS NUMTEMPS_7 -#define bedtemptable temptable_7 -#elif defined BED_USES_THERMISTOR -#error No bed thermistor table specified -#endif - -#endif //THERMISTORTABLES_H_ - +#ifndef THERMISTORTABLES_H_ +#define THERMISTORTABLES_H_ + +#define OVERSAMPLENR 16 + +#if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1) || (THERMISTORBED == 1) //100k bed thermistor + +#define NUMTEMPS_1 61 +const short temptable_1[NUMTEMPS_1][2] = { - { 23*OVERSAMPLENR , 300 }, - { 25*OVERSAMPLENR , 295 }, - { 27*OVERSAMPLENR , 290 }, - { 28*OVERSAMPLENR , 285 }, - { 31*OVERSAMPLENR , 280 }, - { 33*OVERSAMPLENR , 275 }, - { 35*OVERSAMPLENR , 270 }, - { 38*OVERSAMPLENR , 265 }, - { 41*OVERSAMPLENR , 260 }, - { 44*OVERSAMPLENR , 255 }, - { 48*OVERSAMPLENR , 250 }, - { 52*OVERSAMPLENR , 245 }, - { 56*OVERSAMPLENR , 240 }, - { 61*OVERSAMPLENR , 235 }, - { 66*OVERSAMPLENR , 230 }, - { 71*OVERSAMPLENR , 225 }, - { 78*OVERSAMPLENR , 220 }, - { 84*OVERSAMPLENR , 215 }, - { 92*OVERSAMPLENR , 210 }, - { 100*OVERSAMPLENR , 205 }, - { 109*OVERSAMPLENR , 200 }, - { 120*OVERSAMPLENR , 195 }, - { 131*OVERSAMPLENR , 190 }, - { 143*OVERSAMPLENR , 185 }, - { 156*OVERSAMPLENR , 180 }, - { 171*OVERSAMPLENR , 175 }, - { 187*OVERSAMPLENR , 170 }, - { 205*OVERSAMPLENR , 165 }, - { 224*OVERSAMPLENR , 160 }, - { 245*OVERSAMPLENR , 155 }, - { 268*OVERSAMPLENR , 150 }, - { 293*OVERSAMPLENR , 145 }, - { 320*OVERSAMPLENR , 140 }, - { 348*OVERSAMPLENR , 135 }, - { 379*OVERSAMPLENR , 130 }, - { 411*OVERSAMPLENR , 125 }, - { 445*OVERSAMPLENR , 120 }, - { 480*OVERSAMPLENR , 115 }, - { 516*OVERSAMPLENR , 110 }, - { 553*OVERSAMPLENR , 105 }, - { 591*OVERSAMPLENR , 100 }, - { 628*OVERSAMPLENR , 95 }, - { 665*OVERSAMPLENR , 90 }, - { 702*OVERSAMPLENR , 85 }, - { 737*OVERSAMPLENR , 80 }, - { 770*OVERSAMPLENR , 75 }, - { 801*OVERSAMPLENR , 70 }, - { 830*OVERSAMPLENR , 65 }, - { 857*OVERSAMPLENR , 60 }, - { 881*OVERSAMPLENR , 55 }, - { 903*OVERSAMPLENR , 50 }, - { 922*OVERSAMPLENR , 45 }, - { 939*OVERSAMPLENR , 40 }, - { 954*OVERSAMPLENR , 35 }, - { 966*OVERSAMPLENR , 30 }, - { 977*OVERSAMPLENR , 25 }, - { 985*OVERSAMPLENR , 20 }, - { 993*OVERSAMPLENR , 15 }, - { 999*OVERSAMPLENR , 10 }, - { 1004*OVERSAMPLENR , 5 }, - { 1008*OVERSAMPLENR , 0 } //safety ++{ 23*OVERSAMPLENR , 300 }, ++{ 25*OVERSAMPLENR , 295 }, ++{ 27*OVERSAMPLENR , 290 }, ++{ 28*OVERSAMPLENR , 285 }, ++{ 31*OVERSAMPLENR , 280 }, ++{ 33*OVERSAMPLENR , 275 }, ++{ 35*OVERSAMPLENR , 270 }, ++{ 38*OVERSAMPLENR , 265 }, ++{ 41*OVERSAMPLENR , 260 }, ++{ 44*OVERSAMPLENR , 255 }, ++{ 48*OVERSAMPLENR , 250 }, ++{ 52*OVERSAMPLENR , 245 }, ++{ 56*OVERSAMPLENR , 240 }, ++{ 61*OVERSAMPLENR , 235 }, ++{ 66*OVERSAMPLENR , 230 }, ++{ 71*OVERSAMPLENR , 225 }, ++{ 78*OVERSAMPLENR , 220 }, ++{ 84*OVERSAMPLENR , 215 }, ++{ 92*OVERSAMPLENR , 210 }, ++{ 100*OVERSAMPLENR , 205 }, ++{ 109*OVERSAMPLENR , 200 }, ++{ 120*OVERSAMPLENR , 195 }, ++{ 131*OVERSAMPLENR , 190 }, ++{ 143*OVERSAMPLENR , 185 }, ++{ 156*OVERSAMPLENR , 180 }, ++{ 171*OVERSAMPLENR , 175 }, ++{ 187*OVERSAMPLENR , 170 }, ++{ 205*OVERSAMPLENR , 165 }, ++{ 224*OVERSAMPLENR , 160 }, ++{ 245*OVERSAMPLENR , 155 }, ++{ 268*OVERSAMPLENR , 150 }, ++{ 293*OVERSAMPLENR , 145 }, ++{ 320*OVERSAMPLENR , 140 }, ++{ 348*OVERSAMPLENR , 135 }, ++{ 379*OVERSAMPLENR , 130 }, ++{ 411*OVERSAMPLENR , 125 }, ++{ 445*OVERSAMPLENR , 120 }, ++{ 480*OVERSAMPLENR , 115 }, ++{ 516*OVERSAMPLENR , 110 }, ++{ 553*OVERSAMPLENR , 105 }, ++{ 591*OVERSAMPLENR , 100 }, ++{ 628*OVERSAMPLENR , 95 }, ++{ 665*OVERSAMPLENR , 90 }, ++{ 702*OVERSAMPLENR , 85 }, ++{ 737*OVERSAMPLENR , 80 }, ++{ 770*OVERSAMPLENR , 75 }, ++{ 801*OVERSAMPLENR , 70 }, ++{ 830*OVERSAMPLENR , 65 }, ++{ 857*OVERSAMPLENR , 60 }, ++{ 881*OVERSAMPLENR , 55 }, ++{ 903*OVERSAMPLENR , 50 }, ++{ 922*OVERSAMPLENR , 45 }, ++{ 939*OVERSAMPLENR , 40 }, ++{ 954*OVERSAMPLENR , 35 }, ++{ 966*OVERSAMPLENR , 30 }, ++{ 977*OVERSAMPLENR , 25 }, ++{ 985*OVERSAMPLENR , 20 }, ++{ 993*OVERSAMPLENR , 15 }, ++{ 999*OVERSAMPLENR , 10 }, ++{ 1004*OVERSAMPLENR , 5 }, ++{ 1008*OVERSAMPLENR , 0 } //safety +}; +#endif +#if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORBED == 2) //200k bed thermistor +#define NUMTEMPS_2 21 +const short temptable_2[NUMTEMPS_2][2] = { + {1*OVERSAMPLENR, 848}, + {54*OVERSAMPLENR, 275}, + {107*OVERSAMPLENR, 228}, + {160*OVERSAMPLENR, 202}, + {213*OVERSAMPLENR, 185}, + {266*OVERSAMPLENR, 171}, + {319*OVERSAMPLENR, 160}, + {372*OVERSAMPLENR, 150}, + {425*OVERSAMPLENR, 141}, + {478*OVERSAMPLENR, 133}, + {531*OVERSAMPLENR, 125}, + {584*OVERSAMPLENR, 118}, + {637*OVERSAMPLENR, 110}, + {690*OVERSAMPLENR, 103}, + {743*OVERSAMPLENR, 95}, + {796*OVERSAMPLENR, 86}, + {849*OVERSAMPLENR, 77}, + {902*OVERSAMPLENR, 65}, + {955*OVERSAMPLENR, 49}, + {1008*OVERSAMPLENR, 17}, + {1020*OVERSAMPLENR, 0} //safety +}; + +#endif +#if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORBED == 3) //mendel-parts +#define NUMTEMPS_3 28 +const short temptable_3[NUMTEMPS_3][2] = { - {1*OVERSAMPLENR,864}, - {21*OVERSAMPLENR,300}, - {25*OVERSAMPLENR,290}, - {29*OVERSAMPLENR,280}, - {33*OVERSAMPLENR,270}, - {39*OVERSAMPLENR,260}, - {46*OVERSAMPLENR,250}, - {54*OVERSAMPLENR,240}, - {64*OVERSAMPLENR,230}, - {75*OVERSAMPLENR,220}, - {90*OVERSAMPLENR,210}, - {107*OVERSAMPLENR,200}, - {128*OVERSAMPLENR,190}, - {154*OVERSAMPLENR,180}, - {184*OVERSAMPLENR,170}, - {221*OVERSAMPLENR,160}, - {265*OVERSAMPLENR,150}, - {316*OVERSAMPLENR,140}, - {375*OVERSAMPLENR,130}, - {441*OVERSAMPLENR,120}, - {513*OVERSAMPLENR,110}, - {588*OVERSAMPLENR,100}, - {734*OVERSAMPLENR,80}, - {856*OVERSAMPLENR,60}, - {938*OVERSAMPLENR,40}, - {986*OVERSAMPLENR,20}, - {1008*OVERSAMPLENR,0}, - {1018*OVERSAMPLENR,-20} - }; ++ {1*OVERSAMPLENR,864}, ++ {21*OVERSAMPLENR,300}, ++ {25*OVERSAMPLENR,290}, ++ {29*OVERSAMPLENR,280}, ++ {33*OVERSAMPLENR,270}, ++ {39*OVERSAMPLENR,260}, ++ {46*OVERSAMPLENR,250}, ++ {54*OVERSAMPLENR,240}, ++ {64*OVERSAMPLENR,230}, ++ {75*OVERSAMPLENR,220}, ++ {90*OVERSAMPLENR,210}, ++ {107*OVERSAMPLENR,200}, ++ {128*OVERSAMPLENR,190}, ++ {154*OVERSAMPLENR,180}, ++ {184*OVERSAMPLENR,170}, ++ {221*OVERSAMPLENR,160}, ++ {265*OVERSAMPLENR,150}, ++ {316*OVERSAMPLENR,140}, ++ {375*OVERSAMPLENR,130}, ++ {441*OVERSAMPLENR,120}, ++ {513*OVERSAMPLENR,110}, ++ {588*OVERSAMPLENR,100}, ++ {734*OVERSAMPLENR,80}, ++ {856*OVERSAMPLENR,60}, ++ {938*OVERSAMPLENR,40}, ++ {986*OVERSAMPLENR,20}, ++ {1008*OVERSAMPLENR,0}, ++ {1018*OVERSAMPLENR,-20} ++ }; + +#endif +#if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORBED == 4) //10k thermistor + +#define NUMTEMPS_4 20 +short temptable_4[NUMTEMPS_4][2] = { + {1*OVERSAMPLENR, 430}, + {54*OVERSAMPLENR, 137}, + {107*OVERSAMPLENR, 107}, + {160*OVERSAMPLENR, 91}, + {213*OVERSAMPLENR, 80}, + {266*OVERSAMPLENR, 71}, + {319*OVERSAMPLENR, 64}, + {372*OVERSAMPLENR, 57}, + {425*OVERSAMPLENR, 51}, + {478*OVERSAMPLENR, 46}, + {531*OVERSAMPLENR, 41}, + {584*OVERSAMPLENR, 35}, + {637*OVERSAMPLENR, 30}, + {690*OVERSAMPLENR, 25}, + {743*OVERSAMPLENR, 20}, + {796*OVERSAMPLENR, 14}, + {849*OVERSAMPLENR, 7}, + {902*OVERSAMPLENR, 0}, + {955*OVERSAMPLENR, -11}, + {1008*OVERSAMPLENR, -35} +}; +#endif + +#if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2) + +#define NUMTEMPS_5 61 +const short temptable_5[NUMTEMPS_5][2] = { +{1*OVERSAMPLENR, 713}, +{18*OVERSAMPLENR, 316}, +{35*OVERSAMPLENR, 266}, +{52*OVERSAMPLENR, 239}, +{69*OVERSAMPLENR, 221}, +{86*OVERSAMPLENR, 208}, +{103*OVERSAMPLENR, 197}, +{120*OVERSAMPLENR, 188}, +{137*OVERSAMPLENR, 181}, +{154*OVERSAMPLENR, 174}, +{171*OVERSAMPLENR, 169}, +{188*OVERSAMPLENR, 163}, +{205*OVERSAMPLENR, 159}, +{222*OVERSAMPLENR, 154}, +{239*OVERSAMPLENR, 150}, +{256*OVERSAMPLENR, 147}, +{273*OVERSAMPLENR, 143}, +{290*OVERSAMPLENR, 140}, +{307*OVERSAMPLENR, 136}, +{324*OVERSAMPLENR, 133}, +{341*OVERSAMPLENR, 130}, +{358*OVERSAMPLENR, 128}, +{375*OVERSAMPLENR, 125}, +{392*OVERSAMPLENR, 122}, +{409*OVERSAMPLENR, 120}, +{426*OVERSAMPLENR, 117}, +{443*OVERSAMPLENR, 115}, +{460*OVERSAMPLENR, 112}, +{477*OVERSAMPLENR, 110}, +{494*OVERSAMPLENR, 108}, +{511*OVERSAMPLENR, 106}, +{528*OVERSAMPLENR, 103}, +{545*OVERSAMPLENR, 101}, +{562*OVERSAMPLENR, 99}, +{579*OVERSAMPLENR, 97}, +{596*OVERSAMPLENR, 95}, +{613*OVERSAMPLENR, 92}, +{630*OVERSAMPLENR, 90}, +{647*OVERSAMPLENR, 88}, +{664*OVERSAMPLENR, 86}, +{681*OVERSAMPLENR, 84}, +{698*OVERSAMPLENR, 81}, +{715*OVERSAMPLENR, 79}, +{732*OVERSAMPLENR, 77}, +{749*OVERSAMPLENR, 75}, +{766*OVERSAMPLENR, 72}, +{783*OVERSAMPLENR, 70}, +{800*OVERSAMPLENR, 67}, +{817*OVERSAMPLENR, 64}, +{834*OVERSAMPLENR, 61}, +{851*OVERSAMPLENR, 58}, +{868*OVERSAMPLENR, 55}, +{885*OVERSAMPLENR, 52}, +{902*OVERSAMPLENR, 48}, +{919*OVERSAMPLENR, 44}, +{936*OVERSAMPLENR, 40}, +{953*OVERSAMPLENR, 34}, +{970*OVERSAMPLENR, 28}, +{987*OVERSAMPLENR, 20}, +{1004*OVERSAMPLENR, 8}, +{1021*OVERSAMPLENR, 0} +}; +#endif + +#if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor +#define NUMTEMPS_6 36 +const short temptable_6[NUMTEMPS_6][2] = { + {28*OVERSAMPLENR, 250}, + {31*OVERSAMPLENR, 245}, + {35*OVERSAMPLENR, 240}, + {39*OVERSAMPLENR, 235}, + {42*OVERSAMPLENR, 230}, + {44*OVERSAMPLENR, 225}, + {49*OVERSAMPLENR, 220}, + {53*OVERSAMPLENR, 215}, + {62*OVERSAMPLENR, 210}, + {73*OVERSAMPLENR, 205}, + {72*OVERSAMPLENR, 200}, + {94*OVERSAMPLENR, 190}, + {102*OVERSAMPLENR, 185}, + {116*OVERSAMPLENR, 170}, + {143*OVERSAMPLENR, 160}, + {183*OVERSAMPLENR, 150}, + {223*OVERSAMPLENR, 140}, + {270*OVERSAMPLENR, 130}, + {318*OVERSAMPLENR, 120}, + {383*OVERSAMPLENR, 110}, + {413*OVERSAMPLENR, 105}, + {439*OVERSAMPLENR, 100}, + {484*OVERSAMPLENR, 95}, + {513*OVERSAMPLENR, 90}, + {607*OVERSAMPLENR, 80}, + {664*OVERSAMPLENR, 70}, + {781*OVERSAMPLENR, 60}, + {810*OVERSAMPLENR, 55}, + {849*OVERSAMPLENR, 50}, + {914*OVERSAMPLENR, 45}, + {914*OVERSAMPLENR, 40}, + {935*OVERSAMPLENR, 35}, + {954*OVERSAMPLENR, 30}, + {970*OVERSAMPLENR, 25}, + {978*OVERSAMPLENR, 22}, + {1008*OVERSAMPLENR, 3} +}; +#endif + +#if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01 +#define NUMTEMPS_7 54 +const short temptable_7[NUMTEMPS_7][2] = { + {46*OVERSAMPLENR, 270}, + {50*OVERSAMPLENR, 265}, + {54*OVERSAMPLENR, 260}, + {58*OVERSAMPLENR, 255}, + {62*OVERSAMPLENR, 250}, + {67*OVERSAMPLENR, 245}, + {72*OVERSAMPLENR, 240}, + {79*OVERSAMPLENR, 235}, + {85*OVERSAMPLENR, 230}, + {91*OVERSAMPLENR, 225}, + {99*OVERSAMPLENR, 220}, + {107*OVERSAMPLENR, 215}, + {116*OVERSAMPLENR, 210}, + {126*OVERSAMPLENR, 205}, + {136*OVERSAMPLENR, 200}, + {149*OVERSAMPLENR, 195}, + {160*OVERSAMPLENR, 190}, + {175*OVERSAMPLENR, 185}, + {191*OVERSAMPLENR, 180}, + {209*OVERSAMPLENR, 175}, + {224*OVERSAMPLENR, 170}, + {246*OVERSAMPLENR, 165}, + {267*OVERSAMPLENR, 160}, + {293*OVERSAMPLENR, 155}, + {316*OVERSAMPLENR, 150}, + {340*OVERSAMPLENR, 145}, + {364*OVERSAMPLENR, 140}, + {396*OVERSAMPLENR, 135}, + {425*OVERSAMPLENR, 130}, + {460*OVERSAMPLENR, 125}, + {489*OVERSAMPLENR, 120}, + {526*OVERSAMPLENR, 115}, + {558*OVERSAMPLENR, 110}, + {591*OVERSAMPLENR, 105}, + {628*OVERSAMPLENR, 100}, + {660*OVERSAMPLENR, 95}, + {696*OVERSAMPLENR, 90}, + {733*OVERSAMPLENR, 85}, + {761*OVERSAMPLENR, 80}, + {794*OVERSAMPLENR, 75}, + {819*OVERSAMPLENR, 70}, + {847*OVERSAMPLENR, 65}, + {870*OVERSAMPLENR, 60}, + {892*OVERSAMPLENR, 55}, + {911*OVERSAMPLENR, 50}, + {929*OVERSAMPLENR, 45}, + {944*OVERSAMPLENR, 40}, + {959*OVERSAMPLENR, 35}, + {971*OVERSAMPLENR, 30}, + {981*OVERSAMPLENR, 25}, + {989*OVERSAMPLENR, 20}, + {994*OVERSAMPLENR, 15}, + {1001*OVERSAMPLENR, 10}, + {1005*OVERSAMPLENR, 5} +}; +#endif + + + +#if THERMISTORHEATER_0 == 1 +#define NUMTEMPS_HEATER_0 NUMTEMPS_1 +#define heater_0_temptable temptable_1 +#elif THERMISTORHEATER_0 == 2 +#define NUMTEMPS_HEATER_0 NUMTEMPS_2 +#define heater_0_temptable temptable_2 +#elif THERMISTORHEATER_0 == 3 +#define NUMTEMPS_HEATER_0 NUMTEMPS_3 +#define heater_0_temptable temptable_3 +#elif THERMISTORHEATER_0 == 4 +#define NUMTEMPS_HEATER_0 NUMTEMPS_4 +#define heater_0_temptable temptable_4 +#elif THERMISTORHEATER_0 == 5 +#define NUMTEMPS_HEATER_0 NUMTEMPS_5 +#define heater_0_temptable temptable_5 +#elif THERMISTORHEATER_0 == 6 +#define NUMTEMPS_HEATER_0 NUMTEMPS_6 +#define heater_0_temptable temptable_6 +#elif THERMISTORHEATER_0 == 7 +#define NUMTEMPS_HEATER_0 NUMTEMPS_7 +#define heater_0_temptable temptable_7 +#elif defined HEATER_0_USES_THERMISTOR +#error No heater 0 thermistor table specified +#endif + +#if THERMISTORHEATER_1 == 1 +#define NUMTEMPS_HEATER_1 NUMTEMPS_1 +#define heater_1_temptable temptable_1 +#elif THERMISTORHEATER_1 == 2 +#define NUMTEMPS_HEATER_1 NUMTEMPS_2 +#define heater_1_temptable temptable_2 +#elif THERMISTORHEATER_1 == 3 +#define NUMTEMPS_HEATER_1 NUMTEMPS_3 +#define heater_1_temptable temptable_3 +#elif THERMISTORHEATER_1 == 4 +#define NUMTEMPS_HEATER_1 NUMTEMPS_4 +#define heater_1_temptable temptable_4 +#elif THERMISTORHEATER_1 == 5 +#define NUMTEMPS_HEATER_1 NUMTEMPS_5 +#define heater_1_temptable temptable_5 +#elif THERMISTORHEATER_1 == 6 +#define NUMTEMPS_HEATER_1 NUMTEMPS_6 +#define heater_1_temptable temptable_6 +#elif THERMISTORHEATER_1 == 7 +#define NUMTEMPS_HEATER_1 NUMTEMPS_7 +#define heater_1_temptable temptable_7 +#elif defined HEATER_1_USES_THERMISTOR +#error No heater 1 thermistor table specified +#endif + + +#if THERMISTORBED == 1 +#define BNUMTEMPS NUMTEMPS_1 +#define bedtemptable temptable_1 +#elif THERMISTORBED == 2 +#define BNUMTEMPS NUMTEMPS_2 +#define bedtemptable temptable_2 +#elif THERMISTORBED == 3 +#define BNUMTEMPS NUMTEMPS_3 +#define bedtemptable temptable_3 +#elif THERMISTORBED == 4 +#define BNUMTEMPS NUMTEMPS_4 +#define bedtemptable temptable_4 +#elif THERMISTORBED == 5 +#define BNUMTEMPS NUMTEMPS_5 +#define bedtemptable temptable_5 +#elif THERMISTORBED == 6 +#define BNUMTEMPS NUMTEMPS_6 +#define bedtemptable temptable_6 +#elif THERMISTORBED == 7 +#define BNUMTEMPS NUMTEMPS_7 +#define bedtemptable temptable_7 +#elif defined BED_USES_THERMISTOR +#error No bed thermistor table specified +#endif + +#endif //THERMISTORTABLES_H_ +