Commit cf73391b authored by MagoKimbra's avatar MagoKimbra

Update 4.0.7

parents d0cc94cf 9d77c6d5
/**
* 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
#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.7"
#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
...@@ -584,7 +438,7 @@ your extruder heater takes 2 minutes to hit the target on heating. ...@@ -584,7 +438,7 @@ your extruder heater takes 2 minutes to hit the target on heating.
//========================= Bowden Filament management ====================== //========================= Bowden Filament management ======================
//#define EASY_LOAD //#define EASY_LOAD
#ifdef EASY_LOAD #ifdef EASY_LOAD
#define BOWDEN_LENGTH 560 // mm #define BOWDEN_LENGTH 250 // mm
#define LCD_PURGE_LENGTH 3 // mm #define LCD_PURGE_LENGTH 3 // mm
#define LCD_RETRACT_LENGTH 3 // mm #define LCD_RETRACT_LENGTH 3 // mm
#define LCD_PURGE_FEEDRATE 3 // mm/s #define LCD_PURGE_FEEDRATE 3 // mm/s
...@@ -667,10 +521,12 @@ your extruder heater takes 2 minutes to hit the target on heating. ...@@ -667,10 +521,12 @@ your extruder heater takes 2 minutes to hit the target on heating.
// Uncomment below to enable // Uncomment below to enable
//#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_EFFICIENCY 100.0 //(%) The power efficency of the power supply #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
//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.
//#define POWER_CONSUMPTION_LCD_DISPLAY //#define POWER_CONSUMPTION_LCD_DISPLAY
......
...@@ -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 ===========================
//===================================================================================== //=====================================================================================
...@@ -151,11 +147,11 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log ...@@ -151,11 +147,11 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log
#define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // -front +behind #define Y_PROBE_OFFSET_FROM_EXTRUDER 0 // -front +behind
#define Z_PROBE_OFFSET_FROM_EXTRUDER -1 // -below (always!) #define Z_PROBE_OFFSET_FROM_EXTRUDER -1 // -below (always!)
#define Z_RAISE_BEFORE_HOMING 10 // (in mm) Raise Z before homing (G28) for Probe Clearance. #define Z_RAISE_BEFORE_HOMING 10 // (in mm) Raise Z before homing (G28) for Probe Clearance.
// Be sure you have this distance over your Z_MAX_POS in case // Be sure you have this distance over your Z_MAX_POS in case
#define Z_RAISE_BEFORE_PROBING 10 //How much the extruder will be raised before travelling to the first probing point. #define Z_RAISE_BEFORE_PROBING 10 //How much the extruder will be raised before travelling to the first probing point.
#define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when travelling from between next probing points #define Z_RAISE_BETWEEN_PROBINGS 5 //How much the extruder will be raised when travelling from between next probing points
//#define Z_PROBE_SLED // turn on if you have a z-probe mounted on a sled like those designed by Charles Bell //#define Z_PROBE_SLED // turn on if you have a z-probe mounted on a sled like those designed by Charles Bell
//#define SLED_DOCKING_OFFSET 5 // the extra distance the X axis must travel to pick up the sled. 0 should be fine but you can push it further if you'd like. //#define SLED_DOCKING_OFFSET 5 // the extra distance the X axis must travel to pick up the sled. 0 should be fine but you can push it further if you'd like.
......
...@@ -131,9 +131,6 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log ...@@ -131,9 +131,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)
//// MOVEMENT SETTINGS //// MOVEMENT SETTINGS
#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E #define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
...@@ -150,6 +147,12 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log ...@@ -150,6 +147,12 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the log
#define DEFAULT_RETRACT_ACCELERATION 2500 // X, Y, Z and E max acceleration in mm/s^2 for retracts #define DEFAULT_RETRACT_ACCELERATION 2500 // X, Y, Z and E max acceleration in mm/s^2 for retracts
#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration in mm/s^2 for travel (non printing) moves #define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration in mm/s^2 for travel (non printing) moves
// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing).
// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder).
// For the other hotends it is their distance from the extruder 0 hotend.
//#define HOTEND_OFFSET_X {0.0, 5.00, 0.0, 0.0} // (in mm) for each extruder, offset of the hotend on the X axis
//#define HOTEND_OFFSET_Y {0.0, 5.00, 0.0, 0.0} // (in mm) for each extruder, offset of the hotend on the Y axis
// The speed change that does not require acceleration (i.e. the software might assume it can be done instantaneously) // The speed change that does not require acceleration (i.e. the software might assume it can be done instantaneously)
#define DEFAULT_XYJERK 20 // (mm/sec) #define DEFAULT_XYJERK 20 // (mm/sec)
#define DEFAULT_ZJERK 20 // (mm/sec) #define DEFAULT_ZJERK 20 // (mm/sec)
......
...@@ -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 ============================
//=========================================================================== //===========================================================================
...@@ -44,13 +46,25 @@ ...@@ -44,13 +46,25 @@
//The M105 command return, besides traditional information, the ADC value read from temperature sensors. //The M105 command return, besides traditional information, the ADC value read from temperature sensors.
//#define SHOW_TEMP_ADC_VALUES //#define SHOW_TEMP_ADC_VALUES
// 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
//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_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_SECONDS 10
#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_FEEDRATE 50 //default feedrate for recovering from retraction (mm/s)
// 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
#define EXTRUDER_RUNOUT_MINTEMP 190 #define EXTRUDER_RUNOUT_MINTEMP 190
#define EXTRUDER_RUNOUT_SECONDS 30. #define EXTRUDER_RUNOUT_SECONDS 30
#define EXTRUDER_RUNOUT_ESTEPS 14. //mm filament #define EXTRUDER_RUNOUT_ESTEPS 14 //mm filament
#define EXTRUDER_RUNOUT_SPEED 1500. //extrusion speed #define EXTRUDER_RUNOUT_SPEED 1500 //extrusion speed
#define EXTRUDER_RUNOUT_EXTRUDE 100 #define EXTRUDER_RUNOUT_EXTRUDE 100
//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.
...@@ -89,54 +103,6 @@ ...@@ -89,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.
...@@ -147,8 +113,28 @@ ...@@ -147,8 +113,28 @@
//#define Z_DUAL_STEPPER_DRIVERS //#define Z_DUAL_STEPPER_DRIVERS
#ifdef Z_DUAL_STEPPER_DRIVERS #ifdef Z_DUAL_STEPPER_DRIVERS
#undef EXTRUDERS
#define EXTRUDERS 1 // Z_DUAL_ENDSTOPS is a feature to enable the use of 2 endstops for both Z steppers - Let's call them Z stepper and Z2 stepper.
// That way the machine is capable to align the bed during home, since both Z steppers are homed.
// There is also an implementation of M666 (software endstops adjustment) to this feature.
// After Z homing, this adjustment is applied to just one of the steppers in order to align the bed.
// One just need to home the Z axis and measure the distance difference between both Z axis and apply the math: Z adjust = Z - Z2.
// If the Z stepper axis is closer to the bed, the measure Z > Z2 (yes, it is.. think about it) and the Z adjust would be positive.
// Play a little bit with small adjustments (0.5mm) and check the behaviour.
// The M119 (endstops report) will start reporting the Z2 Endstop as well.
#define Z_DUAL_ENDSTOPS
#ifdef Z_DUAL_ENDSTOPS
#define Z2_STEP_PIN E2_STEP_PIN // Stepper to be used to Z2 axis.
#define Z2_DIR_PIN E2_DIR_PIN
#define Z2_ENABLE_PIN E2_ENABLE_PIN
#define Z2_MAX_PIN 36 //Endstop used for Z2 axis. In this case I'm using XMAX in a Rumba Board (pin 36)
const bool Z2_MAX_ENDSTOP_INVERTING = false;
#define DISABLE_XMAX_ENDSTOP //Better to disable the XMAX to avoid conflict. Just rename "XMAX_ENDSTOP" by the endstop you are using for Z2 axis.
#endif
#endif #endif
// Same again but for Y Axis. // Same again but for Y Axis.
...@@ -157,105 +143,81 @@ ...@@ -157,105 +143,81 @@
// 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
#define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // set the speeds for manual moves (mm/min)
#endif
//Comment to disable setting feedrate multiplier via encoder
#ifdef ULTIPANEL #ifdef ULTIPANEL
#define ULTIPANEL_FEEDMULTIPLY #define MANUAL_FEEDRATE {50*60, 50*60, 4*60, 60} // Feedrates for manual moves along X, Y, Z, E from panel
#define ULTIPANEL_FEEDMULTIPLY // Comment to disable setting feedrate multiplier via encoder
#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
...@@ -267,13 +229,6 @@ ...@@ -267,13 +229,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]
...@@ -291,9 +246,9 @@ ...@@ -291,9 +246,9 @@
//=============================Additional Features=========================== //=============================Additional Features===========================
//=========================================================================== //===========================================================================
#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/
...@@ -316,21 +271,11 @@ ...@@ -316,21 +271,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
...@@ -352,16 +297,6 @@ ...@@ -352,16 +297,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)
...@@ -375,12 +310,8 @@ ...@@ -375,12 +310,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:
...@@ -395,26 +326,6 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -395,26 +326,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
...@@ -424,7 +335,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -424,7 +335,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
...@@ -444,23 +355,23 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -444,23 +355,23 @@ const unsigned int dropsegments=5; //everything with less than this number of st
//#define FWRETRACT //ONLY PARTIALLY TESTED //#define FWRETRACT //ONLY PARTIALLY TESTED
#ifdef FWRETRACT #ifdef FWRETRACT
#define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt #define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt
#define RETRACT_LENGTH 3 //default retract length (positive mm) #define RETRACT_LENGTH 3 //default retract length (positive mm)
#define RETRACT_LENGTH_SWAP 13 //default swap retract length (positive mm), for extruder change #define RETRACT_LENGTH_SWAP 13 //default swap retract length (positive mm), for extruder change
#define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s) #define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s)
#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
...@@ -606,76 +517,7 @@ const unsigned int dropsegments=5; //everything with less than this number of st ...@@ -606,76 +517,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)
...@@ -186,7 +176,7 @@ void manage_inactivity(bool ignore_stepper_queue=false); ...@@ -186,7 +176,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
#define disable_e() {disable_e0(); disable_e1(); disable_e2(); disable_e3();} #define disable_e() {disable_e0(); disable_e1(); disable_e2(); disable_e3();}
#ifdef COREXY #ifdef COREXY
enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5}; enum AxisEnum {X_AXIS=0, Y_AXIS=1, A_AXIS=0, B_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
//X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots. //X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
#else #else
enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3}; enum AxisEnum {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, E_AXIS=3};
...@@ -234,7 +224,7 @@ void clamp_to_software_endstops(float target[3]); ...@@ -234,7 +224,7 @@ void clamp_to_software_endstops(float target[3]);
void refresh_cmd_timeout(void); void refresh_cmd_timeout(void);
#ifdef FAST_PWM_FAN #ifdef FAST_PWM_FAN
void setPwmFrequency(uint8_t pin, int val); void setPwmFrequency(uint8_t pin, int val);
#endif #endif
#ifndef CRITICAL_SECTION_START #ifndef CRITICAL_SECTION_START
...@@ -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,15 +278,15 @@ extern float zprobe_zoffset; ...@@ -290,15 +278,15 @@ 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
extern unsigned char fanSpeedSoftPwm; extern unsigned char fanSpeedSoftPwm;
#endif #endif
#if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) #if defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && (FILWIDTH_PIN >= 0)
extern float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75 extern float filament_width_nominal; //holds the theoretical filament diameter ie., 3.00 or 1.75
extern bool filament_sensor; //indicates that filament sensor readings should control extrusion extern bool filament_sensor; //indicates that filament sensor readings should control extrusion
extern float filament_width_meas; //holds the filament diameter as accurately measured extern float filament_width_meas; //holds the filament diameter as accurately measured
...@@ -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,21 +324,20 @@ extern uint8_t active_extruder; ...@@ -336,21 +324,20 @@ 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
extern uint8_t debugLevel; extern uint8_t debugLevel;
extern inline bool debugDryrun() extern inline bool debugDryrun() {
{ return ((debugLevel & 8) != 0);
return ((debugLevel & 8)!=0);
} }
#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
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* 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
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#ifndef DOGM_LCD_IMPLEMENTATION_H #ifndef DOGM_LCD_IMPLEMENTATION_H
#define DOGM_LCD_IMPLEMENTATION_H #define DOGM_LCD_IMPLEMENTATION_H
#define MARLIN_VERSION " 4.0.3" #define MARLIN_VERSION " 4.0.7"
/** /**
* Implementation of the LCD display routines for a DOGM128 graphic display. These are common LCD 128x64 pixel graphic displays. * Implementation of the LCD display routines for a DOGM128 graphic display. These are common LCD 128x64 pixel graphic displays.
...@@ -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"));
......
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
#define MSG_Y_MAX "y_max: " #define MSG_Y_MAX "y_max: "
#define MSG_Z_MIN "z_min: " #define MSG_Z_MIN "z_min: "
#define MSG_Z_MAX "z_max: " #define MSG_Z_MAX "z_max: "
#define MSG_Z2_MAX "z2_max: "
#define MSG_E_MIN "e_min: " #define MSG_E_MIN "e_min: "
#define MSG_PAUSE_PIN "pause pin: " #define MSG_PAUSE_PIN "pause pin: "
#define MSG_M119_REPORT "Reporting endstop status" #define MSG_M119_REPORT "Reporting endstop status"
...@@ -226,8 +227,6 @@ ...@@ -226,8 +227,6 @@
#define STR_h3 "\263" #define STR_h3 "\263"
#define STR_Deg "\337" #define STR_Deg "\337"
#define STR_THERMOMETER "\002" #define STR_THERMOMETER "\002"
#elif defined(ULTRA_LCD)
#error You must enable either DISPLAY_CHARSET_HD44780_JAPAN or DISPLAY_CHARSET_HD44780_WESTERN for your LCD controller.
#endif #endif
#endif #endif
/* /*
......
...@@ -56,9 +56,9 @@ ...@@ -56,9 +56,9 @@
#define MSG_FAN_SPEED "Lüftergeschw." #define MSG_FAN_SPEED "Lüftergeschw."
#define MSG_FLOW "Fluss" #define MSG_FLOW "Fluss"
#define MSG_CONTROL "Einstellungen" #define MSG_CONTROL "Einstellungen"
#define MSG_MIN "\002 Min" #define MSG_MIN STR_THERMOMETER " Min"
#define MSG_MAX "\002 Max" #define MSG_MAX STR_THERMOMETER " Max"
#define MSG_FACTOR "\002 Faktor" #define MSG_FACTOR STR_THERMOMETER " Faktor"
#define MSG_AUTOTEMP "AutoTemp" #define MSG_AUTOTEMP "AutoTemp"
#define MSG_ON "Ein" #define MSG_ON "Ein"
#define MSG_OFF "Aus" #define MSG_OFF "Aus"
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
#define MSG_E "e" #define MSG_E "e"
#define MSG_VMIN "Vmin" #define MSG_VMIN "Vmin"
#define MSG_VTRAV_MIN "VTrav min" #define MSG_VTRAV_MIN "VTrav min"
#define MSG_AMAX "Amax " #define MSG_AMAX "A max"
#define MSG_A_RETRACT "A-Retract" #define MSG_A_RETRACT "A-Retract"
#define MSG_A_TRAVEL "A-travel" #define MSG_A_TRAVEL "A-travel"
#define MSG_XSTEPS "X steps/mm" #define MSG_XSTEPS "X steps/mm"
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
#define MSG_TEMPERATURE "Temperatur" #define MSG_TEMPERATURE "Temperatur"
#define MSG_MOTION "Bewegung" #define MSG_MOTION "Bewegung"
#define MSG_VOLUMETRIC "Filament" #define MSG_VOLUMETRIC "Filament"
#define MSG_VOLUMETRIC_ENABLED "E in mm3" #define MSG_VOLUMETRIC_ENABLED "E in mm" STR_h3
#define MSG_FILAMENT_SIZE_EXTRUDER "Fil. Dia." #define MSG_FILAMENT_SIZE_EXTRUDER "Fil. Dia."
#define MSG_CONTRAST "LCD contrast" #define MSG_CONTRAST "LCD contrast"
#define MSG_STORE_EPROM "EPROM speichern" #define MSG_STORE_EPROM "EPROM speichern"
......
...@@ -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"
......
...@@ -979,9 +979,9 @@ ...@@ -979,9 +979,9 @@
#define SHIFT_CLK 44 // shift register #define SHIFT_CLK 44 // shift register
#define SHIFT_LD 42 // shift register #define SHIFT_LD 42 // shift register
#elif defined(PANEL_ONE) #elif defined(PANEL_ONE)
#define BTN_EN1 59 // AUX2 PIN 3 #define BTN_EN1 59 // AUX2 PIN 3
#define BTN_EN2 63 // AUX2 PIN 4 #define BTN_EN2 63 // AUX2 PIN 4
#define BTN_ENC 49 // AUX3 PIN 7 #define BTN_ENC 49 // AUX3 PIN 7
#else #else
#define BTN_EN1 37 #define BTN_EN1 37
#define BTN_EN2 35 #define BTN_EN2 35
...@@ -4450,7 +4450,7 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a ...@@ -4450,7 +4450,7 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a
************************************* FEATURE ******************************************* ************************************* FEATURE *******************************************
****************************************************************************************/ ****************************************************************************************/
#ifdef SINGLENOZZLE #if HOTENDS == 1
#undef HEATER_1_PIN #undef HEATER_1_PIN
#undef HEATER_2_PIN #undef HEATER_2_PIN
#undef HEATER_3_PIN #undef HEATER_3_PIN
...@@ -4463,7 +4463,21 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a ...@@ -4463,7 +4463,21 @@ DaveX plan for Teensylu/printrboard-type pinouts (ref teensylu & sprinter) for a
#define TEMP_1_PIN -1 #define TEMP_1_PIN -1
#define TEMP_2_PIN -1 #define TEMP_2_PIN -1
#define TEMP_3_PIN -1 #define TEMP_3_PIN -1
#endif //SINGLENOZZLE #elif HOTENDS == 2
#undef HEATER_2_PIN
#undef HEATER_3_PIN
#define HEATER_2_PIN -1
#define HEATER_3_PIN -1
#undef TEMP_2_PIN
#undef TEMP_3_PIN
#define TEMP_2_PIN -1
#define TEMP_3_PIN -1
#elif HOTENDS == 3
#undef HEATER_3_PIN
#define HEATER_3_PIN -1
#undef TEMP_3_PIN
#define TEMP_3_PIN -1
#endif
#ifdef MKR4 #ifdef MKR4
#if (EXTRUDERS == 2) && (DRIVER_EXTRUDERS==1) // Use this for one driver and two extruder #if (EXTRUDERS == 2) && (DRIVER_EXTRUDERS==1) // Use this for one driver and two extruder
......
...@@ -114,39 +114,25 @@ volatile unsigned char block_buffer_tail; // Index of the block to process now ...@@ -114,39 +114,25 @@ volatile unsigned char block_buffer_tail; // Index of the block to process now
float extrude_min_temp = EXTRUDE_MINTEMP; float extrude_min_temp = EXTRUDE_MINTEMP;
#endif #endif
#ifdef XY_FREQUENCY_LIMIT #ifdef XY_FREQUENCY_LIMIT
#define MAX_FREQ_TIME (1000000.0/XY_FREQUENCY_LIMIT) // Used for the frequency limit
// Used for the frequency limit #define MAX_FREQ_TIME (1000000.0/XY_FREQUENCY_LIMIT)
static unsigned char old_direction_bits = 0; // Old direction bits. Used for speed calculations // Old direction bits. Used for speed calculations
static long x_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in us). Used for speed calculations static unsigned char old_direction_bits = 0;
static long y_segment_time[3]={MAX_FREQ_TIME + 1,0,0}; // Segment times (in us). Used for speed calculations
static long axis_segment_time[2][3] = { {MAX_FREQ_TIME+1,0,0}, {MAX_FREQ_TIME+1,0,0} };
#endif #endif
#if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) #ifdef FILAMENT_SENSOR
static char meas_sample; //temporary variable to hold filament measurement sample static char meas_sample; //temporary variable to hold filament measurement sample
#endif #endif
// Returns the index of the next block in the ring buffer // Get the next / previous index of the next block in the ring buffer
// NOTE: Removed modulo (%) operator, which uses an expensive divide and multiplication. // NOTE: Using & here (not %) because BLOCK_BUFFER_SIZE is always a power of 2
static int8_t next_block_index(int8_t block_index) { FORCE_INLINE int8_t next_block_index(int8_t block_index) { return BLOCK_MOD(block_index + 1); }
block_index++; FORCE_INLINE int8_t prev_block_index(int8_t block_index) { return BLOCK_MOD(block_index - 1); }
if (block_index == BLOCK_BUFFER_SIZE) {
block_index = 0;
}
return(block_index);
}
// Returns the index of the previous block in the ring buffer
static int8_t prev_block_index(int8_t block_index) {
if (block_index == 0) {
block_index = BLOCK_BUFFER_SIZE;
}
block_index--;
return(block_index);
}
//=========================================================================== //===========================================================================
//=============================functions ============================ //================================ Functions ================================
//=========================================================================== //===========================================================================
// Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the // Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the
...@@ -201,15 +187,15 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi ...@@ -201,15 +187,15 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi
// block->accelerate_until = accelerate_steps; // block->accelerate_until = accelerate_steps;
// block->decelerate_after = accelerate_steps+plateau_steps; // block->decelerate_after = accelerate_steps+plateau_steps;
CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section
if(block->busy == false) { // Don't update variables if block is busy. if (!block->busy) { // Don't update variables if block is busy.
block->accelerate_until = accelerate_steps; block->accelerate_until = accelerate_steps;
block->decelerate_after = accelerate_steps+plateau_steps; block->decelerate_after = accelerate_steps+plateau_steps;
block->initial_rate = initial_rate; block->initial_rate = initial_rate;
block->final_rate = final_rate; block->final_rate = final_rate;
#ifdef ADVANCE #ifdef ADVANCE
block->initial_advance = initial_advance; block->initial_advance = initial_advance;
block->final_advance = final_advance; block->final_advance = final_advance;
#endif //ADVANCE #endif //ADVANCE
} }
CRITICAL_SECTION_END; CRITICAL_SECTION_END;
} }
...@@ -217,23 +203,12 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi ...@@ -217,23 +203,12 @@ void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exi
// Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the
// acceleration within the allotted distance. // acceleration within the allotted distance.
FORCE_INLINE float max_allowable_speed(float acceleration, float target_velocity, float distance) { FORCE_INLINE float max_allowable_speed(float acceleration, float target_velocity, float distance) {
return sqrt(target_velocity*target_velocity-2*acceleration*distance); return sqrt(target_velocity * target_velocity - 2 * acceleration * distance);
} }
// "Junction jerk" in this context is the immediate change in speed at the junction of two blocks.
// This method will calculate the junction jerk as the euclidean distance between the nominal
// velocities of the respective blocks.
//inline float junction_jerk(block_t *before, block_t *after) {
// return sqrt(
// pow((before->speed_x-after->speed_x), 2)+pow((before->speed_y-after->speed_y), 2));
//}
// The kernel called by planner_recalculate() when scanning the plan from last to first entry. // The kernel called by planner_recalculate() when scanning the plan from last to first entry.
void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *next) { void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *next) {
if(!current) { if (!current) return;
return;
}
if (next) { if (next) {
// If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising.
...@@ -243,9 +218,9 @@ void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *n ...@@ -243,9 +218,9 @@ void planner_reverse_pass_kernel(block_t *previous, block_t *current, block_t *n
// If nominal length true, max junction speed is guaranteed to be reached. Only compute // If nominal length true, max junction speed is guaranteed to be reached. Only compute
// for max allowable speed if block is decelerating and nominal length is false. // for max allowable speed if block is decelerating and nominal length is false.
if ((!current->nominal_length_flag) && (current->max_entry_speed > next->entry_speed)) { if (!current->nominal_length_flag && current->max_entry_speed > next->entry_speed) {
current->entry_speed = min( current->max_entry_speed, current->entry_speed = min(current->max_entry_speed,
max_allowable_speed(-current->acceleration,next->entry_speed,current->millimeters)); max_allowable_speed(-current->acceleration, next->entry_speed, current->millimeters));
} }
else { else {
current->entry_speed = current->max_entry_speed; current->entry_speed = current->max_entry_speed;
...@@ -263,15 +238,14 @@ void planner_reverse_pass() { ...@@ -263,15 +238,14 @@ void planner_reverse_pass() {
//Make a local copy of block_buffer_tail, because the interrupt can alter it //Make a local copy of block_buffer_tail, because the interrupt can alter it
CRITICAL_SECTION_START; CRITICAL_SECTION_START;
unsigned char tail = block_buffer_tail; unsigned char tail = block_buffer_tail;
CRITICAL_SECTION_END CRITICAL_SECTION_END
if(((block_buffer_head-tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1)) > 3) { if (BLOCK_MOD(block_buffer_head - tail + BLOCK_BUFFER_SIZE) > 3) { // moves queued
block_index = (block_buffer_head - 3) & (BLOCK_BUFFER_SIZE - 1); block_index = BLOCK_MOD(block_buffer_head - 3);
block_t *block[3] = { block_t *block[3] = { NULL, NULL, NULL };
NULL, NULL, NULL }; while (block_index != tail) {
while(block_index != tail) { block_index = prev_block_index(block_index);
block_index = prev_block_index(block_index);
block[2]= block[1]; block[2]= block[1];
block[1]= block[0]; block[1]= block[0];
block[0] = &block_buffer[block_index]; block[0] = &block_buffer[block_index];
...@@ -282,9 +256,7 @@ void planner_reverse_pass() { ...@@ -282,9 +256,7 @@ void planner_reverse_pass() {
// The kernel called by planner_recalculate() when scanning the plan from first to last entry. // The kernel called by planner_recalculate() when scanning the plan from first to last entry.
void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *next) { void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *next) {
if(!previous) { if (!previous) return;
return;
}
// If the previous block is an acceleration block, but it is not long enough to complete the // If the previous block is an acceleration block, but it is not long enough to complete the
// full speed change within the block, we need to adjust the entry speed accordingly. Entry // full speed change within the block, we need to adjust the entry speed accordingly. Entry
...@@ -292,8 +264,8 @@ void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *n ...@@ -292,8 +264,8 @@ void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *n
// If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck.
if (!previous->nominal_length_flag) { if (!previous->nominal_length_flag) {
if (previous->entry_speed < current->entry_speed) { if (previous->entry_speed < current->entry_speed) {
double entry_speed = min( current->entry_speed, double entry_speed = min(current->entry_speed,
max_allowable_speed(-previous->acceleration,previous->entry_speed,previous->millimeters) ); max_allowable_speed(-previous->acceleration, previous->entry_speed, previous->millimeters));
// Check for junction speed change // Check for junction speed change
if (current->entry_speed != entry_speed) { if (current->entry_speed != entry_speed) {
...@@ -304,18 +276,17 @@ void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *n ...@@ -304,18 +276,17 @@ void planner_forward_pass_kernel(block_t *previous, block_t *current, block_t *n
} }
} }
// planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This // planner_recalculate() needs to go over the current plan twice. Once in reverse and once forward. This
// implements the forward pass. // implements the forward pass.
void planner_forward_pass() { void planner_forward_pass() {
uint8_t block_index = block_buffer_tail; uint8_t block_index = block_buffer_tail;
block_t *block[3] = { block_t *block[3] = { NULL, NULL, NULL };
NULL, NULL, NULL };
while(block_index != block_buffer_head) { while (block_index != block_buffer_head) {
block[0] = block[1]; block[0] = block[1];
block[1] = block[2]; block[1] = block[2];
block[2] = &block_buffer[block_index]; block[2] = &block_buffer[block_index];
planner_forward_pass_kernel(block[0],block[1],block[2]); planner_forward_pass_kernel(block[0], block[1], block[2]);
block_index = next_block_index(block_index); block_index = next_block_index(block_index);
} }
planner_forward_pass_kernel(block[1], block[2], NULL); planner_forward_pass_kernel(block[1], block[2], NULL);
...@@ -329,24 +300,24 @@ void planner_recalculate_trapezoids() { ...@@ -329,24 +300,24 @@ void planner_recalculate_trapezoids() {
block_t *current; block_t *current;
block_t *next = NULL; block_t *next = NULL;
while(block_index != block_buffer_head) { while (block_index != block_buffer_head) {
current = next; current = next;
next = &block_buffer[block_index]; next = &block_buffer[block_index];
if (current) { if (current) {
// Recalculate if current block entry or exit junction speed has changed. // Recalculate if current block entry or exit junction speed has changed.
if (current->recalculate_flag || next->recalculate_flag) { if (current->recalculate_flag || next->recalculate_flag) {
// NOTE: Entry and exit factors always > 0 by all previous logic operations. // NOTE: Entry and exit factors always > 0 by all previous logic operations.
calculate_trapezoid_for_block(current, current->entry_speed/current->nominal_speed, float nom = current->nominal_speed;
next->entry_speed/current->nominal_speed); calculate_trapezoid_for_block(current, current->entry_speed / nom, next->entry_speed / nom);
current->recalculate_flag = false; // Reset current only to ensure next trapezoid is computed current->recalculate_flag = false; // Reset current only to ensure next trapezoid is computed
} }
} }
block_index = next_block_index( block_index ); block_index = next_block_index( block_index );
} }
// Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated. // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated.
if(next != NULL) { if (next) {
calculate_trapezoid_for_block(next, next->entry_speed/next->nominal_speed, float nom = next->nominal_speed;
MINIMUM_PLANNER_SPEED/next->nominal_speed); calculate_trapezoid_for_block(next, next->entry_speed / nom, MINIMUM_PLANNER_SPEED / nom);
next->recalculate_flag = false; next->recalculate_flag = false;
} }
} }
...@@ -375,161 +346,130 @@ void planner_recalculate() { ...@@ -375,161 +346,130 @@ void planner_recalculate() {
} }
void plan_init() { void plan_init() {
block_buffer_head = 0; block_buffer_head = block_buffer_tail = 0;
block_buffer_tail = 0;
memset(position, 0, sizeof(position)); // clear position memset(position, 0, sizeof(position)); // clear position
previous_speed[0] = 0.0; for (int i=0; i<NUM_AXIS; i++) previous_speed[i] = 0.0;
previous_speed[1] = 0.0;
previous_speed[2] = 0.0;
previous_speed[3] = 0.0;
previous_nominal_speed = 0.0; previous_nominal_speed = 0.0;
} }
#ifdef AUTOTEMP #ifdef AUTOTEMP
void getHighESpeed() void getHighESpeed() {
{ static float oldt = 0;
static float oldt=0;
if(!autotemp_enabled){
return;
}
if(degTargetHotend0()+2<autotemp_min) { //probably temperature set to zero.
return; //do nothing
}
float high=0.0; if (!autotemp_enabled) return;
uint8_t block_index = block_buffer_tail; if (degTargetHotend0() + 2 < autotemp_min) return; // probably temperature set to zero.
while(block_index != block_buffer_head) { float high = 0.0;
if((block_buffer[block_index].steps_x != 0) || uint8_t block_index = block_buffer_tail;
(block_buffer[block_index].steps_y != 0) ||
(block_buffer[block_index].steps_z != 0)) { while (block_index != block_buffer_head) {
float se=(float(block_buffer[block_index].steps_e)/float(block_buffer[block_index].step_event_count))*block_buffer[block_index].nominal_speed; block_t *block = &block_buffer[block_index];
//se; mm/sec; if (block->steps[X_AXIS] || block->steps[Y_AXIS] || block->steps[Z_AXIS]) {
if(se>high) float se = (float)block->steps[E_AXIS] / block->step_event_count * block->nominal_speed; // mm/sec;
{ if (se > high) high = se;
high=se;
} }
block_index = next_block_index(block_index);
} }
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
}
float g=autotemp_min+high*autotemp_factor; float t = autotemp_min + high * autotemp_factor;
float t=g; if (t < autotemp_min) t = autotemp_min;
if(t<autotemp_min) if (t > autotemp_max) t = autotemp_max;
t=autotemp_min; if (oldt > t) t = AUTOTEMP_OLDWEIGHT * oldt + (1 - AUTOTEMP_OLDWEIGHT) * t;
if(t>autotemp_max) oldt = t;
t=autotemp_max; setTargetHotend0(t);
if(oldt>t)
{
t=AUTOTEMP_OLDWEIGHT*oldt+(1-AUTOTEMP_OLDWEIGHT)*t;
} }
oldt=t;
setTargetHotend0(t);
}
#endif #endif
void check_axes_activity() void check_axes_activity() {
{ unsigned char axis_active[NUM_AXIS],
unsigned char x_active = 0; tail_fan_speed = fanSpeed;
unsigned char y_active = 0;
unsigned char z_active = 0;
unsigned char e_active = 0;
unsigned char tail_fan_speed = fanSpeed;
#ifdef BARICUDA #ifdef BARICUDA
unsigned char tail_valve_pressure = ValvePressure; unsigned char tail_valve_pressure = ValvePressure,
unsigned char tail_e_to_p_pressure = EtoPPressure; tail_e_to_p_pressure = EtoPPressure;
#endif #endif
#ifdef LASERBEAM #ifdef LASERBEAM
unsigned char tail_laser_ttl_modulation = laser_ttl_modulation; unsigned char tail_laser_ttl_modulation = laser_ttl_modulation;
#endif #endif
block_t *block; block_t *block;
if(block_buffer_tail != block_buffer_head) if (blocks_queued()) {
{
uint8_t block_index = block_buffer_tail; uint8_t block_index = block_buffer_tail;
tail_fan_speed = block_buffer[block_index].fan_speed; tail_fan_speed = block_buffer[block_index].fan_speed;
#ifdef BARICUDA #ifdef BARICUDA
tail_valve_pressure = block_buffer[block_index].valve_pressure; block = &block_buffer[block_index];
tail_e_to_p_pressure = block_buffer[block_index].e_to_p_pressure; tail_valve_pressure = block->valve_pressure;
tail_e_to_p_pressure = block->e_to_p_pressure;
#endif #endif
#ifdef LASERBEAM #ifdef LASERBEAM
tail_laser_ttl_modulation = block_buffer[block_index].laser_ttlmodulation; tail_laser_ttl_modulation = block_buffer[block_index].laser_ttlmodulation;
#endif #endif
while(block_index != block_buffer_head) while (block_index != block_buffer_head) {
{
block = &block_buffer[block_index]; block = &block_buffer[block_index];
if(block->steps_x != 0) x_active++; for (int i=0; i<NUM_AXIS; i++) if (block->steps[i]) axis_active[i]++;
if(block->steps_y != 0) y_active++; block_index = next_block_index(block_index);
if(block->steps_z != 0) z_active++;
if(block->steps_e != 0) e_active++;
block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
} }
} }
if((DISABLE_X) && (x_active == 0)) disable_x(); if (DISABLE_X && !axis_active[X_AXIS]) disable_x();
if((DISABLE_Y) && (y_active == 0)) disable_y(); if (DISABLE_Y && !axis_active[Y_AXIS]) disable_y();
if((DISABLE_Z) && (z_active == 0)) disable_z(); if (DISABLE_Z && !axis_active[Z_AXIS]) disable_z();
if((DISABLE_E) && (e_active == 0)) if (DISABLE_E && !axis_active[E_AXIS]) {
{
disable_e0(); disable_e0();
disable_e1(); disable_e1();
disable_e2(); disable_e2();
disable_e3(); disable_e3();
} }
#if defined(FAN_PIN) && FAN_PIN > -1
#ifdef FAN_KICKSTART_TIME
static unsigned long fan_kick_end;
if (tail_fan_speed) {
if (fan_kick_end == 0) {
// Just starting up fan - run at full power.
fan_kick_end = millis() + FAN_KICKSTART_TIME;
tail_fan_speed = 255;
} else if (fan_kick_end > millis())
// Fan still spinning up.
tail_fan_speed = 255;
} else {
fan_kick_end = 0;
}
#endif//FAN_KICKSTART_TIME
#ifdef FAN_SOFT_PWM
fanSpeedSoftPwm = tail_fan_speed;
#else
analogWrite(FAN_PIN,tail_fan_speed);
#endif//!FAN_SOFT_PWM
#endif//FAN_PIN > -1
#ifdef AUTOTEMP
getHighESpeed();
#endif
#ifdef BARICUDA #if defined(FAN_PIN) && FAN_PIN > -1 // HAS_FAN
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 #ifdef FAN_KICKSTART_TIME
analogWrite(HEATER_1_PIN,tail_valve_pressure); static unsigned long fan_kick_end;
if (tail_fan_speed) {
if (fan_kick_end == 0) {
// Just starting up fan - run at full power.
fan_kick_end = millis() + FAN_KICKSTART_TIME;
tail_fan_speed = 255;
} else if (fan_kick_end > millis())
// Fan still spinning up.
tail_fan_speed = 255;
} else {
fan_kick_end = 0;
}
#endif//FAN_KICKSTART_TIME
#ifdef FAN_SOFT_PWM
fanSpeedSoftPwm = tail_fan_speed;
#else
analogWrite(FAN_PIN, tail_fan_speed);
#endif //!FAN_SOFT_PWM
#endif //FAN_PIN > -1
#ifdef AUTOTEMP
getHighESpeed();
#endif #endif
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 #ifdef BARICUDA
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 // HAS_HEATER_1
analogWrite(HEATER_1_PIN,tail_valve_pressure);
#endif
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 // HAS_HEATER_2
analogWrite(HEATER_2_PIN,tail_e_to_p_pressure); analogWrite(HEATER_2_PIN,tail_e_to_p_pressure);
#endif
#endif #endif
#endif
// add Laser TTL Modulation(PWM) Control
#ifdef LASERBEAM
analogWrite(LASER_TTL_PIN, tail_laser_ttl_modulation);
#endif
// add Laser TTL Modulation(PWM) Control
#ifdef LASERBEAM
analogWrite(LASER_TTL_PIN, tail_laser_ttl_modulation);
#endif
} }
float junction_deviation = 0.1; float junction_deviation = 0.1;
// Add a new linear movement to the buffer. steps_x, _y and _z is the absolute position in // Add a new linear movement to the buffer. steps[X_AXIS], _y and _z is the absolute position in
// mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration // mm. Microseconds specify how many microseconds the move should take to perform. To aid acceleration
// calculation the caller must also provide the physical length of the line in millimeters. // calculation the caller must also provide the physical length of the line in millimeters.
#ifdef ENABLE_AUTO_BED_LEVELING #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) void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate, const uint8_t &extruder, const uint8_t &driver)
#else #else
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_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)
#endif //ENABLE_AUTO_BED_LEVELING #endif //ENABLE_AUTO_BED_LEVELING
{ {
// Calculate the buffer head after we push this byte // Calculate the buffer head after we push this byte
...@@ -537,68 +477,64 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa ...@@ -537,68 +477,64 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
// If the buffer is full: good! That means we are well ahead of the robot. // If the buffer is full: good! That means we are well ahead of the robot.
// Rest here until there is room in the buffer. // Rest here until there is room in the buffer.
while(block_buffer_tail == next_buffer_head) while(block_buffer_tail == next_buffer_head) {
{
manage_heater(); manage_heater();
manage_inactivity(); manage_inactivity();
lcd_update(); lcd_update();
} }
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
apply_rotation_xyz(plan_bed_level_matrix, x, y, z); apply_rotation_xyz(plan_bed_level_matrix, x, y, z);
#endif // ENABLE_AUTO_BED_LEVELING #endif // ENABLE_AUTO_BED_LEVELING
// The target position of the tool in absolute steps // The target position of the tool in absolute steps
// Calculate target position in absolute steps // Calculate target position in absolute steps
//this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow //this should be done after the wait, because otherwise a M92 code within the gcode disrupts this calculation somehow
long target[4]; long target[NUM_AXIS];
target[X_AXIS] = lround(x*axis_steps_per_unit[X_AXIS]); target[X_AXIS] = lround(x * axis_steps_per_unit[X_AXIS]);
target[Y_AXIS] = lround(y*axis_steps_per_unit[Y_AXIS]); target[Y_AXIS] = lround(y * axis_steps_per_unit[Y_AXIS]);
target[Z_AXIS] = lround(z*axis_steps_per_unit[Z_AXIS]); target[Z_AXIS] = lround(z * axis_steps_per_unit[Z_AXIS]);
target[E_AXIS] = lround(e*axis_steps_per_unit[E_AXIS + active_extruder]); target[E_AXIS] = lround(e * axis_steps_per_unit[E_AXIS + active_extruder]);
#ifdef PREVENT_DANGEROUS_EXTRUDE float dx = target[X_AXIS] - position[X_AXIS],
#ifdef NPR2 dy = target[Y_AXIS] - position[Y_AXIS],
if(target[E_AXIS]!=position[E_AXIS]) dz = target[Z_AXIS] - position[Z_AXIS],
{ de = target[E_AXIS] - position[E_AXIS];
if (active_extruder!=1)
{ #ifdef PREVENT_DANGEROUS_EXTRUDE
if(degHotend(active_extruder)<extrude_min_temp && !debugDryrun()) if (de) {
{ #ifdef NPR2
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part if (active_extruder!=1) {
SERIAL_ECHO_START; if(degHotend(active_extruder) < extrude_min_temp && !debugDryrun()) {
SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); position[E_AXIS] = target[E_AXIS]; //behave as if the move really took place, but ignore E part
} SERIAL_ECHO_START;
} SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
#else // NO NPR2 }
if(target[E_AXIS]!=position[E_AXIS]) }
{ #else // NO NPR2
if(degHotend(active_extruder)<extrude_min_temp && !debugDryrun()) if(degHotend(active_extruder) < extrude_min_temp && !debugDryrun()) {
{ position[E_AXIS] = target[E_AXIS]; //behave as if the move really took place, but ignore E part
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part SERIAL_ECHO_START;
SERIAL_ECHO_START; SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP);
SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); }
} #endif // NPR2
#endif // NPR2
#ifdef PREVENT_LENGTHY_EXTRUDE
#ifdef PREVENT_LENGTHY_EXTRUDE if(labs(de) > axis_steps_per_unit[E_AXIS + active_extruder] * EXTRUDE_MAXLENGTH) {
if(labs(target[E_AXIS]-position[E_AXIS])>axis_steps_per_unit[active_extruder+3]*EXTRUDE_MAXLENGTH) #ifdef EASY_LOAD
{ if (!allow_lengthy_extrude_once) {
#ifdef EASY_LOAD #endif
if (!allow_lengthy_extrude_once) { position[E_AXIS] = target[E_AXIS]; //behave as if the move really took place, but ignore E part
#endif SERIAL_ECHO_START;
position[E_AXIS]=target[E_AXIS]; //behave as if the move really took place, but ignore E part SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP);
SERIAL_ECHO_START; #ifdef EASY_LOAD
SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); }
#ifdef EASY_LOAD allow_lengthy_extrude_once = false;
} #endif
allow_lengthy_extrude_once = false; }
#endif #endif // PREVENT_LENGTHY_EXTRUDE
} }
#endif // PREVENT_LENGTHY_EXTRUDE #endif // PREVENT_DANGEROUS_EXTRUDE
}
#endif // PREVENT_DANGEROUS_EXTRUDE
// Prepare to set up new block // Prepare to set up new block
block_t *block = &block_buffer[block_buffer_head]; block_t *block = &block_buffer[block_buffer_head];
...@@ -607,140 +543,125 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa ...@@ -607,140 +543,125 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
block->busy = false; block->busy = false;
// Number of steps for each axis // Number of steps for each axis
#ifndef COREXY #ifdef COREXY
// default non-h-bot planning // corexy planning
block->steps_x = labs(target[X_AXIS]-position[X_AXIS]); // these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html
block->steps_y = labs(target[Y_AXIS]-position[Y_AXIS]); block->steps[A_AXIS] = labs(dx + dy);
#else block->steps[B_AXIS] = labs(dx - dy);
// corexy planning #else
// these equations follow the form of the dA and dB equations on http://www.corexy.com/theory.html // default non-h-bot planning
block->steps_x = labs((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS])); block->steps[X_AXIS] = labs(dx);
block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS])); block->steps[Y_AXIS] = labs(dy);
#endif #endif
block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]);
block->steps_e = labs(target[E_AXIS]-position[E_AXIS]); block->steps[Z_AXIS] = labs(dz);
block->steps_e *= volumetric_multiplier[active_extruder]; block->steps[E_AXIS] = labs(de);
block->steps_e *= extruder_multiplier[active_extruder]; block->steps[E_AXIS] *= volumetric_multiplier[active_extruder];
block->steps_e /= 100; block->steps[E_AXIS] *= extruder_multiplier[active_extruder];
block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e))); block->steps[E_AXIS] /= 100;
block->step_event_count = max(block->steps[X_AXIS], max(block->steps[Y_AXIS], max(block->steps[Z_AXIS], block->steps[E_AXIS])));
// Bail if this is a zero-length block // Bail if this is a zero-length block
if (block->step_event_count <= dropsegments) if (block->step_event_count <= dropsegments) return;
{
return;
}
block->fan_speed = fanSpeed; block->fan_speed = fanSpeed;
#ifdef BARICUDA #ifdef BARICUDA
block->valve_pressure = ValvePressure; block->valve_pressure = ValvePressure;
block->e_to_p_pressure = EtoPPressure; block->e_to_p_pressure = EtoPPressure;
#endif #endif
// Add update block variables for LASER BEAM control // Add update block variables for LASER BEAM control
#ifdef LASERBEAM #ifdef LASERBEAM
block->laser_ttlmodulation = laser_ttl_modulation; block->laser_ttlmodulation = laser_ttl_modulation;
#endif #endif
// Compute direction bits for this block // Compute direction bits for this block
block->direction_bits = 0; uint8_t db = 0;
#ifndef COREXY #ifdef COREXY
if (target[X_AXIS] < position[X_AXIS]) if (dx < 0) db |= BIT(X_HEAD); // Save the real Extruder (head) direction in X Axis
{ if (dy < 0) db |= BIT(Y_HEAD); // ...and Y
block->direction_bits |= BIT(X_AXIS); if (dx + dy < 0) db |= BIT(A_AXIS); // Motor A direction
} if (dx - dy < 0) db |= BIT(B_AXIS); // Motor B direction
if (target[Y_AXIS] < position[Y_AXIS]) #else
{ if (dx < 0) db |= BIT(X_AXIS);
block->direction_bits |= BIT(Y_AXIS); if (dy < 0) db |= BIT(Y_AXIS);
} #endif
#else //COREXY if (dz < 0) db |= BIT(Z_AXIS);
if (target[X_AXIS] < position[X_AXIS]) if (de < 0) db |= BIT(E_AXIS);
{ block->direction_bits = db;
block->direction_bits |= BIT(X_HEAD);
}
if (target[Y_AXIS] < position[Y_AXIS])
{
block->direction_bits |= BIT(Y_HEAD);
}
if ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]) < 0)
{
block->direction_bits |= BIT(X_AXIS);
}
if ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]) < 0)
{
block->direction_bits |= BIT(Y_AXIS);
}
#endif //COREXY
if (target[Z_AXIS] < position[Z_AXIS])
{
block->direction_bits |= BIT(Z_AXIS);
}
if (target[E_AXIS] < position[E_AXIS])
{
block->direction_bits |= BIT(E_AXIS);
}
block->active_driver = driver; block->active_driver = driver;
//enable active axes //enable active axes
#ifdef COREXY #ifdef COREXY
if((block->steps_x != 0) || (block->steps_y != 0)) { if (block->steps[A_AXIS] || block->steps[B_AXIS]) {
enable_x(); enable_x();
enable_y(); enable_y();
} }
#else //NO COREXY #else
if(block->steps_x != 0) enable_x(); if (block->steps[X_AXIS]) enable_x();
if(block->steps_y != 0) enable_y(); if (block->steps[Y_AXIS]) enable_y();
#endif //NOCOREXY #endif
#ifndef Z_LATE_ENABLE #ifndef Z_LATE_ENABLE
if(block->steps_z != 0) enable_z(); if (block->steps[Z_AXIS]) enable_z();
#endif #endif
// Enable extruder(s) // Enable extruder(s)
if(block->steps_e != 0) if (block->steps[E_AXIS]) {
{
#if !defined(MKR4) && !defined(NPR2) #if !defined(MKR4) && !defined(NPR2)
if (DISABLE_INACTIVE_EXTRUDER) //enable only selected extruder if (DISABLE_INACTIVE_EXTRUDER) { //enable only selected extruder
{
if(g_uc_extruder_last_move[0] > 0) g_uc_extruder_last_move[0]--; for (int i=0; i<EXTRUDERS; i++)
if(g_uc_extruder_last_move[1] > 0) g_uc_extruder_last_move[1]--; if (g_uc_extruder_last_move[i] > 0) g_uc_extruder_last_move[i]--;
if(g_uc_extruder_last_move[2] > 0) g_uc_extruder_last_move[2]--;
if(g_uc_extruder_last_move[3] > 0) g_uc_extruder_last_move[3]--;
switch(extruder) switch(extruder) {
{
case 0: case 0:
enable_e0(); enable_e0();
g_uc_extruder_last_move[0] = BLOCK_BUFFER_SIZE*2; g_uc_extruder_last_move[0] = BLOCK_BUFFER_SIZE * 2;
#if EXTRUDERS > 1
if(g_uc_extruder_last_move[1] == 0) disable_e1(); if (g_uc_extruder_last_move[1] == 0) disable_e1();
if(g_uc_extruder_last_move[2] == 0) disable_e2(); #if EXTRUDERS > 2
if(g_uc_extruder_last_move[3] == 0) disable_e3(); if (g_uc_extruder_last_move[2] == 0) disable_e2();
break; #if EXTRUDERS > 3
case 1: if (g_uc_extruder_last_move[3] == 0) disable_e3();
enable_e1(); #endif
g_uc_extruder_last_move[1] = BLOCK_BUFFER_SIZE*2; #endif
#endif
if(g_uc_extruder_last_move[0] == 0) disable_e0();
if(g_uc_extruder_last_move[2] == 0) disable_e2();
if(g_uc_extruder_last_move[3] == 0) disable_e3();
break;
case 2:
enable_e2();
g_uc_extruder_last_move[2] = BLOCK_BUFFER_SIZE*2;
if(g_uc_extruder_last_move[0] == 0) disable_e0();
if(g_uc_extruder_last_move[1] == 0) disable_e1();
if(g_uc_extruder_last_move[3] == 0) disable_e3();
break;
case 3:
enable_e3();
g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE*2;
if(g_uc_extruder_last_move[0] == 0) disable_e0();
if(g_uc_extruder_last_move[1] == 0) disable_e1();
if(g_uc_extruder_last_move[2] == 0) disable_e2();
break; break;
#if EXTRUDERS > 1
case 1:
enable_e1();
g_uc_extruder_last_move[1] = BLOCK_BUFFER_SIZE*2;
if (g_uc_extruder_last_move[0] == 0) disable_e0();
#if EXTRUDERS > 2
if (g_uc_extruder_last_move[2] == 0) disable_e2();
#if EXTRUDERS > 3
if (g_uc_extruder_last_move[3] == 0) disable_e3();
#endif
#endif
break;
#if EXTRUDERS > 2
case 2:
enable_e2();
g_uc_extruder_last_move[2] = BLOCK_BUFFER_SIZE*2;
if (g_uc_extruder_last_move[0] == 0) disable_e0();
if (g_uc_extruder_last_move[1] == 0) disable_e1();
#if EXTRUDERS > 3
if (g_uc_extruder_last_move[3] == 0) disable_e3();
#endif
break;
#if EXTRUDERS > 3
case 3:
enable_e3();
g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE*2;
if (g_uc_extruder_last_move[0] == 0) disable_e0();
if (g_uc_extruder_last_move[1] == 0) disable_e1();
if (g_uc_extruder_last_move[2] == 0) disable_e2();
break;
#endif // EXTRUDERS > 3
#endif // EXTRUDERS > 2
#endif // EXTRUDERS > 1
} }
} }
else //enable all else //enable all
...@@ -767,133 +688,110 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi ...@@ -767,133 +688,110 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi
break; break;
} }
#endif //!MKR4 && !NPR2 #endif //!MKR4 && !NPR2
if (feed_rate < minimumfeedrate) feed_rate = minimumfeedrate;
} }
else if (feed_rate < mintravelfeedrate) feed_rate = mintravelfeedrate;
if (block->steps_e == 0)
{ /**
if(feed_rate<mintravelfeedrate) feed_rate=mintravelfeedrate; * This part of the code calculates the total length of the movement.
} * For cartesian bots, the X_AXIS is the real X movement and same for Y_AXIS.
else * But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS
{ * and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y.
if(feed_rate<minimumfeedrate) feed_rate=minimumfeedrate; * So we need to create other 2 "AXIS", named X_HEAD and Y_HEAD, meaning the real displacement of the Head.
} * Having the real displacement of the head, we can calculate the total movement length and apply the desired speed.
*/
/* This part of the code calculates the total length of the movement. #ifdef COREXY
For cartesian bots, the X_AXIS is the real X movement and same for Y_AXIS.
But for corexy bots, that is not true. The "X_AXIS" and "Y_AXIS" motors (that should be named to A_AXIS
and B_AXIS) cannot be used for X and Y length, because A=X+Y and B=X-Y.
So we need to create other 2 "AXIS", named X_HEAD and Y_HEAD, meaning the real displacement of the Head.
Having the real displacement of the head, we can calculate the total movement length and apply the desired speed.
*/
#ifndef COREXY
float delta_mm[4];
delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
#else
float delta_mm[6]; float delta_mm[6];
delta_mm[X_HEAD] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS]; delta_mm[X_HEAD] = dx / axis_steps_per_unit[A_AXIS];
delta_mm[Y_HEAD] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS]; delta_mm[Y_HEAD] = dy / axis_steps_per_unit[B_AXIS];
delta_mm[X_AXIS] = ((target[X_AXIS]-position[X_AXIS]) + (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[X_AXIS]; delta_mm[A_AXIS] = (dx + dy) / axis_steps_per_unit[A_AXIS];
delta_mm[Y_AXIS] = ((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-position[Y_AXIS]))/axis_steps_per_unit[Y_AXIS]; delta_mm[B_AXIS] = (dx - dy) / axis_steps_per_unit[B_AXIS];
#else
float delta_mm[4];
delta_mm[X_AXIS] = dx / axis_steps_per_unit[X_AXIS];
delta_mm[Y_AXIS] = dy / axis_steps_per_unit[Y_AXIS];
#endif #endif
delta_mm[Z_AXIS] = (target[Z_AXIS]-position[Z_AXIS])/axis_steps_per_unit[Z_AXIS]; delta_mm[Z_AXIS] = dz / axis_steps_per_unit[Z_AXIS];
delta_mm[E_AXIS] = ((target[E_AXIS]-position[E_AXIS])/axis_steps_per_unit[active_extruder+3])*volumetric_multiplier[active_extruder]*extruder_multiplier[active_extruder]/100.0; delta_mm[E_AXIS] = (de / axis_steps_per_unit[E_AXIS + active_extruder]) * volumetric_multiplier[active_extruder] * extruder_multiplier[active_extruder] / 100.0;
if ( block->steps_x <=dropsegments && block->steps_y <=dropsegments && block->steps_z <=dropsegments )
{ if (block->steps[X_AXIS] <= dropsegments && block->steps[Y_AXIS] <= dropsegments && block->steps[Z_AXIS] <= dropsegments) {
block->millimeters = fabs(delta_mm[E_AXIS]); block->millimeters = fabs(delta_mm[E_AXIS]);
}
else
{
#ifndef COREXY
block->millimeters = sqrt(square(delta_mm[X_AXIS]) + square(delta_mm[Y_AXIS]) + square(delta_mm[Z_AXIS]));
#else
block->millimeters = sqrt(square(delta_mm[X_HEAD]) + square(delta_mm[Y_HEAD]) + square(delta_mm[Z_AXIS]));
#endif
} }
float inverse_millimeters = 1.0/block->millimeters; // Inverse millimeters to remove multiple divides else {
block->millimeters = sqrt(
#ifdef COREXY
square(delta_mm[X_HEAD]) + square(delta_mm[Y_HEAD])
#else
square(delta_mm[X_AXIS]) + square(delta_mm[Y_AXIS])
#endif
+ square(delta_mm[Z_AXIS])
);
}
float inverse_millimeters = 1.0 / block->millimeters; // Inverse millimeters to remove multiple divides
// Calculate speed in mm/second for each axis. No divide by zero due to previous checks. // Calculate speed in mm/second for each axis. No divide by zero due to previous checks.
float inverse_second = feed_rate * inverse_millimeters; float inverse_second = feed_rate * inverse_millimeters;
int moves_queued=(block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1); 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
#ifdef OLD_SLOWDOWN bool mq = moves_queued > 1 && moves_queued < BLOCK_BUFFER_SIZE / 2;
if(moves_queued < (BLOCK_BUFFER_SIZE * 0.5) && moves_queued > 1) #ifdef OLD_SLOWDOWN
feed_rate = feed_rate*moves_queued / (BLOCK_BUFFER_SIZE * 0.5); if (mq) feed_rate *= 2.0 * moves_queued / BLOCK_BUFFER_SIZE;
#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)); #ifdef XY_FREQUENCY_LIMIT
#ifdef XY_FREQUENCY_LIMIT segment_time = lround(1000000.0 / inverse_second);
segment_time = lround(1000000.0/inverse_second); #endif
#endif }
} }
} #endif // SLOWDOWN
#endif // SLOWDOWN // END OF SLOW DOWN SECTION
// END OF SLOW DOWN SECTION
block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0 block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0
block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0 block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0
#if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) #ifdef FILAMENT_SENSOR
//FMM update ring buffer used for delay with filament measurements //FMM update ring buffer used for delay with filament measurements
if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM && delay_index2 > -1) { //only for extruder with filament sensor and if ring buffer is initialized
if((extruder==FILAMENT_SENSOR_EXTRUDER_NUM) && (delay_index2 > -1)) //only for extruder with filament sensor and if ring buffer is initialized
{ const int MMD = MAX_MEASUREMENT_DELAY + 1, MMD10 = MMD * 10;
delay_dist = 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 >= (10*(MAX_MEASUREMENT_DELAY+1))) //check if counter is over max buffer size in mm while (delay_dist >= MMD10) delay_dist -= MMD10; // loop around the buffer
delay_dist = delay_dist - 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer while (delay_dist < 0) delay_dist += MMD10;
while (delay_dist<0)
delay_dist = delay_dist + 10*(MAX_MEASUREMENT_DELAY+1); //loop around the buffer
delay_index1=delay_dist/10.0; //calculate index
//ensure the number is within range of the array after converting from floating point
if(delay_index1<0)
delay_index1=0;
else if (delay_index1>MAX_MEASUREMENT_DELAY)
delay_index1=MAX_MEASUREMENT_DELAY;
if(delay_index1 != delay_index2) //moved index
{
meas_sample=widthFil_to_size_ratio()-100; //subtract off 100 to reduce magnitude - to store in a signed char
}
while( delay_index1 != delay_index2)
{
delay_index2 = delay_index2 + 1;
if(delay_index2>MAX_MEASUREMENT_DELAY)
delay_index2=delay_index2-(MAX_MEASUREMENT_DELAY+1); //loop around buffer when incrementing
if(delay_index2<0)
delay_index2=0;
else if (delay_index2>MAX_MEASUREMENT_DELAY)
delay_index2=MAX_MEASUREMENT_DELAY;
measurement_delay[delay_index2]=meas_sample;
}
}
#endif
delay_index1 = delay_dist / 10.0; // calculate index
delay_index1 = constrain(delay_index1, 0, MAX_MEASUREMENT_DELAY); // (already constrained above)
if (delay_index1 != delay_index2) { // moved index
meas_sample = widthFil_to_size_ratio() - 100; // Subtract 100 to reduce magnitude - to store in a signed char
while (delay_index1 != delay_index2) {
// Increment and loop around buffer
if (++delay_index2 >= MMD) delay_index2 -= MMD;
delay_index2 = constrain(delay_index2, 0, MAX_MEASUREMENT_DELAY);
measurement_delay[delay_index2] = meas_sample;
}
}
}
#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;
if(fabs(current_speed[i]) > max_feedrate[i]) float cs = fabs(current_speed[i]), mf = max_feedrate[i];
speed_factor = min(speed_factor, max_feedrate[i] / fabs(current_speed[i])); if (cs > mf) speed_factor = min(speed_factor, mf / cs);
} }
current_speed[E_AXIS] = delta_mm[E_AXIS] * inverse_second; current_speed[E_AXIS] = delta_mm[E_AXIS] * inverse_second;
...@@ -909,148 +807,149 @@ Having the real displacement of the head, we can calculate the total movement le ...@@ -909,148 +807,149 @@ Having the real displacement of the head, we can calculate the total movement le
} }
// 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
unsigned char direction_change = block->direction_bits ^ old_direction_bits; // Check and limit the xy direction change frequency
old_direction_bits = block->direction_bits; unsigned char direction_change = block->direction_bits ^ old_direction_bits;
segment_time = lround((float)segment_time / speed_factor); old_direction_bits = block->direction_bits;
segment_time = lround((float)segment_time / speed_factor);
if((direction_change & BIT(X_AXIS)) == 0) long xs0 = axis_segment_time[X_AXIS][0],
{ xs1 = axis_segment_time[X_AXIS][1],
x_segment_time[0] += segment_time; xs2 = axis_segment_time[X_AXIS][2],
} ys0 = axis_segment_time[Y_AXIS][0],
else ys1 = axis_segment_time[Y_AXIS][1],
{ ys2 = axis_segment_time[Y_AXIS][2];
x_segment_time[2] = x_segment_time[1];
x_segment_time[1] = x_segment_time[0]; if ((direction_change & BIT(X_AXIS)) != 0) {
x_segment_time[0] = segment_time; xs2 = axis_segment_time[X_AXIS][2] = xs1;
} xs1 = axis_segment_time[X_AXIS][1] = xs0;
if((direction_change & BIT(Y_AXIS)) == 0) xs0 = 0;
{ }
y_segment_time[0] += segment_time; xs0 = axis_segment_time[X_AXIS][0] = xs0 + segment_time;
}
else
{
y_segment_time[2] = y_segment_time[1];
y_segment_time[1] = y_segment_time[0];
y_segment_time[0] = segment_time;
}
long max_x_segment_time = max(x_segment_time[0], max(x_segment_time[1], x_segment_time[2]));
long max_y_segment_time = max(y_segment_time[0], max(y_segment_time[1], y_segment_time[2]));
long min_xy_segment_time =min(max_x_segment_time, max_y_segment_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);
#endif // XY_FREQUENCY_LIMIT
// Correct the speed if ((direction_change & BIT(Y_AXIS)) != 0) {
if( speed_factor < 1.0) 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];
for(unsigned char i=0; i < 4; i++) ys0 = 0;
{ }
current_speed[i] *= speed_factor; ys0 = axis_segment_time[Y_AXIS][0] = ys0 + segment_time;
long max_x_segment_time = max(xs0, max(xs1, xs2)),
max_y_segment_time = max(ys0, max(ys1, ys2)),
min_xy_segment_time = min(max_x_segment_time, max_y_segment_time);
if (min_xy_segment_time < 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
// Correct the speed
if (speed_factor < 1.0) {
for (unsigned char i = 0; i < NUM_AXIS; i++) 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 == 0 && block->steps_y == 0 && block->steps_z == 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 == 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 / (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 / (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 / (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 / (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_st = acc_st;
block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); 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
// Compute path unit vector #if 0 // Use old jerk for now
double unit_vec[3]; // Compute path unit vector
double unit_vec[3];
unit_vec[X_AXIS] = delta_mm[X_AXIS]*inverse_millimeters;
unit_vec[Y_AXIS] = delta_mm[Y_AXIS]*inverse_millimeters; unit_vec[X_AXIS] = delta_mm[X_AXIS]*inverse_millimeters;
unit_vec[Z_AXIS] = delta_mm[Z_AXIS]*inverse_millimeters; unit_vec[Y_AXIS] = delta_mm[Y_AXIS]*inverse_millimeters;
unit_vec[Z_AXIS] = delta_mm[Z_AXIS]*inverse_millimeters;
// Compute maximum allowable entry speed at junction by centripetal acceleration approximation.
// Let a circle be tangent to both previous and current path line segments, where the junction // Compute maximum allowable entry speed at junction by centripetal acceleration approximation.
// deviation is defined as the distance from the junction to the closest edge of the circle, // Let a circle be tangent to both previous and current path line segments, where the junction
// colinear with the circle center. The circular segment joining the two paths represents the // deviation is defined as the distance from the junction to the closest edge of the circle,
// path of centripetal acceleration. Solve for max velocity based on max acceleration about the // colinear with the circle center. The circular segment joining the two paths represents the
// radius of the circle, defined indirectly by junction deviation. This may be also viewed as // path of centripetal acceleration. Solve for max velocity based on max acceleration about the
// path width or max_jerk in the previous grbl version. This approach does not actually deviate // radius of the circle, defined indirectly by junction deviation. This may be also viewed as
// from path, but used as a robust way to compute cornering speeds, as it takes into account the // path width or max_jerk in the previous grbl version. This approach does not actually deviate
// nonlinearities of both the junction angle and junction velocity. // from path, but used as a robust way to compute cornering speeds, as it takes into account the
double vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed // nonlinearities of both the junction angle and junction velocity.
double vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed
// Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
if ((block_buffer_head != block_buffer_tail) && (previous_nominal_speed > 0.0)) { // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
// Compute cosine of angle between previous and current path. (prev_unit_vec is negative) if ((block_buffer_head != block_buffer_tail) && (previous_nominal_speed > 0.0)) {
// NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity. // Compute cosine of angle between previous and current path. (prev_unit_vec is negative)
double cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] // NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity.
- previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] double cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS]
- previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ; - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS]
- previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ;
// Skip and use default max junction speed for 0 degree acute junction.
if (cos_theta < 0.95) { // Skip and use default max junction speed for 0 degree acute junction.
vmax_junction = min(previous_nominal_speed,block->nominal_speed); if (cos_theta < 0.95) {
// Skip and avoid divide by zero for straight junctions at 180 degrees. Limit to min() of nominal speeds. vmax_junction = min(previous_nominal_speed,block->nominal_speed);
if (cos_theta > -0.95) { // Skip and avoid divide by zero for straight junctions at 180 degrees. Limit to min() of nominal speeds.
// Compute maximum junction velocity based on maximum acceleration and junction deviation if (cos_theta > -0.95) {
double sin_theta_d2 = sqrt(0.5*(1.0-cos_theta)); // Trig half angle identity. Always positive. // Compute maximum junction velocity based on maximum acceleration and junction deviation
vmax_junction = min(vmax_junction, double sin_theta_d2 = sqrt(0.5*(1.0-cos_theta)); // Trig half angle identity. Always positive.
sqrt(block->acceleration * junction_deviation * sin_theta_d2/(1.0-sin_theta_d2)) ); vmax_junction = min(vmax_junction,
sqrt(block->acceleration * junction_deviation * sin_theta_d2/(1.0-sin_theta_d2)) );
}
} }
} }
} #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
...@@ -1061,115 +960,91 @@ Having the real displacement of the head, we can calculate the total movement le ...@@ -1061,115 +960,91 @@ Having the real displacement of the head, we can calculate the total movement le
// 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 (!bse || (!bsx && !bsy && !bsz)) {
if((block->steps_e == 0) || (block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)) {
block->advance_rate = 0;
block->advance = 0;
}
else {
long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st);
float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) *
(current_speed[E_AXIS] * current_speed[E_AXIS] * EXTRUSION_AREA * EXTRUSION_AREA)*256;
block->advance = advance;
if(acc_dist == 0) {
block->advance_rate = 0; block->advance_rate = 0;
} block->advance = 0;
}
else { else {
block->advance_rate = advance / (float)acc_dist; long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st);
float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) * (cse * cse * EXTRUSION_AREA * EXTRUSION_AREA) * 256;
block->advance = advance;
block->advance_rate = acc_dist ? advance / (float)acc_dist : 0;
} }
} /*
/* SERIAL_ECHO_START;
SERIAL_ECHO_START; SERIAL_ECHOPGM("advance :");
SERIAL_ECHOPGM("advance :"); SERIAL_ECHO(block->advance/256.0);
SERIAL_ECHO(block->advance/256.0); SERIAL_ECHOPGM("advance rate :");
SERIAL_ECHOPGM("advance rate :"); SERIAL_ECHOLN(block->advance_rate/256.0);
SERIAL_ECHOLN(block->advance_rate/256.0); */
*/ #endif // ADVANCE
#endif // ADVANCE
calculate_trapezoid_for_block(block, block->entry_speed / block->nominal_speed, safe_speed / block->nominal_speed);
calculate_trapezoid_for_block(block, block->entry_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");
//plan_bed_level_matrix.debug("in plan_get bed_level"); //plan_bed_level_matrix.debug("in plan_get bed_level");
matrix_3x3 inverse = matrix_3x3::transpose(plan_bed_level_matrix); matrix_3x3 inverse = matrix_3x3::transpose(plan_bed_level_matrix);
//inverse.debug("in plan_get inverse"); //inverse.debug("in plan_get inverse");
position.apply_rotation(inverse); position.apply_rotation(inverse);
//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];
}
} }
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
// the source g-code and may never actually be reached if acceleration management is active. // the source g-code and may never actually be reached if acceleration management is active.
typedef struct { typedef struct {
// Fields used by the bresenham algorithm for tracing the line // Fields used by the bresenham algorithm for tracing the line
long steps_x, steps_y, steps_z, steps_e; // Step count along each axis long steps[NUM_AXIS]; // Step count along each axis
unsigned long step_event_count; // The number of step events required to complete this block unsigned long step_event_count; // The number of step events required to complete this block
long accelerate_until; // The index of the step event on which to stop acceleration long accelerate_until; // The index of the step event on which to stop acceleration
long decelerate_after; // The index of the step event on which to start decelerating long decelerate_after; // The index of the step event on which to start decelerating
...@@ -49,7 +49,7 @@ typedef struct { ...@@ -49,7 +49,7 @@ typedef struct {
#endif #endif
// Fields used by the motion planner to manage acceleration // Fields used by the motion planner to manage acceleration
// float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis // float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis
float nominal_speed; // The nominal speed for this block in mm/sec float nominal_speed; // The nominal speed for this block in mm/sec
float entry_speed; // Entry speed at previous-current junction in mm/sec float entry_speed; // Entry speed at previous-current junction in mm/sec
float max_entry_speed; // Maximum allowable junction entry speed in mm/sec float max_entry_speed; // Maximum allowable junction entry speed in mm/sec
...@@ -74,40 +74,36 @@ typedef struct { ...@@ -74,40 +74,36 @@ typedef struct {
volatile char busy; volatile char busy;
} block_t; } block_t;
#ifdef ENABLE_AUTO_BED_LEVELING #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
// 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
...@@ -124,41 +120,39 @@ extern float mintravelfeedrate; ...@@ -124,41 +120,39 @@ extern float mintravelfeedrate;
extern unsigned long axis_steps_per_sqr_second[3 + EXTRUDERS]; extern unsigned long axis_steps_per_sqr_second[3 + EXTRUDERS];
#ifdef AUTOTEMP #ifdef AUTOTEMP
extern bool autotemp_enabled; extern bool autotemp_enabled;
extern float autotemp_max; extern float autotemp_max;
extern float autotemp_min; extern float autotemp_min;
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) { block_t *block = &block_buffer[block_buffer_tail];
return(NULL); block->busy = true;
return block;
} }
block_t *block = &block_buffer[block_buffer_tail]; else
block->busy = true; return NULL;
return(block);
} }
// 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
...@@ -49,6 +49,12 @@ block_t *current_block; // A pointer to the block currently being traced ...@@ -49,6 +49,12 @@ block_t *current_block; // A pointer to the block currently being traced
static unsigned char out_bits; // The next stepping-bits to be output static unsigned char out_bits; // The next stepping-bits to be output
static unsigned int cleaning_buffer_counter; static unsigned int cleaning_buffer_counter;
#ifdef Z_DUAL_ENDSTOPS
static bool performing_homing = false,
locked_z_motor = false,
locked_z2_motor = false;
#endif
// Counter variables for the bresenham line tracer // Counter variables for the bresenham line tracer
static long counter_x, counter_y, counter_z, counter_e; static long counter_x, counter_y, counter_z, counter_e;
volatile static unsigned long step_events_completed; // The number of step events executed in the current block volatile static unsigned long step_events_completed; // The number of step events executed in the current block
...@@ -73,8 +79,8 @@ static volatile bool endstop_y_hit = false; ...@@ -73,8 +79,8 @@ static volatile bool endstop_y_hit = false;
static volatile bool endstop_z_hit = false; static volatile bool endstop_z_hit = false;
#ifdef NPR2 #ifdef NPR2
static volatile bool endstop_e_hit=false; static volatile bool endstop_e_hit = false;
static bool old_e_min_endstop=false; static bool old_e_min_endstop = false;
#endif #endif
#ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
...@@ -89,7 +95,13 @@ static bool old_x_min_endstop = false, ...@@ -89,7 +95,13 @@ static bool old_x_min_endstop = false,
old_y_min_endstop = false, old_y_min_endstop = false,
old_y_max_endstop = false, old_y_max_endstop = false,
old_z_min_endstop = false, old_z_min_endstop = false,
old_z_max_endstop = false; #ifndef Z_DUAL_ENDSTOPS
old_z_max_endstop = false;
#else
old_z_max_endstop = false,
old_z2_min_endstop = false,
old_z2_max_endstop = false;
#endif
static bool check_endstops = true; static bool check_endstops = true;
...@@ -133,7 +145,27 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; ...@@ -133,7 +145,27 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
#ifdef Z_DUAL_STEPPER_DRIVERS #ifdef Z_DUAL_STEPPER_DRIVERS
#define Z_APPLY_DIR(v,Q) { Z_DIR_WRITE(v); Z2_DIR_WRITE(v); } #define Z_APPLY_DIR(v,Q) { Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }
<<<<<<< HEAD
#define Z_APPLY_STEP(v,Q) { Z_STEP_WRITE(v); Z2_STEP_WRITE(v); } #define Z_APPLY_STEP(v,Q) { Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }
=======
#ifdef Z_DUAL_ENDSTOPS
#define Z_APPLY_STEP(v,Q) \
if (performing_homing) { \
if (Z_HOME_DIR > 0) {\
if (!(old_z_max_endstop && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
if (!(old_z2_max_endstop && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
} else {\
if (!(old_z_min_endstop && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
if (!(old_z2_min_endstop && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
} \
} else { \
Z_STEP_WRITE(v); \
Z2_STEP_WRITE(v); \
}
#else
#define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v), Z2_STEP_WRITE(v)
#endif
>>>>>>> origin/master
#else #else
#define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v) #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v)
#define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v) #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v)
...@@ -417,7 +449,7 @@ ISR(TIMER1_COMPA_vect) { ...@@ -417,7 +449,7 @@ ISR(TIMER1_COMPA_vect) {
step_events_completed = 0; step_events_completed = 0;
#ifdef Z_LATE_ENABLE #ifdef Z_LATE_ENABLE
if (current_block->steps_z > 0) { if (current_block->steps[Z_AXIS] > 0) {
enable_z(); enable_z();
OCR1A = 2000; //1ms wait OCR1A = 2000; //1ms wait
return; return;
...@@ -458,7 +490,7 @@ ISR(TIMER1_COMPA_vect) { ...@@ -458,7 +490,7 @@ ISR(TIMER1_COMPA_vect) {
#define UPDATE_ENDSTOP(axis,AXIS,minmax,MINMAX) \ #define UPDATE_ENDSTOP(axis,AXIS,minmax,MINMAX) \
bool axis ##_## minmax ##_endstop = (READ(AXIS ##_## MINMAX ##_PIN) != AXIS ##_## MINMAX ##_ENDSTOP_INVERTING); \ bool axis ##_## minmax ##_endstop = (READ(AXIS ##_## MINMAX ##_PIN) != AXIS ##_## MINMAX ##_ENDSTOP_INVERTING); \
if (axis ##_## minmax ##_endstop && old_## axis ##_## minmax ##_endstop && (current_block->steps_## axis > 0)) { \ if (axis ##_## minmax ##_endstop && old_## axis ##_## minmax ##_endstop && (current_block->steps[AXIS ##_AXIS] > 0)) { \
endstops_trigsteps[AXIS ##_AXIS] = count_position[AXIS ##_AXIS]; \ endstops_trigsteps[AXIS ##_AXIS] = count_position[AXIS ##_AXIS]; \
endstop_## axis ##_hit = true; \ endstop_## axis ##_hit = true; \
step_events_completed = current_block->step_event_count; \ step_events_completed = current_block->step_event_count; \
...@@ -467,80 +499,117 @@ ISR(TIMER1_COMPA_vect) { ...@@ -467,80 +499,117 @@ ISR(TIMER1_COMPA_vect) {
// Check X and Y endstops // Check X and Y endstops
if (check_endstops) { if (check_endstops) {
#ifndef COREXY #ifdef COREXY
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular cartesians bot)
#else
// Head direction in -X axis for CoreXY bots. // Head direction in -X axis for CoreXY bots.
// If DeltaX == -DeltaY, the movement is only in Y axis // If DeltaX == -DeltaY, the movement is only in Y axis
if (current_block->steps_x != current_block->steps_y || (TEST(out_bits, X_AXIS) == TEST(out_bits, Y_AXIS))) if (current_block->steps[A_AXIS] != current_block->steps[B_AXIS] || (TEST(out_bits, A_AXIS) == TEST(out_bits, B_AXIS)))
if (TEST(out_bits, X_HEAD)) if (TEST(out_bits, X_HEAD))
#else
if (TEST(out_bits, X_AXIS)) // stepping along -X axis (regular cartesians bot)
#endif #endif
{ // -direction { // -direction
#ifdef DUAL_X_CARRIAGE #ifdef DUAL_X_CARRIAGE
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1)) if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1))
#endif #endif
{ {
#if defined(X_MIN_PIN) && X_MIN_PIN >= 0 #if defined(X_MIN_PIN) && X_MIN_PIN >= 0
UPDATE_ENDSTOP(x, X, min, MIN); UPDATE_ENDSTOP(x, X, min, MIN);
#endif #endif
} }
} }
else { // +direction else { // +direction
#ifdef DUAL_X_CARRIAGE #ifdef DUAL_X_CARRIAGE
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder // with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((current_block->active_driver == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1)) if ((current_block->active_driver == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1))
#endif #endif
{ {
#if defined(X_MAX_PIN) && X_MAX_PIN >= 0 #if defined(X_MAX_PIN) && X_MAX_PIN >= 0
UPDATE_ENDSTOP(x, X, max, MAX); UPDATE_ENDSTOP(x, X, max, MAX);
#endif #endif
} }
} }
#ifdef COREXY
#ifndef COREXY // Head direction in -Y axis for CoreXY bots.
// If DeltaX == DeltaY, the movement is only in X axis
if (current_block->steps[A_AXIS] != current_block->steps[B_AXIS] || (TEST(out_bits, A_AXIS) != TEST(out_bits, B_AXIS)))
if (TEST(out_bits, Y_HEAD))
#else
if (TEST(out_bits, Y_AXIS)) // -direction if (TEST(out_bits, Y_AXIS)) // -direction
#else #endif
// Head direction in -Y axis for CoreXY bots. { // -direction
// If DeltaX == DeltaY, the movement is only in X axis #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0
if (current_block->steps_x != current_block->steps_y || (TEST(out_bits, X_AXIS) != TEST(out_bits, Y_AXIS))) UPDATE_ENDSTOP(y, Y, min, MIN);
if (TEST(out_bits, Y_HEAD)) #endif
#endif }
{ // -direction else { // +direction
#if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0 #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
UPDATE_ENDSTOP(y, Y, min, MIN); UPDATE_ENDSTOP(y, Y, max, MAX);
#endif #endif
} }
else { // +direction
#if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
UPDATE_ENDSTOP(y, Y, max, MAX);
#endif
}
} }
if (TEST(out_bits, Z_AXIS)) { // -direction if (TEST(out_bits, Z_AXIS)) { // -direction
Z_DIR_WRITE(INVERT_Z_DIR); Z_APPLY_DIR(INVERT_Z_DIR,0);
#ifdef Z_DUAL_STEPPER_DRIVERS
Z2_DIR_WRITE(INVERT_Z_DIR);
#endif
count_direction[Z_AXIS] = -1; count_direction[Z_AXIS] = -1;
if (check_endstops) { if (check_endstops)
#if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0 {
UPDATE_ENDSTOP(z, Z, min, MIN); #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
#ifndef Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(z, Z, min, MIN);
#else
bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
#if defined(Z2_MIN_PIN) && Z2_MIN_PIN > -1
bool z2_min_endstop=(READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING);
#else
bool z2_min_endstop=z_min_endstop;
#endif
if(((z_min_endstop && old_z_min_endstop) || (z2_min_endstop && old_z2_min_endstop)) && (current_block->steps[Z_AXIS] > 0))
{
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_z_hit=true;
if (!(performing_homing) || ((performing_homing)&&(z_min_endstop && old_z_min_endstop)&&(z2_min_endstop && old_z2_min_endstop))) //if not performing home or if both endstops were trigged during homing...
{
step_events_completed = current_block->step_event_count;
}
}
old_z_min_endstop = z_min_endstop;
old_z2_min_endstop = z2_min_endstop;
#endif
#endif #endif
} }
} }
else { // +direction else { // +direction
Z_DIR_WRITE(!INVERT_Z_DIR); Z_APPLY_DIR(!INVERT_Z_DIR,0);
#ifdef Z_DUAL_STEPPER_DRIVERS
Z2_DIR_WRITE(!INVERT_Z_DIR);
#endif
count_direction[Z_AXIS] = 1; count_direction[Z_AXIS] = 1;
if (check_endstops) { if (check_endstops) {
#if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0 #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
UPDATE_ENDSTOP(z, Z, max, MAX); #ifndef Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(z, Z, max, MAX);
#else
bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING);
#if defined(Z2_MAX_PIN) && Z2_MAX_PIN > -1
bool z2_max_endstop=(READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING);
#else
bool z2_max_endstop=z_max_endstop;
#endif
if(((z_max_endstop && old_z_max_endstop) || (z2_max_endstop && old_z2_max_endstop)) && (current_block->steps[Z_AXIS] > 0))
{
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_z_hit=true;
// if (z_max_endstop && old_z_max_endstop) SERIAL_ECHOLN("z_max_endstop = true");
// if (z2_max_endstop && old_z2_max_endstop) SERIAL_ECHOLN("z2_max_endstop = true");
if (!(performing_homing) || ((performing_homing)&&(z_max_endstop && old_z_max_endstop)&&(z2_max_endstop && old_z2_max_endstop))) //if not performing home or if both endstops were trigged during homing...
{
step_events_completed = current_block->step_event_count;
}
}
old_z_max_endstop = z_max_endstop;
old_z2_max_endstop = z2_max_endstop;
#endif
#endif #endif
} }
} }
...@@ -553,9 +622,9 @@ ISR(TIMER1_COMPA_vect) { ...@@ -553,9 +622,9 @@ ISR(TIMER1_COMPA_vect) {
if (check_endstops) { if (check_endstops) {
#if defined(E_MIN_PIN) && E_MIN_PIN > -1 #if defined(E_MIN_PIN) && E_MIN_PIN > -1
bool e_min_endstop=(READ(E_MIN_PIN) != E_MIN_ENDSTOP_INVERTING); bool e_min_endstop=(READ(E_MIN_PIN) != E_MIN_ENDSTOP_INVERTING);
if (e_min_endstop && old_e_min_endstop && (current_block->steps_e > 0)) { if (e_min_endstop && old_e_min_endstop && (current_block->steps[E_AXIS] > 0)) {
endstops_trigsteps[E_AXIS] = count_position[E_AXIS]; endstops_trigsteps[E_AXIS] = count_position[E_AXIS];
endstop_e_hit=true; endstop_e_hit = true;
step_events_completed = current_block->step_event_count; step_events_completed = current_block->step_event_count;
} }
old_e_min_endstop = e_min_endstop; old_e_min_endstop = e_min_endstop;
...@@ -576,7 +645,7 @@ ISR(TIMER1_COMPA_vect) { ...@@ -576,7 +645,7 @@ ISR(TIMER1_COMPA_vect) {
#endif #endif
#ifdef ADVANCE #ifdef ADVANCE
counter_e += current_block->steps_e; counter_e += current_block->steps[E_AXIS];
if (counter_e > 0) { if (counter_e > 0) {
counter_e -= current_block->step_event_count; counter_e -= current_block->step_event_count;
e_steps[current_block->active_driver] += TEST(out_bits, E_AXIS) ? -1 : 1; e_steps[current_block->active_driver] += TEST(out_bits, E_AXIS) ? -1 : 1;
...@@ -590,15 +659,14 @@ ISR(TIMER1_COMPA_vect) { ...@@ -590,15 +659,14 @@ ISR(TIMER1_COMPA_vect) {
* instead of doing each in turn. The extra tests add enough * instead of doing each in turn. The extra tests add enough
* lag to allow it work with without needing NOPs * lag to allow it work with without needing NOPs
*/ */
counter_x += current_block->steps_x; #define STEP_ADD(axis, AXIS) \
if (counter_x > 0) X_STEP_WRITE(HIGH); counter_## axis += current_block->steps[AXIS ##_AXIS]; \
counter_y += current_block->steps_y; if (counter_## axis > 0) { AXIS ##_STEP_WRITE(HIGH); }
if (counter_y > 0) Y_STEP_WRITE(HIGH); STEP_ADD(x,X);
counter_z += current_block->steps_z; STEP_ADD(y,Y);
if (counter_z > 0) Z_STEP_WRITE(HIGH); STEP_ADD(z,Z);
#ifndef ADVANCE #ifndef ADVANCE
counter_e += current_block->steps_e; STEP_ADD(e,E);
if (counter_e > 0) E_STEP_WRITE(HIGH);
#endif #endif
#define STEP_IF_COUNTER(axis, AXIS) \ #define STEP_IF_COUNTER(axis, AXIS) \
...@@ -618,7 +686,7 @@ ISR(TIMER1_COMPA_vect) { ...@@ -618,7 +686,7 @@ ISR(TIMER1_COMPA_vect) {
#else // !CONFIG_STEPPERS_TOSHIBA #else // !CONFIG_STEPPERS_TOSHIBA
#define APPLY_MOVEMENT(axis, AXIS) \ #define APPLY_MOVEMENT(axis, AXIS) \
counter_## axis += current_block->steps_## axis; \ counter_## axis += current_block->steps[AXIS ##_AXIS]; \
if (counter_## axis > 0) { \ if (counter_## axis > 0) { \
AXIS ##_APPLY_STEP(!INVERT_## AXIS ##_STEP_PIN,0); \ AXIS ##_APPLY_STEP(!INVERT_## AXIS ##_STEP_PIN,0); \
counter_## axis -= current_block->step_event_count; \ counter_## axis -= current_block->step_event_count; \
...@@ -931,6 +999,13 @@ void st_init() { ...@@ -931,6 +999,13 @@ void st_init() {
#endif #endif
#endif #endif
#if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
SET_INPUT(Z2_MAX_PIN);
#ifdef ENDSTOPPULLUP_ZMAX
WRITE(Z2_MAX_PIN,HIGH);
#endif
#endif
#define AXIS_INIT(axis, AXIS, PIN) \ #define AXIS_INIT(axis, AXIS, PIN) \
AXIS ##_STEP_INIT; \ AXIS ##_STEP_INIT; \
AXIS ##_STEP_WRITE(INVERT_## PIN ##_STEP_PIN); \ AXIS ##_STEP_WRITE(INVERT_## PIN ##_STEP_PIN); \
...@@ -1275,3 +1350,9 @@ void microstep_readings() { ...@@ -1275,3 +1350,9 @@ void microstep_readings() {
SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN)); SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN));
#endif #endif
} }
#ifdef Z_DUAL_ENDSTOPS
void In_Homing_Process(bool state) { performing_homing = state; }
void Lock_z_motor(bool state) { locked_z_motor = state; }
void Lock_z2_motor(bool state) { locked_z2_motor = state; }
#endif
...@@ -97,6 +97,12 @@ void digipot_current(uint8_t driver, int current); ...@@ -97,6 +97,12 @@ void digipot_current(uint8_t driver, int current);
void microstep_init(); void microstep_init();
void microstep_readings(); void microstep_readings();
#ifdef Z_DUAL_ENDSTOPS
void In_Homing_Process(bool state);
void Lock_z_motor(bool state);
void Lock_z2_motor(bool state);
#endif
#ifdef BABYSTEPPING #ifdef BABYSTEPPING
void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention void babystep(const uint8_t axis,const bool direction); // perform a short step with a single stepper motor, outside of any convention
#endif //BABYSTEPPING #endif //BABYSTEPPING
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
//================================== macros ================================= //================================== macros =================================
//=========================================================================== //===========================================================================
<<<<<<< HEAD
#if HOTENDS > 4 #if HOTENDS > 4
#error Unsupported number of hotends #error Unsupported number of hotends
#elif HOTENDS > 3 #elif HOTENDS > 3
...@@ -71,11 +72,21 @@ ...@@ -71,11 +72,21 @@
#define HAS_AUTO_FAN_3 (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_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_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) #define HAS_FAN (defined(FAN_PIN) && FAN_PIN >= 0)
=======
#ifdef K1 // Defined in Configuration.h in the PID settings
#define K2 (1.0 - K1)
#endif
#if defined(PIDTEMPBED) || defined(PIDTEMP)
#define PID_dT ((OVERSAMPLENR * 14.0)/(F_CPU / 64.0 / 256.0))
#endif
>>>>>>> origin/master
//=========================================================================== //===========================================================================
//============================= public variables ============================ //============================= public variables ============================
//=========================================================================== //===========================================================================
<<<<<<< HEAD
// Sampling period of the temperature routine // Sampling period of the temperature routine
#ifdef PID_dT #ifdef PID_dT
#undef PID_dT #undef PID_dT
...@@ -86,16 +97,24 @@ int target_temperature[HOTENDS] = { 0 }; ...@@ -86,16 +97,24 @@ int target_temperature[HOTENDS] = { 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[HOTENDS] = { 0 };
>>>>>>> origin/master
int target_temperature_bed = 0; int target_temperature_bed = 0;
int current_temperature_raw[HOTENDS] = { 0 };
float current_temperature[HOTENDS] = { 0.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
<<<<<<< HEAD
#ifdef PIDTEMP #ifdef PIDTEMP
float Kp[HOTENDS],Ki[HOTENDS],Kd[HOTENDS]; float Kp[HOTENDS],Ki[HOTENDS],Kd[HOTENDS];
#endif //PIDTEMP #endif //PIDTEMP
=======
>>>>>>> origin/master
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
float bedKp=DEFAULT_bedKp; float bedKp=DEFAULT_bedKp;
...@@ -119,6 +138,7 @@ unsigned char soft_pwm_bed; ...@@ -119,6 +138,7 @@ unsigned char soft_pwm_bed;
#if HAS_POWER_CONSUMPTION_SENSOR #if HAS_POWER_CONSUMPTION_SENSOR
int current_raw_powconsumption = 0; //Holds measured power consumption int current_raw_powconsumption = 0; //Holds measured power consumption
static unsigned long raw_powconsumption_value = 0;
#endif #endif
//=========================================================================== //===========================================================================
...@@ -162,11 +182,18 @@ static unsigned char soft_pwm[HOTENDS]; ...@@ -162,11 +182,18 @@ 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);
<<<<<<< HEAD
static int minttemp[HOTENDS] = ARRAY_BY_HOTENDS( 0, 0, 0, 0 ); static int minttemp[HOTENDS] = ARRAY_BY_HOTENDS( 0, 0, 0, 0 );
=======
static int minttemp[HOTENDS] = { 0 };
>>>>>>> origin/master
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 +214,13 @@ static float analog2tempBed(int raw); ...@@ -187,8 +214,13 @@ static float analog2tempBed(int raw);
static void updateTemperaturesFromRawValues(); static void updateTemperaturesFromRawValues();
#ifdef WATCH_TEMP_PERIOD #ifdef WATCH_TEMP_PERIOD
<<<<<<< HEAD
int watch_start_temp[HOTENDS] = ARRAY_BY_HOTENDS(0,0,0,0); int watch_start_temp[HOTENDS] = ARRAY_BY_HOTENDS(0,0,0,0);
unsigned long watchmillis[HOTENDS] = ARRAY_BY_HOTENDS(0,0,0,0); unsigned long watchmillis[HOTENDS] = ARRAY_BY_HOTENDS(0,0,0,0);
=======
int watch_start_temp[HOTENDS] = { 0 };
unsigned long watchmillis[HOTENDS] = { 0 };
>>>>>>> origin/master
#endif //WATCH_TEMP_PERIOD #endif //WATCH_TEMP_PERIOD
#ifndef SOFT_PWM_SCALE #ifndef SOFT_PWM_SCALE
...@@ -204,7 +236,7 @@ static void updateTemperaturesFromRawValues(); ...@@ -204,7 +236,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 +399,11 @@ void PID_autotune(float temp, int hotend, int ncycles) ...@@ -367,7 +399,11 @@ 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++) {
<<<<<<< HEAD
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e]; temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e];
=======
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
>>>>>>> origin/master
} }
#endif #endif
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
...@@ -380,6 +416,7 @@ int getHeaterPower(int heater) { ...@@ -380,6 +416,7 @@ int getHeaterPower(int heater) {
} }
#if HAS_AUTO_FAN #if HAS_AUTO_FAN
<<<<<<< HEAD
#if HAS_FAN #if HAS_FAN
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN #if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN" #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
...@@ -467,11 +504,88 @@ int getHeaterPower(int heater) { ...@@ -467,11 +504,88 @@ int getHeaterPower(int heater) {
setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0); setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
#endif #endif
} }
=======
void setExtruderAutoFanState(int pin, bool state)
{
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
// this idiom allows both digital and PWM fan outputs (see M42 handling).
pinMode(pin, OUTPUT);
digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed);
}
void checkExtruderAutoFans()
{
uint8_t fanState = 0;
// which fan pins need to be turned on?
#if HAS_AUTO_FAN_0
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1;
#endif
#if HAS_AUTO_FAN_1
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else
fanState |= 2;
}
#endif
#if HAS_AUTO_FAN_2
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else
fanState |= 4;
}
#endif
#if HAS_AUTO_FAN_3
if (current_temperature[3] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else if (EXTRUDER_3_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN)
fanState |= 4;
else
fanState |= 8;
}
#endif
// update extruder auto fan states
#if HAS_AUTO_FAN_0
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif
#if HAS_AUTO_FAN_1
if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
#endif
#if HAS_AUTO_FAN_2
if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
&& EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
#endif
#if HAS_AUTO_FAN_3
if (EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN
&& EXTRUDER_3_AUTO_FAN_PIN != EXTRUDER_2_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_3_AUTO_FAN_PIN, (fanState & 8) != 0);
#endif
}
>>>>>>> origin/master
#endif // any extruder auto fan pins set #endif // any extruder auto fan pins set
// //
// Error checking and Write Routines // Temperature Error Handlers
// //
<<<<<<< HEAD
#if HOTENDS > 0 #if HOTENDS > 0
#if !HAS_HEATER_0 #if !HAS_HEATER_0
#error HEATER_0_PIN not defined for this board #error HEATER_0_PIN not defined for this board
...@@ -510,6 +624,8 @@ int getHeaterPower(int heater) { ...@@ -510,6 +624,8 @@ int getHeaterPower(int heater) {
#define WRITE_FAN(v) WRITE(FAN_PIN, v) #define WRITE_FAN(v) WRITE(FAN_PIN, v)
#endif #endif
=======
>>>>>>> origin/master
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,12 +656,117 @@ void bed_max_temp_error(void) { ...@@ -540,12 +656,117 @@ 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));
} }
float get_pid_output(int e) {
float pid_output;
#ifdef PIDTEMP
#ifndef PID_OPENLOOP
pid_error[e] = target_temperature[e] - current_temperature[e];
if (pid_error[e] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX;
pid_reset[e] = true;
}
else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
pid_output = 0;
pid_reset[e] = true;
}
else {
if (pid_reset[e]) {
temp_iState[e] = 0.0;
pid_reset[e] = false;
}
pTerm[e] = PID_PARAM(Kp,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]);
iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
dTerm[e] = K2 * PID_PARAM(Kd,e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e];
pid_output = pTerm[e] + iTerm[e] - dTerm[e];
if (pid_output > PID_MAX) {
if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = PID_MAX;
}
else if (pid_output < 0) {
if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = 0;
}
}
temp_dState[e] = current_temperature[e];
#else
pid_output = constrain(target_temperature[e], 0, PID_MAX);
#endif //PID_OPENLOOP
#ifdef PID_DEBUG
SERIAL_ECHO_START;
SERIAL_ECHO(MSG_PID_DEBUG);
SERIAL_ECHO(e);
SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
SERIAL_ECHO(current_temperature[e]);
SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
SERIAL_ECHO(pid_output);
SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
SERIAL_ECHO(pTerm[e]);
SERIAL_ECHO(MSG_PID_DEBUG_ITERM);
SERIAL_ECHO(iTerm[e]);
SERIAL_ECHO(MSG_PID_DEBUG_DTERM);
SERIAL_ECHOLN(dTerm[e]);
#endif //PID_DEBUG
#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;
}
#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() { void manage_heater() {
if (!temp_meas_ready) return; if (!temp_meas_ready) return;
float pid_input, pid_output;
updateTemperaturesFromRawValues(); updateTemperaturesFromRawValues();
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
...@@ -557,74 +778,18 @@ void manage_heater() { ...@@ -557,74 +778,18 @@ void manage_heater() {
unsigned long ms = millis(); unsigned long ms = millis();
// Loop through all hotends // Loop through all hotends
<<<<<<< HEAD
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++)
{ {
=======
for (int e = 0; e < HOTENDS; e++) {
>>>>>>> origin/master
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0 #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); 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 #endif
#ifdef PIDTEMP float pid_output = get_pid_output(e);
pid_input = current_temperature[e];
#ifndef PID_OPENLOOP
pid_error[e] = target_temperature[e] - pid_input;
if (pid_error[e] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX;
pid_reset[e] = true;
}
else if (pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
pid_output = 0;
pid_reset[e] = true;
}
else {
if (pid_reset[e] == true) {
temp_iState[e] = 0.0;
pid_reset[e] = false;
}
pTerm[e] = Kp[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]);
iTerm[e] = Ki[e] * temp_iState[e];
//K1 defined in Configuration.h in the PID settings
#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];
if (pid_output > PID_MAX) {
if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = PID_MAX;
}
else if (pid_output < 0) {
if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output = 0;
}
}
temp_dState[e] = pid_input;
#else
pid_output = constrain(target_temperature[e], 0, PID_MAX);
#endif //PID_OPENLOOP
#ifdef PID_DEBUG
SERIAL_ECHO_START;
SERIAL_ECHO(MSG_PID_DEBUG);
SERIAL_ECHO(e);
SERIAL_ECHO(MSG_PID_DEBUG_INPUT);
SERIAL_ECHO(pid_input);
SERIAL_ECHO(MSG_PID_DEBUG_OUTPUT);
SERIAL_ECHO(pid_output);
SERIAL_ECHO(MSG_PID_DEBUG_PTERM);
SERIAL_ECHO(pTerm[e]);
SERIAL_ECHO(MSG_PID_DEBUG_ITERM);
SERIAL_ECHO(iTerm[e]);
SERIAL_ECHO(MSG_PID_DEBUG_DTERM);
SERIAL_ECHOLN(dTerm[e]);
#endif //PID_DEBUG
#else /* PID off */
pid_output = 0;
if (current_temperature[e] < target_temperature[e]) pid_output = PID_MAX;
#endif //PIDTEMP
// 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;
...@@ -646,9 +811,13 @@ void manage_heater() { ...@@ -646,9 +811,13 @@ void manage_heater() {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT #ifdef TEMP_SENSOR_1_AS_REDUNDANT
if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) { if (fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
disable_heater(); disable_heater();
_temp_error(-1, MSG_EXTRUDER_SWITCHED_OFF, MSG_ERR_REDUNDANT_TEMP); _temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP));
} }
#endif //TEMP_SENSOR_1_AS_REDUNDANT #endif //TEMP_SENSOR_1_AS_REDUNDANT
<<<<<<< HEAD
=======
>>>>>>> origin/master
} // Hotends Loop } // Hotends Loop
#if HAS_AUTO_FAN #if HAS_AUTO_FAN
...@@ -670,48 +839,7 @@ void manage_heater() { ...@@ -670,48 +839,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 +887,11 @@ void manage_heater() { ...@@ -759,11 +887,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 +929,7 @@ static float analog2temp(int raw, uint8_t e) { ...@@ -801,7 +929,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 +956,7 @@ static float analog2tempBed(int raw) { ...@@ -828,7 +956,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 +968,13 @@ static void updateTemperaturesFromRawValues() { ...@@ -840,9 +968,13 @@ 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
<<<<<<< HEAD
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++)
{ {
=======
for (int e = 0; e < HOTENDS; e++) {
>>>>>>> origin/master
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 +988,10 @@ static void updateTemperaturesFromRawValues() { ...@@ -856,10 +988,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 +1007,10 @@ static void updateTemperaturesFromRawValues() { ...@@ -875,9 +1007,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;
} }
...@@ -895,8 +1028,13 @@ static void updateTemperaturesFromRawValues() { ...@@ -895,8 +1028,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
>>>>>>> origin/master >>>>>>> origin/master
...@@ -910,13 +1048,17 @@ void tp_init() ...@@ -910,13 +1048,17 @@ void tp_init()
#endif #endif
// Finish init of mult hotends arrays // Finish init of mult hotends arrays
<<<<<<< HEAD
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++)
{ {
=======
for (int e = 0; e < HOTENDS; e++) {
>>>>>>> origin/master
// 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;
...@@ -958,7 +1100,7 @@ void tp_init() ...@@ -958,7 +1100,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);
...@@ -1080,14 +1222,18 @@ void tp_init() ...@@ -1080,14 +1222,18 @@ void tp_init()
void setWatch() { void setWatch() {
#ifdef WATCH_TEMP_PERIOD #ifdef WATCH_TEMP_PERIOD
unsigned long ms = millis(); unsigned long ms = millis();
<<<<<<< HEAD
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++)
{ {
=======
for (int e = 0; e < HOTENDS; e++) {
>>>>>>> origin/master
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
...@@ -1156,16 +1302,28 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat ...@@ -1156,16 +1302,28 @@ void thermal_runaway_protection(int *state, unsigned long *timer, float temperat
void disable_heater() { void disable_heater() {
<<<<<<< HEAD
for (int e = 0; e < HOTENDS; e++) for (int e = 0; e < HOTENDS; e++)
setTargetHotend(0, e); setTargetHotend(0, e);
=======
for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i);
>>>>>>> origin/master
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
<<<<<<< HEAD
target_temperature[1] = 0; target_temperature[1] = 0;
soft_pwm[1] = 0; soft_pwm[1] = 0;
WRITE_HEATER_1(LOW); WRITE_HEATER_1(LOW);
...@@ -1181,6 +1339,17 @@ void disable_heater() { ...@@ -1181,6 +1339,17 @@ void disable_heater() {
target_temperature[3] = 0; target_temperature[3] = 0;
soft_pwm[3] = 0; soft_pwm[3] = 0;
WRITE_HEATER_3(LOW); WRITE_HEATER_3(LOW);
=======
DISABLE_HEATER(1);
#endif
#if HOTENDS > 2 && HAS_TEMP_2
DISABLE_HEATER(2);
#endif
#if HOTENDS > 3 && HAS_TEMP_3
DISABLE_HEATER(3);
>>>>>>> origin/master
#endif #endif
#if HAS_TEMP_BED #if HAS_TEMP_BED
...@@ -1245,9 +1414,12 @@ void disable_heater() { ...@@ -1245,9 +1414,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,
...@@ -1266,12 +1438,50 @@ enum TempState { ...@@ -1266,12 +1438,50 @@ 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
}; };
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
#define TEMP_SENSOR_COUNT 2
#else
#define TEMP_SENSOR_COUNT HOTENDS
#endif
static unsigned long raw_temp_value[TEMP_SENSOR_COUNT] = { 0 };
static unsigned long raw_temp_bed_value = 0;
static void set_current_temp_raw() {
#ifndef HEATER_0_USES_MAX6675
current_temperature_raw[0] = raw_temp_value[0];
#endif
#if HOTENDS > 1
current_temperature_raw[1] = raw_temp_value[1];
#if HOTENDS > 2
current_temperature_raw[2] = raw_temp_value[2];
#if HOTENDS > 3
current_temperature_raw[3] = raw_temp_value[3];
#endif
#endif
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature_raw = raw_temp_value[1];
#endif
current_temperature_bed_raw = raw_temp_bed_value;
#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
}
//
// Timer 0 is shared with millies // Timer 0 is shared with millies
//
ISR(TIMER0_COMPB_vect) { ISR(TIMER0_COMPB_vect) {
//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;
<<<<<<< HEAD
static unsigned long raw_temp_value[HOTENDS] = { 0 }; static unsigned long raw_temp_value[HOTENDS] = { 0 };
static unsigned long raw_temp_bed_value = 0; static unsigned long raw_temp_bed_value = 0;
=======
>>>>>>> origin/master
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);
...@@ -1305,11 +1515,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1305,11 +1515,7 @@ ISR(TIMER0_COMPB_vect) {
#if HAS_FILAMENT_SENSOR #if HAS_FILAMENT_SENSOR
static unsigned long raw_filwidth_value = 0; static unsigned long raw_filwidth_value = 0;
#endif #endif
#if HAS_POWER_CONSUMPTION_SENSOR
static unsigned long raw_powconsumption_value = 0;
#endif
#ifndef SLOW_PWM_HEATERS #ifndef SLOW_PWM_HEATERS
/** /**
* standard PWM modulation * standard PWM modulation
...@@ -1345,7 +1551,10 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1345,7 +1551,10 @@ ISR(TIMER0_COMPB_vect) {
} }
if (soft_pwm_0 < pwm_count) { WRITE_HEATER_0(0); } if (soft_pwm_0 < pwm_count) { WRITE_HEATER_0(0); }
<<<<<<< HEAD
=======
>>>>>>> origin/master
#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
...@@ -1495,6 +1704,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1495,6 +1704,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);
...@@ -1508,6 +1718,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1508,6 +1718,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);
...@@ -1521,6 +1732,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1521,6 +1732,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);
...@@ -1534,6 +1746,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1534,6 +1746,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);
...@@ -1547,6 +1760,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1547,6 +1760,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);
...@@ -1563,7 +1777,8 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1563,7 +1777,8 @@ 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);
...@@ -1573,13 +1788,12 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1573,13 +1788,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;
...@@ -1589,9 +1803,10 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1589,9 +1803,10 @@ ISR(TIMER0_COMPB_vect) {
// SERIAL_ERRORLNPGM("Temp measurement error!"); // SERIAL_ERRORLNPGM("Temp measurement error!");
// 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)
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.
<<<<<<< HEAD
#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];
#endif #endif
...@@ -1609,19 +1824,19 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1609,19 +1824,19 @@ ISR(TIMER0_COMPB_vect) {
redundant_temperature_raw = raw_temp_value[1]; redundant_temperature_raw = raw_temp_value[1];
#endif #endif
current_temperature_bed_raw = raw_temp_bed_value; current_temperature_bed_raw = raw_temp_bed_value;
=======
set_current_temp_raw();
>>>>>>> origin/master
} //!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-16384 range since we used 1/128 IIR filter approach
#endif #endif
// Power Sensor - can be read any time since IIR filtering is used
#if HAS_POWER_CONSUMPTION_SENSOR
current_raw_powconsumption = raw_powconsumption_value >> 10; // Divide to get to 0-16384 range since we used 1/128 IIR filter approach
#endif
temp_meas_ready = true; temp_meas_ready = true;
temp_count = 0; temp_count = 0;
<<<<<<< HEAD
for (int i = 0; i < HOTENDS; i++) raw_temp_value[i] = 0; for (int i = 0; i < HOTENDS; i++) raw_temp_value[i] = 0;
raw_temp_bed_value = 0; raw_temp_bed_value = 0;
...@@ -1631,6 +1846,13 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1631,6 +1846,13 @@ ISR(TIMER0_COMPB_vect) {
#else #else
#define GE0 >= #define GE0 >=
#define LE0 <= #define LE0 <=
=======
for (int i = 0; i < TEMP_SENSOR_COUNT; i++) raw_temp_value[i] = 0;
raw_temp_bed_value = 0;
#if HAS_POWER_CONSUMPTION_SENSOR
raw_powconsumption_value = 0;
>>>>>>> origin/master
#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 (current_temperature_raw[0] LE0 minttemp_raw[0]) min_temp_error(0);
...@@ -1669,6 +1891,7 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1669,6 +1891,7 @@ ISR(TIMER0_COMPB_vect) {
#endif // HOTENDS > 2 #endif // HOTENDS > 2
#endif // HOTENDS > 1 #endif // HOTENDS > 1
<<<<<<< HEAD
#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 <=
...@@ -1676,12 +1899,61 @@ ISR(TIMER0_COMPB_vect) { ...@@ -1676,12 +1899,61 @@ ISR(TIMER0_COMPB_vect) {
#else #else
#define GEBED >= #define GEBED >=
#define LEBED <= #define LEBED <=
=======
#ifndef HEATER_0_USES_MAX6675
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
#define GE0 <=
#else
#define GE0 >=
#endif
if (current_temperature_raw[0] GE0 maxttemp_raw[0]) max_temp_error(0);
if (minttemp_raw[0] GE0 current_temperature_raw[0]) min_temp_error(0);
#endif
#if HOTENDS > 1
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
#define GE1 <=
#else
#define GE1 >=
#endif
if (current_temperature_raw[1] GE1 maxttemp_raw[1]) max_temp_error(1);
if (minttemp_raw[1] GE0 current_temperature_raw[1]) min_temp_error(1);
#if HOTENDS > 2
#if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
#define GE2 <=
#else
#define GE2 >=
#endif
if (current_temperature_raw[2] GE2 maxttemp_raw[2]) max_temp_error(2);
if (minttemp_raw[2] GE0 current_temperature_raw[2]) min_temp_error(2);
#if HOTENDS > 3
#if HEATER_3_RAW_LO_TEMP > HEATER_3_RAW_HI_TEMP
#define GE3 <=
#else
#define GE3 >=
#endif
if (current_temperature_raw[3] GE3 maxttemp_raw[3]) max_temp_error(3);
if (minttemp_raw[3] GE0 current_temperature_raw[3]) min_temp_error(3);
#endif // HOTENDS > 3
#endif // HOTENDS > 2
#endif // HOTENDS > 1
#if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
#if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
#define GEBED <=
#else
#define GEBED >=
>>>>>>> origin/master
#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,12 @@ extern float current_temperature_bed; ...@@ -63,7 +64,12 @@ extern float current_temperature_bed;
#endif #endif
#ifdef PIDTEMP #ifdef PIDTEMP
<<<<<<< HEAD
extern float Kp[HOTENDS],Ki[HOTENDS],Kd[HOTENDS]; 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
>>>>>>> origin/master
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 +99,7 @@ FORCE_INLINE float degBed() { return current_temperature_bed; } ...@@ -93,7 +99,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]; }
...@@ -144,7 +150,11 @@ FORCE_INLINE bool isCoolingBed() { return target_temperature_bed < current_tempe ...@@ -144,7 +150,11 @@ FORCE_INLINE bool isCoolingBed() { return target_temperature_bed < current_tempe
#define setTargetHotend3(_celsius) do{}while(0) #define setTargetHotend3(_celsius) do{}while(0)
#endif #endif
#if HOTENDS > 4 #if HOTENDS > 4
<<<<<<< HEAD
#error Invalid number of hotend #error Invalid number of hotend
=======
#error Invalid number of hotends
>>>>>>> origin/master
#endif #endif
int getHeaterPower(int heater); int getHeaterPower(int heater);
......
...@@ -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_Printpos(x, y) u8g.setPrintPos(x, y)
#else #else
#include "ultralcd_implementation_hitachi_HD44780.h" #include "ultralcd_implementation_hitachi_HD44780.h"
#define LCD_Printpos(x, y) lcd.setCursor(x, y)
#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,11 @@ static void menu_action_setting_edit_callback_long5(const char* pstr, unsigned l ...@@ -215,7 +214,11 @@ 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() \
<<<<<<< HEAD
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 >= _menuItemNr) { encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; }\
>>>>>>> origin/master
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 +278,17 @@ static void lcd_status_screen() ...@@ -275,17 +278,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,12 +314,6 @@ static void lcd_status_screen() ...@@ -311,12 +314,6 @@ 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 (millis() > message_millis + 15000) message_millis = millis();
#else
if (millis() > message_millis + 10000) message_millis = millis();
#endif
#ifdef ULTIPANEL #ifdef ULTIPANEL
bool current_click = LCD_CLICKED; bool current_click = LCD_CLICKED;
...@@ -339,12 +336,22 @@ static void lcd_status_screen() ...@@ -339,12 +336,22 @@ static void lcd_status_screen()
if (current_click) if (current_click)
{ {
lcd_goto_menu(lcd_main_menu); lcd_goto_menu(lcd_main_menu);
lcd_implementation_init( // to maybe revive the LCD if static electricity killed it. lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
currentMenu == lcd_status_screen currentMenu == lcd_status_screen
#endif #endif
); );
#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)
#else
if (millis() > message_millis + 10000)
#endif
{
message_millis = millis();
}
#endif
} }
#ifdef ULTIPANEL_FEEDMULTIPLY #ifdef ULTIPANEL_FEEDMULTIPLY
...@@ -690,86 +697,73 @@ void config_lcd_level_bed() ...@@ -690,86 +697,73 @@ 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_Printpos(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;
} }
break; break;
case 1: case 1:
{ {
lcd.setCursor(0, 1); LCD_Printpos(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;
} }
break;
break;
case 2: case 2:
{ {
lcd.setCursor(0, 1); LCD_Printpos(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;
} }
break;
break;
case 3: case 3:
{ {
lcd.setCursor(0, 1); LCD_Printpos(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;
} }
break;
break; case 4:
case 4: {
{ LCD_Printpos(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;
} }
break;
break; case 5:
{
case 5: LCD_Printpos(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;
} }
break;
break; case 6:
case 6:
{ {
lcd.setCursor(2, 2); LCD_Printpos(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;
} }
break; break;
} }
} }
} }
static void lcd_prepare_menu() { static void lcd_prepare_menu() {
START_MENU(); START_MENU();
MENU_ITEM(back, MSG_MAIN, lcd_main_menu); MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
...@@ -969,6 +963,35 @@ static void lcd_config_menu() { ...@@ -969,6 +963,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);
...@@ -1002,6 +1025,7 @@ static void lcd_control_temperature_menu() { ...@@ -1002,6 +1025,7 @@ 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
<<<<<<< HEAD
raw_Ki = unscalePID_i(Ki[0]); raw_Ki = unscalePID_i(Ki[0]);
raw_Kd = unscalePID_d(Kd[0]); raw_Kd = unscalePID_d(Kd[0]);
MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp[0], 1, 9990); MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp[0], 1, 9990);
...@@ -1035,6 +1059,41 @@ static void lcd_control_temperature_menu() { ...@@ -1035,6 +1059,41 @@ static void lcd_control_temperature_menu() {
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 " E4", &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
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 " E4", &raw_Kd, 1, 9990, copy_and_scalePID_d);
#endif //HOTENDS > 2 #endif //HOTENDS > 2
=======
raw_Ki = unscalePID_i(PID_PARAM(Ki,0));
raw_Kd = unscalePID_d(PID_PARAM(Kd,0));
MENU_ITEM_EDIT(float52, MSG_PID_P, &PID_PARAM(Kp,0), 1, 9990);
// 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_E1);
MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d_E1);
#if HOTENDS > 1
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki,1));
raw_Kd = unscalePID_d(PID_PARAM(Kd,1));
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
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 MSG_E2, &raw_Kd, 1, 9990, copy_and_scalePID_d_E2);
#if HOTENDS > 2
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki,2));
raw_Kd = unscalePID_d(PID_PARAM(Kd,2));
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
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 MSG_E3, &raw_Kd, 1, 9990, copy_and_scalePID_d_E3);
#if HOTENDS > 3
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki,3));
raw_Kd = unscalePID_d(PID_PARAM(Kd,3));
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
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 MSG_E4, &raw_Kd, 1, 9990, copy_and_scalePID_d_E4);
#endif //HOTENDS > 3
#endif //HOTENDS > 2
#endif //HOTENDS > 1
>>>>>>> origin/master
#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);
...@@ -1094,9 +1153,9 @@ static void lcd_control_motion_menu() { ...@@ -1094,9 +1153,9 @@ static void lcd_control_motion_menu() {
START_MENU(); START_MENU();
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, 0.5, 50); MENU_ITEM_EDIT(float32, MSG_ZPROBE_ZOFFSET, &zprobe_zoffset, 0.0, 50);
#endif #endif
MENU_ITEM_EDIT(float5, MSG_ACC, &acceleration, 500, 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);
...@@ -1108,7 +1167,7 @@ static void lcd_control_motion_menu() { ...@@ -1108,7 +1167,7 @@ static void lcd_control_motion_menu() {
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], 100, 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], 100, 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], 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_E, &max_acceleration_units_per_sq_second[E_AXIS], 100, 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, 100, 99000); MENU_ITEM_EDIT(float5, MSG_A_RETRACT, &retract_acceleration, 100, 99000);
MENU_ITEM_EDIT(float5, MSG_A_TRAVEL, &travel_acceleration, 100, 99000); MENU_ITEM_EDIT(float5, MSG_A_TRAVEL, &travel_acceleration, 100, 99000);
...@@ -1391,10 +1450,6 @@ void lcd_init() { ...@@ -1391,10 +1450,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
...@@ -1569,7 +1624,7 @@ void lcd_finishstatus() { ...@@ -1569,7 +1624,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();
...@@ -2006,24 +2061,4 @@ char *ftostr52(const float &x) ...@@ -2006,24 +2061,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
...@@ -33,32 +33,30 @@ ...@@ -33,32 +33,30 @@
#define LCD_TIMEOUT_TO_STATUS 15000 #define LCD_TIMEOUT_TO_STATUS 15000
#ifdef ULTIPANEL #ifdef ULTIPANEL
void lcd_buttons_update(); void lcd_buttons_update();
extern volatile uint8_t buttons; //the last checked buttons in a bit array. extern volatile uint8_t buttons; //the last checked buttons in a bit array.
#ifdef REPRAPWORLD_KEYPAD #ifdef REPRAPWORLD_KEYPAD
extern volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shift register values extern volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shift register values
#endif #endif
#else #else
FORCE_INLINE void lcd_buttons_update() {} FORCE_INLINE void lcd_buttons_update() {}
#endif #endif
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,16 +382,16 @@ static void lcd_set_custom_characters( ...@@ -382,16 +382,16 @@ 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);
#ifdef LCD_I2C_PIN_BL #ifdef LCD_I2C_PIN_BL
lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE); lcd.setBacklightPin(LCD_I2C_PIN_BL,POSITIVE);
lcd.setBacklight(HIGH); lcd.setBacklight(HIGH);
#endif #endif
#elif defined(LCD_I2C_TYPE_MCP23017) #elif defined(LCD_I2C_TYPE_MCP23017)
lcd.setMCPType(LTI_TYPE_MCP23017); lcd.setMCPType(LTI_TYPE_MCP23017);
...@@ -408,9 +408,9 @@ static void lcd_implementation_init ( ...@@ -408,9 +408,9 @@ static void lcd_implementation_init (
#endif #endif
lcd_set_custom_characters( lcd_set_custom_characters(
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
progress_bar_set progress_bar_set
#endif #endif
); );
lcd.clear(); lcd.clear();
...@@ -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);
...@@ -468,6 +470,7 @@ static void lcd_implementation_status_screen() { ...@@ -468,6 +470,7 @@ static void lcd_implementation_status_screen() {
lcd.print('/'); lcd.print('/');
lcd.print(itostr3left(tTarget)); lcd.print(itostr3left(tTarget));
<<<<<<< HEAD
<<<<<<< HEAD <<<<<<< HEAD
#if HOTENDS > 1 || TEMP_SENSOR_BED != 0 #if HOTENDS > 1 || TEMP_SENSOR_BED != 0
//If we have an 2nd extruder or heated bed, show that in the top right corner //If we have an 2nd extruder or heated bed, show that in the top right corner
...@@ -478,6 +481,12 @@ static void lcd_implementation_status_screen() { ...@@ -478,6 +481,12 @@ static void lcd_implementation_status_screen() {
//If we have an 2nd extruder or heated bed, show that in the top right corner //If we have an 2nd extruder or heated bed, show that in the top right corner
lcd.setCursor(8, 0); lcd.setCursor(8, 0);
#if EXTRUDERS > 1 && !defined(SINGLENOZZLE) #if EXTRUDERS > 1 && !defined(SINGLENOZZLE)
>>>>>>> origin/master
=======
#if HOTENDS > 1 || TEMP_SENSOR_BED != 0
//If we have an 2nd extruder or heated bed, show that in the top right corner
lcd.setCursor(8, 0);
#if HOTENDS > 1
>>>>>>> origin/master >>>>>>> origin/master
tHotend = int(degHotend(1) + 0.5); tHotend = int(degHotend(1) + 0.5);
tTarget = int(degTargetHotend(1) + 0.5); tTarget = int(degTargetHotend(1) + 0.5);
...@@ -490,11 +499,15 @@ static void lcd_implementation_status_screen() { ...@@ -490,11 +499,15 @@ static void lcd_implementation_status_screen() {
lcd.print(itostr3(tHotend)); lcd.print(itostr3(tHotend));
lcd.print('/'); lcd.print('/');
lcd.print(itostr3left(tTarget)); lcd.print(itostr3left(tTarget));
<<<<<<< HEAD
<<<<<<< HEAD <<<<<<< HEAD
#endif //HOTENDS > 1 || TEMP_SENSOR_BED != 0 #endif //HOTENDS > 1 || TEMP_SENSOR_BED != 0
======= =======
#endif //(EXTRUDERS > 1 && !defined(SINGLENOZZLE)) || TEMP_SENSOR_BED != 0 #endif //(EXTRUDERS > 1 && !defined(SINGLENOZZLE)) || TEMP_SENSOR_BED != 0
>>>>>>> origin/master >>>>>>> origin/master
=======
#endif //HOTENDS > 1 || TEMP_SENSOR_BED != 0
>>>>>>> origin/master
#else//LCD_WIDTH > 19 #else//LCD_WIDTH > 19
lcd.setCursor(0, 0); lcd.setCursor(0, 0);
...@@ -505,6 +518,7 @@ static void lcd_implementation_status_screen() { ...@@ -505,6 +518,7 @@ static void lcd_implementation_status_screen() {
lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
if (tTarget < 10) lcd.print(' '); if (tTarget < 10) lcd.print(' ');
<<<<<<< HEAD
<<<<<<< HEAD <<<<<<< HEAD
#if HOTENDS > 1 || TEMP_SENSOR_BED != 0 #if HOTENDS > 1 || TEMP_SENSOR_BED != 0
//If we have an 2nd extruder or heated bed, show that in the top right corner //If we have an 2nd extruder or heated bed, show that in the top right corner
...@@ -515,6 +529,12 @@ static void lcd_implementation_status_screen() { ...@@ -515,6 +529,12 @@ static void lcd_implementation_status_screen() {
//If we have an 2nd extruder or heated bed, show that in the top right corner //If we have an 2nd extruder or heated bed, show that in the top right corner
lcd.setCursor(10, 0); lcd.setCursor(10, 0);
#if EXTRUDERS > 1 && !defined(SINGLENOZZLE) #if EXTRUDERS > 1 && !defined(SINGLENOZZLE)
>>>>>>> origin/master
=======
#if HOTENDS > 1 || TEMP_SENSOR_BED != 0
//If we have an 2nd extruder or heated bed, show that in the top right corner
lcd.setCursor(10, 0);
#if HOTENDS > 1
>>>>>>> origin/master >>>>>>> origin/master
tHotend = int(degHotend(1) + 0.5); tHotend = int(degHotend(1) + 0.5);
tTarget = int(degTargetHotend(1) + 0.5); tTarget = int(degTargetHotend(1) + 0.5);
...@@ -529,6 +549,7 @@ static void lcd_implementation_status_screen() { ...@@ -529,6 +549,7 @@ static void lcd_implementation_status_screen() {
lcd.print(itostr3left(tTarget)); lcd.print(itostr3left(tTarget));
lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
if (tTarget < 10) lcd.print(' '); if (tTarget < 10) lcd.print(' ');
<<<<<<< HEAD
<<<<<<< HEAD <<<<<<< HEAD
#endif//HOTENDS > 1 || TEMP_SENSOR_BED != 0 #endif//HOTENDS > 1 || TEMP_SENSOR_BED != 0
#endif//LCD_WIDTH > 19 #endif//LCD_WIDTH > 19
...@@ -630,6 +651,57 @@ static void lcd_implementation_status_screen() { ...@@ -630,6 +651,57 @@ static void lcd_implementation_status_screen() {
#endif//LCD_HEIGHT > 2 #endif//LCD_HEIGHT > 2
#if LCD_HEIGHT > 3 #if LCD_HEIGHT > 3
>>>>>>> origin/master
=======
#endif//HOTENDS > 1 || TEMP_SENSOR_BED != 0
#endif//LCD_WIDTH > 19
#if LCD_HEIGHT > 2
//Lines 2 for 4 line LCD
#if LCD_WIDTH < 20
#ifdef SDSUPPORT
lcd.setCursor(0, 2);
lcd_printPGM(PSTR("SD"));
if (IS_SD_PRINTING)
lcd.print(itostr3(card.percentDone()));
else
lcd_printPGM(PSTR("---"));
lcd.print('%');
#endif//SDSUPPORT
#else //LCD_WIDTH > 19
#if HOTENDS > 1 && TEMP_SENSOR_BED != 0
//If we both have a 2nd extruder and a heated bed, show the heated bed temp on the 2nd line on the left, as the first line is filled with extruder temps
tHotend=int(degBed() + 0.5);
tTarget=int(degTargetBed() + 0.5);
lcd.setCursor(0, 1);
lcd.print(LCD_STR_BEDTEMP[0]);
lcd.print(itostr3(tHotend));
lcd.print('/');
lcd.print(itostr3left(tTarget));
lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
if (tTarget < 10) lcd.print(' ');
#else
lcd.setCursor(0,1);
#ifdef DELTA
lcd.print('X');
lcd.print(ftostr30(current_position[X_AXIS]));
lcd_printPGM(PSTR(" Y"));
lcd.print(ftostr30(current_position[Y_AXIS]));
#else
lcd.print('X');
lcd.print(ftostr3(current_position[X_AXIS]));
lcd_printPGM(PSTR(" Y"));
lcd.print(ftostr3(current_position[Y_AXIS]));
#endif // DELTA
#endif //HOTENDS > 1 || TEMP_SENSOR_BED != 0
#endif //LCD_WIDTH > 19
lcd.setCursor(LCD_WIDTH - 8, 1);
lcd.print('Z');
lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001));
#endif //LCD_HEIGHT > 2
#if LCD_HEIGHT > 3
>>>>>>> origin/master >>>>>>> origin/master
lcd.setCursor(0, 2); lcd.setCursor(0, 2);
lcd.print(LCD_STR_FEEDRATE[0]); lcd.print(LCD_STR_FEEDRATE[0]);
...@@ -703,21 +775,21 @@ static void lcd_implementation_status_screen() { ...@@ -703,21 +775,21 @@ static void lcd_implementation_status_screen() {
lcd.print(lcd_status_message); lcd.print(lcd_status_message);
>>>>>>> origin/master >>>>>>> origin/master
} }
#if (defined(POWER_CONSUMPTION) && defined(POWER_CONSUMPTION_PIN) && POWER_CONSUMPTION_PIN >= 0) && defined(POWER_CONSUMPTION_LCD_DISPLAY) #if 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) #if defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && (FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY)
else if (millis() < message_millis + 10000) else if (millis() < message_millis + 10000)
#else #else
else else
#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"));
} }
#endif #endif
#if (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY) #if defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && (FILWIDTH_PIN >= 0) && defined(FILAMENT_LCD_DISPLAY)
else { else {
lcd_printPGM(PSTR("D:")); lcd_printPGM(PSTR("D:"));
lcd.print(ftostr12ns(filament_width_meas)); lcd.print(ftostr12ns(filament_width_meas));
...@@ -726,7 +798,8 @@ static void lcd_implementation_status_screen() { ...@@ -726,7 +798,8 @@ static void lcd_implementation_status_screen() {
lcd.print('%'); lcd.print('%');
return; return;
} }
#else #endif
#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