Commit 3f5fe261 authored by MagoKimbra's avatar MagoKimbra

Update 4.0.6

parent a2bbff0f
/**
* Conditionals.h
* Defines that depend on configuration but are not editable.
*/
#ifndef CONDITIONALS_H
#ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
#define CONFIGURATION_LCD
#if defined(MAKRPANEL)
#define DOGLCD
#define SDSUPPORT
#define DEFAULT_LCD_CONTRAST 17
#define ULTIPANEL
#define NEWPANEL
#endif
#if defined(miniVIKI) || defined(VIKI2)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#ifdef miniVIKI
#define DEFAULT_LCD_CONTRAST 95
#else
#define DEFAULT_LCD_CONTRAST 40
#endif
#define ENCODER_PULSES_PER_STEP 4
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#ifdef PANEL_ONE
#define SDSUPPORT
#define ULTIMAKERCONTROLLER
#endif
#ifdef REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if defined(ULTIMAKERCONTROLLER) || defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL)
#define ULTIPANEL
#define NEWPANEL
#endif
#ifdef REPRAPWORLD_KEYPAD
#define ULTIPANEL
#define NEWPANEL
#endif
#ifdef RA_CONTROL_PANEL
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
/**
* I2C PANELS
*/
#ifdef LCD_I2C_SAINSMART_YWROBOT
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
#ifdef LCD_I2C_PANELOLU2
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// (v1.2.3 no longer requires you to define PANELOLU in the LiquidTWI2.h library header file)
// Note: The PANELOLU2 encoder click input can either be directly connected to a pin
// (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1).
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#ifdef LCD_USE_I2C_BUZZER
#define LCD_FEEDBACK_FREQUENCY_HZ 1000
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
#endif
#define ULTIPANEL
#define NEWPANEL
#endif
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
#ifdef LCD_I2C_VIKI
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define ULTIPANEL
#define NEWPANEL
#endif
// Shift register panels
// ---------------------
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
#ifdef SAV_3DLCD
#define SR_LCD_2W_NL // Non latching 2 wire shiftregister
#define ULTIPANEL
#define NEWPANEL
#endif
#ifdef ULTIPANEL
#define NEWPANEL //enable this if you have a click-encoder panel
#define SDSUPPORT
#define ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the DOG graphic display
#define LCD_WIDTH 22
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
#endif
#else //no panel but just LCD
#ifdef ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the 128x64 graphics display
#define LCD_WIDTH 22
#define LCD_HEIGHT 5
#else
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif
#endif
#endif
/**
* Default LCD contrast for dogm-like LCD displays
*/
#if defined(DOGLCD) && !defined(DEFAULT_LCD_CONTRAST)
#define DEFAULT_LCD_CONTRAST 32
#endif
#else // CONFIGURATION_LCD
#define CONDITIONALS_H
/**
* Firmware Test
*/
#ifdef FIRMWARE_TEST
#undef BAUDRATE
#define BAUDRATE 115200 // Baudrate setting to 115200 because serial monitor arduino function at max 115200 baudrate.
#endif
/**
* SINGLENOZZLE
*/
#ifdef SINGLENOZZLE
#define HOTENDS 1
#undef TEMP_SENSOR_1_AS_REDUNDANT
#else
#define HOTENDS EXTRUDERS
#endif
/**
* DRIVER_EXTRUDERS
*/
#if !defined(MKR4) && !defined(NPR2)
#define DRIVER_EXTRUDERS EXTRUDERS // This defines the number of Driver extruder
#endif
#ifndef AT90USB
#define HardwareSerial_h // trick to disable the standard HWserial
#endif
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "pins.h"
/**
* Axis lengths
*/
#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS)
#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS)
#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS)
/**
* SCARA
*/
#ifdef SCARA
#undef SLOWDOWN
#define QUICK_HOME //SCARA needs Quickhome
#endif
/**
* DELTA
*/
#ifdef DELTA
#undef SLOWDOWN //DELTA not needs SLOWDOWN
// DELTA must have same valour for 3 axis endstop hits
#undef Y_HOME_RETRACT_MM
#undef Z_HOME_RETRACT_MM
#define Y_HOME_RETRACT_MM X_HOME_RETRACT_MM
#define Z_HOME_RETRACT_MM X_HOME_RETRACT_MM
#endif
/**
* AUTOSET LOCATIONS OF LIMIT SWITCHES
* Added by ZetaPhoenix 09-15-2012
*/
#ifdef MANUAL_HOME_POSITIONS // Use manual limit switch locations
#define X_HOME_POS MANUAL_X_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else //!MANUAL_HOME_POSITIONS – Use home switch positions based on homing direction and travel limits
#ifdef BED_CENTER_AT_0_0
#define X_HOME_POS X_MAX_LENGTH * X_HOME_DIR * 0.5
#define Y_HOME_POS Y_MAX_LENGTH * Y_HOME_DIR * 0.5
#else
#define X_HOME_POS (X_HOME_DIR < 0 ? X_MIN_POS : X_MAX_POS)
#define Y_HOME_POS (Y_HOME_DIR < 0 ? Y_MIN_POS : Y_MAX_POS)
#endif
#define Z_HOME_POS (Z_HOME_DIR < 0 ? Z_MIN_POS : Z_MAX_POS)
#endif //!MANUAL_HOME_POSITIONS
/**
* Auto Bed Leveling
*/
#ifdef ENABLE_AUTO_BED_LEVELING
// Boundaries for probing based on set limits
#define MIN_PROBE_X (max(X_MIN_POS, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_X (min(X_MAX_POS, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MIN_PROBE_Y (max(Y_MIN_POS, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#endif
/**
* MAX_STEP_FREQUENCY differs for TOSHIBA
*/
#ifdef CONFIG_STEPPERS_TOSHIBA
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
#else
#define MAX_STEP_FREQUENCY 40000 // Max step frequency for Ultimaker (5000 pps / half step)
#endif
// MS1 MS2 Stepper Driver Microstepping mode table
#define MICROSTEP1 LOW,LOW
#define MICROSTEP2 HIGH,LOW
#define MICROSTEP4 LOW,HIGH
#define MICROSTEP8 HIGH,HIGH
#define MICROSTEP16 HIGH,HIGH
/**
* Advance calculated values
*/
#ifdef ADVANCE
#define EXTRUSION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS] / EXTRUSION_AREA)
#endif
#ifdef ULTIPANEL
#undef SDCARDDETECTINVERTED
#endif
// Power Signal Control Definitions
// By default use Normal definition
#ifndef POWER_SUPPLY
#define POWER_SUPPLY 0
#endif
// 0 = Normal - 1 = ATX
#if (POWER_SUPPLY <= 1)
#define PS_ON_AWAKE LOW
#define PS_ON_ASLEEP HIGH
#endif
// 2 = X-Box 360 203W
#if (POWER_SUPPLY == 2)
#define PS_ON_AWAKE HIGH
#define PS_ON_ASLEEP LOW
#endif
/**
* Temp Sensor defines
*/
#if TEMP_SENSOR_0 == -2
#define HEATER_0_USES_MAX6675
#elif TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#elif TEMP_SENSOR_0 == 0
#undef HEATER_0_MINTEMP
#undef HEATER_0_MAXTEMP
#elif TEMP_SENSOR_0 > 0
#define THERMISTORHEATER_0 TEMP_SENSOR_0
#define HEATER_0_USES_THERMISTOR
#endif
#if TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#elif TEMP_SENSOR_1 == 0
#undef HEATER_1_MINTEMP
#undef HEATER_1_MAXTEMP
#elif TEMP_SENSOR_1 > 0
#define THERMISTORHEATER_1 TEMP_SENSOR_1
#define HEATER_1_USES_THERMISTOR
#endif
#if TEMP_SENSOR_2 == -1
#define HEATER_2_USES_AD595
#elif TEMP_SENSOR_2 == 0
#undef HEATER_2_MINTEMP
#undef HEATER_2_MAXTEMP
#elif TEMP_SENSOR_2 > 0
#define THERMISTORHEATER_2 TEMP_SENSOR_2
#define HEATER_2_USES_THERMISTOR
#endif
#if TEMP_SENSOR_3 == -1
#define HEATER_3_USES_AD595
#elif TEMP_SENSOR_3 == 0
#undef HEATER_3_MINTEMP
#undef HEATER_3_MAXTEMP
#elif TEMP_SENSOR_3 > 0
#define THERMISTORHEATER_3 TEMP_SENSOR_3
#define HEATER_3_USES_THERMISTOR
#endif
#if TEMP_SENSOR_BED == -1
#define BED_USES_AD595
#elif TEMP_SENSOR_BED == 0
#undef BED_MINTEMP
#undef BED_MAXTEMP
#elif TEMP_SENSOR_BED > 0
#define THERMISTORBED TEMP_SENSOR_BED
#define BED_USES_THERMISTOR
#endif
/**
* ARRAY_BY_HOTENDS based on HOTENDS
*/
#if HOTENDS > 3
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3, v4 }
#elif HOTENDS > 2
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3 }
#elif HOTENDS > 1
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2 }
#else
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1 }
#endif
/**
* Shorthand for pin tests, for temperature.cpp
*/
#define HAS_TEMP_0 (defined(TEMP_0_PIN) && TEMP_0_PIN >= 0)
#define HAS_TEMP_1 (defined(TEMP_1_PIN) && TEMP_1_PIN >= 0)
#define HAS_TEMP_2 (defined(TEMP_2_PIN) && TEMP_2_PIN >= 0)
#define HAS_TEMP_3 (defined(TEMP_3_PIN) && TEMP_3_PIN >= 0)
#define HAS_TEMP_BED (defined(TEMP_BED_PIN) && TEMP_BED_PIN >= 0)
#define HAS_FILAMENT_SENSOR (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0)
#define HAS_POWER_CONSUMPTION_SENSOR (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0)
#define HAS_HEATER_0 (defined(HEATER_0_PIN) && HEATER_0_PIN >= 0)
#define HAS_HEATER_1 (defined(HEATER_1_PIN) && HEATER_1_PIN >= 0)
#define HAS_HEATER_2 (defined(HEATER_2_PIN) && HEATER_2_PIN >= 0)
#define HAS_HEATER_3 (defined(HEATER_3_PIN) && HEATER_3_PIN >= 0)
#define HAS_HEATER_BED (defined(HEATER_BED_PIN) && HEATER_BED_PIN >= 0)
#define HAS_AUTO_FAN_0 (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_1 (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_2 (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_3 (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3
#define HAS_FAN (defined(FAN_PIN) && FAN_PIN >= 0)
/**
* Helper Macros for heaters and extruder fan
*/
#define WRITE_HEATER_0P(v) WRITE(HEATER_0_PIN, v)
#if HOTENDS > 1 || defined(HEATERS_PARALLEL)
#define WRITE_HEATER_1(v) WRITE(HEATER_1_PIN, v)
#if HOTENDS > 2
#define WRITE_HEATER_2(v) WRITE(HEATER_2_PIN, v)
#if HOTENDS > 3
#define WRITE_HEATER_3(v) WRITE(HEATER_3_PIN, v)
#endif
#endif
#endif
#ifdef HEATERS_PARALLEL
#define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); }
#else
#define WRITE_HEATER_0(v) WRITE_HEATER_0P(v)
#endif
#if HAS_HEATER_BED
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN, v)
#endif
#if HAS_FAN
#define WRITE_FAN(v) WRITE(FAN_PIN, v)
#endif
/**
* Sampling period of the temperature routine
* This override comes originally from temperature.cpp
* The Configuration.h option is basically ignored.
*/
#ifdef PID_dT
#undef PID_dT
#endif
#define PID_dT ((OVERSAMPLENR * 14.0)/(F_CPU / 64.0 / 256.0))
#endif //CONFIGURATION_LCD
#endif //CONDITIONALS_H
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
// User-specified version info of this build to display in [Pronterface, etc] terminal window during // User-specified version info of this build to display in [Pronterface, etc] terminal window during
// startup. Implementation of an idea by Prof Braino to inform user that any changes made to this // startup. Implementation of an idea by Prof Braino to inform user that any changes made to this
// build by the user have been successfully uploaded into firmware. // build by the user have been successfully uploaded into firmware.
#define STRING_VERSION " 4.0.4" #define STRING_VERSION " 4.0.6"
#define STRING_URL "reprap.org" #define STRING_URL "reprap.org"
#define STRING_VERSION_CONFIG_H __DATE__ " " __TIME__ // build date and time #define STRING_VERSION_CONFIG_H __DATE__ " " __TIME__ // build date and time
#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. #define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes.
...@@ -44,11 +44,7 @@ ...@@ -44,11 +44,7 @@
//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
// If you want test the firmware uncomment below. Use Serial arduino monitor... // If you want test the firmware uncomment below. Use Serial arduino monitor...
//#define FIRMWARE_TEST //#define FIRMWARE_TEST // ONLY BAUDRATE 115200
#ifdef FIRMWARE_TEST
#undef BAUDRATE
#define BAUDRATE 115200 // Baudrate setting to 115200 because serial monitor arduino function at max 115200 baudrate.
#endif
/***********************************************************************\ /***********************************************************************\
**************************** Define type printer ********************** **************************** Define type printer **********************
...@@ -75,11 +71,6 @@ ...@@ -75,11 +71,6 @@
// This is used for single nozzle and multiple extrusion configuration // This is used for single nozzle and multiple extrusion configuration
// Uncomment below to enable (One Hotend) // Uncomment below to enable (One Hotend)
//#define SINGLENOZZLE //#define SINGLENOZZLE
#ifdef SINGLENOZZLE
#define HOTENDS 1
#else
#define HOTENDS EXTRUDERS
#endif
/*********************************************************************** /***********************************************************************
*********************** Multiextruder MKR4 *************************** *********************** Multiextruder MKR4 ***************************
...@@ -122,10 +113,6 @@ ...@@ -122,10 +113,6 @@
#endif #endif
//********************************************************************** //**********************************************************************
#if !defined(MKR4) && !defined(NPR2)
#define DRIVER_EXTRUDERS EXTRUDERS // This defines the number of Driver extruder
#endif
// The following define selects which power supply you have. Please choose the one that matches your setup // The following define selects which power supply you have. Please choose the one that matches your setup
// 0 = Normal power // 0 = Normal power
...@@ -186,10 +173,6 @@ ...@@ -186,10 +173,6 @@
//#define TEMP_SENSOR_1_AS_REDUNDANT //#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 // (degC) #define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10 // (degC)
#ifdef SINGLENOZZLE
#undef TEMP_SENSOR_1_AS_REDUNDANT
#endif
// Actual temperature must be close to target for this long before M109 returns success // Actual temperature must be close to target for this long before M109 returns success
#define TEMP_RESIDENCY_TIME 10 // (seconds) #define TEMP_RESIDENCY_TIME 10 // (seconds)
#define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one #define TEMP_HYSTERESIS 3 // (degC) range of +/- temperatures considered "close" to the target one
...@@ -395,110 +378,17 @@ your extruder heater takes 2 minutes to hit the target on heating. ...@@ -395,110 +378,17 @@ your extruder heater takes 2 minutes to hit the target on heating.
// REMEMBER TO INSTALL LiquidCrystal_I2C.h in your ARDUINO library folder: https://github.com/kiyoshigawa/LiquidCrystal_I2C // REMEMBER TO INSTALL LiquidCrystal_I2C.h in your ARDUINO library folder: https://github.com/kiyoshigawa/LiquidCrystal_I2C
//#define RA_CONTROL_PANEL //#define RA_CONTROL_PANEL
//automatic expansion /**
#if defined (MAKRPANEL) * I2C Panels
#define DOGLCD */
#define SDSUPPORT
#define ULTIPANEL
#define NEWPANEL
#define DEFAULT_LCD_CONTRAST 17
#endif //defined (MAKRPANEL)
#if defined(miniVIKI) || defined(VIKI2)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#ifdef miniVIKI
#define DEFAULT_LCD_CONTRAST 95
#else
#define DEFAULT_LCD_CONTRAST 40
#endif
#define ENCODER_PULSES_PER_STEP 4
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif //defined(miniVIKI) || defined(VIKI2)
#if defined (PANEL_ONE)
#define SDSUPPORT
#define ULTIMAKERCONTROLLER
#endif //defined (PANEL_ONE)
#if defined (REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif //defined (REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
#if defined(ULTIMAKERCONTROLLER) || defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL)
#define ULTIPANEL
#define NEWPANEL
#endif //defined(ULTIMAKERCONTROLLER) || defined(REPRAP_DISCOUNT_SMART_CONTROLLER) || defined(G3D_PANEL)
#if defined(REPRAPWORLD_KEYPAD)
#define NEWPANEL
#define ULTIPANEL
#endif //defined(REPRAPWORLD_KEYPAD)
#if defined(RA_CONTROL_PANEL)
#define ULTIPANEL
#define NEWPANEL
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#endif //defined(RA_CONTROL_PANEL)
//I2C PANELS
//#define LCD_I2C_SAINSMART_YWROBOT //#define LCD_I2C_SAINSMART_YWROBOT
#ifdef LCD_I2C_SAINSMART_YWROBOT
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define NEWPANEL
#define ULTIPANEL
#endif //LCD_I2C_SAINSMART_YWROBOT
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs // PANELOLU2 LCD with status LEDs, separate encoder and click inputs
//#define LCD_I2C_PANELOLU2 //#define LCD_I2C_PANELOLU2
#ifdef LCD_I2C_PANELOLU2
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// (v1.2.3 no longer requires you to define PANELOLU in the LiquidTWI2.h library header file)
// Note: The PANELOLU2 encoder click input can either be directly connected to a pin
// (if BTN_ENC defined to != -1) or read through I2C (when BTN_ENC == -1).
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
#define NEWPANEL
#define ULTIPANEL
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#ifdef LCD_USE_I2C_BUZZER
#define LCD_FEEDBACK_FREQUENCY_HZ 1000
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 100
#endif
#endif //LCD_I2C_PANELOLU2
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs // Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
//#define LCD_I2C_VIKI //#define LCD_I2C_VIKI
#ifdef LCD_I2C_VIKI
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define NEWPANEL
#define ULTIPANEL
#endif //LCD_I2C_VIKI
// Shift register panels // Shift register panels
// --------------------- // ---------------------
...@@ -506,42 +396,6 @@ your extruder heater takes 2 minutes to hit the target on heating. ...@@ -506,42 +396,6 @@ your extruder heater takes 2 minutes to hit the target on heating.
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
//#define SAV_3DLCD //#define SAV_3DLCD
#ifdef SAV_3DLCD
#define SR_LCD_2W_NL // Non latching 2 wire shiftregister
#define NEWPANEL
#define ULTIPANEL
#endif //SAV_3DLCD
#ifdef ULTIPANEL
//#define NEWPANEL //enable this if you have a click-encoder panel
#define SDSUPPORT
#define ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the DOG graphic display
#define LCD_WIDTH 22
#define LCD_HEIGHT 5
#else //NO DOGLCD
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
#endif //DOGLCD
#else //no ULTIPANEL
#ifdef ULTRA_LCD
#ifdef DOGLCD // Change number of lines to match the 128x64 graphics display
#define LCD_WIDTH 22
#define LCD_HEIGHT 5
#else //NO DOGLCD
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif //DOGLCD
#endif //ULTRA_LCD
#endif //ULTIPANEL
// default LCD contrast for dogm-like LCD displays
#ifdef DOGLCD
#ifndef DEFAULT_LCD_CONTRAST
#define DEFAULT_LCD_CONTRAST 32
#endif
#endif //DOGLCD
// option for invert rotary switch // option for invert rotary switch
//#define INVERT_ROTARY_SWITCH //#define INVERT_ROTARY_SWITCH
...@@ -668,8 +522,10 @@ your extruder heater takes 2 minutes to hit the target on heating. ...@@ -668,8 +522,10 @@ your extruder heater takes 2 minutes to hit the target on heating.
//#define POWER_CONSUMPTION //#define POWER_CONSUMPTION
#define POWER_VOLTAGE 12.00 //(V) The power supply OUT voltage #define POWER_VOLTAGE 12.00 //(V) The power supply OUT voltage
#define POWER_ZERO 2.5 //(V) The /\V coming out from the sensor when no current flow. #define POWER_ZERO 2.54459 //(V) The /\V coming out from the sensor when no current flow.
#define POWER_SENSITIVITY 0.066 //(V/A) How much increase V for 1A of increase #define POWER_SENSITIVITY 0.066 //(V/A) How much increase V for 1A of increase
#define POWER_OFFSET 0.015 //(A) Help to get 0A when no load is connected.
#define POWER_ERROR 3.0 //(%) Ammortize measure error.
#define POWER_EFFICIENCY 100.0 //(%) The power efficency of the power supply #define POWER_EFFICIENCY 100.0 //(%) The power efficency of the power supply
//When using an LCD, uncomment the line below to display the Power consumption sensor data on the last line instead of status. Status will appear for 5 sec. //When using an LCD, uncomment the line below to display the Power consumption sensor data on the last line instead of status. Status will appear for 5 sec.
......
...@@ -80,10 +80,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log ...@@ -80,10 +80,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log
#define Z_MIN_POS 0 #define Z_MIN_POS 0
#define E_MIN_POS 0 #define E_MIN_POS 0
#define X_MAX_LENGTH (X_MAX_POS - X_MIN_POS)
#define Y_MAX_LENGTH (Y_MAX_POS - Y_MIN_POS)
#define Z_MAX_LENGTH (Z_MAX_POS - Z_MIN_POS)
//===================================================================================== //=====================================================================================
//============================= Bed Manual or Auto Leveling =========================== //============================= Bed Manual or Auto Leveling ===========================
//===================================================================================== //=====================================================================================
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#ifndef CONFIGURATION_ADV_H #ifndef CONFIGURATION_ADV_H
#define CONFIGURATION_ADV_H #define CONFIGURATION_ADV_H
#include "Conditionals.h"
//=========================================================================== //===========================================================================
//=============================Thermal Settings ============================ //=============================Thermal Settings ============================
//=========================================================================== //===========================================================================
...@@ -46,17 +48,16 @@ ...@@ -46,17 +48,16 @@
// extruder idle oozing prevention // extruder idle oozing prevention
//if the extruder motor is idle for more than SECONDS, and the temperature over MINTEMP, some filament is retracted. The filament retracted is re-added before the next extrusion //if the extruder motor is idle for more than SECONDS, and the temperature over MINTEMP, some filament is retracted. The filament retracted is re-added before the next extrusion
//or when the target temperature is less than EXTRUDE_MINTEMP and the actual temperature is greater than IDLE_OOZING_MINTEMP and less than IDLE_OOZING_FEEDRATE
//#define IDLE_OOZING_PREVENT //#define IDLE_OOZING_PREVENT
#define IDLE_OOZING_MINTEMP 170 #define IDLE_OOZING_MINTEMP EXTRUDE_MINTEMP + 5
#define IDLE_OOZING_MAXTEMP IDLE_OOZING_MINTEMP + 5
#define IDLE_OOZING_FEEDRATE 45 //default feedrate for retracting (mm/s) #define IDLE_OOZING_FEEDRATE 45 //default feedrate for retracting (mm/s)
#define IDLE_OOZING_SECONDS 10 #define IDLE_OOZING_SECONDS 10
#define IDLE_OOZING_LENGTH 15 //default retract length (positive mm) #define IDLE_OOZING_LENGTH 15 //default retract length (positive mm)
#define IDLE_OOZING_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering) #define IDLE_OOZING_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering)
#define IDLE_OOZING_RECOVER_FEEDRATE 50 //default feedrate for recovering from retraction (mm/s) #define IDLE_OOZING_RECOVER_FEEDRATE 50 //default feedrate for recovering from retraction (mm/s)
#if defined(IDLE_OOZING_PREVENT) && IDLE_OOZING_MINTEMP < EXTRUDE_MINTEMP
#error IDLE_OOZING_MINTEMP have to be greater than EXTRUDE_MINTEMP
#endif
// extruder run-out prevention. // extruder run-out prevention.
//if the machine is idle, and the temperature over MINTEMP, every couple of SECONDS some filament is extruded //if the machine is idle, and the temperature over MINTEMP, every couple of SECONDS some filament is extruded
//#define EXTRUDER_RUNOUT_PREVENT //#define EXTRUDER_RUNOUT_PREVENT
...@@ -66,14 +67,6 @@ ...@@ -66,14 +67,6 @@
#define EXTRUDER_RUNOUT_SPEED 1500 //extrusion speed #define EXTRUDER_RUNOUT_SPEED 1500 //extrusion speed
#define EXTRUDER_RUNOUT_EXTRUDE 100 #define EXTRUDER_RUNOUT_EXTRUDE 100
#if defined(EXTRUDER_RUNOUT_PREVENT) && EXTRUDER_RUNOUT_MINTEMP < EXTRUDE_MINTEMP
#error EXTRUDER_RUNOUT_MINTEMP have to be greater than EXTRUDE_MINTEMP
#endif
#if defined(EXTRUDER_RUNOUT_PREVENT) && defined(IDLE_OOZING_PREVENT)
#error EXTRUDER_RUNOUT_PREVENT and IDLE_OOZING_PREVENT are incopatible. Please comment one of them.
#endif
//These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements. //These defines help to calibrate the AD595 sensor in case you get wrong temperature measurements.
//The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET" //The measured temperature is defined as "actualTemp = (measuredTemp * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET"
#define TEMP_SENSOR_AD595_OFFSET 0.0 #define TEMP_SENSOR_AD595_OFFSET 0.0
...@@ -110,54 +103,6 @@ ...@@ -110,54 +103,6 @@
#define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing #define ENDSTOPS_ONLY_FOR_HOMING // If defined the endstops will only be used for homing
//// AUTOSET LOCATIONS OF LIMIT SWITCHES
//// Added by ZetaPhoenix 09-15-2012
#ifdef MANUAL_HOME_POSITIONS // Use manual limit switch locations
#define X_HOME_POS MANUAL_X_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#define Z_HOME_POS MANUAL_Z_HOME_POS
#else //Set min/max homing switch positions based upon homing direction and min/max travel limits
//X axis
#if X_HOME_DIR == -1
#ifdef BED_CENTER_AT_0_0
#define X_HOME_POS X_MAX_LENGTH * -0.5
#else
#define X_HOME_POS X_MIN_POS
#endif //BED_CENTER_AT_0_0
#else
#ifdef BED_CENTER_AT_0_0
#define X_HOME_POS X_MAX_LENGTH * 0.5
#else
#define X_HOME_POS X_MAX_POS
#endif //BED_CENTER_AT_0_0
#endif //X_HOME_DIR == -1
//Y axis
#if Y_HOME_DIR == -1
#ifdef BED_CENTER_AT_0_0
#define Y_HOME_POS Y_MAX_LENGTH * -0.5
#else
#define Y_HOME_POS Y_MIN_POS
#endif //BED_CENTER_AT_0_0
#else
#ifdef BED_CENTER_AT_0_0
#define Y_HOME_POS Y_MAX_LENGTH * 0.5
#else
#define Y_HOME_POS Y_MAX_POS
#endif //BED_CENTER_AT_0_0
#endif //Y_HOME_DIR == -1
// Z axis
#if Z_HOME_DIR == -1 //BED_CENTER_AT_0_0 not used
#define Z_HOME_POS Z_MIN_POS
#else
#define Z_HOME_POS Z_MAX_POS
#endif //Z_HOME_DIR == -1
#endif //End auto min/max positions
//END AUTOSET LOCATIONS OF LIMIT SWITCHES -ZP
//#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats. //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
// A single Z stepper driver is usually used to drive 2 stepper motors. // A single Z stepper driver is usually used to drive 2 stepper motors.
...@@ -167,116 +112,87 @@ ...@@ -167,116 +112,87 @@
// On a RAMPS (or other 5 driver) motherboard, using this feature will limit you to using 1 extruder. // On a RAMPS (or other 5 driver) motherboard, using this feature will limit you to using 1 extruder.
//#define Z_DUAL_STEPPER_DRIVERS //#define Z_DUAL_STEPPER_DRIVERS
#ifdef Z_DUAL_STEPPER_DRIVERS
#undef EXTRUDERS
#define EXTRUDERS 1
#endif
// Same again but for Y Axis. // Same again but for Y Axis.
//#define Y_DUAL_STEPPER_DRIVERS //#define Y_DUAL_STEPPER_DRIVERS
// Define if the two Y drives need to rotate in opposite directions // Define if the two Y drives need to rotate in opposite directions
#define INVERT_Y2_VS_Y_DIR true #define INVERT_Y2_VS_Y_DIR true
#ifdef Y_DUAL_STEPPER_DRIVERS
#undef EXTRUDERS
#define EXTRUDERS 1
#endif
#if defined (Z_DUAL_STEPPER_DRIVERS) && defined (Y_DUAL_STEPPER_DRIVERS)
#error "You cannot have dual drivers for both Y and Z"
#endif
// Enable this for dual x-carriage printers. // Enable this for dual x-carriage printers.
// A dual x-carriage design has the advantage that the inactive extruder can be parked which // A dual x-carriage design has the advantage that the inactive extruder can be parked which
// prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage // prevents hot-end ooze contaminating the print. It also reduces the weight of each x-carriage
// allowing faster printing speeds. // allowing faster printing speeds.
//#define DUAL_X_CARRIAGE //#define DUAL_X_CARRIAGE
#ifdef DUAL_X_CARRIAGE #ifdef DUAL_X_CARRIAGE
// Configuration for second X-carriage // Configuration for second X-carriage
// Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop; // Note: the first x-carriage is defined as the x-carriage which homes to the minimum endstop;
// the second x-carriage always homes to the maximum endstop. // the second x-carriage always homes to the maximum endstop.
#define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage #define X2_MIN_POS 80 // set minimum to ensure second x-carriage doesn't hit the parked first X-carriage
#define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed #define X2_MAX_POS 353 // set maximum to the distance between toolheads when both heads are homed
#define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position #define X2_HOME_DIR 1 // the second X-carriage always homes to the maximum endstop position
#define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position #define X2_HOME_POS X2_MAX_POS // default home position is the maximum carriage position
// However: In this mode the EXTRUDER_OFFSET_X value for the second extruder provides a software // However: In this mode the EXTRUDER_OFFSET_X value for the second extruder provides a software
// override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops // override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops
// without modifying the firmware (through the "M218 T1 X???" command). // without modifying the firmware (through the "M218 T1 X???" command).
// Remember: you should set the second extruder x-offset to 0 in your slicer. // Remember: you should set the second extruder x-offset to 0 in your slicer.
// Pins for second x-carriage stepper driver (defined here to avoid further complicating pins.h) // Pins for second x-carriage stepper driver (defined here to avoid further complicating pins.h)
#define X2_ENABLE_PIN 29 #define X2_ENABLE_PIN 29
#define X2_STEP_PIN 25 #define X2_STEP_PIN 25
#define X2_DIR_PIN 23 #define X2_DIR_PIN 23
// There are a few selectable movement modes for dual x-carriages using M605 S<mode> // There are a few selectable movement modes for dual x-carriages using M605 S<mode>
// Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results // Mode 0: Full control. The slicer has full control over both x-carriages and can achieve optimal travel results
// as long as it supports dual x-carriages. (M605 S0) // as long as it supports dual x-carriages. (M605 S0)
// Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so // Mode 1: Auto-park mode. The firmware will automatically park and unpark the x-carriages on tool changes so
// that additional slicer support is not required. (M605 S1) // that additional slicer support is not required. (M605 S1)
// Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all // Mode 2: Duplication mode. The firmware will transparently make the second x-carriage and extruder copy all
// actions of the first x-carriage. This allows the printer to print 2 arbitrary items at // actions of the first x-carriage. This allows the printer to print 2 arbitrary items at
// once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm]) // once. (2nd extruder x offset and temp offset are set using: M605 S2 [Xnnn] [Rmmm])
// This is the default power-up mode which can be later using M605. // This is the default power-up mode which can be later using M605.
#define DEFAULT_DUAL_X_CARRIAGE_MODE 0 #define DEFAULT_DUAL_X_CARRIAGE_MODE 0
// Default settings in "Auto-park Mode" // Default settings in "Auto-park Mode"
#define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder #define TOOLCHANGE_PARK_ZLIFT 0.2 // the distance to raise Z axis when parking an extruder
#define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder #define TOOLCHANGE_UNPARK_ZLIFT 1 // the distance to raise Z axis when unparking an extruder
// Default x offset in duplication mode (typically set to half print bed width) // Default x offset in duplication mode (typically set to half print bed width)
#define DEFAULT_DUPLICATION_X_OFFSET 100 #define DEFAULT_DUPLICATION_X_OFFSET 100
#endif //DUAL_X_CARRIAGE #endif //DUAL_X_CARRIAGE
//homing hits the endstop, then retracts by this distance, before it tries to slowly bump again: //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
#define X_HOME_RETRACT_MM 5 #define X_HOME_RETRACT_MM 5
#define Y_HOME_RETRACT_MM 5 #define Y_HOME_RETRACT_MM 5
#ifdef DELTA
#define Z_HOME_RETRACT_MM 5 // deltas need the same for all three axis
#else
#define Z_HOME_RETRACT_MM 2 #define Z_HOME_RETRACT_MM 2
#endif #define HOMING_BUMP_DIVISOR {10, 10, 5} // Re-Bump Speed Divisor (Divides the Homing Feedrate)
#define HOMING_BUMP_DIVISOR {10, 10, 2} // Re-Bump Speed Divisor (Divides the Homing Feedrate)
//#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially. //#define QUICK_HOME //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
#define AXIS_RELATIVE_MODES {false, false, false, false} #define AXIS_RELATIVE_MODES {false, false, false, false}
#ifdef CONFIG_STEPPERS_TOSHIBA
#define MAX_STEP_FREQUENCY 10000 // Max step frequency for Toshiba Stepper Controllers
#else
#define MAX_STEP_FREQUENCY 40000
#endif
//By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step. //By default pololu step drivers require an active high signal. However, some high power drivers require an active low signal as step.
#define INVERT_X_STEP_PIN false #define INVERT_X_STEP_PIN false
#define INVERT_Y_STEP_PIN false #define INVERT_Y_STEP_PIN false
#define INVERT_Z_STEP_PIN false #define INVERT_Z_STEP_PIN false
#define INVERT_E_STEP_PIN false #define INVERT_E_STEP_PIN false
//default stepper release if idle. Set to 0 to deactivate. // Default stepper release if idle. Set to 0 to deactivate.
#define DEFAULT_STEPPER_DEACTIVE_TIME 60 #define DEFAULT_STEPPER_DEACTIVE_TIME 60
#define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate #define DEFAULT_MINIMUMFEEDRATE 0.0 // minimum feedrate
#define DEFAULT_MINTRAVELFEEDRATE 0.0 #define DEFAULT_MINTRAVELFEEDRATE 0.0
// Feedrates for manual moves along X, Y, Z, E from panel
#ifdef ULTIPANEL #ifdef ULTIPANEL
#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // set the speeds for manual moves (mm/min) #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel
#endif #define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder
//Comment to disable setting feedrate multiplier via encoder
#ifdef ULTIPANEL
#define ULTIPANEL_FEEDMULTIPLY
#endif #endif
// minimum time in microseconds that a movement needs to take if the buffer is emptied. // minimum time in microseconds that a movement needs to take if the buffer is emptied.
#define DEFAULT_MINSEGMENTTIME 20000 #define DEFAULT_MINSEGMENTTIME 20000
// If defined the movements slow down when the look ahead buffer is only half full // If defined the movements slow down when the look ahead buffer is only half full
#ifndef DELTA
#define SLOWDOWN #define SLOWDOWN
#endif
// Frequency limit // Frequency limit
// See nophead's blog for more info // See nophead's blog for more info
...@@ -288,13 +204,6 @@ ...@@ -288,13 +204,6 @@
// if unwanted behavior is observed on a user's machine when running at very slow speeds. // if unwanted behavior is observed on a user's machine when running at very slow speeds.
#define MINIMUM_PLANNER_SPEED 0.05// (mm/sec) #define MINIMUM_PLANNER_SPEED 0.05// (mm/sec)
// MS1 MS2 Stepper Driver Microstepping mode table
#define MICROSTEP1 LOW,LOW
#define MICROSTEP2 HIGH,LOW
#define MICROSTEP4 LOW,HIGH
#define MICROSTEP8 HIGH,HIGH
#define MICROSTEP16 HIGH,HIGH
// Microstep setting (Only functional when stepper driver microstep pins are connected to MCU. // Microstep setting (Only functional when stepper driver microstep pins are connected to MCU.
#define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16] #define MICROSTEP_MODES {16,16,16,16,16} // [1,2,4,8,16]
...@@ -313,8 +222,8 @@ ...@@ -313,8 +222,8 @@
//=========================================================================== //===========================================================================
#define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly #define ENCODER_RATE_MULTIPLIER // If defined, certain menu edit operations automatically multiply the steps when the encoder is moved quickly
#define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceed this value, multiple the steps moved by ten to quickly advance the value #define ENCODER_10X_STEPS_PER_SEC 75 // If the encoder steps per sec exceeds this value, multiple the steps moved by ten to quickly advance the value
#define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceed this value, multiple the steps moved by 100 to really quickly advance the value #define ENCODER_100X_STEPS_PER_SEC 160 // If the encoder steps per sec exceeds this value, multiple the steps moved by 100 to really quickly advance the value
//#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value //#define ENCODER_RATE_MULTIPLIER_DEBUG // If defined, output the encoder steps per second value
//#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/ //#define CHDK 4 //Pin for triggering CHDK to take a picture see how to use it here http://captain-slow.dk/2014/03/09/3d-printing-timelapses/
...@@ -337,21 +246,11 @@ ...@@ -337,21 +246,11 @@
// Amount of time (ms) to show the status message // Amount of time (ms) to show the status message
#define PROGRESS_BAR_MSG_TIME 3000 #define PROGRESS_BAR_MSG_TIME 3000
// Amount of time (ms) to retain the status message (0=forever) // Amount of time (ms) to retain the status message (0=forever)
#define PROGRESS_BAR_MSG_EXPIRE 0 #define PROGRESS_MSG_EXPIRE 0
// Enable this to show messages for MSG_TIME then hide them // Enable this to show messages for MSG_TIME then hide them
//#define PROGRESS_BAR_MSG_ONCE //#define PROGRESS_MSG_ONCE
#ifdef DOGLCD
#warning LCD_PROGRESS_BAR does not apply to graphical displays at this time.
#endif
#ifdef FILAMENT_LCD_DISPLAY
#error LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both.
#endif
#ifdef POWER_CONSUMPTION_LCD_DISPLAY
#error LCD_PROGRESS_BAR and POWER_CONSUMPTION_LCD_DISPLAY are not fully compatible. Comment out this line to use both.
#endif
#endif #endif
// The hardware watchdog should reset the microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation. // The hardware watchdog should reset the microcontroller disabling all outputs, in case the firmware gets stuck and doesn't do temperature regulation.
//#define USE_WATCHDOG //#define USE_WATCHDOG
...@@ -373,16 +272,6 @@ ...@@ -373,16 +272,6 @@
#define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions #define BABYSTEP_XY //not only z, but also XY in the menu. more clutter, more functions
#define BABYSTEP_INVERT_Z false //true for inverse movements in Z #define BABYSTEP_INVERT_Z false //true for inverse movements in Z
#define BABYSTEP_Z_MULTIPLICATOR 2 //faster z movements #define BABYSTEP_Z_MULTIPLICATOR 2 //faster z movements
#ifdef COREXY
#error BABYSTEPPING not implemented for COREXY yet.
#endif
#ifdef DELTA
#ifdef BABYSTEP_XY
#error BABYSTEPPING only implemented for Z axis on deltabots.
#endif
#endif
#endif #endif
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)
...@@ -396,12 +285,8 @@ ...@@ -396,12 +285,8 @@
#ifdef ADVANCE #ifdef ADVANCE
#define EXTRUDER_ADVANCE_K .0 #define EXTRUDER_ADVANCE_K .0
#define D_FILAMENT 2.85 #define D_FILAMENT 2.85
#define STEPS_MM_E 836 #define STEPS_MM_E 836
#define EXTRUSION_AREA (0.25 * D_FILAMENT * D_FILAMENT * 3.14159)
#define STEPS_PER_CUBIC_MM_E (axis_steps_per_unit[E_AXIS]/ EXTRUSION_AREA)
#endif // ADVANCE #endif // ADVANCE
// Arc interpretation settings: // Arc interpretation settings:
...@@ -416,26 +301,6 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -416,26 +301,6 @@ const unsigned int dropsegments=5; //everything with less than this number of st
// be commented out otherwise // be commented out otherwise
#define SDCARDDETECTINVERTED #define SDCARDDETECTINVERTED
#ifdef ULTIPANEL
#undef SDCARDDETECTINVERTED
#endif
// Power Signal Control Definitions
// By default use Normal definition
#ifndef POWER_SUPPLY
#define POWER_SUPPLY 0
#endif
// 0 = Normal - 1 = ATX
#if (POWER_SUPPLY <= 1)
#define PS_ON_AWAKE LOW
#define PS_ON_ASLEEP HIGH
#endif
// 2 = X-Box 360 203W
#if (POWER_SUPPLY == 2)
#define PS_ON_AWAKE HIGH
#define PS_ON_ASLEEP LOW
#endif
// Control heater 0 and heater 1 in parallel. // Control heater 0 and heater 1 in parallel.
//#define HEATERS_PARALLEL //#define HEATERS_PARALLEL
...@@ -445,7 +310,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -445,7 +310,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st
// The number of linear motions that can be in the plan at any give time. // The number of linear motions that can be in the plan at any give time.
// THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering. // THE BLOCK_BUFFER_SIZE NEEDS TO BE A POWER OF 2, i.g. 8,16,32 because shifts and ors are used to do the ring-buffering.
#if defined SDSUPPORT #ifdef SDSUPPORT
#define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller #define BLOCK_BUFFER_SIZE 16 // SD,LCD,Buttons take more memory, block buffer needs to be smaller
#else #else
#define BLOCK_BUFFER_SIZE 16 // maximize block buffer #define BLOCK_BUFFER_SIZE 16 // maximize block buffer
...@@ -472,16 +337,16 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -472,16 +337,16 @@ const unsigned int dropsegments=5; //everything with less than this number of st
#define RETRACT_ZLIFT 0 //default retract Z-lift #define RETRACT_ZLIFT 0 //default retract Z-lift
#define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering) #define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering)
#define RETRACT_RECOVER_LENGTH_SWAP 0 //default additional swap recover length (mm, added to retract length when recovering from extruder change) #define RETRACT_RECOVER_LENGTH_SWAP 0 //default additional swap recover length (mm, added to retract length when recovering from extruder change)
#define RETRACT_RECOVER_FEEDRATE 80 //default feedrate for recovering from retraction (mm/s) #define RETRACT_RECOVER_FEEDRATE 8 //default feedrate for recovering from retraction (mm/s)
#endif #endif
//adds support for experimental filament exchange support M600; requires display // Add support for experimental filament exchange support M600; requires display
#ifdef ULTIPANEL #ifdef ULTIPANEL
#define FILAMENTCHANGEENABLE #define FILAMENTCHANGEENABLE
#ifdef FILAMENTCHANGEENABLE #ifdef FILAMENTCHANGEENABLE
#define FILAMENTCHANGE_XPOS 3 #define FILAMENTCHANGE_XPOS 3
#define FILAMENTCHANGE_YPOS 3 #define FILAMENTCHANGE_YPOS 3
#define FILAMENTCHANGE_ZADD 5 #define FILAMENTCHANGE_ZADD 10
#define FILAMENTCHANGE_FIRSTRETRACT -2 #define FILAMENTCHANGE_FIRSTRETRACT -2
#define FILAMENTCHANGE_FINALRETRACT -100 #define FILAMENTCHANGE_FINALRETRACT -100
#endif #endif
...@@ -627,76 +492,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -627,76 +492,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st
#endif #endif
#include "Conditionals.h"
#include "SanityCheck.h"
//=========================================================================== #endif //CONFIGURATION_ADV_H
//============================= Define Defines ============================
//===========================================================================
#if EXTRUDERS > 1 && defined TEMP_SENSOR_1_AS_REDUNDANT
#error "You cannot use TEMP_SENSOR_1_AS_REDUNDANT if EXTRUDERS > 1"
#endif
#if EXTRUDERS > 1 && defined HEATERS_PARALLEL
#error "You cannot use HEATERS_PARALLEL if EXTRUDERS > 1"
#endif
#if TEMP_SENSOR_0 > 0
#define THERMISTORHEATER_0 TEMP_SENSOR_0
#define HEATER_0_USES_THERMISTOR
#endif
#if TEMP_SENSOR_1 > 0
#define THERMISTORHEATER_1 TEMP_SENSOR_1
#define HEATER_1_USES_THERMISTOR
#endif
#if TEMP_SENSOR_2 > 0
#define THERMISTORHEATER_2 TEMP_SENSOR_2
#define HEATER_2_USES_THERMISTOR
#endif
#if TEMP_SENSOR_3 > 0
#define THERMISTORHEATER_3 TEMP_SENSOR_3
#define HEATER_3_USES_THERMISTOR
#endif
#if TEMP_SENSOR_BED > 0
#define THERMISTORBED TEMP_SENSOR_BED
#define BED_USES_THERMISTOR
#endif
#if TEMP_SENSOR_0 == -1
#define HEATER_0_USES_AD595
#endif
#if TEMP_SENSOR_1 == -1
#define HEATER_1_USES_AD595
#endif
#if TEMP_SENSOR_2 == -1
#define HEATER_2_USES_AD595
#endif
#if TEMP_SENSOR_3 == -1
#define HEATER_3_USES_AD595
#endif
#if TEMP_SENSOR_BED == -1
#define BED_USES_AD595
#endif
#if TEMP_SENSOR_0 == -2
#define HEATER_0_USES_MAX6675
#endif
#if TEMP_SENSOR_0 == 0
#undef HEATER_0_MINTEMP
#undef HEATER_0_MAXTEMP
#endif
#if TEMP_SENSOR_1 == 0
#undef HEATER_1_MINTEMP
#undef HEATER_1_MAXTEMP
#endif
#if TEMP_SENSOR_2 == 0
#undef HEATER_2_MINTEMP
#undef HEATER_2_MAXTEMP
#endif
#if TEMP_SENSOR_3 == 0
#undef HEATER_3_MINTEMP
#undef HEATER_3_MAXTEMP
#endif
#if TEMP_SENSOR_BED == 0
#undef BED_MINTEMP
#undef BED_MAXTEMP
#endif
#endif //__CONFIGURATION_ADV_H
// Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware. // Tonokip RepRap firmware rewrite based off of Hydra-mmm firmware.
// License: GPL // License: GPL
#ifndef __MARLIN_H #ifndef MARLIN_H
#define __MARLIN_H #define MARLIN_H
#define FORCE_INLINE __attribute__((always_inline)) inline #define FORCE_INLINE __attribute__((always_inline)) inline
...@@ -22,16 +22,6 @@ ...@@ -22,16 +22,6 @@
#include "Configuration.h" #include "Configuration.h"
#include "pins.h" #include "pins.h"
#ifndef AT90USB
#define HardwareSerial_h // trick to disable the standard HWserial
#endif
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define BIT(b) (1<<(b)) #define BIT(b) (1<<(b))
#define TEST(n,b) (((n)&BIT(b))!=0) #define TEST(n,b) (((n)&BIT(b))!=0)
...@@ -265,21 +255,19 @@ extern float home_offset[3]; ...@@ -265,21 +255,19 @@ extern float home_offset[3];
#endif // HOTENDS > 1 #endif // HOTENDS > 1
#ifdef NPR2 #ifdef NPR2
extern int old_color; // old color for system NPR2 extern int old_color; // old color for system NPR2
#endif #endif
#ifdef DELTA #ifdef DELTA
extern float z_probe_offset[3]; extern float z_probe_offset[3];
extern float endstop_adj[3]; extern float endstop_adj[3];
extern float tower_adj[6]; extern float tower_adj[6];
extern float delta_radius; extern float delta_radius;
extern float delta_diagonal_rod; extern float delta_diagonal_rod;
//*extern float Z_MAX_POS;
//*extern float Z_MAX_LENGTH;
#endif #endif
#ifdef SCARA #ifdef SCARA
extern float axis_scaling[3]; // Build size scaling extern float axis_scaling[3]; // Build size scaling
#endif #endif
extern float min_pos[3]; extern float min_pos[3];
...@@ -290,8 +278,8 @@ extern float zprobe_zoffset; ...@@ -290,8 +278,8 @@ extern float zprobe_zoffset;
extern int fanSpeed; extern int fanSpeed;
#ifdef BARICUDA #ifdef BARICUDA
extern int ValvePressure; extern int ValvePressure;
extern int EtoPPressure; extern int EtoPPressure;
#endif #endif
#ifdef FAN_SOFT_PWM #ifdef FAN_SOFT_PWM
...@@ -309,23 +297,23 @@ extern unsigned char fanSpeedSoftPwm; ...@@ -309,23 +297,23 @@ extern unsigned char fanSpeedSoftPwm;
#endif #endif
#if (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) #if (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0)
extern unsigned int power_consumption_meas; //holds the power consumption as accurately measured extern float power_consumption_meas; //holds the power consumption as accurately measured
extern unsigned long power_consumption_hour; //holds the power consumption per hour as accurately measured extern unsigned long power_consumption_hour; //holds the power consumption per hour as accurately measured
#endif #endif
#ifdef FWRETRACT #ifdef FWRETRACT
extern bool autoretract_enabled; extern bool autoretract_enabled;
extern bool retracted[EXTRUDERS]; extern bool retracted[EXTRUDERS];
extern float retract_length, retract_length_swap, retract_feedrate, retract_zlift; extern float retract_length, retract_length_swap, retract_feedrate, retract_zlift;
extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate; extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate;
#endif #endif
#ifdef EASY_LOAD #ifdef EASY_LOAD
extern bool allow_lengthy_extrude_once; // for load/unload extern bool allow_lengthy_extrude_once; // for load/unload
#endif #endif
#ifdef LASERBEAM #ifdef LASERBEAM
extern int laser_ttl_modulation; extern int laser_ttl_modulation;
#endif #endif
extern unsigned long starttime; extern unsigned long starttime;
...@@ -336,8 +324,8 @@ extern uint8_t active_extruder; ...@@ -336,8 +324,8 @@ extern uint8_t active_extruder;
extern uint8_t active_driver; extern uint8_t active_driver;
#ifdef DIGIPOT_I2C #ifdef DIGIPOT_I2C
extern void digipot_i2c_set_current( int channel, float current ); extern void digipot_i2c_set_current( int channel, float current );
extern void digipot_i2c_init(); extern void digipot_i2c_init();
#endif #endif
// Debug with repetier // Debug with repetier
...@@ -348,9 +336,9 @@ extern inline bool debugDryrun() ...@@ -348,9 +336,9 @@ extern inline bool debugDryrun()
} }
#ifdef FIRMWARE_TEST #ifdef FIRMWARE_TEST
void FirmwareTest(); void FirmwareTest();
#endif #endif
extern void calculate_volumetric_multipliers(); extern void calculate_volumetric_multipliers();
#endif //__MARLIN_H #endif //MARLIN_H
...@@ -22,9 +22,6 @@ ...@@ -22,9 +22,6 @@
#include "Marlin.h" #include "Marlin.h"
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
#if Z_MIN_PIN == -1
#error "You must have a Z_MIN endstop to enable Auto Bed Leveling feature. Z_MIN_PIN must point to a valid hardware pin."
#endif
#include "vector_3.h" #include "vector_3.h"
#ifdef AUTO_BED_LEVELING_GRID #ifdef AUTO_BED_LEVELING_GRID
#include "qr_solve.h" #include "qr_solve.h"
...@@ -202,9 +199,7 @@ M999 - Restart after being stopped by error ...@@ -202,9 +199,7 @@ M999 - Restart after being stopped by error
unsigned long baudrate; unsigned long baudrate;
float homing_feedrate[] = HOMING_FEEDRATE; float homing_feedrate[] = HOMING_FEEDRATE;
#ifdef ENABLE_AUTO_BED_LEVELING int xy_travel_speed = XY_TRAVEL_SPEED;
int xy_travel_speed = XY_TRAVEL_SPEED;
#endif
int homing_bump_divisor[] = HOMING_BUMP_DIVISOR; int homing_bump_divisor[] = HOMING_BUMP_DIVISOR;
bool axis_relative_modes[] = AXIS_RELATIVE_MODES; bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
int feedmultiply = 100; //100->1 200->2 int feedmultiply = 100; //100->1 200->2
...@@ -316,12 +311,11 @@ float lastpos[4]; ...@@ -316,12 +311,11 @@ float lastpos[4];
}; };
#endif //HOTENDS > 1 #endif //HOTENDS > 1
uint8_t active_extruder = 0; uint8_t active_extruder = 0;
uint8_t active_driver = 0; uint8_t active_driver = 0;
uint8_t debugLevel = 0; uint8_t debugLevel = 0;
#ifdef NUM_SERVOS > 0 #if NUM_SERVOS > 0
int servo_endstops[] = SERVO_ENDSTOPS; int servo_endstops[] = SERVO_ENDSTOPS;
int servo_endstop_angles[] = SERVO_ENDSTOP_ANGLES; int servo_endstop_angles[] = SERVO_ENDSTOP_ANGLES;
#endif //NUM_SERVOS > 0 #endif //NUM_SERVOS > 0
...@@ -413,7 +407,7 @@ uint8_t debugLevel = 0; ...@@ -413,7 +407,7 @@ uint8_t debugLevel = 0;
#endif #endif
#if defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0 #if defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0
unsigned int power_consumption_meas = 0; float power_consumption_meas = 0;
unsigned long power_consumption_hour = 0.0; unsigned long power_consumption_hour = 0.0;
#endif #endif
...@@ -424,11 +418,9 @@ uint8_t debugLevel = 0; ...@@ -424,11 +418,9 @@ uint8_t debugLevel = 0;
const char errormagic[] PROGMEM = "Error:"; const char errormagic[] PROGMEM = "Error:";
const char echomagic[] PROGMEM = "echo:"; const char echomagic[] PROGMEM = "echo:";
//===========================================================================
//=============================Private Variables=============================
//===========================================================================
const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
static float offset[3] = { 0.0, 0.0, 0.0 };
static float offset[3] = { 0, 0, 0 };
static bool home_all_axis = true; static bool home_all_axis = true;
#ifdef DELTA #ifdef DELTA
...@@ -443,16 +435,16 @@ static bool home_all_axis = true; ...@@ -443,16 +435,16 @@ static bool home_all_axis = true;
{ 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 },
}; };
static float feedrate = 1500.0, next_feedrate, saved_feedrate, z_offset; static float z_offset;
static float bed_level_x, bed_level_y, bed_level_z; static float bed_level_x, bed_level_y, bed_level_z;
static float bed_level_c = 20; //used for inital bed probe safe distance (to avoid crashing into bed) static float bed_level_c = 20; //used for inital bed probe safe distance (to avoid crashing into bed)
static float bed_level_ox, bed_level_oy, bed_level_oz; static float bed_level_ox, bed_level_oy, bed_level_oz;
static int loopcount; static int loopcount;
#else // No DELTA
static float feedrate = 1500.0, next_feedrate, saved_feedrate;
#endif // No DELTA #endif // No DELTA
static float feedrate = 1500.0, next_feedrate, saved_feedrate;
static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0; static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
static bool relative_mode = false; //Determines Absolute or Relative Coordinates static bool relative_mode = false; //Determines Absolute or Relative Coordinates
static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE]; static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
...@@ -1080,43 +1072,36 @@ XYZ_CONSTS_FROM_CONFIG(float, home_retract_mm, HOME_RETRACT_MM); ...@@ -1080,43 +1072,36 @@ XYZ_CONSTS_FROM_CONFIG(float, home_retract_mm, HOME_RETRACT_MM);
XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR); XYZ_CONSTS_FROM_CONFIG(signed char, home_dir, HOME_DIR);
#ifdef DUAL_X_CARRIAGE #ifdef DUAL_X_CARRIAGE
#if EXTRUDERS == 1 || defined(COREXY) \
|| !defined(X2_ENABLE_PIN) || !defined(X2_STEP_PIN) || !defined(X2_DIR_PIN) \
|| !defined(X2_HOME_POS) || !defined(X2_MIN_POS) || !defined(X2_MAX_POS) \
|| !defined(X_MAX_PIN) || X_MAX_PIN < 0
#error "Missing or invalid definitions for DUAL_X_CARRIAGE mode."
#endif
#if X_HOME_DIR != -1 || X2_HOME_DIR != 1
#error "Please use canonical x-carriage assignment" // the x-carriages are defined by their homing directions
#endif
#define DXC_FULL_CONTROL_MODE 0 #define DXC_FULL_CONTROL_MODE 0
#define DXC_AUTO_PARK_MODE 1 #define DXC_AUTO_PARK_MODE 1
#define DXC_DUPLICATION_MODE 2 #define DXC_DUPLICATION_MODE 2
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
static int dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
static float x_home_pos(int extruder) { static float x_home_pos(int extruder) {
if (extruder == 0) if (extruder == 0)
return base_home_pos(X_AXIS) + home_offset[X_AXIS]; return base_home_pos(X_AXIS) + add_homing[X_AXIS];
else else
// In dual carriage mode the extruder offset provides an override of the // In dual carriage mode the extruder offset provides an override of the
// second X-carriage offset when homed - otherwise X2_HOME_POS is used. // second X-carriage offset when homed - otherwise X2_HOME_POS is used.
// This allow soft recalibration of the second extruder offset position without firmware reflash // This allow soft recalibration of the second extruder offset position without firmware reflash
// (through the M218 command). // (through the M218 command).
return (hotend_offset[X_AXIS][1] > 0) ? hotend_offset[X_AXIS][1] : X2_HOME_POS; return (extruder_offset[X_AXIS][1] > 0) ? extruder_offset[X_AXIS][1] : X2_HOME_POS;
} }
static int x_home_dir(int extruder) { static int x_home_dir(int extruder) {
return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR; return (extruder == 0) ? X_HOME_DIR : X2_HOME_DIR;
} }
static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1
static bool active_extruder_parked = false; // used in mode 1 & 2
static float raised_parked_position[NUM_AXIS]; // used in mode 1
static unsigned long delayed_move_time = 0; // used in mode 1
static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2
static float duplicate_extruder_temp_offset = 0; // used in mode 2
bool extruder_duplication_enabled = false; // used in mode 2
static float inactive_extruder_x_pos = X2_MAX_POS; // used in mode 0 & 1
static bool active_extruder_parked = false; // used in mode 1 & 2
static float raised_parked_position[NUM_AXIS]; // used in mode 1
static unsigned long delayed_move_time = 0; // used in mode 1
static float duplicate_extruder_x_offset = DEFAULT_DUPLICATION_X_OFFSET; // used in mode 2
static float duplicate_extruder_temp_offset = 0; // used in mode 2
bool extruder_duplication_enabled = false; // used in mode 2
#endif //DUAL_X_CARRIAGE #endif //DUAL_X_CARRIAGE
#if defined(CARTESIAN) || defined(COREXY) || defined(SCARA) #if defined(CARTESIAN) || defined(COREXY) || defined(SCARA)
...@@ -1201,7 +1186,7 @@ bool extruder_duplication_enabled = false; // used in mode 2 ...@@ -1201,7 +1186,7 @@ bool extruder_duplication_enabled = false; // used in mode 2
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder, active_driver); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder, active_driver);
st_synchronize(); st_synchronize();
feedrate = XY_TRAVEL_SPEED; feedrate = xy_travel_speed;
current_position[X_AXIS] = x; current_position[X_AXIS] = x;
current_position[Y_AXIS] = y; current_position[Y_AXIS] = y;
...@@ -1235,7 +1220,6 @@ bool extruder_duplication_enabled = false; // used in mode 2 ...@@ -1235,7 +1220,6 @@ bool extruder_duplication_enabled = false; // used in mode 2
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
} }
#else // not AUTO_BED_LEVELING_GRID #else // not AUTO_BED_LEVELING_GRID
static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) {
plan_bed_level_matrix.set_to_identity(); plan_bed_level_matrix.set_to_identity();
vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1); vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1);
...@@ -2560,7 +2544,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2560,7 +2544,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER); destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER);
destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER); destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER);
destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS); // Set destination away from bed destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS); // Set destination away from bed
feedrate = XY_TRAVEL_SPEED / 60; feedrate = xy_travel_speed / 60;
current_position[Z_AXIS] = 0; current_position[Z_AXIS] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
...@@ -2568,17 +2552,18 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2568,17 +2552,18 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
st_synchronize(); st_synchronize();
current_position[X_AXIS] = destination[X_AXIS]; current_position[X_AXIS] = destination[X_AXIS];
current_position[Y_AXIS] = destination[Y_AXIS]; current_position[Y_AXIS] = destination[Y_AXIS];
HOMEAXIS(Z); HOMEAXIS(Z);
} }
// Let's see if X and Y are homed and probe is inside bed area. // Let's see if X and Y are homed and probe is inside bed area.
if (code_seen(axis_codes[Z_AXIS])) { if (code_seen(axis_codes[Z_AXIS])) {
if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) { if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) {
float cpx = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER, float cpx = current_position[X_AXIS], cpy = current_position[Y_AXIS];
cpy = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER; if ( cpx >= X_MIN_POS - X_PROBE_OFFSET_FROM_EXTRUDER
if (cpx >= X_MIN_POS && cpx <= X_MAX_POS && cpy >= Y_MIN_POS && cpy <= Y_MAX_POS) { && cpx <= X_MAX_POS - X_PROBE_OFFSET_FROM_EXTRUDER
&& cpy >= Y_MIN_POS - Y_PROBE_OFFSET_FROM_EXTRUDER
&& cpy <= Y_MAX_POS - Y_PROBE_OFFSET_FROM_EXTRUDER) {
current_position[Z_AXIS] = 0; current_position[Z_AXIS] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(cpx, cpy, current_position[Z_AXIS], current_position[E_AXIS]);
destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS); // Set destination away from bed destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS); // Set destination away from bed
feedrate = max_feedrate[Z_AXIS]; feedrate = max_feedrate[Z_AXIS];
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder, active_driver); plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder, active_driver);
...@@ -2601,7 +2586,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2601,7 +2586,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
if(home_all_axis || (code_seen(axis_codes[Z_AXIS]))) { if(home_all_axis || (code_seen(axis_codes[Z_AXIS]))) {
destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT); destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT);
destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT); destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT);
feedrate = XY_TRAVEL_SPEED / 60; feedrate = xy_travel_speed / 60;
destination[Z_AXIS] = current_position[Z_AXIS] = 0; destination[Z_AXIS] = current_position[Z_AXIS] = 0;
plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder, active_driver); plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder, active_driver);
...@@ -2641,44 +2626,6 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2641,44 +2626,6 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
// Define the possible boundaries for probing based on set limits
#define MIN_PROBE_X (max(X_MIN_POS, X_MIN_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_X (min(X_MAX_POS, X_MAX_POS + X_PROBE_OFFSET_FROM_EXTRUDER))
#define MIN_PROBE_Y (max(Y_MIN_POS, Y_MIN_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#ifdef AUTO_BED_LEVELING_GRID
// Make sure probing points are reachable
#if LEFT_PROBE_BED_POSITION < MIN_PROBE_X
#error "The given LEFT_PROBE_BED_POSITION can't be reached by the probe."
#elif RIGHT_PROBE_BED_POSITION > MAX_PROBE_X
#error "The given RIGHT_PROBE_BED_POSITION can't be reached by the probe."
#elif FRONT_PROBE_BED_POSITION < MIN_PROBE_Y
#error "The given FRONT_PROBE_BED_POSITION can't be reached by the probe."
#elif BACK_PROBE_BED_POSITION > MAX_PROBE_Y
#error "The given BACK_PROBE_BED_POSITION can't be reached by the probe."
#endif
#else // !AUTO_BED_LEVELING_GRID
#if ABL_PROBE_PT_1_X < MIN_PROBE_X || ABL_PROBE_PT_1_X > MAX_PROBE_X
#error "The given ABL_PROBE_PT_1_X can't be reached by the probe."
#elif ABL_PROBE_PT_2_X < MIN_PROBE_X || ABL_PROBE_PT_2_X > MAX_PROBE_X
#error "The given ABL_PROBE_PT_2_X can't be reached by the probe."
#elif ABL_PROBE_PT_3_X < MIN_PROBE_X || ABL_PROBE_PT_3_X > MAX_PROBE_X
#error "The given ABL_PROBE_PT_3_X can't be reached by the probe."
#elif ABL_PROBE_PT_1_Y < MIN_PROBE_Y || ABL_PROBE_PT_1_Y > MAX_PROBE_Y
#error "The given ABL_PROBE_PT_1_Y can't be reached by the probe."
#elif ABL_PROBE_PT_2_Y < MIN_PROBE_Y || ABL_PROBE_PT_2_Y > MAX_PROBE_Y
#error "The given ABL_PROBE_PT_2_Y can't be reached by the probe."
#elif ABL_PROBE_PT_3_Y < MIN_PROBE_Y || ABL_PROBE_PT_3_Y > MAX_PROBE_Y
#error "The given ABL_PROBE_PT_3_Y can't be reached by the probe."
#endif
#endif // !AUTO_BED_LEVELING_GRID
/** /**
* G29: Detailed Z-Probe, probes the bed at 3 or more points. * G29: Detailed Z-Probe, probes the bed at 3 or more points.
* Will fail if the printer has not been homed with G28. * Will fail if the printer has not been homed with G28.
...@@ -2825,8 +2772,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2825,8 +2772,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
int probePointCounter = 0; int probePointCounter = 0;
bool zig = true; bool zig = true;
for (int yCount=0; yCount < auto_bed_leveling_grid_points; yCount++) for (int yCount=0; yCount < auto_bed_leveling_grid_points; yCount++) {
{
double yProbe = front_probe_bed_position + yGridSpacing * yCount; double yProbe = front_probe_bed_position + yGridSpacing * yCount;
int xStart, xStop, xInc; int xStart, xStop, xInc;
...@@ -2835,22 +2781,19 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2835,22 +2781,19 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
xStart = 0; xStart = 0;
xStop = auto_bed_leveling_grid_points; xStop = auto_bed_leveling_grid_points;
xInc = 1; xInc = 1;
zig = false;
} }
else else
{ {
xStart = auto_bed_leveling_grid_points - 1; xStart = auto_bed_leveling_grid_points - 1;
xStop = -1; xStop = -1;
xInc = -1; xInc = -1;
zig = true;
} }
// If topo_flag is set then don't zig-zag. Just scan in one direction. // If topo_flag is set then don't zig-zag. Just scan in one direction.
// This gets the probe points in more readable order. // This gets the probe points in more readable order.
if (do_topography_map) zig = !zig; if (!do_topography_map) zig = !zig;
for (int xCount=xStart; xCount != xStop; xCount += xInc) for (int xCount = xStart; xCount != xStop; xCount += xInc) {
{
double xProbe = left_probe_bed_position + xGridSpacing * xCount; double xProbe = left_probe_bed_position + xGridSpacing * xCount;
// raise extruder // raise extruder
...@@ -2915,7 +2858,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) { ...@@ -2915,7 +2858,7 @@ inline void gcode_G28(boolean home_x=false, boolean home_y=false) {
SERIAL_PROTOCOLPGM("+-----------+\n"); SERIAL_PROTOCOLPGM("+-----------+\n");
for (int yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) { for (int yy = auto_bed_leveling_grid_points - 1; yy >= 0; yy--) {
for (int xx = auto_bed_leveling_grid_points - 1; xx >= 0; xx--) { for (int xx = 0; xx < auto_bed_leveling_grid_points; xx++) {
int ind = yy * auto_bed_leveling_grid_points + xx; int ind = yy * auto_bed_leveling_grid_points + xx;
float diff = eqnBVector[ind] - mean; float diff = eqnBVector[ind] - mean;
if (diff >= 0.0) if (diff >= 0.0)
......
/**
* SanityCheck.h
*
* Test configuration values for errors at compile-time.
*/
#ifndef SANITYCHECK_H
#define SANITYCHECK_H
/**
* Dual Stepper Drivers
*/
#if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Y_DUAL_STEPPER_DRIVERS)
#error You cannot have dual stepper drivers for both Y and Z.
#endif
/**
* Progress Bar
*/
#ifdef LCD_PROGRESS_BAR
#ifdef DOGLCD
#warning LCD_PROGRESS_BAR does not apply to graphical displays.
#endif
#ifdef FILAMENT_LCD_DISPLAY
#error LCD_PROGRESS_BAR and FILAMENT_LCD_DISPLAY are not fully compatible. Comment out this line to use both.
#endif
#ifdef POWER_CONSUMPTION_LCD_DISPLAY
#error LCD_PROGRESS_BAR and POWER_CONSUMPTION_LCD_DISPLAY are not fully compatible. Comment out this line to use both.
#endif
#endif
/**
* Babystepping
*/
#ifdef BABYSTEPPING
#ifdef COREXY
#error BABYSTEPPING not implemented for COREXY yet.
#endif
#ifdef SCARA
#error BABYSTEPPING is not implemented for SCARA yet.
#endif
#if defined(DELTA) && defined(BABYSTEP_XY)
#error BABYSTEPPING only implemented for Z axis on deltabots.
#endif
#endif
/**
* Filament Change with Extruder Runout Prevention
*/
#if defined(FILAMENTCHANGEENABLE) && defined(EXTRUDER_RUNOUT_PREVENT)
#error EXTRUDER_RUNOUT_PREVENT currently incompatible with FILAMENTCHANGE.
#endif
/**
* Extruder Runout Prevention
*/
#if defined(EXTRUDER_RUNOUT_PREVENT) && EXTRUDER_RUNOUT_MINTEMP < EXTRUDE_MINTEMP
#error EXTRUDER_RUNOUT_MINTEMP have to be greater than EXTRUDE_MINTEMP
#endif
/**
* Idle oozing prevent with Extruder Runout Prevention
*/
#if defined(EXTRUDER_RUNOUT_PREVENT) && defined(IDLE_OOZING_PREVENT)
#error EXTRUDER_RUNOUT_PREVENT and IDLE_OOZING_PREVENT are incopatible. Please comment one of them.
#endif
/**
* Idle oozing prevent
*/
#if defined(IDLE_OOZING_PREVENT) && IDLE_OOZING_MINTEMP < EXTRUDE_MINTEMP
#error IDLE_OOZING_MINTEMP have to be greater than EXTRUDE_MINTEMP
#endif
/**
* Options only for EXTRUDERS == 1
*/
#if EXTRUDERS > 1
#if EXTRUDERS > 4
#error The maximum number of EXTRUDERS is 4.
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
#error EXTRUDERS must be 1 with TEMP_SENSOR_1_AS_REDUNDANT.
#endif
#ifdef HEATERS_PARALLEL
#error EXTRUDERS must be 1 with HEATERS_PARALLEL.
#endif
#ifdef Y_DUAL_STEPPER_DRIVERS
#error EXTRUDERS must be 1 with Y_DUAL_STEPPER_DRIVERS.
#endif
#ifdef Z_DUAL_STEPPER_DRIVERS
#error EXTRUDERS must be 1 with Z_DUAL_STEPPER_DRIVERS.
#endif
#endif // EXTRUDERS > 1
/**
* Required LCD language
*/
#if !defined(DOGLCD) && defined(ULTRA_LCD) && !defined(DISPLAY_CHARSET_HD44780_JAPAN) && !defined(DISPLAY_CHARSET_HD44780_WESTERN)
#error You must enable either DISPLAY_CHARSET_HD44780_JAPAN or DISPLAY_CHARSET_HD44780_WESTERN for your LCD controller.
#endif
/**
* Auto Bed Leveling
*/
#ifdef ENABLE_AUTO_BED_LEVELING
/**
* Require a Z Min pin
*/
#if Z_MIN_PIN == -1
#ifdef Z_PROBE_REPEATABILITY_TEST
#error You must have a Z_MIN endstop to enable Z_PROBE_REPEATABILITY_TEST.
#else
#error ENABLE_AUTO_BED_LEVELING requires a Z_MIN endstop. Z_MIN_PIN must point to a valid hardware pin.
#endif
#endif
/**
* Check if Probe_Offset * Grid Points is greater than Probing Range
*/
#ifdef AUTO_BED_LEVELING_GRID
// Make sure probing points are reachable
#if LEFT_PROBE_BED_POSITION < MIN_PROBE_X
#error The given LEFT_PROBE_BED_POSITION can't be reached by the probe.
#elif RIGHT_PROBE_BED_POSITION > MAX_PROBE_X
#error The given RIGHT_PROBE_BED_POSITION can't be reached by the probe.
#elif FRONT_PROBE_BED_POSITION < MIN_PROBE_Y
#error The given FRONT_PROBE_BED_POSITION can't be reached by the probe.
#elif BACK_PROBE_BED_POSITION > MAX_PROBE_Y
#error The given BACK_PROBE_BED_POSITION can't be reached by the probe.
#endif
#define PROBE_SIZE_X (X_PROBE_OFFSET_FROM_EXTRUDER * (AUTO_BED_LEVELING_GRID_POINTS-1))
#define PROBE_SIZE_Y (Y_PROBE_OFFSET_FROM_EXTRUDER * (AUTO_BED_LEVELING_GRID_POINTS-1))
#define PROBE_AREA_WIDTH (RIGHT_PROBE_BED_POSITION - LEFT_PROBE_BED_POSITION)
#define PROBE_AREA_DEPTH (BACK_PROBE_BED_POSITION - FRONT_PROBE_BED_POSITION)
#if X_PROBE_OFFSET_FROM_EXTRUDER < 0
#if PROBE_SIZE_X <= -PROBE_AREA_WIDTH
#define X_PROBE_ERROR
#endif
#elif PROBE_SIZE_X >= PROBE_AREA_WIDTH
#define X_PROBE_ERROR
#endif
#ifdef X_PROBE_ERROR
#error The X axis probing range is too small to fit all the points defined in AUTO_BED_LEVELING_GRID_POINTS
#endif
#if Y_PROBE_OFFSET_FROM_EXTRUDER < 0
#if PROBE_SIZE_Y <= -PROBE_AREA_DEPTH
#define Y_PROBE_ERROR
#endif
#elif PROBE_SIZE_Y >= PROBE_AREA_DEPTH
#define Y_PROBE_ERROR
#endif
#ifdef Y_PROBE_ERROR
#error The Y axis probing range is to small to fit all the points defined in AUTO_BED_LEVELING_GRID_POINTS
#endif
#undef PROBE_SIZE_X
#undef PROBE_SIZE_Y
#undef PROBE_AREA_WIDTH
#undef PROBE_AREA_DEPTH
#else // !AUTO_BED_LEVELING_GRID
// Check the triangulation points
#if ABL_PROBE_PT_1_X < MIN_PROBE_X || ABL_PROBE_PT_1_X > MAX_PROBE_X
#error "The given ABL_PROBE_PT_1_X can't be reached by the probe."
#elif ABL_PROBE_PT_2_X < MIN_PROBE_X || ABL_PROBE_PT_2_X > MAX_PROBE_X
#error "The given ABL_PROBE_PT_2_X can't be reached by the probe."
#elif ABL_PROBE_PT_3_X < MIN_PROBE_X || ABL_PROBE_PT_3_X > MAX_PROBE_X
#error "The given ABL_PROBE_PT_3_X can't be reached by the probe."
#elif ABL_PROBE_PT_1_Y < MIN_PROBE_Y || ABL_PROBE_PT_1_Y > MAX_PROBE_Y
#error "The given ABL_PROBE_PT_1_Y can't be reached by the probe."
#elif ABL_PROBE_PT_2_Y < MIN_PROBE_Y || ABL_PROBE_PT_2_Y > MAX_PROBE_Y
#error "The given ABL_PROBE_PT_2_Y can't be reached by the probe."
#elif ABL_PROBE_PT_3_Y < MIN_PROBE_Y || ABL_PROBE_PT_3_Y > MAX_PROBE_Y
#error "The given ABL_PROBE_PT_3_Y can't be reached by the probe."
#endif
#endif // !AUTO_BED_LEVELING_GRID
#endif // ENABLE_AUTO_BED_LEVELING
/**
* ULTIPANEL encoder
*/
#if defined(ULTIPANEL) && !defined(NEWPANEL) && !defined(SR_LCD_2W_NL) && !defined(SHIFT_CLK)
#error ULTIPANEL requires some kind of encoder.
#endif
/**
* Delta has limited bed leveling options
*/
#ifdef DELTA
#ifdef ENABLE_AUTO_BED_LEVELING
#ifndef AUTO_BED_LEVELING_GRID
#error Only AUTO_BED_LEVELING_GRID is supported with DELTA.
#endif
#ifdef Z_PROBE_SLED
#error You cannot use Z_PROBE_SLED with DELTA.
#endif
#ifdef Z_PROBE_REPEATABILITY_TEST
#error Z_PROBE_REPEATABILITY_TEST is not supported with DELTA yet.
#endif
#endif
#endif
/**
* Allen Key Z Probe requires Auto Bed Leveling grid and Delta
*/
#if defined(Z_PROBE_ALLEN_KEY) && !(defined(AUTO_BED_LEVELING_GRID) && defined(DELTA))
#error Invalid use of Z_PROBE_ALLEN_KEY.
#endif
/**
* Dual X Carriage requirements
*/
#ifdef DUAL_X_CARRIAGE
#if EXTRUDERS == 1 || defined(COREXY) \
|| !defined(X2_ENABLE_PIN) || !defined(X2_STEP_PIN) || !defined(X2_DIR_PIN) \
|| !defined(X2_HOME_POS) || !defined(X2_MIN_POS) || !defined(X2_MAX_POS) \
|| !defined(X_MAX_PIN) || X_MAX_PIN < 0
#error Missing or invalid definitions for DUAL_X_CARRIAGE mode.
#endif
#if X_HOME_DIR != -1 || X2_HOME_DIR != 1
#error Please use canonical x-carriage assignment.
#endif
#endif // DUAL_X_CARRIAGE
/**
* Make sure auto fan pins don't conflict with the fan pin
*/
#if HAS_AUTO_FAN && HAS_FAN
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN
#elif EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
#error You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN
#elif EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
#error You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN
#elif EXTRUDER_3_AUTO_FAN_PIN == FAN_PIN
#error You cannot set EXTRUDER_3_AUTO_FAN_PIN equal to FAN_PIN
#endif
#endif
/**
* Test required HEATER defines
*/
#if HOTENDS > 3
#if !HAS_HEATER_3
#error HEATER_3_PIN not defined for this board
#endif
#elif HOTENDS > 2
#if !HAS_HEATER_2
#error HEATER_2_PIN not defined for this board
#endif
#elif HOTENDS > 1 || defined(HEATERS_PARALLEL)
#if !HAS_HEATER_1
#error HEATER_1_PIN not defined for this board
#endif
#endif
#if !HAS_HEATER_0
#error HEATER_0_PIN not defined for this board
#endif
#endif //SANITYCHECK_H
...@@ -33,9 +33,7 @@ struct pin_map_t { ...@@ -33,9 +33,7 @@ struct pin_map_t {
uint8_t bit; uint8_t bit;
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if defined(__AVR_ATmega1280__)\ #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // Mega
|| defined(__AVR_ATmega2560__)
// Mega
// Two Wire (aka I2C) ports // Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 20; // D1 uint8_t const SDA_PIN = 20; // D1
...@@ -43,6 +41,7 @@ uint8_t const SCL_PIN = 21; // D0 ...@@ -43,6 +41,7 @@ uint8_t const SCL_PIN = 21; // D0
#undef MOSI_PIN #undef MOSI_PIN
#undef MISO_PIN #undef MISO_PIN
#undef SCK_PIN
// SPI port // SPI port
uint8_t const SS_PIN = 53; // B0 uint8_t const SS_PIN = 53; // B0
uint8_t const MOSI_PIN = 51; // B2 uint8_t const MOSI_PIN = 51; // B2
......
...@@ -267,7 +267,7 @@ static void lcd_implementation_status_screen() { ...@@ -267,7 +267,7 @@ static void lcd_implementation_status_screen() {
// Status line // Status line
u8g.setFont(FONT_STATUSMENU); u8g.setFont(FONT_STATUSMENU);
u8g.setPrintPos(0,63); u8g.setPrintPos(0,63);
#if defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && (FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) || (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && (POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY) #if defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && (FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) || (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && (POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY))
if (millis() < message_millis + 5000) { //Display both Status message line and Filament display on the last line if (millis() < message_millis + 5000) { //Display both Status message line and Filament display on the last line
u8g.print(lcd_status_message); u8g.print(lcd_status_message);
} }
...@@ -279,7 +279,7 @@ static void lcd_implementation_status_screen() { ...@@ -279,7 +279,7 @@ static void lcd_implementation_status_screen() {
#endif #endif
{ {
lcd_printPGM(PSTR("P:")); lcd_printPGM(PSTR("P:"));
u8g.print(itostr3(power_consumption_meas)); u8g.print(ftostr31(power_consumption_meas));
lcd_printPGM(PSTR("W C:")); lcd_printPGM(PSTR("W C:"));
u8g.print(ltostr7(power_consumption_hour)); u8g.print(ltostr7(power_consumption_hour));
lcd_printPGM(PSTR("Wh")); lcd_printPGM(PSTR("Wh"));
......
...@@ -65,6 +65,9 @@ ...@@ -65,6 +65,9 @@
#define MSG_PID_P "PID-P" #define MSG_PID_P "PID-P"
#define MSG_PID_I "PID-I" #define MSG_PID_I "PID-I"
#define MSG_PID_D "PID-D" #define MSG_PID_D "PID-D"
#define MSG_E2 " E2"
#define MSG_E3 " E3"
#define MSG_E4 " E4"
#define MSG_ACC "Accel" #define MSG_ACC "Accel"
#define MSG_VXY_JERK "Vxy-jerk" #define MSG_VXY_JERK "Vxy-jerk"
#define MSG_VZ_JERK "Vz-jerk" #define MSG_VZ_JERK "Vz-jerk"
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define MSG_PREHEAT_GUM "Preriscalda GOMMA" #define MSG_PREHEAT_GUM "Preriscalda GOMMA"
#define MSG_PREHEAT_GUM_ALL "Preri. GOMMA Tutto" #define MSG_PREHEAT_GUM_ALL "Preri. GOMMA Tutto"
#define MSG_PREHEAT_GUM_BEDONLY "Preri. GOMMA Piatto" #define MSG_PREHEAT_GUM_BEDONLY "Preri. GOMMA Piatto"
#define MSG_PREHEAT_GUM_SETTINGS "Preris. GOMMA Conf" #define MSG_PREHEAT_GUM_SETTINGS "Config. prer. GOMMA"
#define MSG_COOLDOWN "Raffredda" #define MSG_COOLDOWN "Raffredda"
#define MSG_SWITCH_PS_ON "Accendi aliment." #define MSG_SWITCH_PS_ON "Accendi aliment."
#define MSG_SWITCH_PS_OFF "Spegni aliment." #define MSG_SWITCH_PS_OFF "Spegni aliment."
...@@ -65,6 +65,9 @@ ...@@ -65,6 +65,9 @@
#define MSG_PID_P "PID-P" #define MSG_PID_P "PID-P"
#define MSG_PID_I "PID-I" #define MSG_PID_I "PID-I"
#define MSG_PID_D "PID-D" #define MSG_PID_D "PID-D"
#define MSG_E2 " E2"
#define MSG_E3 " E3"
#define MSG_E4 " E4"
#define MSG_ACC "Accel." #define MSG_ACC "Accel."
#define MSG_VXY_JERK "Vxy-jerk" #define MSG_VXY_JERK "Vxy-jerk"
#define MSG_VZ_JERK "Vz-jerk" #define MSG_VZ_JERK "Vz-jerk"
......
...@@ -119,8 +119,7 @@ volatile unsigned char block_buffer_tail; // Index of the block to process now ...@@ -119,8 +119,7 @@ volatile unsigned char block_buffer_tail; // Index of the block to process now
// Old direction bits. Used for speed calculations // Old direction bits. Used for speed calculations
static unsigned char old_direction_bits = 0; static unsigned char old_direction_bits = 0;
// Segment times (in us). Used for speed calculations // Segment times (in us). Used for speed calculations
static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; static long axis_segment_time[2][3] = { {MAX_FREQ_TIME+1,0,0}, {MAX_FREQ_TIME+1,0,0} };
static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0};
#endif #endif
#ifdef FILAMENT_SENSOR #ifdef FILAMENT_SENSOR
...@@ -737,15 +736,15 @@ float junction_deviation = 0.1; ...@@ -737,15 +736,15 @@ float junction_deviation = 0.1;
int moves_queued = movesplanned(); int moves_queued = movesplanned();
// slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill // slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
bool mq = moves_queued > 1 && moves_queued < BLOCK_BUFFER_SIZE / 2;
#ifdef OLD_SLOWDOWN #ifdef OLD_SLOWDOWN
if(moves_queued < (BLOCK_BUFFER_SIZE * 0.5) && moves_queued > 1) if (mq) feed_rate *= 2.0 * moves_queued / BLOCK_BUFFER_SIZE;
feed_rate = feed_rate*moves_queued / (BLOCK_BUFFER_SIZE * 0.5);
#endif #endif
#ifdef SLOWDOWN #ifdef SLOWDOWN
// segment time im micro seconds // segment time im micro seconds
unsigned long segment_time = lround(1000000.0 / inverse_second); unsigned long segment_time = lround(1000000.0/inverse_second);
if ((moves_queued > 1) && (moves_queued < (BLOCK_BUFFER_SIZE * 0.5))) { if (mq) {
if (segment_time < minsegmenttime) { if (segment_time < minsegmenttime) {
// buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
inverse_second = 1000000.0 / (segment_time + lround(2 * (minsegmenttime - segment_time) / moves_queued)); inverse_second = 1000000.0 / (segment_time + lround(2 * (minsegmenttime - segment_time) / moves_queued));
...@@ -767,7 +766,7 @@ float junction_deviation = 0.1; ...@@ -767,7 +766,7 @@ float junction_deviation = 0.1;
const int MMD = MAX_MEASUREMENT_DELAY + 1, MMD10 = MMD * 10; const int MMD = MAX_MEASUREMENT_DELAY + 1, MMD10 = MMD * 10;
delay_dist += delta_mm[E_AXIS]; //increment counter with next move in e axis delay_dist += delta_mm[E_AXIS]; // increment counter with next move in e axis
while (delay_dist >= MMD10) delay_dist -= MMD10; // loop around the buffer while (delay_dist >= MMD10) delay_dist -= MMD10; // loop around the buffer
while (delay_dist < 0) delay_dist += MMD10; while (delay_dist < 0) delay_dist += MMD10;
...@@ -787,9 +786,9 @@ float junction_deviation = 0.1; ...@@ -787,9 +786,9 @@ float junction_deviation = 0.1;
#endif #endif
// Calculate and limit speed in mm/sec for each axis // Calculate and limit speed in mm/sec for each axis
float current_speed[4]; float current_speed[NUM_AXIS];
float speed_factor = 1.0; //factor <=1 do decrease speed float speed_factor = 1.0; //factor <=1 do decrease speed
for(int i=0; i < 3; i++) { for (int i = 0; i < 3; i++) {
current_speed[i] = delta_mm[i] * inverse_second; current_speed[i] = delta_mm[i] * inverse_second;
float cs = fabs(current_speed[i]), mf = max_feedrate[i]; float cs = fabs(current_speed[i]), mf = max_feedrate[i];
if (cs > mf) speed_factor = min(speed_factor, mf / cs); if (cs > mf) speed_factor = min(speed_factor, mf / cs);
...@@ -809,69 +808,76 @@ float junction_deviation = 0.1; ...@@ -809,69 +808,76 @@ float junction_deviation = 0.1;
// Max segement time in us. // Max segement time in us.
#ifdef XY_FREQUENCY_LIMIT #ifdef XY_FREQUENCY_LIMIT
#define MAX_FREQ_TIME (1000000.0/XY_FREQUENCY_LIMIT) #define MAX_FREQ_TIME (1000000.0 / XY_FREQUENCY_LIMIT)
// Check and limit the xy direction change frequency // Check and limit the xy direction change frequency
unsigned char direction_change = block->direction_bits ^ old_direction_bits; unsigned char direction_change = block->direction_bits ^ old_direction_bits;
old_direction_bits = block->direction_bits; old_direction_bits = block->direction_bits;
segment_time = lround((float)segment_time / speed_factor); segment_time = lround((float)segment_time / speed_factor);
if((direction_change & BIT(X_AXIS)) == 0) { long xs0 = axis_segment_time[X_AXIS][0],
x_segment_time[0] += segment_time; xs1 = axis_segment_time[X_AXIS][1],
} xs2 = axis_segment_time[X_AXIS][2],
else { ys0 = axis_segment_time[Y_AXIS][0],
x_segment_time[2] = x_segment_time[1]; ys1 = axis_segment_time[Y_AXIS][1],
x_segment_time[1] = x_segment_time[0]; ys2 = axis_segment_time[Y_AXIS][2];
x_segment_time[0] = segment_time;
}
if((direction_change & BIT(Y_AXIS)) == 0) { if ((direction_change & BIT(X_AXIS)) != 0) {
y_segment_time[0] += segment_time; xs2 = axis_segment_time[X_AXIS][2] = xs1;
xs1 = axis_segment_time[X_AXIS][1] = xs0;
xs0 = 0;
} }
else { xs0 = axis_segment_time[X_AXIS][0] = xs0 + segment_time;
y_segment_time[2] = y_segment_time[1];
y_segment_time[1] = y_segment_time[0]; if ((direction_change & BIT(Y_AXIS)) != 0) {
y_segment_time[0] = segment_time; ys2 = axis_segment_time[Y_AXIS][2] = axis_segment_time[Y_AXIS][1];
ys1 = axis_segment_time[Y_AXIS][1] = axis_segment_time[Y_AXIS][0];
ys0 = 0;
} }
ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time;
long max_x_segment_time = max(x_segment_time[0], max(x_segment_time[1], x_segment_time[2])); long max_x_segment_time = max(xs0, max(xs1, xs2)),
long max_y_segment_time = max(y_segment_time[0], max(y_segment_time[1], y_segment_time[2])); max_y_segment_time = max(ys0, max(ys1, ys2)),
long min_xy_segment_time =min(max_x_segment_time, max_y_segment_time); min_xy_segment_time = min(max_x_segment_time, max_y_segment_time);
if(min_xy_segment_time < MAX_FREQ_TIME) if (min_xy_segment_time < MAX_FREQ_TIME) {
speed_factor = min(speed_factor, speed_factor * (float)min_xy_segment_time / (float)MAX_FREQ_TIME); float low_sf = speed_factor * min_xy_segment_time / MAX_FREQ_TIME;
speed_factor = min(speed_factor, low_sf);
}
#endif // XY_FREQUENCY_LIMIT #endif // XY_FREQUENCY_LIMIT
// Correct the speed // Correct the speed
if( speed_factor < 1.0) { if (speed_factor < 1.0) {
for(unsigned char i=0; i < 4; i++) { for (unsigned char i = 0; i < NUM_AXIS; i++) current_speed[i] *= speed_factor;
current_speed[i] *= speed_factor;
}
block->nominal_speed *= speed_factor; block->nominal_speed *= speed_factor;
block->nominal_rate *= speed_factor; block->nominal_rate *= speed_factor;
} }
// Compute and limit the acceleration rate for the trapezoid generator. // Compute and limit the acceleration rate for the trapezoid generator.
float steps_per_mm = block->step_event_count/block->millimeters; float steps_per_mm = block->step_event_count / block->millimeters;
if(block->steps[X_AXIS] == 0 && block->steps[Y_AXIS] == 0 && block->steps[Z_AXIS] == 0) { long bsx = block->steps[X_AXIS], bsy = block->steps[Y_AXIS], bsz = block->steps[Z_AXIS], bse = block->steps[E_AXIS];
if (bsx == 0 && bsy == 0 && bsz == 0) {
block->acceleration_st = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 block->acceleration_st = ceil(retract_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
} }
else if(block->steps[E_AXIS] == 0) { else if (bse == 0) {
block->acceleration_st = ceil(travel_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 block->acceleration_st = ceil(travel_acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
} }
else { else {
block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2 block->acceleration_st = ceil(acceleration * steps_per_mm); // convert to: acceleration steps/sec^2
} }
// Limit acceleration per axis // Limit acceleration per axis
if(((float)block->acceleration_st * (float)block->steps[X_AXIS] / (float)block->step_event_count) > axis_steps_per_sqr_second[X_AXIS]) unsigned long acc_st = block->acceleration_st,
block->acceleration_st = axis_steps_per_sqr_second[X_AXIS]; xsteps = axis_steps_per_sqr_second[X_AXIS],
if(((float)block->acceleration_st * (float)block->steps[Y_AXIS] / (float)block->step_event_count) > axis_steps_per_sqr_second[Y_AXIS]) ysteps = axis_steps_per_sqr_second[Y_AXIS],
block->acceleration_st = axis_steps_per_sqr_second[Y_AXIS]; zsteps = axis_steps_per_sqr_second[Z_AXIS],
if(((float)block->acceleration_st * (float)block->steps[E_AXIS] / (float)block->step_event_count) > axis_steps_per_sqr_second[E_AXIS]) esteps = axis_steps_per_sqr_second[E_AXIS];
block->acceleration_st = axis_steps_per_sqr_second[E_AXIS]; if ((float)acc_st * bsx / block->step_event_count > xsteps) acc_st = xsteps;
if(((float)block->acceleration_st * (float)block->steps[Z_AXIS] / (float)block->step_event_count ) > axis_steps_per_sqr_second[Z_AXIS]) if ((float)acc_st * bsy / block->step_event_count > ysteps) acc_st = ysteps;
block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS]; if ((float)acc_st * bsz / block->step_event_count > zsteps) acc_st = zsteps;
if ((float)acc_st * bse / block->step_event_count > esteps) acc_st = esteps;
block->acceleration = block->acceleration_st / steps_per_mm;
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); block->acceleration_st = acc_st;
block->acceleration = acc_st / steps_per_mm;
block->acceleration_rate = (long)(acc_st * 16777216.0 / (F_CPU / 8.0));
#if 0 // Use old jerk for now #if 0 // Use old jerk for now
// Compute path unit vector // Compute path unit vector
...@@ -913,36 +919,37 @@ float junction_deviation = 0.1; ...@@ -913,36 +919,37 @@ float junction_deviation = 0.1;
} }
} }
#endif #endif
// Start with a safe speed // Start with a safe speed
float vmax_junction = max_xy_jerk/2; float vmax_junction = max_xy_jerk / 2;
float vmax_junction_factor = 1.0; float vmax_junction_factor = 1.0;
if(fabs(current_speed[Z_AXIS]) > max_z_jerk/2) float mz2 = max_z_jerk / 2, me2 = max_e_jerk / 2;
vmax_junction = min(vmax_junction, max_z_jerk/2); float csz = current_speed[Z_AXIS], cse = current_speed[E_AXIS];
if(fabs(current_speed[E_AXIS]) > max_e_jerk/2) if (fabs(csz) > mz2) vmax_junction = min(vmax_junction, mz2);
vmax_junction = min(vmax_junction, max_e_jerk/2); if (fabs(cse) > me2) vmax_junction = min(vmax_junction, me2);
vmax_junction = min(vmax_junction, block->nominal_speed); vmax_junction = min(vmax_junction, block->nominal_speed);
float safe_speed = vmax_junction; float safe_speed = vmax_junction;
if ((moves_queued > 1) && (previous_nominal_speed > 0.0001)) { if ((moves_queued > 1) && (previous_nominal_speed > 0.0001)) {
float jerk = sqrt(pow((current_speed[X_AXIS]-previous_speed[X_AXIS]), 2)+pow((current_speed[Y_AXIS]-previous_speed[Y_AXIS]), 2)); float dx = current_speed[X_AXIS] - previous_speed[X_AXIS],
// if((fabs(previous_speed[X_AXIS]) > 0.0001) || (fabs(previous_speed[Y_AXIS]) > 0.0001)) { dy = current_speed[Y_AXIS] - previous_speed[Y_AXIS],
dz = fabs(csz - previous_speed[Z_AXIS]),
de = fabs(cse - previous_speed[E_AXIS]),
jerk = sqrt(dx * dx + dy * dy);
// if ((fabs(previous_speed[X_AXIS]) > 0.0001) || (fabs(previous_speed[Y_AXIS]) > 0.0001)) {
vmax_junction = block->nominal_speed; vmax_junction = block->nominal_speed;
// } // }
if (jerk > max_xy_jerk) { if (jerk > max_xy_jerk) vmax_junction_factor = max_xy_jerk / jerk;
vmax_junction_factor = (max_xy_jerk/jerk); if (dz > max_z_jerk) vmax_junction_factor = min(vmax_junction_factor, max_z_jerk / dz);
} if (de > max_e_jerk) vmax_junction_factor = min(vmax_junction_factor, max_e_jerk / de);
if(fabs(current_speed[Z_AXIS] - previous_speed[Z_AXIS]) > max_z_jerk) {
vmax_junction_factor= min(vmax_junction_factor, (max_z_jerk/fabs(current_speed[Z_AXIS] - previous_speed[Z_AXIS])));
}
if(fabs(current_speed[E_AXIS] - previous_speed[E_AXIS]) > max_e_jerk) {
vmax_junction_factor = min(vmax_junction_factor, (max_e_jerk/fabs(current_speed[E_AXIS] - previous_speed[E_AXIS])));
}
vmax_junction = min(previous_nominal_speed, vmax_junction * vmax_junction_factor); // Limit speed to max previous speed vmax_junction = min(previous_nominal_speed, vmax_junction * vmax_junction_factor); // Limit speed to max previous speed
} }
block->max_entry_speed = vmax_junction; block->max_entry_speed = vmax_junction;
// Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED. // Initialize block entry speed. Compute based on deceleration to user-defined MINIMUM_PLANNER_SPEED.
double v_allowable = max_allowable_speed(-block->acceleration,MINIMUM_PLANNER_SPEED,block->millimeters); double v_allowable = max_allowable_speed(-block->acceleration, MINIMUM_PLANNER_SPEED, block->millimeters);
block->entry_speed = min(vmax_junction, v_allowable); block->entry_speed = min(vmax_junction, v_allowable);
// Initialize planner efficiency flags // Initialize planner efficiency flags
...@@ -953,35 +960,24 @@ float junction_deviation = 0.1; ...@@ -953,35 +960,24 @@ float junction_deviation = 0.1;
// block nominal speed limits both the current and next maximum junction speeds. Hence, in both // block nominal speed limits both the current and next maximum junction speeds. Hence, in both
// the reverse and forward planners, the corresponding block junction speed will always be at the // the reverse and forward planners, the corresponding block junction speed will always be at the
// the maximum junction speed and may always be ignored for any speed reduction checks. // the maximum junction speed and may always be ignored for any speed reduction checks.
if (block->nominal_speed <= v_allowable) { block->nominal_length_flag = (block->nominal_speed <= v_allowable);
block->nominal_length_flag = true;
}
else {
block->nominal_length_flag = false;
}
block->recalculate_flag = true; // Always calculate trapezoid for new block block->recalculate_flag = true; // Always calculate trapezoid for new block
// Update previous path unit_vector and nominal speed // Update previous path unit_vector and nominal speed
memcpy(previous_speed, current_speed, sizeof(previous_speed)); // previous_speed[] = current_speed[] for (int i = 0; i < NUM_AXIS; i++) previous_speed[i] = current_speed[i];
previous_nominal_speed = block->nominal_speed; previous_nominal_speed = block->nominal_speed;
#ifdef ADVANCE #ifdef ADVANCE
// Calculate advance rate // Calculate advance rate
if((block->steps[E_AXIS] == 0) || (block->steps[X_AXIS] == 0 && block->steps[Y_AXIS] == 0 && block->steps[Z_AXIS] == 0)) { if (!bse || (!bsx && !bsy && !bsz)) {
block->advance_rate = 0; block->advance_rate = 0;
block->advance = 0; block->advance = 0;
} }
else { else {
long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st); long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st);
float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) * float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) * (cse * cse * EXTRUSION_AREA * EXTRUSION_AREA) * 256;
(current_speed[E_AXIS] * current_speed[E_AXIS] * EXTRUSION_AREA * EXTRUSION_AREA)*256;
block->advance = advance; block->advance = advance;
if(acc_dist == 0) { block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
block->advance_rate = 0;
}
else {
block->advance_rate = advance / (float)acc_dist;
}
} }
/* /*
SERIAL_ECHO_START; SERIAL_ECHO_START;
...@@ -992,22 +988,22 @@ float junction_deviation = 0.1; ...@@ -992,22 +988,22 @@ float junction_deviation = 0.1;
*/ */
#endif // ADVANCE #endif // ADVANCE
calculate_trapezoid_for_block(block, block->entry_speed/block->nominal_speed, calculate_trapezoid_for_block(block, block->entry_speed / block->nominal_speed, safe_speed / block->nominal_speed);
safe_speed/block->nominal_speed);
// Move buffer head // Move buffer head
block_buffer_head = next_buffer_head; block_buffer_head = next_buffer_head;
// Update position // Update position
memcpy(position, target, sizeof(target)); // position[] = target[] for (int i = 0; i < NUM_AXIS; i++) position[i] = target[i];
planner_recalculate(); planner_recalculate();
st_wake_up(); st_wake_up();
}
} // plan_buffer_line()
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
vector_3 plan_get_position() { vector_3 plan_get_position() {
vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS)); vector_3 position = vector_3(st_get_position_mm(X_AXIS), st_get_position_mm(Y_AXIS), st_get_position_mm(Z_AXIS));
//position.debug("in plan_get position"); //position.debug("in plan_get position");
...@@ -1018,49 +1014,37 @@ vector_3 plan_get_position() { ...@@ -1018,49 +1014,37 @@ vector_3 plan_get_position() {
//position.debug("after rotation"); //position.debug("after rotation");
return position; return position;
} }
#endif // ENABLE_AUTO_BED_LEVELING #endif // ENABLE_AUTO_BED_LEVELING
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
void plan_set_position(float x, float y, float z, const float &e) void plan_set_position(float x, float y, float z, const float &e) {
{
apply_rotation_xyz(plan_bed_level_matrix, x, y, z); apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
#else #else
void plan_set_position(const float &x, const float &y, const float &z, const float &e) void plan_set_position(const float &x, const float &y, const float &z, const float &e) {
{
#endif // ENABLE_AUTO_BED_LEVELING #endif // ENABLE_AUTO_BED_LEVELING
position[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]); float nx = position[X_AXIS] = lround(x * axis_steps_per_unit[X_AXIS]);
position[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]); float ny = position[Y_AXIS] = lround(y * axis_steps_per_unit[Y_AXIS]);
position[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]); float nz = position[Z_AXIS] = lround(z * axis_steps_per_unit[Z_AXIS]);
position[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS + active_extruder]); float ne = position[E_AXIS] = lround(e * axis_steps_per_unit[E_AXIS + active_extruder]);
st_set_position(position[X_AXIS], position[Y_AXIS], position[Z_AXIS], position[E_AXIS]); st_set_position(nx, ny, nz, ne);
previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest. previous_nominal_speed = 0.0; // Resets planner junction speeds. Assumes start from rest.
previous_speed[0] = 0.0;
previous_speed[1] = 0.0;
previous_speed[2] = 0.0;
previous_speed[3] = 0.0;
}
void plan_set_e_position(const float &e) for (int i=0; i<NUM_AXIS; i++) previous_speed[i] = 0.0;
{ }
position[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS + active_extruder]);
st_set_e_position(position[E_AXIS]);
}
uint8_t movesplanned() void plan_set_e_position(const float &e) {
{ position[E_AXIS] = lround(e * axis_steps_per_unit[E_AXIS + active_extruder]);
return (block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1); st_set_e_position(position[E_AXIS]);
} }
#ifdef PREVENT_DANGEROUS_EXTRUDE #ifdef PREVENT_DANGEROUS_EXTRUDE
void set_extrude_min_temp(float temp) { extrude_min_temp = temp; } void set_extrude_min_temp(float temp) { extrude_min_temp = temp; }
#endif #endif
// Calculate the steps/s^2 acceleration rates, based on the mm/s^s // Calculate the steps/s^2 acceleration rates, based on the mm/s^s
void reset_acceleration_rates() void reset_acceleration_rates() {
{ for(int8_t i=0; i < E_AXIS + EXTRUDERS; i++)
for(int8_t i=0; i < 3 + EXTRUDERS; i++) {
axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i]; axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i];
}
} }
...@@ -76,40 +76,34 @@ typedef struct { ...@@ -76,40 +76,34 @@ typedef struct {
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
#ifdef ENABLE_AUTO_BED_LEVELING
// this holds the required transform to compensate for bed level
extern matrix_3x3 plan_bed_level_matrix;
#endif // #ifdef ENABLE_AUTO_BED_LEVELING
// Initialize the motion plan subsystem // Initialize the motion plan subsystem
void plan_init(); void plan_init();
// Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in void check_axes_activity();
// millimaters. Feed rate specifies the speed of the motion.
#ifdef ENABLE_AUTO_BED_LEVELING
void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder, const uint8_t &driver);
// Get the position applying the bed level matrix if enabled // Get the number of buffered moves
vector_3 plan_get_position(); extern volatile unsigned char block_buffer_head;
#else extern volatile unsigned char block_buffer_tail;
void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder, const uint8_t &driver); FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail + BLOCK_BUFFER_SIZE); }
#endif // ENABLE_AUTO_BED_LEVELING
// Set position. Used for G92 instructions.
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
void plan_set_position(float x, float y, float z, const float &e); #include "vector_3.h"
// this holds the required transform to compensate for bed level
extern matrix_3x3 plan_bed_level_matrix;
// Get the position applying the bed level matrix if enabled
vector_3 plan_get_position();
// Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in
// millimeters. Feed rate specifies the speed of the motion.
void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder, const uint8_t &driver);
// Set position. Used for G92 instructions.
void plan_set_position(float x, float y, float z, const float &e);
#else #else
void plan_set_position(const float &x, const float &y, const float &z, const float &e); void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder, const uint8_t &driver);
void plan_set_position(const float &x, const float &y, const float &z, const float &e);
#endif // ENABLE_AUTO_BED_LEVELING #endif // ENABLE_AUTO_BED_LEVELING
void plan_set_e_position(const float &e); void plan_set_e_position(const float &e);
void check_axes_activity();
uint8_t movesplanned(); //return the nr of buffered moves
extern unsigned long minsegmenttime; extern unsigned long minsegmenttime;
extern float max_feedrate[3 + EXTRUDERS]; // set the max speeds extern float max_feedrate[3 + EXTRUDERS]; // set the max speeds
extern float max_retraction_feedrate[EXTRUDERS]; // set the max speeds for retraction extern float max_retraction_feedrate[EXTRUDERS]; // set the max speeds for retraction
...@@ -132,35 +126,33 @@ extern unsigned long axis_steps_per_sqr_second[3 + EXTRUDERS]; ...@@ -132,35 +126,33 @@ extern unsigned long axis_steps_per_sqr_second[3 + EXTRUDERS];
extern float autotemp_factor; extern float autotemp_factor;
#endif #endif
extern block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instfructions extern block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instructions
extern volatile unsigned char block_buffer_head; // Index of the next block to be pushed
extern volatile unsigned char block_buffer_tail; // Returns true if the buffer has a queued block, false otherwise
// Called when the current block is no longer needed. Discards the block and makes the memory FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
// availible for new blocks.
FORCE_INLINE void plan_discard_current_block() // Called when the current block is no longer needed. Discards
{ // the block and makes the memory available for new blocks.
if (block_buffer_head != block_buffer_tail) { FORCE_INLINE void plan_discard_current_block() {
block_buffer_tail = (block_buffer_tail + 1) & (BLOCK_BUFFER_SIZE - 1); if (blocks_queued())
} block_buffer_tail = BLOCK_MOD(block_buffer_tail + 1);
} }
// Gets the current block. Returns NULL if buffer empty // Gets the current block. Returns NULL if buffer empty
FORCE_INLINE block_t *plan_get_current_block() FORCE_INLINE block_t *plan_get_current_block() {
{ if (blocks_queued()) {
if (block_buffer_head == block_buffer_tail) {
return(NULL);
}
block_t *block = &block_buffer[block_buffer_tail]; block_t *block = &block_buffer[block_buffer_tail];
block->busy = true; block->busy = true;
return(block); return block;
}
else
return NULL;
} }
// Returns true if the buffer has a queued block, false otherwise
FORCE_INLINE bool blocks_queued() { return (block_buffer_head != block_buffer_tail); }
#ifdef PREVENT_DANGEROUS_EXTRUDE #ifdef PREVENT_DANGEROUS_EXTRUDE
void set_extrude_min_temp(float temp); void set_extrude_min_temp(float temp);
#endif #endif
void reset_acceleration_rates(); void reset_acceleration_rates();
#endif
#endif //PLANNER_H
...@@ -41,61 +41,24 @@ ...@@ -41,61 +41,24 @@
//================================== macros ================================= //================================== macros =================================
//=========================================================================== //===========================================================================
#if HOTENDS > 4 #ifdef K1 // Defined in Configuration.h in the PID settings
#error Unsupported number of hotends #define K2 (1.0 - K1)
#elif HOTENDS > 3
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3, v4 }
#elif HOTENDS > 2
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2, v3 }
#elif HOTENDS > 1
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1, v2 }
#else
#define ARRAY_BY_HOTENDS(v1, v2, v3, v4) { v1 }
#endif #endif
#define HAS_TEMP_0 (defined(TEMP_0_PIN) && TEMP_0_PIN >= 0)
#define HAS_TEMP_1 (defined(TEMP_1_PIN) && TEMP_1_PIN >= 0)
#define HAS_TEMP_2 (defined(TEMP_2_PIN) && TEMP_2_PIN >= 0)
#define HAS_TEMP_3 (defined(TEMP_3_PIN) && TEMP_3_PIN >= 0)
#define HAS_TEMP_BED (defined(TEMP_BED_PIN) && TEMP_BED_PIN >= 0)
#define HAS_FILAMENT_SENSOR (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0)
#define HAS_POWER_CONSUMPTION_SENSOR (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0)
#define HAS_HEATER_0 (defined(HEATER_0_PIN) && HEATER_0_PIN >= 0)
#define HAS_HEATER_1 (defined(HEATER_1_PIN) && HEATER_1_PIN >= 0)
#define HAS_HEATER_2 (defined(HEATER_2_PIN) && HEATER_2_PIN >= 0)
#define HAS_HEATER_3 (defined(HEATER_3_PIN) && HEATER_3_PIN >= 0)
#define HAS_HEATER_BED (defined(HEATER_BED_PIN) && HEATER_BED_PIN >= 0)
#define HAS_AUTO_FAN_0 (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_1 (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_2 (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN_3 (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN >= 0)
#define HAS_AUTO_FAN HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3
#define HAS_FAN (defined(FAN_PIN) && FAN_PIN >= 0)
//=========================================================================== //===========================================================================
//============================= public variables ============================ //============================= public variables ============================
//=========================================================================== //===========================================================================
// Sampling period of the temperature routine
#ifdef PID_dT
#undef PID_dT
#endif
#define PID_dT ((OVERSAMPLENR * 14.0)/(F_CPU / 64.0 / 256.0))
int target_temperature[HOTENDS] = { 0 }; int target_temperature[HOTENDS] = { 0 };
int target_temperature_bed = 0;
int current_temperature_raw[HOTENDS] = { 0 }; int current_temperature_raw[HOTENDS] = { 0 };
float current_temperature[HOTENDS] = { 0.0 }; float current_temperature[HOTENDS] = { 0.0 };
int target_temperature_bed = 0;
int current_temperature_bed_raw = 0; int current_temperature_bed_raw = 0;
float current_temperature_bed = 0.0; float current_temperature_bed = 0.0;
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
int redundant_temperature_raw = 0; int redundant_temperature_raw = 0;
float redundant_temperature = 0.0; float redundant_temperature = 0.0;
#endif #endif
#ifdef PIDTEMP
float Kp[HOTENDS],Ki[HOTENDS],Kd[HOTENDS];
#endif //PIDTEMP
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
float bedKp=DEFAULT_bedKp; float bedKp=DEFAULT_bedKp;
...@@ -162,11 +125,14 @@ static unsigned char soft_pwm[HOTENDS]; ...@@ -162,11 +125,14 @@ static unsigned char soft_pwm[HOTENDS];
#if HAS_AUTO_FAN #if HAS_AUTO_FAN
static unsigned long extruder_autofan_last_check; static unsigned long extruder_autofan_last_check;
#endif #endif
#ifdef PIDTEMP
float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS];
#endif //PIDTEMP
// Init min and max temp with extreme values to prevent false errors during startup // Init min and max temp with extreme values to prevent false errors during startup
static int minttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP); static int minttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP, HEATER_3_RAW_LO_TEMP);
static int maxttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP); static int maxttemp_raw[HOTENDS] = ARRAY_BY_HOTENDS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP, HEATER_3_RAW_HI_TEMP);
static int minttemp[HOTENDS] = ARRAY_BY_HOTENDS( 0, 0, 0, 0 ); static int minttemp[HOTENDS] = { 0 };
static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS( 16383, 16383, 16383, 16383 ); static int maxttemp[HOTENDS] = ARRAY_BY_HOTENDS( 16383, 16383, 16383, 16383 );
//static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */ //static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */
...@@ -187,8 +153,8 @@ static float analog2tempBed(int raw); ...@@ -187,8 +153,8 @@ static float analog2tempBed(int raw);
static void updateTemperaturesFromRawValues(); static void updateTemperaturesFromRawValues();
#ifdef WATCH_TEMP_PERIOD #ifdef WATCH_TEMP_PERIOD
int watch_start_temp[HOTENDS] = ARRAY_BY_HOTENDS(0,0,0,0); int watch_start_temp[HOTENDS] = { 0 };
unsigned long watchmillis[HOTENDS] = ARRAY_BY_HOTENDS(0,0,0,0); unsigned long watchmillis[HOTENDS] = { 0 };
#endif //WATCH_TEMP_PERIOD #endif //WATCH_TEMP_PERIOD
#ifndef SOFT_PWM_SCALE #ifndef SOFT_PWM_SCALE
...@@ -204,7 +170,7 @@ static void updateTemperaturesFromRawValues(); ...@@ -204,7 +170,7 @@ static void updateTemperaturesFromRawValues();
#endif #endif
//=========================================================================== //===========================================================================
//============================= functions ============================ //============================= Functions ============================
//=========================================================================== //===========================================================================
void PID_autotune(float temp, int hotend, int ncycles) void PID_autotune(float temp, int hotend, int ncycles)
...@@ -367,7 +333,7 @@ void PID_autotune(float temp, int hotend, int ncycles) ...@@ -367,7 +333,7 @@ void PID_autotune(float temp, int hotend, int ncycles)
void updatePID() { void updatePID() {
#ifdef PIDTEMP #ifdef PIDTEMP
for (int e = 0; e < HOTENDS; e++) { for (int e = 0; e < HOTENDS; e++) {
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e]; temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
} }
#endif #endif
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
...@@ -380,32 +346,18 @@ int getHeaterPower(int heater) { ...@@ -380,32 +346,18 @@ int getHeaterPower(int heater) {
} }
#if HAS_AUTO_FAN #if HAS_AUTO_FAN
#if HAS_FAN
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_3_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_3_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#endif
void setExtruderAutoFanState(int pin, bool state) void setExtruderAutoFanState(int pin, bool state)
{ {
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0; unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
// this idiom allows both digital and PWM fan outputs (see M42 handling). // this idiom allows both digital and PWM fan outputs (see M42 handling).
pinMode(pin, OUTPUT); pinMode(pin, OUTPUT);
digitalWrite(pin, newFanSpeed); digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed); analogWrite(pin, newFanSpeed);
} }
void checkExtruderAutoFans() void checkExtruderAutoFans()
{ {
uint8_t fanState = 0; uint8_t fanState = 0;
// which fan pins need to be turned on? // which fan pins need to be turned on?
...@@ -413,7 +365,6 @@ int getHeaterPower(int heater) { ...@@ -413,7 +365,6 @@ int getHeaterPower(int heater) {
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1; fanState |= 1;
#endif #endif
#if HAS_AUTO_FAN_1 #if HAS_AUTO_FAN_1
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{ {
...@@ -424,7 +375,8 @@ int getHeaterPower(int heater) { ...@@ -424,7 +375,8 @@ int getHeaterPower(int heater) {
} }
#endif #endif
#if HAS_AUTO_FAN_2 #if HAS_AUTO_FAN_2
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE) { if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1; fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
...@@ -434,7 +386,8 @@ int getHeaterPower(int heater) { ...@@ -434,7 +386,8 @@ int getHeaterPower(int heater) {
} }
#endif #endif
#if HAS_AUTO_FAN_3 #if HAS_AUTO_FAN_3
if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE) { if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1; fanState |= 1;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN) else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
...@@ -450,7 +403,6 @@ int getHeaterPower(int heater) { ...@@ -450,7 +403,6 @@ int getHeaterPower(int heater) {
#if HAS_AUTO_FAN_0 #if HAS_AUTO_FAN_0
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0); setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif #endif
#if HAS_AUTO_FAN_1 #if HAS_AUTO_FAN_1
if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN) if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0); setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
...@@ -466,50 +418,13 @@ int getHeaterPower(int heater) { ...@@ -466,50 +418,13 @@ int getHeaterPower(int heater) {
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0); setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
#endif #endif
} }
#endif // any extruder auto fan pins set #endif // any extruder auto fan pins set
// //
// Error checking and Write Routines // Temperature Error Handlers
// //
#if HOTENDS > 0
#if !HAS_HEATER_0
#error HEATER_0_PIN not defined for this board
#endif
#define WRITE_HEATER_0P(v) WRITE(HEATER_0_PIN, v)
#endif
#if HOTENDS > 1 || defined(HEATERS_PARALLEL)
#if !HAS_HEATER_1
#error HEATER_1_PIN not defined for this board
#endif
#define WRITE_HEATER_1(v) WRITE(HEATER_1_PIN, v)
#if HOTENDS > 2
#if !HAS_HEATER_2
#error HEATER_2_PIN not defined for this board
#endif
#define WRITE_HEATER_2(v) WRITE(HEATER_2_PIN, v)
#if HOTENDS > 3
#if !HAS_HEATER_3
#error HEATER_3_PIN not defined for this board
#endif
#define WRITE_HEATER_3(v) WRITE(HEATER_3_PIN, v)
#endif
#endif
#endif
#ifdef HEATERS_PARALLEL
#define WRITE_HEATER_0(v) { WRITE_HEATER_0P(v); WRITE_HEATER_1(v); }
#else
#define WRITE_HEATER_0(v) WRITE_HEATER_0P(v)
#endif
#if HAS_HEATER_BED
#define WRITE_HEATER_BED(v) WRITE(HEATER_BED_PIN, v)
#endif
#if HAS_FAN
#define WRITE_FAN(v) WRITE(FAN_PIN, v)
#endif
inline void _temp_error(int e, const char *msg1, const char *msg2) { inline void _temp_error(int e, const char *msg1, const char *msg2) {
if (!IsStopped()) { if (!IsStopped()) {
SERIAL_ERROR_START; SERIAL_ERROR_START;
...@@ -540,34 +455,11 @@ void bed_max_temp_error(void) { ...@@ -540,34 +455,11 @@ void bed_max_temp_error(void) {
_temp_error(-1, PSTR(MSG_MAXTEMP_BED_OFF), PSTR(MSG_ERR_MAXTEMP_BED)); _temp_error(-1, PSTR(MSG_MAXTEMP_BED_OFF), PSTR(MSG_ERR_MAXTEMP_BED));
} }
void manage_heater() { float get_pid_output(int e) {
float pid_output;
if (!temp_meas_ready) return;
float pid_input, pid_output;
updateTemperaturesFromRawValues();
#ifdef HEATER_0_USES_MAX6675
float ct = current_temperature[0];
if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0);
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#endif //HEATER_0_USES_MAX6675
unsigned long ms = millis();
// Loop through all hotends
for (int e = 0; e < HOTENDS; e++)
{
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
#endif
#ifdef PIDTEMP #ifdef PIDTEMP
pid_input = current_temperature[e];
#ifndef PID_OPENLOOP #ifndef PID_OPENLOOP
pid_error[e] = target_temperature[e] - pid_input; pid_error[e] = target_temperature[e] - current_temperature[e];
if (pid_error[e] > PID_FUNCTIONAL_RANGE) { if (pid_error[e] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX; pid_output = BANG_MAX;
pid_reset[e] = true; pid_reset[e] = true;
...@@ -577,18 +469,16 @@ void manage_heater() { ...@@ -577,18 +469,16 @@ void manage_heater() {
pid_reset[e] = true; pid_reset[e] = true;
} }
else { else {
if (pid_reset[e] == true) { if (pid_reset[e]) {
temp_iState[e] = 0.0; temp_iState[e] = 0.0;
pid_reset[e] = false; pid_reset[e] = false;
} }
pTerm[e] = Kp[e] * pid_error[e]; pTerm[e] = PID_PARAM(Kp,e) * pid_error[e];
temp_iState[e] += pid_error[e]; temp_iState[e] += pid_error[e];
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
iTerm[e] = Ki[e] * temp_iState[e]; iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
//K1 defined in Configuration.h in the PID settings dTerm[e] = K2 * PID_PARAM(Kd,e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e];
#define K2 (1.0-K1)
dTerm[e] = (Kd[e] * (pid_input - temp_dState[e])) * K2 + (K1 * dTerm[e]);
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; pid_output = pTerm[e] + iTerm[e] - dTerm[e];
if (pid_output > PID_MAX) { if (pid_output > PID_MAX) {
if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
...@@ -599,7 +489,7 @@ void manage_heater() { ...@@ -599,7 +489,7 @@ void manage_heater() {
pid_output = 0; pid_output = 0;
} }
} }
temp_dState[e] = pid_input; temp_dState[e] = current_temperature[e];
#else #else
pid_output = constrain(target_temperature[e], 0, PID_MAX); pid_output = constrain(target_temperature[e], 0, PID_MAX);
#endif //PID_OPENLOOP #endif //PID_OPENLOOP
...@@ -609,7 +499,7 @@ void manage_heater() { ...@@ -609,7 +499,7 @@ void manage_heater() {
SERIAL_ECHO(MSG_PID_DEBUG); SERIAL_ECHO(MSG_PID_DEBUG);
SERIAL_ECHO(e); SERIAL_ECHO(e);
SERIAL_ECHO(MSG_PID_DEBUG_INPUT); SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
SERIAL_ECHO(pid_input); SERIAL_ECHO(current_temperature[e]);
SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT); SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
SERIAL_ECHO(pid_output); SERIAL_ECHO(pid_output);
SERIAL_ECHO(MSG_PID_DEBUG_PTERM); SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
...@@ -621,10 +511,73 @@ void manage_heater() { ...@@ -621,10 +511,73 @@ void manage_heater() {
#endif //PID_DEBUG #endif //PID_DEBUG
#else /* PID off */ #else /* PID off */
pid_output = (current_temperature[e] < target_temperature[e]) ? PID_MAX : 0;
#endif
return pid_output;
}
#ifdef PIDTEMPBED
float get_pid_output_bed() {
float pid_output;
#ifndef PID_OPENLOOP
pid_error_bed = target_temperature_bed - current_temperature_bed;
pTerm_bed = bedKp * pid_error_bed;
temp_iState_bed += pid_error_bed;
temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
iTerm_bed = bedKi * temp_iState_bed;
dTerm_bed = K2 * bedKd * (current_temperature_bed - temp_dState_bed) + K1 * dTerm_bed;
temp_dState_bed = current_temperature_bed;
pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
if (pid_output > MAX_BED_POWER) {
if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output = MAX_BED_POWER;
}
else if (pid_output < 0) {
if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output = 0; pid_output = 0;
if (current_temperature[e] < target_temperature[e]) pid_output = PID_MAX; }
#endif //PIDTEMP #else
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#endif // PID_OPENLOOP
#ifdef PID_BED_DEBUG
SERIAL_ECHO_START;
SERIAL_ECHO(" PID_BED_DEBUG ");
SERIAL_ECHO(": Input ");
SERIAL_ECHO(current_temperature_bed);
SERIAL_ECHO(" Output ");
SERIAL_ECHO(pid_output);
SERIAL_ECHO(" pTerm ");
SERIAL_ECHO(pTerm_bed);
SERIAL_ECHO(" iTerm ");
SERIAL_ECHO(iTerm_bed);
SERIAL_ECHO(" dTerm ");
SERIAL_ECHOLN(dTerm_bed);
#endif //PID_BED_DEBUG
return pid_output;
}
#endif
void manage_heater() {
if (!temp_meas_ready) return;
updateTemperaturesFromRawValues();
unsigned long ms = millis();
// Loop through all hotends
for (int e = 0; e < HOTENDS; e++) {
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
#endif
float pid_output = get_pid_output(e);
// Check if temperature is within the correct range // Check if temperature is within the correct range
soft_pwm[e] = current_temperature[e] > minttemp[e] && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0; soft_pwm[e] = current_temperature[e] > minttemp[e] && current_temperature[e] < maxttemp[e] ? (int)pid_output >> 1 : 0;
...@@ -649,6 +602,7 @@ void manage_heater() { ...@@ -649,6 +602,7 @@ void manage_heater() {
_temp_error(-1, MSG_EXTRUDER_SWITCHED_OFF, MSG_ERR_REDUNDANT_TEMP); _temp_error(-1, MSG_EXTRUDER_SWITCHED_OFF, MSG_ERR_REDUNDANT_TEMP);
} }
#endif //TEMP_SENSOR_1_AS_REDUNDANT #endif //TEMP_SENSOR_1_AS_REDUNDANT
} // Hotends Loop } // Hotends Loop
#if HAS_AUTO_FAN #if HAS_AUTO_FAN
...@@ -670,48 +624,7 @@ void manage_heater() { ...@@ -670,48 +624,7 @@ void manage_heater() {
#endif #endif
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
pid_input = current_temperature_bed; float pid_output = get_pid_output_bed();
#ifndef PID_OPENLOOP
pid_error_bed = target_temperature_bed - pid_input;
pTerm_bed = bedKp * pid_error_bed;
temp_iState_bed += pid_error_bed;
temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
iTerm_bed = bedKi * temp_iState_bed;
//K1 defined in Configuration.h in the PID settings
#define K2 (1.0-K1)
dTerm_bed = (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
temp_dState_bed = pid_input;
pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
if (pid_output > MAX_BED_POWER) {
if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output = MAX_BED_POWER;
}
else if (pid_output < 0) {
if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output = 0;
}
#else
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#endif //PID_OPENLOOP
#ifdef PID_BED_DEBUG
SERIAL_ECHO_START;
SERIAL_ECHO(" PID_BED_DEBUG ");
SERIAL_ECHO(": Input ");
SERIAL_ECHO(pid_input);
SERIAL_ECHO(" Output ");
SERIAL_ECHO(pid_output);
SERIAL_ECHO(" pTerm ");
SERIAL_ECHO(pTerm_bed);
SERIAL_ECHO(" iTerm ");
SERIAL_ECHO(iTerm_bed);
SERIAL_ECHO(" dTerm ");
SERIAL_ECHOLN(dTerm_bed);
#endif //PID_BED_DEBUG
soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0; soft_pwm_bed = current_temperature_bed > BED_MINTEMP && current_temperature_bed < BED_MAXTEMP ? (int)pid_output >> 1 : 0;
...@@ -759,11 +672,11 @@ void manage_heater() { ...@@ -759,11 +672,11 @@ void manage_heater() {
// Derived from RepRap FiveD extruder::getTemperature() // Derived from RepRap FiveD extruder::getTemperature()
// For hot end temperature measurement. // For hot end temperature measurement.
static float analog2temp(int raw, uint8_t e) { static float analog2temp(int raw, uint8_t e) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (e > EXTRUDERS) if (e > EXTRUDERS)
#else #else
if (e >= EXTRUDERS) if (e >= EXTRUDERS)
#endif #endif
{ {
SERIAL_ERROR_START; SERIAL_ERROR_START;
SERIAL_ERROR((int)e); SERIAL_ERROR((int)e);
...@@ -801,7 +714,7 @@ static float analog2temp(int raw, uint8_t e) { ...@@ -801,7 +714,7 @@ static float analog2temp(int raw, uint8_t e) {
return celsius; return celsius;
} }
return ((raw * ((5.0 * 100) / 1024) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET; return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
} }
// Derived from RepRap FiveD extruder::getTemperature() // Derived from RepRap FiveD extruder::getTemperature()
...@@ -828,7 +741,7 @@ static float analog2tempBed(int raw) { ...@@ -828,7 +741,7 @@ static float analog2tempBed(int raw) {
return celsius; return celsius;
#elif defined BED_USES_AD595 #elif defined BED_USES_AD595
return ((raw * ((5.0 * 100) / 1024) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET; return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#else //NO BED_USES_THERMISTOR #else //NO BED_USES_THERMISTOR
return 0; return 0;
#endif //BED_USES_THERMISTOR #endif //BED_USES_THERMISTOR
...@@ -840,9 +753,7 @@ static void updateTemperaturesFromRawValues() { ...@@ -840,9 +753,7 @@ static void updateTemperaturesFromRawValues() {
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
current_temperature_raw[0] = read_max6675(); current_temperature_raw[0] = read_max6675();
#endif #endif
for (int e = 0; e < HOTENDS; e++) {
for (int e = 0; e < HOTENDS; e++)
{
current_temperature[e] = analog2temp(current_temperature_raw[e], e); current_temperature[e] = analog2temp(current_temperature_raw[e], e);
} }
current_temperature_bed = analog2tempBed(current_temperature_bed_raw); current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
...@@ -856,10 +767,10 @@ static void updateTemperaturesFromRawValues() { ...@@ -856,10 +767,10 @@ static void updateTemperaturesFromRawValues() {
static float watt_overflow = 0.0; static float watt_overflow = 0.0;
static unsigned long last_power_update = millis(); static unsigned long last_power_update = millis();
unsigned long temp_last_power_update = millis(); unsigned long temp_last_power_update = millis();
float power_temp = analog2power(); power_consumption_meas = analog2power();
power_consumption_meas = (unsigned int)power_temp; //MYSERIAL.println(analog2current(),3);
watt_overflow += (power_temp*(temp_last_power_update-last_power_update))/3600000.0; watt_overflow += (power_consumption_meas * (temp_last_power_update - last_power_update)) / 3600000.0;
if(watt_overflow >= 1.0) { if (watt_overflow >= 1.0) {
power_consumption_hour++; power_consumption_hour++;
watt_overflow--; watt_overflow--;
} }
...@@ -875,9 +786,10 @@ static void updateTemperaturesFromRawValues() { ...@@ -875,9 +786,10 @@ static void updateTemperaturesFromRawValues() {
#if HAS_FILAMENT_SENSOR #if HAS_FILAMENT_SENSOR
// Convert raw Filament Width to millimeters // Convert raw Filament Width to millimeters
float analog2widthFil() { float analog2widthFil() {
return current_raw_filwidth / (1024 * OVERSAMPLENR) * 5.0; return current_raw_filwidth / (1023 * OVERSAMPLENR) * 5.0;
//return current_raw_filwidth; //return current_raw_filwidth;
} }
...@@ -893,8 +805,13 @@ static void updateTemperaturesFromRawValues() { ...@@ -893,8 +805,13 @@ static void updateTemperaturesFromRawValues() {
#if HAS_POWER_CONSUMPTION_SENSOR #if HAS_POWER_CONSUMPTION_SENSOR
// Convert raw Power Consumption to watt // Convert raw Power Consumption to watt
float analog2current() {
float temp = (((5.0 * current_raw_powconsumption) / (1023 * OVERSAMPLENR)) - POWER_ZERO) / POWER_SENSITIVITY;
temp = ((100 - POWER_ERROR) / 100) * (temp + (temp / 100)) - POWER_OFFSET;
return temp > 0 ? temp : 0;
}
float analog2power() { float analog2power() {
return (((((5.0 * current_raw_powconsumption) / (1024.0 * OVERSAMPLENR)) - POWER_ZERO) * (POWER_VOLTAGE * 100.0)) / (POWER_SENSITIVITY * POWER_EFFICIENCY)); return (analog2current() * POWER_VOLTAGE * 100) / POWER_EFFICIENCY;
} }
#endif #endif
...@@ -907,13 +824,12 @@ void tp_init() ...@@ -907,13 +824,12 @@ void tp_init()
#endif #endif
// Finish init of mult hotends arrays // Finish init of mult hotends arrays
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++) {
{
// populate with the first value // populate with the first value
maxttemp[e] = maxttemp[0]; maxttemp[e] = maxttemp[0];
#ifdef PIDTEMP #ifdef PIDTEMP
temp_iState_min[e] = 0.0; temp_iState_min[e] = 0.0;
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e]; temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
#endif //PIDTEMP #endif //PIDTEMP
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
temp_iState_min_bed = 0.0; temp_iState_min_bed = 0.0;
...@@ -955,7 +871,7 @@ void tp_init() ...@@ -955,7 +871,7 @@ void tp_init()
#else #else
pinMode(SS_PIN, OUTPUT); pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH); digitalWrite(SS_PIN, HIGH);
#endif //SDSUPPORT #endif
OUT_WRITE(MAX6675_SS,HIGH); OUT_WRITE(MAX6675_SS,HIGH);
...@@ -1077,14 +993,13 @@ void tp_init() ...@@ -1077,14 +993,13 @@ void tp_init()
void setWatch() { void setWatch() {
#ifdef WATCH_TEMP_PERIOD #ifdef WATCH_TEMP_PERIOD
unsigned long ms = millis(); unsigned long ms = millis();
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++) {
{
if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) { if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) {
watch_start_temp[e] = degHotend(e); watch_start_temp[e] = degHotend(e);
watchmillis[e] = ms; watchmillis[e] = ms;
} }
} }
#endif //WATCH_TEMP_PERIOD #endif
} }
#if defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 #if defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
...@@ -1153,31 +1068,31 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat ...@@ -1153,31 +1068,31 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
void disable_heater() { void disable_heater() {
for (int e = 0; e < HOTENDS; e++) for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i);
setTargetHotend(0, e);
setTargetBed(0); setTargetBed(0);
#define DISABLE_HEATER(NR) { \
target_temperature[NR] = 0; \
soft_pwm[NR] = 0; \
WRITE_HEATER_ ## NR (LOW); \
}
#if HAS_TEMP_0 #if HAS_TEMP_0
target_temperature[0] = 0; target_temperature[0] = 0;
soft_pwm[0] = 0; soft_pwm[0] = 0;
WRITE_HEATER_0P(LOW); // If HEATERS_PARALLEL should apply, change to WRITE_HEATER_0 WRITE_HEATER_0P(LOW); // Should HEATERS_PARALLEL apply here? Then change to DISABLE_HEATER(0)
#endif #endif
#if HOTENDS > 1 && HAS_TEMP_1 #if HOTENDS > 1 && HAS_TEMP_1
target_temperature[1] = 0; DISABLE_HEATER(1);
soft_pwm[1] = 0;
WRITE_HEATER_1(LOW);
#endif #endif
#if HOTENDS > 2 && HAS_TEMP_2 #if HOTENDS > 2 && HAS_TEMP_2
target_temperature[2] = 0; DISABLE_HEATER(2);
soft_pwm[2] = 0;
WRITE_HEATER_2(LOW);
#endif #endif
#if HOTENDS > 3 && HAS_TEMP_3 #if HOTENDS > 3 && HAS_TEMP_3
target_temperature[3] = 0; DISABLE_HEATER(3);
soft_pwm[3] = 0;
WRITE_HEATER_3(LOW);
#endif #endif
#if HAS_TEMP_BED #if HAS_TEMP_BED
...@@ -1242,9 +1157,12 @@ void disable_heater() { ...@@ -1242,9 +1157,12 @@ void disable_heater() {
return max6675_temp; return max6675_temp;
} }
#endif //HEATER_0_USES_MAX6675 #endif //HEATER_0_USES_MAX6675
//Stages in the ISR loop /**
* Stages in the ISR loop
*/
enum TempState { enum TempState {
PrepareTemp_0, PrepareTemp_0,
MeasureTemp_0, MeasureTemp_0,
...@@ -1263,11 +1181,19 @@ enum TempState { ...@@ -1263,11 +1181,19 @@ enum TempState {
StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle
}; };
//
// Timer 0 is shared with millies // Timer 0 is shared with millies
//
ISR(TIMER0_COMPB_vect) { ISR(TIMER0_COMPB_vect) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
#define TEMP_SENSOR_COUNT 2
#else
#define TEMP_SENSOR_COUNT HOTENDS
#endif
//these variables are only accessible from the ISR, but static, so they don't lose their value //these variables are only accessible from the ISR, but static, so they don't lose their value
static unsigned char temp_count = 0; static unsigned char temp_count = 0;
static unsigned long raw_temp_value[HOTENDS] = { 0 }; static unsigned long raw_temp_value[TEMP_SENSOR_COUNT] = { 0 };
static unsigned long raw_temp_bed_value = 0; static unsigned long raw_temp_bed_value = 0;
static TempState temp_state = StartupDelay; static TempState temp_state = StartupDelay;
static unsigned char pwm_count = BIT(SOFT_PWM_SCALE); static unsigned char pwm_count = BIT(SOFT_PWM_SCALE);
...@@ -1342,7 +1268,6 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1342,7 +1268,6 @@ ISR(TIMER0_COMPB_vect) {
} }
if (soft_pwm_0 < pwm_count) { WRITE_HEATER_0(0); } if (soft_pwm_0 < pwm_count) { WRITE_HEATER_0(0); }
#if HOTENDS > 1 #if HOTENDS > 1
if (soft_pwm_1 < pwm_count) WRITE_HEATER_1(0); if (soft_pwm_1 < pwm_count) WRITE_HEATER_1(0);
#if HOTENDS > 2 #if HOTENDS > 2
...@@ -1492,6 +1417,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1492,6 +1417,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
temp_state = PrepareTemp_BED; temp_state = PrepareTemp_BED;
break; break;
case PrepareTemp_BED: case PrepareTemp_BED:
#if HAS_TEMP_BED #if HAS_TEMP_BED
START_ADC(TEMP_BED_PIN); START_ADC(TEMP_BED_PIN);
...@@ -1505,6 +1431,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1505,6 +1431,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
temp_state = PrepareTemp_1; temp_state = PrepareTemp_1;
break; break;
case PrepareTemp_1: case PrepareTemp_1:
#if HAS_TEMP_1 #if HAS_TEMP_1
START_ADC(TEMP_1_PIN); START_ADC(TEMP_1_PIN);
...@@ -1518,6 +1445,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1518,6 +1445,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
temp_state = PrepareTemp_2; temp_state = PrepareTemp_2;
break; break;
case PrepareTemp_2: case PrepareTemp_2:
#if HAS_TEMP_2 #if HAS_TEMP_2
START_ADC(TEMP_2_PIN); START_ADC(TEMP_2_PIN);
...@@ -1531,6 +1459,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1531,6 +1459,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
temp_state = PrepareTemp_3; temp_state = PrepareTemp_3;
break; break;
case PrepareTemp_3: case PrepareTemp_3:
#if HAS_TEMP_3 #if HAS_TEMP_3
START_ADC(TEMP_3_PIN); START_ADC(TEMP_3_PIN);
...@@ -1544,6 +1473,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1544,6 +1473,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
temp_state = Prepare_FILWIDTH; temp_state = Prepare_FILWIDTH;
break; break;
case Prepare_FILWIDTH: case Prepare_FILWIDTH:
#if HAS_FILAMENT_SENSOR #if HAS_FILAMENT_SENSOR
START_ADC(FILWIDTH_PIN); START_ADC(FILWIDTH_PIN);
...@@ -1561,6 +1491,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1561,6 +1491,7 @@ ISR(TIMER0_COMPB_vect) {
#endif #endif
temp_state = Prepare_POWCONSUMPTION; temp_state = Prepare_POWCONSUMPTION;
break; break;
case Prepare_POWCONSUMPTION: case Prepare_POWCONSUMPTION:
#if HAS_POWER_CONSUMPTION_SENSOR #if HAS_POWER_CONSUMPTION_SENSOR
START_ADC(POWER_CONSUMPTION_PIN); START_ADC(POWER_CONSUMPTION_PIN);
...@@ -1570,13 +1501,12 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1570,13 +1501,12 @@ ISR(TIMER0_COMPB_vect) {
break; break;
case Measure_POWCONSUMPTION: case Measure_POWCONSUMPTION:
#if HAS_POWER_CONSUMPTION_SENSOR #if HAS_POWER_CONSUMPTION_SENSOR
// raw_powconsumption_value += ADC; //remove to use an IIR filter approach raw_powconsumption_value += ADC;
raw_powconsumption_value -= (raw_powconsumption_value>>7); //multiply raw_powconsumption_value by 127/128
raw_powconsumption_value += ((unsigned long)((ADC < (POWER_ZERO*1024)/5.0) ? (1024 - ADC) : (ADC))<<7); //add new ADC reading
#endif #endif
temp_state = PrepareTemp_0; temp_state = PrepareTemp_0;
temp_count++; temp_count++;
break; break;
case StartupDelay: case StartupDelay:
temp_state = PrepareTemp_0; temp_state = PrepareTemp_0;
break; break;
...@@ -1587,7 +1517,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1587,7 +1517,7 @@ ISR(TIMER0_COMPB_vect) {
// break; // break;
} // switch(temp_state) } // switch(temp_state)
if (temp_count >= OVERSAMPLENR) { // 12 * 16 * 1/(16000000/64/256) = 164ms. if (temp_count >= OVERSAMPLENR) { // 14 * 16 * 1/(16000000/64/256) = 229ms.
if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading. if (!temp_meas_ready) { //Only update the raw values if they have been read. Else we could be updating them during reading.
#ifndef HEATER_0_USES_MAX6675 #ifndef HEATER_0_USES_MAX6675
current_temperature_raw[0] = raw_temp_value[0]; current_temperature_raw[0] = raw_temp_value[0];
...@@ -1605,59 +1535,70 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1605,59 +1535,70 @@ ISR(TIMER0_COMPB_vect) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature_raw = raw_temp_value[1]; redundant_temperature_raw = raw_temp_value[1];
#endif #endif
#if HAS_POWER_CONSUMPTION_SENSOR
float power_zero_raw = (POWER_ZERO * 1023 * OVERSAMPLENR) / 5.0;
current_raw_powconsumption = (raw_powconsumption_value < power_zero_raw) ? (2 * power_zero_raw - raw_powconsumption_value) : (raw_powconsumption_value);
#endif
current_temperature_bed_raw = raw_temp_bed_value; current_temperature_bed_raw = raw_temp_bed_value;
} //!temp_meas_ready } //!temp_meas_ready
// Filament Sensor - can be read any time since IIR filtering is used // Filament Sensor - can be read any time since IIR filtering is used
#if HAS_FILAMENT_SENSOR #if HAS_FILAMENT_SENSOR
current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach current_raw_filwidth = raw_filwidth_value >> 10; // Divide to get to 0-16368 range since we used 1/128 IIR filter approach
#endif #endif
temp_meas_ready = true; temp_meas_ready = true;
temp_count = 0; temp_count = 0;
for (int i = 0; i < HOTENDS; i++) raw_temp_value[i] = 0; for (int i = 0; i < TEMP_SENSOR_COUNT; i++) raw_temp_value[i] = 0;
raw_temp_bed_value = 0; raw_temp_bed_value = 0;
#if HAS_POWER_CONSUMPTION_SENSOR
raw_powconsumption_value = 0;
#endif
#ifdef HEATER_0_USES_MAX6675
float ct = current_temperature[0];
if (ct > min(HEATER_0_MAXTEMP, 1023)) max_temp_error(0);
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#else
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
#define GE0 <= #define GE0 <=
#define LE0 >=
#else #else
#define GE0 >= #define GE0 >=
#define LE0 <=
#endif #endif
if (current_temperature_raw[0] GE0 maxttemp_raw[0]) max_temp_error(0); if (current_temperature_raw[0] GE0 maxttemp_raw[0]) max_temp_error(0);
if (current_temperature_raw[0] LE0 minttemp_raw[0]) min_temp_error(0); if (minttemp_raw[0] GE0 current_temperature_raw[0]) min_temp_error(0);
#endif
#if HOTENDS > 1 #if HOTENDS > 1
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
#define GE1 <= #define GE1 <=
#define LE1 >=
#else #else
#define GE1 >= #define GE1 >=
#define LE1 <=
#endif #endif
if (current_temperature_raw[1] GE1 maxttemp_raw[1]) max_temp_error(1); if (current_temperature_raw[1] GE1 maxttemp_raw[1]) max_temp_error(1);
if (current_temperature_raw[1] LE1 minttemp_raw[1]) min_temp_error(1); if (minttemp_raw[1] GE0 current_temperature_raw[1]) min_temp_error(1);
#if HOTENDS > 2 #if HOTENDS > 2
#if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
#define GE2 <= #define GE2 <=
#define LE2 >=
#else #else
#define GE2 >= #define GE2 >=
#define LE2 <=
#endif #endif
if (current_temperature_raw[2] GE2 maxttemp_raw[2]) max_temp_error(2); if (current_temperature_raw[2] GE2 maxttemp_raw[2]) max_temp_error(2);
if (current_temperature_raw[2] LE2 minttemp_raw[2]) min_temp_error(2); if (minttemp_raw[2] GE0 current_temperature_raw[2]) min_temp_error(2);
#if HOTENDS > 3 #if HOTENDS > 3
#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP #if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
#define GE3 <= #define GE3 <=
#define LE3 >=
#else #else
#define GE3 >= #define GE3 >=
#define LE3 <=
#endif #endif
if (current_temperature_raw[3] GE3 maxttemp_raw[3]) max_temp_error(3); if (current_temperature_raw[3] GE3 maxttemp_raw[3]) max_temp_error(3);
if (current_temperature_raw[3] LE3 minttemp_raw[3]) min_temp_error(3); if (minttemp_raw[3] GE0 current_temperature_raw[3]) min_temp_error(3);
#endif // HOTENDS > 3 #endif // HOTENDS > 3
#endif // HOTENDS > 2 #endif // HOTENDS > 2
#endif // HOTENDS > 1 #endif // HOTENDS > 1
...@@ -1665,16 +1606,15 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1665,16 +1606,15 @@ ISR(TIMER0_COMPB_vect) {
#if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0) #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
#if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP #if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
#define GEBED <= #define GEBED <=
#define LEBED >=
#else #else
#define GEBED >= #define GEBED >=
#define LEBED <=
#endif #endif
if (current_temperature_bed_raw GEBED bed_maxttemp_raw) { if (current_temperature_bed_raw GEBED bed_maxttemp_raw) {
target_temperature_bed = 0; target_temperature_bed = 0;
bed_max_temp_error(); bed_max_temp_error();
} }
#endif #endif
} // temp_count >= OVERSAMPLENR } // temp_count >= OVERSAMPLENR
#ifdef BABYSTEPPING #ifdef BABYSTEPPING
......
...@@ -40,6 +40,7 @@ void manage_heater(); //it is critical that this is called periodically. ...@@ -40,6 +40,7 @@ void manage_heater(); //it is critical that this is called periodically.
#if (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) #if (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0)
// For converting raw Power Consumption to watt // For converting raw Power Consumption to watt
float analog2current();
float analog2power(); float analog2power();
#endif #endif
...@@ -63,7 +64,8 @@ extern float current_temperature_bed; ...@@ -63,7 +64,8 @@ extern float current_temperature_bed;
#endif #endif
#ifdef PIDTEMP #ifdef PIDTEMP
extern float Kp[HOTENDS],Ki[HOTENDS],Kd[HOTENDS]; extern float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS];
#define PID_PARAM(param,e) param[e] // use macro to point to array value
float scalePID_i(float i); float scalePID_i(float i);
float scalePID_d(float d); float scalePID_d(float d);
float unscalePID_i(float i); float unscalePID_i(float i);
...@@ -93,7 +95,7 @@ FORCE_INLINE float degBed() { return current_temperature_bed; } ...@@ -93,7 +95,7 @@ FORCE_INLINE float degBed() { return current_temperature_bed; }
#ifdef SHOW_TEMP_ADC_VALUES #ifdef SHOW_TEMP_ADC_VALUES
FORCE_INLINE float rawHotendTemp(uint8_t hotend) { return current_temperature_raw[HOTEND_ARG]; } FORCE_INLINE float rawHotendTemp(uint8_t hotend) { return current_temperature_raw[HOTEND_ARG]; }
FORCE_INLINE float rawBedTemp() { return current_temperature_bed_raw; } FORCE_INLINE float rawBedTemp() { return current_temperature_bed_raw; }
#endif //SHOW_TEMP_ADC_VALUES #endif
FORCE_INLINE float degTargetHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG]; } FORCE_INLINE float degTargetHotend(uint8_t hotend) { return target_temperature[HOTEND_ARG]; }
......
...@@ -51,14 +51,13 @@ uint8_t lcd_status_message_level; ...@@ -51,14 +51,13 @@ uint8_t lcd_status_message_level;
char lcd_status_message[LCD_WIDTH+1] = WELCOME_MSG; char lcd_status_message[LCD_WIDTH+1] = WELCOME_MSG;
#ifdef DOGLCD #ifdef DOGLCD
#include "dogm_lcd_implementation.h" #include "dogm_lcd_implementation.h"
#define LCD u8g
#else #else
#include "ultralcd_implementation_hitachi_HD44780.h" #include "ultralcd_implementation_hitachi_HD44780.h"
#define LCD lcd
#endif #endif
void copy_and_scalePID_i();
void copy_and_scalePID_d();
/* Different menus */ /* Different menus */
static void lcd_status_screen(); static void lcd_status_screen();
#ifdef ULTIPANEL #ifdef ULTIPANEL
...@@ -215,7 +214,7 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l ...@@ -215,7 +214,7 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l
#define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args) #define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
#endif //!ENCODER_RATE_MULTIPLIER #endif //!ENCODER_RATE_MULTIPLIER
#define END_MENU() \ #define END_MENU() \
if (encoderLine >= _menuItemNr) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM;\ if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; }\
if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \ if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - LCD_HEIGHT + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
} } while(0) } } while(0)
...@@ -275,17 +274,17 @@ static void lcd_status_screen() ...@@ -275,17 +274,17 @@ static void lcd_status_screen()
encoderRateMultiplierEnabled = false; encoderRateMultiplierEnabled = false;
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
uint16_t mil = millis(); uint16_t mil = millis();
#ifndef PROGRESS_BAR_MSG_ONCE #ifndef PROGRESS_MSG_ONCE
if (mil > progressBarTick + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME) { if (mil > progressBarTick + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME) {
progressBarTick = mil; progressBarTick = mil;
} }
#endif #endif
#if PROGRESS_BAR_MSG_EXPIRE > 0 #if PROGRESS_MSG_EXPIRE > 0
// keep the message alive if paused, count down otherwise // keep the message alive if paused, count down otherwise
if (messageTick > 0) { if (messageTick > 0) {
if (card.isFileOpen()) { if (card.isFileOpen()) {
if (IS_SD_PRINTING) { if (IS_SD_PRINTING) {
if ((mil-messageTick) >= PROGRESS_BAR_MSG_EXPIRE) { if ((mil-messageTick) >= PROGRESS_MSG_EXPIRE) {
lcd_status_message[0] = '\0'; lcd_status_message[0] = '\0';
messageTick = 0; messageTick = 0;
} }
...@@ -311,10 +310,15 @@ static void lcd_status_screen() ...@@ -311,10 +310,15 @@ static void lcd_status_screen()
lcd_status_update_delay = 10; /* redraw the main screen every second. This is easier then trying keep track of all things that change on the screen */ lcd_status_update_delay = 10; /* redraw the main screen every second. This is easier then trying keep track of all things that change on the screen */
} }
#if defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && (FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) || defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && (POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY) #if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) || (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY)
if (millis() > message_millis + 15000) message_millis = millis(); #if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) && (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY)
if (millis() > message_millis + 15000)
#else #else
if (millis() > message_millis + 10000) message_millis = millis(); if (millis() > message_millis + 10000)
#endif
{
message_millis = millis();
}
#endif #endif
#ifdef ULTIPANEL #ifdef ULTIPANEL
...@@ -690,11 +694,11 @@ void config_lcd_level_bed() ...@@ -690,11 +694,11 @@ void config_lcd_level_bed()
void lcd_level_bed() void lcd_level_bed()
{ {
if(ChangeScreen) { if(ChangeScreen) {
lcd.clear(); lcd_implementation_clear;
switch(pageShowInfo) { switch(pageShowInfo) {
case 0: case 0:
{ {
lcd.setCursor(0, 1); LCD.setCursor(0, 1);
lcd_printPGM(PSTR(MSG_LP_INTRO)); lcd_printPGM(PSTR(MSG_LP_INTRO));
currentMenu = lcd_level_bed; currentMenu = lcd_level_bed;
ChangeScreen=false; ChangeScreen=false;
...@@ -702,7 +706,7 @@ void lcd_level_bed() ...@@ -702,7 +706,7 @@ void lcd_level_bed()
break; break;
case 1: case 1:
{ {
lcd.setCursor(0, 1); LCD.setCursor(0, 1);
lcd_printPGM(PSTR(MSG_LP_1)); lcd_printPGM(PSTR(MSG_LP_1));
currentMenu = lcd_level_bed; currentMenu = lcd_level_bed;
ChangeScreen=false; ChangeScreen=false;
...@@ -710,7 +714,7 @@ void lcd_level_bed() ...@@ -710,7 +714,7 @@ void lcd_level_bed()
break; break;
case 2: case 2:
{ {
lcd.setCursor(0, 1); LCD.setCursor(0, 1);
lcd_printPGM(PSTR(MSG_LP_2)); lcd_printPGM(PSTR(MSG_LP_2));
currentMenu = lcd_level_bed; currentMenu = lcd_level_bed;
ChangeScreen=false; ChangeScreen=false;
...@@ -718,7 +722,7 @@ void lcd_level_bed() ...@@ -718,7 +722,7 @@ void lcd_level_bed()
break; break;
case 3: case 3:
{ {
lcd.setCursor(0, 1); LCD.setCursor(0, 1);
lcd_printPGM(PSTR(MSG_LP_3)); lcd_printPGM(PSTR(MSG_LP_3));
currentMenu = lcd_level_bed; currentMenu = lcd_level_bed;
ChangeScreen=false; ChangeScreen=false;
...@@ -726,7 +730,7 @@ void lcd_level_bed() ...@@ -726,7 +730,7 @@ void lcd_level_bed()
break; break;
case 4: case 4:
{ {
lcd.setCursor(0, 1); LCD.setCursor(0, 1);
lcd_printPGM(PSTR(MSG_LP_4)); lcd_printPGM(PSTR(MSG_LP_4));
currentMenu = lcd_level_bed; currentMenu = lcd_level_bed;
ChangeScreen=false; ChangeScreen=false;
...@@ -734,7 +738,7 @@ void lcd_level_bed() ...@@ -734,7 +738,7 @@ void lcd_level_bed()
break; break;
case 5: case 5:
{ {
lcd.setCursor(0, 1); LCD.setCursor(0, 1);
lcd_printPGM(PSTR(MSG_LP_5)); lcd_printPGM(PSTR(MSG_LP_5));
currentMenu = lcd_level_bed; currentMenu = lcd_level_bed;
ChangeScreen=false; ChangeScreen=false;
...@@ -742,12 +746,12 @@ void lcd_level_bed() ...@@ -742,12 +746,12 @@ void lcd_level_bed()
break; break;
case 6: case 6:
{ {
lcd.setCursor(2, 2); LCD.setCursor(2, 2);
lcd_printPGM(PSTR(MSG_LP_6)); lcd_printPGM(PSTR(MSG_LP_6));
ChangeScreen=false; ChangeScreen=false;
delay(1200); delay(1200);
encoderPosition = 0; encoderPosition = 0;
lcd.clear(); lcd_implementation_clear();
currentMenu = lcd_status_screen; currentMenu = lcd_status_screen;
lcd_status_screen(); lcd_status_screen();
pageShowInfo=0; pageShowInfo=0;
...@@ -956,6 +960,35 @@ static void lcd_config_menu() { ...@@ -956,6 +960,35 @@ static void lcd_config_menu() {
END_MENU(); END_MENU();
} }
#ifdef PIDTEMP
// Helpers for editing PID Ki & Kd values
// grab the PID value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_i(int e) {
PID_PARAM(Ki, e) = scalePID_i(raw_Ki);
updatePID();
}
void copy_and_scalePID_d(int e) {
PID_PARAM(Kd, e) = scalePID_d(raw_Kd);
updatePID();
}
void copy_and_scalePID_i_E1() { copy_and_scalePID_i(0); }
void copy_and_scalePID_d_E1() { copy_and_scalePID_d(0); }
#if HOTENDS > 1
void copy_and_scalePID_i_E2() { copy_and_scalePID_i(1); }
void copy_and_scalePID_d_E2() { copy_and_scalePID_d(1); }
#if HOTENDS > 2
void copy_and_scalePID_i_E3() { copy_and_scalePID_i(2); }
void copy_and_scalePID_d_E3() { copy_and_scalePID_d(2); }
#if HOTENDS > 3
void copy_and_scalePID_i_E4() { copy_and_scalePID_i(3); }
void copy_and_scalePID_d_E4() { copy_and_scalePID_d(3); }
#endif //HOTENDS > 3
#endif //HOTENDS > 2
#endif //HOTENDS > 1
#endif //PIDTEMP
static void lcd_control_temperature_menu() { static void lcd_control_temperature_menu() {
START_MENU(); START_MENU();
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
...@@ -989,39 +1022,39 @@ static void lcd_control_temperature_menu() { ...@@ -989,39 +1022,39 @@ static void lcd_control_temperature_menu() {
#endif #endif
#ifdef PIDTEMP #ifdef PIDTEMP
// set up temp variables - undo the default scaling // set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(Ki[0]); raw_Ki = unscalePID_i(PID_PARAM(Ki,0));
raw_Kd = unscalePID_d(Kd[0]); raw_Kd = unscalePID_d(PID_PARAM(Kd,0));
MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp[0], 1, 9990); MENU_ITEM_EDIT(float52, MSG_PID_P, &PID_PARAM(Kp,0), 1, 9990);
// i is typically a small value so allows values below 1 // i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E1);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d_E1);
#if HOTENDS > 1 #if HOTENDS > 1
// set up temp variables - undo the default scaling // set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(Ki[1]); raw_Ki = unscalePID_i(PID_PARAM(Ki,1));
raw_Kd = unscalePID_d(Kd[1]); raw_Kd = unscalePID_d(PID_PARAM(Kd,1));
MENU_ITEM_EDIT(float52, MSG_PID_P " E2", &Kp[1], 1, 9990); MENU_ITEM_EDIT(float52, MSG_PID_P MSG_E2, &PID_PARAM(Kp,1), 1, 9990);
// i is typically a small value so allows values below 1 // i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I " E2", &raw_Ki, 0.01, 9990, copy_and_scalePID_i); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I MSG_E2, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E2);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D " E2", &raw_Kd, 1, 9990, copy_and_scalePID_d); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D MSG_E2, &raw_Kd, 1, 9990, copy_and_scalePID_d_E2);
#endif //HOTENDS > 1
#if HOTENDS > 2 #if HOTENDS > 2
// set up temp variables - undo the default scaling // set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(Ki[2]); raw_Ki = unscalePID_i(PID_PARAM(Ki,2));
raw_Kd = unscalePID_d(Kd[2]); raw_Kd = unscalePID_d(PID_PARAM(Kd,2));
MENU_ITEM_EDIT(float52, MSG_PID_P " E3", &Kp[2], 1, 9990); MENU_ITEM_EDIT(float52, MSG_PID_P MSG_E3, &PID_PARAM(Kp,2), 1, 9990);
// i is typically a small value so allows values below 1 // i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I " E3", &raw_Ki, 0.01, 9990, copy_and_scalePID_i); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I MSG_E3, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E3);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D " E3", &raw_Kd, 1, 9990, copy_and_scalePID_d); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D MSG_E3, &raw_Kd, 1, 9990, copy_and_scalePID_d_E3);
#endif //HOTENDS > 2
#if HOTENDS > 3 #if HOTENDS > 3
// set up temp variables - undo the default scaling // set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(Ki[3]); raw_Ki = unscalePID_i(PID_PARAM(Ki,3));
raw_Kd = unscalePID_d(Kd[3]); raw_Kd = unscalePID_d(PID_PARAM(Kd,3));
MENU_ITEM_EDIT(float52, MSG_PID_P " E4", &Kp[3], 1, 9990); MENU_ITEM_EDIT(float52, MSG_PID_P MSG_E4, &PID_PARAM(Kp,3), 1, 9990);
// i is typically a small value so allows values below 1 // i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I " E4", &raw_Ki, 0.01, 9990, copy_and_scalePID_i); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I MSG_E4, &raw_Ki, 0.01, 9990, copy_and_scalePID_i_E4);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D " E4", &raw_Kd, 1, 9990, copy_and_scalePID_d); MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D MSG_E4, &raw_Kd, 1, 9990, copy_and_scalePID_d_E4);
#endif //HOTENDS > 3
#endif //HOTENDS > 2 #endif //HOTENDS > 2
#endif //HOTENDS > 1
#endif //PIDTEMP #endif //PIDTEMP
MENU_ITEM(submenu, MSG_PREHEAT_PLA_SETTINGS, lcd_control_temperature_preheat_pla_settings_menu); MENU_ITEM(submenu, MSG_PREHEAT_PLA_SETTINGS, lcd_control_temperature_preheat_pla_settings_menu);
MENU_ITEM(submenu, MSG_PREHEAT_ABS_SETTINGS, lcd_control_temperature_preheat_abs_settings_menu); MENU_ITEM(submenu, MSG_PREHEAT_ABS_SETTINGS, lcd_control_temperature_preheat_abs_settings_menu);
...@@ -1083,7 +1116,7 @@ static void lcd_control_motion_menu() { ...@@ -1083,7 +1116,7 @@ static void lcd_control_motion_menu() {
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, 0.0, 50); MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, 0.0, 50);
#endif #endif
MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 100, 99000); MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 10, 99000);
MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &max_xy_jerk, 1, 990); MENU_ITEM_EDIT(float3, MSG_VXY_JERK, &max_xy_jerk, 1, 990);
MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &max_z_jerk, 0.1, 990); MENU_ITEM_EDIT(float52, MSG_VZ_JERK, &max_z_jerk, 0.1, 990);
MENU_ITEM_EDIT(float3, MSG_VE_JERK, &max_e_jerk, 1, 990); MENU_ITEM_EDIT(float3, MSG_VE_JERK, &max_e_jerk, 1, 990);
...@@ -1093,12 +1126,12 @@ static void lcd_control_motion_menu() { ...@@ -1093,12 +1126,12 @@ static void lcd_control_motion_menu() {
MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &max_feedrate[E_AXIS], 1, 999); MENU_ITEM_EDIT(float3, MSG_VMAX MSG_E, &max_feedrate[E_AXIS], 1, 999);
MENU_ITEM_EDIT(float3, MSG_VMIN, &minimumfeedrate, 0, 999); MENU_ITEM_EDIT(float3, MSG_VMIN, &minimumfeedrate, 0, 999);
MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &mintravelfeedrate, 0, 999); MENU_ITEM_EDIT(float3, MSG_VTRAV_MIN, &mintravelfeedrate, 0, 999);
MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &max_acceleration_units_per_sq_second[X_AXIS], 10, 99000, reset_acceleration_rates); MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_X, &max_acceleration_units_per_sq_second[X_AXIS], 100, 99000, reset_acceleration_rates);
MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &max_acceleration_units_per_sq_second[Y_AXIS], 10, 99000, reset_acceleration_rates); MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Y, &max_acceleration_units_per_sq_second[Y_AXIS], 100, 99000, reset_acceleration_rates);
MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &max_acceleration_units_per_sq_second[Z_AXIS], 10, 99000, reset_acceleration_rates); MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_Z, &max_acceleration_units_per_sq_second[Z_AXIS], 10, 99000, reset_acceleration_rates);
MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &max_acceleration_units_per_sq_second[E_AXIS], 10, 99000, reset_acceleration_rates); MENU_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &max_acceleration_units_per_sq_second[E_AXIS], 100, 99000, reset_acceleration_rates);
MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &retract_acceleration, 10, 99000); MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &retract_acceleration, 100, 99000);
MENU_ITEM_EDIT(float5, MSG_A_TRAVEL, &travel_acceleration, 10, 99000); MENU_ITEM_EDIT(float5, MSG_A_TRAVEL, &travel_acceleration, 100, 99000);
MENU_ITEM_EDIT(float52, MSG_XSTEPS, &axis_steps_per_unit[X_AXIS], 5, 9999); MENU_ITEM_EDIT(float52, MSG_XSTEPS, &axis_steps_per_unit[X_AXIS], 5, 9999);
MENU_ITEM_EDIT(float52, MSG_YSTEPS, &axis_steps_per_unit[Y_AXIS], 5, 9999); MENU_ITEM_EDIT(float52, MSG_YSTEPS, &axis_steps_per_unit[Y_AXIS], 5, 9999);
MENU_ITEM_EDIT(float51, MSG_ZSTEPS, &axis_steps_per_unit[Z_AXIS], 5, 9999); MENU_ITEM_EDIT(float51, MSG_ZSTEPS, &axis_steps_per_unit[Z_AXIS], 5, 9999);
...@@ -1378,10 +1411,6 @@ void lcd_init() { ...@@ -1378,10 +1411,6 @@ void lcd_init() {
WRITE(SHIFT_OUT,HIGH); WRITE(SHIFT_OUT,HIGH);
WRITE(SHIFT_LD,HIGH); WRITE(SHIFT_LD,HIGH);
WRITE(SHIFT_EN,LOW); WRITE(SHIFT_EN,LOW);
#else
#ifdef ULTIPANEL
#error ULTIPANEL requires an encoder
#endif
#endif // SR_LCD_2W_NL #endif // SR_LCD_2W_NL
#endif//!NEWPANEL #endif//!NEWPANEL
...@@ -1556,7 +1585,7 @@ void lcd_finishstatus() { ...@@ -1556,7 +1585,7 @@ void lcd_finishstatus() {
} }
lcd_status_message[LCD_WIDTH] = '\0'; lcd_status_message[LCD_WIDTH] = '\0';
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
#if PROGRESS_BAR_MSG_EXPIRE > 0 #if PROGRESS_MSG_EXPIRE > 0
messageTick = messageTick =
#endif #endif
progressBarTick = millis(); progressBarTick = millis();
...@@ -1993,24 +2022,4 @@ char *ftostr52(const float &x) ...@@ -1993,24 +2022,4 @@ char *ftostr52(const float &x)
return conv; return conv;
} }
// Callback for after editing PID i value
// grab the PID i value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_i()
{
#ifdef PIDTEMP
Ki[active_extruder] = scalePID_i(raw_Ki);
updatePID();
#endif
}
// Callback for after editing PID d value
// grab the PID d value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_d()
{
#ifdef PIDTEMP
Kd[active_extruder] = scalePID_d(raw_Kd);
updatePID();
#endif
}
#endif //ULTRA_LCD #endif //ULTRA_LCD
...@@ -45,20 +45,18 @@ ...@@ -45,20 +45,18 @@
extern int plaPreheatHotendTemp; extern int plaPreheatHotendTemp;
extern int plaPreheatHPBTemp; extern int plaPreheatHPBTemp;
extern int plaPreheatFanSpeed; extern int plaPreheatFanSpeed;
extern int absPreheatHotendTemp; extern int absPreheatHotendTemp;
extern int absPreheatHPBTemp; extern int absPreheatHPBTemp;
extern int absPreheatFanSpeed; extern int absPreheatFanSpeed;
extern int gumPreheatHotendTemp; extern int gumPreheatHotendTemp;
extern int gumPreheatHPBTemp; extern int gumPreheatHPBTemp;
extern int gumPreheatFanSpeed; extern int gumPreheatFanSpeed;
extern bool cancel_heatup; extern bool cancel_heatup;
#if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) || (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY) #if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) || (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY)
extern unsigned long message_millis; extern unsigned long message_millis;
#endif #endif
void lcd_buzz(long duration,uint16_t freq); void lcd_buzz(long duration,uint16_t freq);
bool lcd_clicked(); bool lcd_clicked();
......
...@@ -200,7 +200,7 @@ ...@@ -200,7 +200,7 @@
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
static uint16_t progressBarTick = 0; static uint16_t progressBarTick = 0;
#if PROGRESS_BAR_MSG_EXPIRE > 0 #if PROGRESS_MSG_EXPIRE > 0
static uint16_t messageTick = 0; static uint16_t messageTick = 0;
#endif #endif
#define LCD_STR_PROGRESS "\x03\x04\x05" #define LCD_STR_PROGRESS "\x03\x04\x05"
...@@ -382,9 +382,9 @@ static void lcd_set_custom_characters( ...@@ -382,9 +382,9 @@ static void lcd_set_custom_characters(
static void lcd_implementation_init ( static void lcd_implementation_init (
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
bool progress_bar_set = true bool progress_bar_set=true
#endif #endif
){ ) {
#if defined(LCD_I2C_TYPE_PCF8575) #if defined(LCD_I2C_TYPE_PCF8575)
lcd.begin(LCD_WIDTH, LCD_HEIGHT); lcd.begin(LCD_WIDTH, LCD_HEIGHT);
...@@ -421,7 +421,8 @@ static void lcd_implementation_clear() { ...@@ -421,7 +421,8 @@ static void lcd_implementation_clear() {
} }
/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */ /* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
static void lcd_printPGM(const char* str) { static void lcd_printPGM(const char* str)
{
char c; char c;
while((c = pgm_read_byte(str++)) != '\0') while((c = pgm_read_byte(str++)) != '\0')
{ {
...@@ -458,7 +459,8 @@ Possible status screens: ...@@ -458,7 +459,8 @@ Possible status screens:
|Status line.........| |Status line.........|
*/ */
static void lcd_implementation_status_screen() { static void lcd_implementation_status_screen()
{
int tHotend=int(degHotend(0) + 0.5); int tHotend=int(degHotend(0) + 0.5);
int tTarget=int(degTargetHotend(0) + 0.5); int tTarget=int(degTargetHotend(0) + 0.5);
...@@ -629,7 +631,7 @@ static void lcd_implementation_status_screen() { ...@@ -629,7 +631,7 @@ static void lcd_implementation_status_screen() {
#endif #endif
{ {
lcd_printPGM(PSTR("P:")); lcd_printPGM(PSTR("P:"));
lcd.print(itostr3(power_consumption_meas)); lcd.print(ftostr31(power_consumption_meas));
lcd_printPGM(PSTR("W C:")); lcd_printPGM(PSTR("W C:"));
lcd.print(ltostr7(power_consumption_hour)); lcd.print(ltostr7(power_consumption_hour));
lcd_printPGM(PSTR("Wh")); lcd_printPGM(PSTR("Wh"));
...@@ -644,6 +646,7 @@ static void lcd_implementation_status_screen() { ...@@ -644,6 +646,7 @@ static void lcd_implementation_status_screen() {
lcd.print('%'); lcd.print('%');
return; return;
} }
#endif
#else #else
lcd.print(lcd_status_message); lcd.print(lcd_status_message);
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment