Commit caf65063 authored by MagoKimbra's avatar MagoKimbra

Update 4.1.3

parent 7d3d03a2
...@@ -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.1.2" #define STRING_VERSION "4.1.3"
#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.
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#define SERIAL_PORT 0 #define SERIAL_PORT 0
// This determines the communication speed of the printer // This determines the communication speed of the printer
// 115200 - 250000 // 2400,9600,19200,38400,57600,115200,250000
#define BAUDRATE 115200 #define BAUDRATE 115200
// This enables the serial port associated to the Bluetooth interface on AT90USB devices // This enables the serial port associated to the Bluetooth interface on AT90USB devices
...@@ -158,7 +158,7 @@ ...@@ -158,7 +158,7 @@
// 1010 is Pt1000 with 1k pullup (non standard) // 1010 is Pt1000 with 1k pullup (non standard)
// 147 is Pt100 with 4k7 pullup // 147 is Pt100 with 4k7 pullup
// 110 is Pt100 with 1k pullup (non standard) // 110 is Pt100 with 1k pullup (non standard)
// 998 and 999 are Dummy Tables. They will ALWAYS read 25°C or the temperature defined below. // 998 and 999 are Dummy Tables. They will ALWAYS read 25°C or the temperature defined below.
// Use it for Testing or Development purposes. NEVER for production machine. // Use it for Testing or Development purposes. NEVER for production machine.
// #define DUMMY_THERMISTOR_998_VALUE 25 // #define DUMMY_THERMISTOR_998_VALUE 25
// #define DUMMY_THERMISTOR_999_VALUE 100 // #define DUMMY_THERMISTOR_999_VALUE 100
...@@ -278,7 +278,6 @@ ...@@ -278,7 +278,6 @@
#define EXTRUDE_MINTEMP 170 // degC #define EXTRUDE_MINTEMP 170 // degC
#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances. #define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances.
//=========================================================================== //===========================================================================
//======================== Thermal Runaway Protection ======================= //======================== Thermal Runaway Protection =======================
//=========================================================================== //===========================================================================
...@@ -294,30 +293,16 @@ ...@@ -294,30 +293,16 @@
* The solution: Once the temperature reaches the target, start observing. * The solution: Once the temperature reaches the target, start observing.
* If the temperature stays too far below the target (hysteresis) for too long, * If the temperature stays too far below the target (hysteresis) for too long,
* the firmware will halt as a safety precaution. * the firmware will halt as a safety precaution.
*
* Note that because the countdown starts only AFTER the temperature reaches
* the target, this will not catch a thermistor that is already disconnected
* when the print starts!
*
* To enable for all extruder heaters, uncomment the two defines below:
*/ */
// Parameters for all extruder heaters //#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders
#define THERMAL_RUNAWAY_PROTECTION_PERIOD 40 // in seconds //#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed
#define THERMAL_RUNAWAY_PROTECTION_HYSTERESIS 4 // in degree Celsius
// To enable for the bed heater, uncomment the two defines below:
// Parameters for the bed heater
#define THERMAL_RUNAWAY_PROTECTION_BED_PERIOD 20 // in seconds
#define THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS 2 // in degree Celsius
//=========================================================================== //===========================================================================
//============================ User Interfaces ============================== //============================ User Interfaces ==============================
//=========================================================================== //===========================================================================
//==============================LCD and SD support============================= //============================ LCD and SD support ===========================
// Choose ONE of these 3 charsets. This has to match your hardware. Ignored for full graphic display. // Choose ONE of these 3 charsets. This has to match your hardware. Ignored for full graphic display.
// To find out what type you have - compile with (test) - upload - click to get the menu. You'll see two typical lines from the upper half of the charset. // To find out what type you have - compile with (test) - upload - click to get the menu. You'll see two typical lines from the upper half of the charset.
...@@ -402,13 +387,13 @@ ...@@ -402,13 +387,13 @@
// #define LCD_SCREEN_ROT_270 // #define LCD_SCREEN_ROT_270
// SPLASH SCREEN duration in millisecond // SPLASH SCREEN duration in millisecond
#define SPLASH_SCREEN_DURATION 2000 // Millisecond #define SPLASH_SCREEN_DURATION 5000 // Millisecond
/** Display Voltage Logic Selector on Alligator Board /** Display Voltage Logic Selector on Alligator Board
0 = Voltage level 3.3V 0 = Voltage level 3.3V
1 = Voltage level 5V 1 = Voltage level 5V
*/ */
#define UI_VOLTAGE_LEVEL 0 // Set 5 o 3.3 V #define UI_VOLTAGE_LEVEL 1 // Set 5 o 3.3 V
//============================== Languages UI ========================= //============================== Languages UI =========================
...@@ -441,7 +426,7 @@ ...@@ -441,7 +426,7 @@
// M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to. // M502 - reverts to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
//define this to enable EEPROM support //define this to enable EEPROM support
//#define EEPROM_SETTINGS //#define EEPROM_SETTINGS
//#define EEPROM_CHITCHAT #define EEPROM_CHITCHAT
// to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out: // to disable EEPROM Serial responses and decrease program space by ~1700 byte: comment this out:
// please keep turned on if you can. // please keep turned on if you can.
//#define DISABLE_M503 //#define DISABLE_M503
...@@ -496,9 +481,9 @@ ...@@ -496,9 +481,9 @@
* Support for a filament diameter sensor * Support for a filament diameter sensor
* Also allows adjustment of diameter at print time (vs at slicing) * Also allows adjustment of diameter at print time (vs at slicing)
* Single extruder only at this point (extruder 0) * Single extruder only at this point (extruder 0)
* *
* Motherboards * Motherboards
* 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector * 34 - RAMPS1.4 - uses Analog input 5 on the AUX2 connector
* 81 - Printrboard - Uses Analog input 2 on the Exp1 connector (version B,C,D,E) * 81 - Printrboard - Uses Analog input 2 on the Exp1 connector (version B,C,D,E)
* 301 - Rambo - uses Analog input 3 * 301 - Rambo - uses Analog input 3
* Note may require analog pins to be defined for different motherboards * Note may require analog pins to be defined for different motherboards
......
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
#define X_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define X_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Y_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Z_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z2_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define E_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define E_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define X_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Y_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Z_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z2_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z_PROBE_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Z_PROBE_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
// ENDSTOP SETTINGS: // ENDSTOP SETTINGS:
......
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
#define X_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define X_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Y_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Z_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z2_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define E_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define E_MIN_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define X_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Y_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Z_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z2_MAX_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
#define Z_PROBE_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop. #define Z_PROBE_ENDSTOP_LOGIC false // set to true to invert the logic of the endstop.
// ENDSTOP SETTINGS: // ENDSTOP SETTINGS:
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// QHARLEYS Autobedlevelling has not been ported, because Marlin has now Bed-levelling // QHARLEYS Autobedlevelling has not been ported, because Marlin has now Bed-levelling
// You might need Z-Min endstop on SCARA-Printer to use this feature. Actually untested! // You might need Z-Min endstop on SCARA-Printer to use this feature. Actually untested!
// Uncomment to use Morgan scara mode // Uncomment to use Morgan scara mode
#define scara_segments_per_second 200 //careful, two much will decrease performance... #define SCARA_SEGMENTS_PER_SECOND 200 // If movement is choppy try lowering this value
// Length of inner support arm // Length of inner support arm
#define Linkage_1 150 //mm Preprocessor cannot handle decimal point... #define Linkage_1 150 //mm Preprocessor cannot handle decimal point...
// Length of outer support arm Measure arm lengths precisely and enter // Length of outer support arm Measure arm lengths precisely and enter
......
...@@ -23,24 +23,38 @@ ...@@ -23,24 +23,38 @@
#define BED_CHECK_INTERVAL 5000 //ms between checks in bang-bang control #define BED_CHECK_INTERVAL 5000 //ms between checks in bang-bang control
/** /**
* Heating Sanity Check * Thermal Protection parameters
*
* Whenever an M104 or M109 increases the target temperature this will wait for WATCH_TEMP_PERIOD milliseconds,
* and if the temperature hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted, requiring a
* hard reset. This test restarts with any M104/M109, but only if the current temperature is below the target
* by at least 2 * WATCH_TEMP_INCREASE degrees celsius.
*/ */
//#define WATCH_TEMP_PERIOD 16000 // 16 seconds #ifdef THERMAL_PROTECTION_HOTENDS
//#define WATCH_TEMP_INCREASE 4 // Heat up at least 4 degrees in 16 seconds #define THERMAL_PROTECTION_PERIOD 40 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius
/**
* Whenever an M104 or M109 increases the target temperature the firmware will wait for the
* WATCH_TEMP_PERIOD to transpire, and if the temperature hasn't increased by WATCH_TEMP_INCREASE
* degrees, the machine is halted, requiring a hard reset. This test restarts with any M104/M109,
* but only if the current temperature is far enough below the target for a reliable test.
*/
#define WATCH_TEMP_PERIOD 16 // Seconds
#define WATCH_TEMP_INCREASE 4 // Degrees Celsius
#endif
#ifdef THERMAL_PROTECTION_BED
#define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius
#endif
//automatic temperature: The hot end target temperature is calculated by all the buffered lines of gcode.
//The maximum buffered steps/sec of the extruder motor are called "se". /**
//You enter the autotemp mode by a M109 S<mintemp> B<maxtemp> F<factor> * Automatic Temperature:
// the target temperature is set to mintemp+factor*se[steps/sec] and limited by mintemp and maxtemp * The hotend target temperature is calculated by all the buffered lines of gcode.
// you exit the value by any M109 without F* * The maximum buffered steps/sec of the extruder motor is called "se".
// Also, if the temperature is set to a value <mintemp, it is not changed by autotemp. * Start autotemp mode with M109 S<mintemp> B<maxtemp> F<factor>
// on an Ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode * The target temperature is set to mintemp+factor*se[steps/sec] and is limited by
* mintemp and maxtemp. Turn this off by excuting M109 without F*
* Also, if the temperature is set to a value below mintemp, it will not be changed by autotemp.
* On an Ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode
*/
#define AUTOTEMP #define AUTOTEMP
#ifdef AUTOTEMP #ifdef AUTOTEMP
#define AUTOTEMP_OLDWEIGHT 0.98 #define AUTOTEMP_OLDWEIGHT 0.98
...@@ -50,11 +64,13 @@ ...@@ -50,11 +64,13 @@
//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, * extruder idle oozing prevention
//some filament is retracted. The filament retracted is re-added before the next extrusion * if the extruder motor is idle for more than SECONDS, and the temperature over MINTEMP,
//or when the target temperature is less than EXTRUDE_MINTEMP and the actual temperature * some filament is retracted. The filament retracted is re-added before the next extrusion
//is greater than IDLE_OOZING_MINTEMP and less than IDLE_OOZING_FEEDRATE * or when the target temperature is less than EXTRUDE_MINTEMP and the actual temperature
* is greater than IDLE_OOZING_MINTEMP and less than IDLE_OOZING_FEEDRATE
*/
//#define IDLE_OOZING_PREVENT //#define IDLE_OOZING_PREVENT
#define IDLE_OOZING_MINTEMP EXTRUDE_MINTEMP + 5 #define IDLE_OOZING_MINTEMP EXTRUDE_MINTEMP + 5
#define IDLE_OOZING_MAXTEMP IDLE_OOZING_MINTEMP + 5 #define IDLE_OOZING_MAXTEMP IDLE_OOZING_MINTEMP + 5
...@@ -275,8 +291,11 @@ ...@@ -275,8 +291,11 @@
// be commented out otherwise // be commented out otherwise
#define SDCARDDETECTINVERTED #define SDCARDDETECTINVERTED
#define SD_FINISHED_STEPPERRELEASE true //if sd support and the file is finished: disable steppers? // Disable steppers when the file is done printing
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E" // You might want to keep the z enabled so your bed stays in place. #define SD_FINISHED_STEPPERRELEASE true
// Command to send. You may want to keep Z enabled so your bed stays in place.
#define SD_FINISHED_RELEASECOMMAND "M84 X Y Z E"
#define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order. #define SDCARD_RATHERRECENTFIRST //reverse file order of sd card menu display. Its sorted practically after the file system block order.
// if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that. // if a file is deleted, it frees a block. hence, the order is not purely chronological. To still have auto0.g accessible, there is again the option to do that.
...@@ -284,7 +303,7 @@ ...@@ -284,7 +303,7 @@
//#define MENU_ADDAUTOSTART //#define MENU_ADDAUTOSTART
// Show a progress bar on HD44780 LCDs for SD printing // Show a progress bar on HD44780 LCDs for SD printing
#define LCD_PROGRESS_BAR //#define LCD_PROGRESS_BAR
#ifdef LCD_PROGRESS_BAR #ifdef LCD_PROGRESS_BAR
// Amount of time (ms) to show the bar // Amount of time (ms) to show the bar
......
...@@ -266,8 +266,8 @@ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy ...@@ -266,8 +266,8 @@ VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
endif endif
CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \ CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \
MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \ MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \
SdFile.cpp SdVolume.cpp motion_control.cpp planner.cpp \ SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \
stepper.cpp temperature.cpp cardreader.cpp configuration_store.cpp \ temperature.cpp cardreader.cpp configuration_store.cpp \
watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \ watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \
vector_3.cpp qr_solve.cpp vector_3.cpp qr_solve.cpp
ifeq ($(LIQUID_TWI2), 0) ifeq ($(LIQUID_TWI2), 0)
......
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "Configuration.h" #include "Configuration.h"
#ifndef SANITYCHECK_H
#error Your Configuration.h and Configuration_adv.h files are outdated!
#endif
#if (ARDUINO >= 100) #if (ARDUINO >= 100)
#include "Arduino.h" #include "Arduino.h"
#else #else
...@@ -134,14 +138,14 @@ void manage_inactivity(bool ignore_stepper_queue=false); ...@@ -134,14 +138,14 @@ void manage_inactivity(bool ignore_stepper_queue=false);
* 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.
*/ */
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}; 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};
enum EndstopEnum {X_MIN=0, Y_MIN=1, Z_MIN=2, Z_PROBE=3, X_MAX=4, Y_MAX=5, Z_MAX=6};
void enable_all_steppers(); void enable_all_steppers();
void disable_all_steppers(); void disable_all_steppers();
void FlushSerialRequestResend(); void FlushSerialRequestResend();
void ClearToSend(); void ok_to_send();
void get_coordinates();
#ifdef DELTA #ifdef DELTA
float probe_bed(float x, float y); float probe_bed(float x, float y);
void set_delta_constants(); void set_delta_constants();
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "planner.h" #include "planner.h"
#include "stepper.h" #include "stepper.h"
#include "temperature.h" #include "temperature.h"
#include "motion_control.h"
#include "cardreader.h" #include "cardreader.h"
#include "watchdog.h" #include "watchdog.h"
#include "configuration_store.h" #include "configuration_store.h"
...@@ -221,7 +220,7 @@ bool Running = true; ...@@ -221,7 +220,7 @@ bool Running = true;
uint8_t debugLevel = DEBUG_INFO|DEBUG_COMMUNICATION; uint8_t debugLevel = DEBUG_INFO|DEBUG_COMMUNICATION;
static float feedrate = 1500.0, next_feedrate, saved_feedrate; static float feedrate = 1500.0, saved_feedrate;
float current_position[NUM_AXIS] = { 0.0 }; float current_position[NUM_AXIS] = { 0.0 };
float destination[NUM_AXIS] = { 0.0 }; float destination[NUM_AXIS] = { 0.0 };
float lastpos[NUM_AXIS] = { 0.0 }; float lastpos[NUM_AXIS] = { 0.0 };
...@@ -254,7 +253,6 @@ bool cancel_heatup = false; ...@@ -254,7 +253,6 @@ bool cancel_heatup = false;
const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
static float offset[3] = { 0 };
static bool relative_mode = false; //Determines Absolute or Relative Coordinates static bool relative_mode = false; //Determines Absolute or Relative Coordinates
static char serial_char; static char serial_char;
static int serial_count = 0; static int serial_count = 0;
...@@ -272,10 +270,6 @@ static uint8_t target_extruder; ...@@ -272,10 +270,6 @@ static uint8_t target_extruder;
bool no_wait_for_cooling = true; bool no_wait_for_cooling = true;
bool target_direction; bool target_direction;
// Lifetime stats
unsigned long printer_usage_seconds;
millis_t config_last_update = 0;
#ifndef DELTA #ifndef DELTA
int xy_travel_speed = XY_TRAVEL_SPEED; int xy_travel_speed = XY_TRAVEL_SPEED;
float zprobe_zoffset = 0; float zprobe_zoffset = 0;
...@@ -340,7 +334,8 @@ millis_t config_last_update = 0; ...@@ -340,7 +334,8 @@ millis_t config_last_update = 0;
float tower_adj[6] = { 0, 0, 0, 0, 0, 0 }; float tower_adj[6] = { 0, 0, 0, 0, 0, 0 };
float delta_radius; // = DEFAULT_delta_radius; float delta_radius; // = DEFAULT_delta_radius;
float delta_diagonal_rod; // = DEFAULT_DELTA_DIAGONAL_ROD; float delta_diagonal_rod; // = DEFAULT_DELTA_DIAGONAL_ROD;
float DELTA_DIAGONAL_ROD_2; float delta_diagonal_rod_2;
float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
float ac_prec = AUTOCALIBRATION_PRECISION / 2; float ac_prec = AUTOCALIBRATION_PRECISION / 2;
float bed_radius = PRINTER_RADIUS; float bed_radius = PRINTER_RADIUS;
float delta_tower1_x, delta_tower1_y; float delta_tower1_x, delta_tower1_y;
...@@ -390,6 +385,7 @@ millis_t config_last_update = 0; ...@@ -390,6 +385,7 @@ millis_t config_last_update = 0;
#endif // DELTA #endif // DELTA
#ifdef SCARA #ifdef SCARA
float delta_segments_per_second = SCARA_SEGMENTS_PER_SECOND;
static float delta[3] = { 0 }; static float delta[3] = { 0 };
float axis_scaling[3] = { 1, 1, 1 }; // Build size scaling, default to 1 float axis_scaling[3] = { 1, 1, 1 }; // Build size scaling, default to 1
#endif #endif
...@@ -462,7 +458,6 @@ millis_t config_last_update = 0; ...@@ -462,7 +458,6 @@ millis_t config_last_update = 0;
//================================ Functions ================================ //================================ Functions ================================
//=========================================================================== //===========================================================================
void get_arc_coordinates();
bool setTargetedHotend(int code); bool setTargetedHotend(int code);
#ifdef PREVENT_DANGEROUS_EXTRUDE #ifdef PREVENT_DANGEROUS_EXTRUDE
...@@ -548,7 +543,6 @@ bool enqueuecommand(const char *cmd) { ...@@ -548,7 +543,6 @@ bool enqueuecommand(const char *cmd) {
return true; return true;
} }
#if MB(ALLIGATOR) #if MB(ALLIGATOR)
void setup_alligator_board() { void setup_alligator_board() {
// Init Expansion Port Voltage logic Selector // Init Expansion Port Voltage logic Selector
...@@ -697,9 +691,6 @@ void setup() { ...@@ -697,9 +691,6 @@ void setup() {
for (int8_t i = 0; i < BUFSIZE; i++) fromsd[i] = false; for (int8_t i = 0; i < BUFSIZE; i++) fromsd[i] = false;
#endif #endif
// load lifetime stats and power consumation from EEPROM
load_lifetime_stats();
// loads data from EEPROM if available else uses defaults (and resets step acceleration rate) // loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
Config_RetrieveSettings(); Config_RetrieveSettings();
...@@ -820,7 +811,9 @@ void get_command() { ...@@ -820,7 +811,9 @@ void get_command() {
#endif #endif
while (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) { while (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
#ifdef NO_TIMEOUTS
last_command_time = ms;
#endif
serial_char = MYSERIAL.read(); serial_char = MYSERIAL.read();
if (serial_char == '\n' || serial_char == '\r' || if (serial_char == '\n' || serial_char == '\r' ||
...@@ -1115,17 +1108,17 @@ static void axis_is_at_home(int axis) { ...@@ -1115,17 +1108,17 @@ static void axis_is_at_home(int axis) {
} }
else { else {
current_position[axis] = base_home_pos(axis) + home_offset[axis]; current_position[axis] = base_home_pos(axis) + home_offset[axis];
min_pos[axis] = base_min_pos(axis) + home_offset[axis]; min_pos[axis] = base_min_pos(axis) + home_offset[axis];
max_pos[axis] = base_max_pos(axis) + home_offset[axis]; max_pos[axis] = base_max_pos(axis) + home_offset[axis];
} }
#elif defined(DELTA) #elif defined(DELTA)
current_position[axis] = base_home_pos[axis] + home_offset[axis]; current_position[axis] = base_home_pos[axis] + home_offset[axis];
min_pos[axis] = base_min_pos(axis) + home_offset[axis]; min_pos[axis] = base_min_pos(axis) + home_offset[axis];
max_pos[axis] = base_max_pos[axis] + home_offset[axis]; max_pos[axis] = base_max_pos[axis] + home_offset[axis];
#else #else
current_position[axis] = base_home_pos(axis) + home_offset[axis]; current_position[axis] = base_home_pos(axis) + home_offset[axis];
min_pos[axis] = base_min_pos(axis) + home_offset[axis]; min_pos[axis] = base_min_pos(axis) + home_offset[axis];
max_pos[axis] = base_max_pos(axis) + home_offset[axis]; max_pos[axis] = base_max_pos(axis) + home_offset[axis];
#endif #endif
#if defined(ENABLE_AUTO_BED_LEVELING) && Z_HOME_DIR < 0 #if defined(ENABLE_AUTO_BED_LEVELING) && Z_HOME_DIR < 0
...@@ -1179,6 +1172,14 @@ inline void sync_plan_position() { ...@@ -1179,6 +1172,14 @@ inline void sync_plan_position() {
inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); } inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); }
inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); } inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); }
static void setup_for_endstop_move() {
saved_feedrate = feedrate;
saved_feedrate_multiplier = feedrate_multiplier;
feedrate_multiplier = 100;
refresh_cmd_timeout();
enable_endstops(true);
}
#if defined(CARTESIAN) || defined(COREXY) || defined(SCARA) #if defined(CARTESIAN) || defined(COREXY) || defined(SCARA)
static void do_blocking_move_to(float x, float y, float z) { static void do_blocking_move_to(float x, float y, float z) {
...@@ -1218,7 +1219,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1218,7 +1219,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
current_position[Z_AXIS] = corrected_position.z; current_position[Z_AXIS] = corrected_position.z;
// put the bed at 0 so we don't go below it. // put the bed at 0 so we don't go below it.
current_position[Z_AXIS] = zprobe_zoffset; // in the lsq we reach here after raising the extruder due to the loop structure //current_position[Z_AXIS] = zprobe_zoffset; // in the lsq we reach here after raising the extruder due to the loop structure
sync_plan_position(); sync_plan_position();
} }
...@@ -1246,7 +1247,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1246,7 +1247,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
current_position[Z_AXIS] = corrected_position.z; current_position[Z_AXIS] = corrected_position.z;
// put the bed at 0 so we don't go below it. // put the bed at 0 so we don't go below it.
current_position[Z_AXIS] += zprobe_zoffset; //current_position[Z_AXIS] += zprobe_zoffset;
sync_plan_position(); sync_plan_position();
} }
...@@ -1285,14 +1286,6 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1285,14 +1286,6 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
sync_plan_position(); sync_plan_position();
} }
static void setup_for_endstop_move() {
saved_feedrate = feedrate;
saved_feedrate_multiplier = feedrate_multiplier;
feedrate_multiplier = 100;
refresh_cmd_timeout();
enable_endstops(true);
}
static void clean_up_after_endstop_move() { static void clean_up_after_endstop_move() {
#ifdef ENDSTOPS_ONLY_FOR_HOMING #ifdef ENDSTOPS_ONLY_FOR_HOMING
enable_endstops(false); enable_endstops(false);
...@@ -1306,39 +1299,42 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1306,39 +1299,42 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
#if NUM_SERVOS > 0 #if NUM_SERVOS > 0
// Engage Z Servo endstop if enabled // Engage Z Servo endstop if enabled
if (servo_endstops[Z_AXIS] >= 0) { if (servo_endstops[Z_AXIS] >= 0) {
Servo *srv = &servo[servo_endstops[Z_AXIS]];
#if SERVO_LEVELING #if SERVO_LEVELING
servo[servo_endstops[Z_AXIS]].attach(0); srv->attach(0);
#endif #endif
servo[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2]); srv->write(servo_endstop_angles[Z_AXIS * 2]);
#if SERVO_LEVELING_DELAY #if SERVO_LEVELING_DELAY
delay(PROBE_SERVO_DEACTIVATION_DELAY); delay(PROBE_SERVO_DEACTIVATION_DELAY);
servo[servo_endstops[Z_AXIS]].detach(); srv->detach();
#endif #endif
} }
#endif //NUM_SERVOS > 0 #endif //NUM_SERVOS > 0
} }
static void stow_z_probe() { static void stow_z_probe(bool doRaise = true) {
#if NUM_SERVOS > 0 #if NUM_SERVOS > 0
// Retract Z Servo endstop if enabled // Retract Z Servo endstop if enabled
if (servo_endstops[Z_AXIS] >= 0) { if (servo_endstops[Z_AXIS] >= 0) {
/* NON FUNZIONA DA VERIFICARE
#if Z_RAISE_AFTER_PROBING > 0 #if Z_RAISE_AFTER_PROBING > 0
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], Z_RAISE_AFTER_PROBING); if (doRaise) {
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_AFTER_PROBING); // this also updates current_position
st_synchronize();
}
#endif #endif
*/
// Change the Z servo angle
Servo *srv = &servo[servo_endstops[Z_AXIS]];
#if SERVO_LEVELING #if SERVO_LEVELING
servo[servo_endstops[Z_AXIS]].attach(0); srv->attach(0);
#endif #endif
servo[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2 + 1]);
#if SERVO_LEVELING #if SERVO_LEVELING
delay(PROBE_SERVO_DEACTIVATION_DELAY); delay(PROBE_SERVO_DEACTIVATION_DELAY);
servo[servo_endstops[Z_AXIS]].detach(); srv->detach();
#endif #endif
} }
#endif //NUM_SERVOS > 0 #endif //NUM_SERVOS > 0
} }
...@@ -1351,7 +1347,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1351,7 +1347,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
}; };
// Probe bed height at position (x,y), returns the measured z value // Probe bed height at position (x,y), returns the measured z value
static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeDeployAndStow, int verbose_level=1) { static float probe_pt(float x, float y, float z_before, ProbeAction retract_action = ProbeDeployAndStow, int verbose_level = 1) {
// move to right place // move to right place
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before); do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]); do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
...@@ -1363,16 +1359,6 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1363,16 +1359,6 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
run_z_probe(); run_z_probe();
float measured_z = current_position[Z_AXIS]; float measured_z = current_position[Z_AXIS];
/* NON FUNZIONA CONTROLLARE
#if Z_RAISE_BETWEEN_PROBINGS > 0
if (retract_action == ProbeStay) {
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS);
st_synchronize();
}
#endif
*/
#ifndef Z_PROBE_SLED #ifndef Z_PROBE_SLED
if (retract_action & ProbeStow) stow_z_probe(); if (retract_action & ProbeStow) stow_z_probe();
#endif #endif
...@@ -1403,17 +1389,29 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1403,17 +1389,29 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
current_position[axis] = 0; current_position[axis] = 0;
sync_plan_position(); sync_plan_position();
// Engage Servo endstop if enabled #ifdef Z_PROBE_SLED
#if (NUM_SERVOS > 0) && !defined(Z_PROBE_SLED) // Get Probe
#if SERVO_LEVELING if (axis == Z_AXIS) {
if (axis == Z_AXIS) deploy_z_probe(); else if (axis_home_dir < 0) dock_sled(false);
#endif }
{ #endif
if (servo_endstops[axis] > -1)
servo[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
}
#endif // SERVO_ENDSTOPS && !Z_PROBE_SLED
#if SERVO_LEVELING && !defined(Z_PROBE_SLED)
// Deploy a probe if there is one, and homing towards the bed
if (axis == Z_AXIS) {
if (axis_home_dir < 0) deploy_z_probe();
}
else
#endif
#if SERVO_LEVELING
{
// Engage Servo endstop if enabled
if (servo_endstops[axis] > -1)
servo[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
}
#endif
// Set a flag for Z motor locking
#ifdef Z_DUAL_ENDSTOPS #ifdef Z_DUAL_ENDSTOPS
if (axis == Z_AXIS) In_Homing_Process(true); if (axis == Z_AXIS) In_Homing_Process(true);
#endif #endif
...@@ -1479,14 +1477,26 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1479,14 +1477,26 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
endstops_hit_on_purpose(); // clear endstop hit flags endstops_hit_on_purpose(); // clear endstop hit flags
axis_known_position[axis] = true; axis_known_position[axis] = true;
// Retract Servo endstop if enabled #ifdef Z_PROBE_SLED
#if NUM_SERVOS > 0 // bring probe back
if (servo_endstops[axis] > -1) if (axis == Z_AXIS) {
servo[servo_endstops[axis]].write(servo_endstop_angles[axis * 2 + 1]); if (axis_home_dir < 0) dock_sled(true);
}
#endif #endif
#if SERVO_LEVELING && !defined(Z_PROBE_SLED) #if SERVO_LEVELING && !defined(Z_PROBE_SLED)
if (axis == Z_AXIS) stow_z_probe(); // Deploy a probe if there is one, and homing towards the bed
if (axis == Z_AXIS) {
if (axis_home_dir < 0) stow_z_probe();
}
else
#endif
#if SERVO_LEVELING
{
// Retract Servo endstop if enabled
if (servo_endstops[axis] > -1)
servo[servo_endstops[axis]].write(servo_endstop_angles[axis * 2 + 1]);
}
#endif #endif
} }
} }
...@@ -1561,22 +1571,13 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1561,22 +1571,13 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
} }
void set_delta_constants() { void set_delta_constants() {
max_length[Z_AXIS] = max_pos[Z_AXIS] - Z_MIN_POS; max_length[Z_AXIS] = max_pos[Z_AXIS] - Z_MIN_POS;
base_max_pos[Z_AXIS] = max_pos[Z_AXIS]; base_max_pos[Z_AXIS] = max_pos[Z_AXIS];
base_home_pos[Z_AXIS] = max_pos[Z_AXIS]; base_home_pos[Z_AXIS] = max_pos[Z_AXIS];
DELTA_DIAGONAL_ROD_2 = pow(delta_diagonal_rod,2); delta_diagonal_rod_2 = sq(delta_diagonal_rod);
// Effective X/Y positions of the three vertical towers. // Effective X/Y positions of the three vertical towers.
/*
delta_tower1_x = (-SIN_60 * delta_radius) + tower_adj[0]; // front left tower + xa
delta_tower1_y = (-COS_60 * delta_radius) - tower_adj[0] ;
delta_tower2_x = -(-SIN_60 * delta_radius) + tower_adj[1]; // front right tower + xb
delta_tower2_y = (-COS_60 * delta_radius) + tower_adj[1]; //
delta_tower3_x = tower_adj[2] ; // back middle tower + xc
delta_tower3_y = -2 * (-COS_60 * delta_radius);
*/
delta_tower1_x = (delta_radius + tower_adj[3]) * cos((210 + tower_adj[0]) * PI/180); // front left tower delta_tower1_x = (delta_radius + tower_adj[3]) * cos((210 + tower_adj[0]) * PI/180); // front left tower
delta_tower1_y = (delta_radius + tower_adj[3]) * sin((210 + tower_adj[0]) * PI/180); delta_tower1_y = (delta_radius + tower_adj[3]) * sin((210 + tower_adj[0]) * PI/180);
delta_tower2_x = (delta_radius + tower_adj[4]) * cos((330 + tower_adj[1]) * PI/180); // front right tower delta_tower2_x = (delta_radius + tower_adj[4]) * cos((330 + tower_adj[1]) * PI/180); // front right tower
...@@ -1614,7 +1615,6 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1614,7 +1615,6 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
destination[X_AXIS] = z_probe_retract_start_location[X_AXIS]; destination[X_AXIS] = z_probe_retract_start_location[X_AXIS];
destination[Y_AXIS] = z_probe_retract_start_location[Y_AXIS]; destination[Y_AXIS] = z_probe_retract_start_location[Y_AXIS];
destination[Z_AXIS] = z_probe_retract_start_location[Z_AXIS]; destination[Z_AXIS] = z_probe_retract_start_location[Z_AXIS];
prepare_move();
prepare_move_raw(); prepare_move_raw();
// Move the nozzle below the print surface to push the probe up. // Move the nozzle below the print surface to push the probe up.
...@@ -1635,9 +1635,9 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1635,9 +1635,9 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
float z_probe() { float z_probe() {
enable_endstops(true); enable_endstops(true);
feedrate = homing_feedrate[X_AXIS]; //feedrate = homing_feedrate[X_AXIS];
prepare_move_raw(); //prepare_move_raw();
st_synchronize(); //st_synchronize();
float start_z = current_position[Z_AXIS]; float start_z = current_position[Z_AXIS];
long start_steps = st_get_position(Z_AXIS); long start_steps = st_get_position(Z_AXIS);
...@@ -1649,23 +1649,19 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1649,23 +1649,19 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
endstops_hit_on_purpose(); // clear endstop hit flags endstops_hit_on_purpose(); // clear endstop hit flags
#ifdef ENDSTOPS_ONLY_FOR_HOMING #ifdef ENDSTOPS_ONLY_FOR_HOMING
enable_endstops(false); enable_endstops(false);
#endif #endif
long stop_steps = st_get_position(Z_AXIS); long stop_steps = st_get_position(Z_AXIS);
saved_position[X_AXIS] = float((st_get_position(X_AXIS)) / axis_steps_per_unit[X_AXIS]);
saved_position[Y_AXIS] = float((st_get_position(Y_AXIS)) / axis_steps_per_unit[Y_AXIS]);
saved_position[Z_AXIS] = float((st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS]);
float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS]; float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
current_position[Z_AXIS] = mm; current_position[Z_AXIS] = mm;
sync_plan_position_delta(); sync_plan_position_delta();
saved_position[X_AXIS] = float((st_get_position(X_AXIS)) / axis_steps_per_unit[X_AXIS]); // Save tower carriage positions for G30 diagnostic reports
saved_position[Y_AXIS] = float((st_get_position(Y_AXIS)) / axis_steps_per_unit[Y_AXIS]); for(int8_t i=0; i < 3; i++) {
saved_position[Z_AXIS] = float((st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS]); saved_position[i] = st_get_position_mm(i);
}
feedrate = homing_feedrate[Z_AXIS]; feedrate = homing_feedrate[Z_AXIS];
destination[Z_AXIS] = mm + Z_RAISE_BETWEEN_PROBINGS; destination[Z_AXIS] = mm + Z_RAISE_BETWEEN_PROBINGS;
prepare_move_raw(); prepare_move_raw();
...@@ -1805,6 +1801,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1805,6 +1801,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
//Probe all bed positions & store carriage positions //Probe all bed positions & store carriage positions
bed_level_c = probe_bed(0.0, 0.0); bed_level_c = probe_bed(0.0, 0.0);
save_carriage_positions(0); save_carriage_positions(0);
//Probe all bed positions & store carriage positions
bed_level_z = probe_bed(0.0, bed_radius); bed_level_z = probe_bed(0.0, bed_radius);
save_carriage_positions(1); save_carriage_positions(1);
bed_level_oy = probe_bed(-SIN_60 * bed_radius, COS_60 * bed_radius); bed_level_oy = probe_bed(-SIN_60 * bed_radius, COS_60 * bed_radius);
...@@ -1818,37 +1815,47 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1818,37 +1815,47 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
bed_level_ox = probe_bed(SIN_60 * bed_radius, COS_60 * bed_radius); bed_level_ox = probe_bed(SIN_60 * bed_radius, COS_60 * bed_radius);
save_carriage_positions(6); save_carriage_positions(6);
} }
void calibration_report() { void calibration_report() {
//Display Report //Display Report
ECHO_SMV(DB, "\tZ-Tower\t\t\tEndstop Offsets\t", bed_level_z, 4); ECHO_LM(DB, "|\tZ-Tower\t\t\tEndstop Offsets");
ECHO_SM(DB, "| \t");
if (bed_level_z >= 0) ECHO_M(" ");
ECHO_MV("", bed_level_z, 4);
ECHO_MV("\t\t\tX:", endstop_adj[0]); ECHO_MV("\t\t\tX:", endstop_adj[0]);
ECHO_MV(" Y:", endstop_adj[1]); ECHO_MV(" Y:", endstop_adj[1]);
ECHO_EMV(" Z:", endstop_adj[2]); ECHO_EMV(" Z:", endstop_adj[2]);
ECHO_SVM(DB, bed_level_oy, "\t\t", 4); ECHO_SMV(DB, "| ", bed_level_oy, 4);
ECHO_EVM(bed_level_ox, "\t\tTower Position Adjust", 4); ECHO_M("\t\t");
ECHO_EVM(bed_level_ox, "\t\tTower Offsets", 4);
ECHO_SMV(DB, "\t", bed_level_c, 4); ECHO_SM(DB, "| \t");
if (bed_level_c >= 0) ECHO_M(" ");
ECHO_MV("", bed_level_c, 4);
ECHO_MV("\t\t\tA:",tower_adj[0]); ECHO_MV("\t\t\tA:",tower_adj[0]);
ECHO_MV(" B:",tower_adj[1]); ECHO_MV(" B:",tower_adj[1]);
ECHO_EMV(" C:",tower_adj[2]); ECHO_EMV(" C:",tower_adj[2]);
ECHO_SV(DB, bed_level_x, 4); ECHO_SMV(DB, "| ", bed_level_x, 4);
ECHO_MV("\t\t", bed_level_y, 4); ECHO_MV("\t\t", bed_level_y, 4);
ECHO_MV("\t\tI:",tower_adj[3]); ECHO_MV("\t\tI:",tower_adj[3]);
ECHO_MV(" J:",tower_adj[4]); ECHO_MV(" J:",tower_adj[4]);
ECHO_EMV(" K:",tower_adj[5]); ECHO_EMV(" K:",tower_adj[5]);
ECHO_SMV(DB, "\t", bed_level_oz, 4); ECHO_SM(DB, "| \t");
if (bed_level_oz >=0) {ECHO_M(" ");}
ECHO_MV("", bed_level_oz, 4);
ECHO_EMV("\t\t\tDelta Radius: ", delta_radius, 4); ECHO_EMV("\t\t\tDelta Radius: ", delta_radius, 4);
ECHO_LMV(DB, "X-Tower\t\tY-Tower\t\tDiag Rod: ", delta_diagonal_rod, 4); ECHO_LMV(DB, "| X-Tower\t\tY-Tower\t\tDiagonal Rod: ", delta_diagonal_rod, 4);
ECHO_E;
} }
void save_carriage_positions(int position_num) { void save_carriage_positions(int position_num) {
for(int8_t i=0; i < NUM_AXIS; i++) { for(int8_t i = 0; i < 3; i++) {
saved_positions[position_num][i] = saved_position[i]; saved_positions[position_num][i] = saved_position[i];
} }
} }
...@@ -1869,14 +1876,14 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1869,14 +1876,14 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
sync_plan_position(); sync_plan_position();
// Move all carriages up together until the first endstop is hit. // Move all carriages up together until the first endstop is hit.
for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * Z_MAX_LENGTH; for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * max_length[Z_AXIS];
feedrate = 1.732 * homing_feedrate[X_AXIS]; feedrate = 1.732 * homing_feedrate[X_AXIS];
line_to_destination(); line_to_destination();
st_synchronize(); st_synchronize();
endstops_hit_on_purpose(); // clear endstop hit flags endstops_hit_on_purpose(); // clear endstop hit flags
// Destination reached // Destination reached
for (int i = X_AXIS; i <= Z_AXIS; i++) current_position[i] = destination[i]; set_current_to_destination();
// take care of back off and rehome now we are all at the top // take care of back off and rehome now we are all at the top
HOMEAXIS(X); HOMEAXIS(X);
...@@ -1903,15 +1910,15 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -1903,15 +1910,15 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
} }
void calculate_delta(float cartesian[3]) { void calculate_delta(float cartesian[3]) {
delta[X_AXIS] = sqrt(DELTA_DIAGONAL_ROD_2 delta[X_AXIS] = sqrt(delta_diagonal_rod_2
- sq(delta_tower1_x-cartesian[X_AXIS]) - sq(delta_tower1_x-cartesian[X_AXIS])
- sq(delta_tower1_y-cartesian[Y_AXIS]) - sq(delta_tower1_y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS]; ) + cartesian[Z_AXIS];
delta[Y_AXIS] = sqrt(DELTA_DIAGONAL_ROD_2 delta[Y_AXIS] = sqrt(delta_diagonal_rod_2
- sq(delta_tower2_x-cartesian[X_AXIS]) - sq(delta_tower2_x-cartesian[X_AXIS])
- sq(delta_tower2_y-cartesian[Y_AXIS]) - sq(delta_tower2_y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS]; ) + cartesian[Z_AXIS];
delta[Z_AXIS] = sqrt(DELTA_DIAGONAL_ROD_2 delta[Z_AXIS] = sqrt(delta_diagonal_rod_2
- sq(delta_tower3_x-cartesian[X_AXIS]) - sq(delta_tower3_x-cartesian[X_AXIS])
- sq(delta_tower3_y-cartesian[Y_AXIS]) - sq(delta_tower3_y-cartesian[Y_AXIS])
) + cartesian[Z_AXIS]; ) + cartesian[Z_AXIS];
...@@ -2352,7 +2359,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -2352,7 +2359,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
#endif #endif
#ifdef FWRETRACT #ifdef FWRETRACT
void retract(bool retracting, bool swapretract = false) { void retract(bool retracting, bool swapping = false) {
if (retracting == retracted[active_extruder]) return; if (retracting == retracted[active_extruder]) return;
...@@ -2363,7 +2370,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -2363,7 +2370,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
if (retracting) { if (retracting) {
feedrate = retract_feedrate * 60; feedrate = retract_feedrate * 60;
current_position[E_AXIS] += (swapretract ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder]; current_position[E_AXIS] += (swapping ? retract_length_swap : retract_length) / volumetric_multiplier[active_extruder];
plan_set_e_position(current_position[E_AXIS]); plan_set_e_position(current_position[E_AXIS]);
prepare_move(); prepare_move();
...@@ -2390,7 +2397,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -2390,7 +2397,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
} }
feedrate = retract_recover_feedrate * 60; feedrate = retract_recover_feedrate * 60;
float move_e = swapretract ? retract_length_swap + retract_recover_length_swap : retract_length + retract_recover_length; float move_e = swapping ? retract_length_swap + retract_recover_length_swap : retract_length + retract_recover_length;
current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder]; current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder];
plan_set_e_position(current_position[E_AXIS]); plan_set_e_position(current_position[E_AXIS]);
prepare_move(); prepare_move();
...@@ -2435,7 +2442,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position, ...@@ -2435,7 +2442,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
inline void wait_heater() { inline void wait_heater() {
#ifdef WATCH_TEMP_PERIOD #ifdef THERMAL_PROTECTION_HOTENDS
start_watching_heater(target_extruder); start_watching_heater(target_extruder);
#endif #endif
...@@ -2522,6 +2529,26 @@ inline void wait_bed() { ...@@ -2522,6 +2529,26 @@ inline void wait_bed() {
***************************** G-Code Functions ******************************** ***************************** G-Code Functions ********************************
*******************************************************************************/ *******************************************************************************/
/**
* Set XYZE destination and feedrate from the current GCode command
*
* - Set destination from included axis codes
* - Set to current for missing axis codes
* - Set the feedrate, if included
*/
void gcode_get_destination() {
for (int i = 0; i < NUM_AXIS; i++) {
if (code_seen(axis_codes[i]))
destination[i] = code_value() + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0);
else
destination[i] = current_position[i];
}
if (code_seen('F')) {
float next_feedrate = code_value();
if (next_feedrate > 0.0) feedrate = next_feedrate;
}
}
/** /**
* G0, G1: Coordinated movement of X Y Z E axes * G0, G1: Coordinated movement of X Y Z E axes
*/ */
...@@ -2532,26 +2559,148 @@ inline void gcode_G0_G1() { ...@@ -2532,26 +2559,148 @@ inline void gcode_G0_G1() {
IDLE_OOZING_retract(false); IDLE_OOZING_retract(false);
#endif #endif
get_coordinates(); // For X Y Z E F gcode_get_destination(); // For X Y Z E F
#ifdef FWRETRACT #ifdef FWRETRACT
if (autoretract_enabled) { if (autoretract_enabled && !(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) {
if (!(code_seen('X') || code_seen('Y') || code_seen('Z')) && code_seen('E')) { float echange = destination[E_AXIS] - current_position[E_AXIS];
float echange = destination[E_AXIS] - current_position[E_AXIS]; // Is this move an attempt to retract or recover?
// Is this move an attempt to retract or recover? if ((echange < -MIN_RETRACT && !retracted[active_extruder]) || (echange > MIN_RETRACT && retracted[active_extruder])) {
if ((echange < -MIN_RETRACT && !retracted[active_extruder]) || (echange > MIN_RETRACT && retracted[active_extruder])) { current_position[E_AXIS] = destination[E_AXIS]; // hide the slicer-generated retract/recover from calculations
current_position[E_AXIS] = destination[E_AXIS]; // hide the slicer-generated retract/recover from calculations plan_set_e_position(current_position[E_AXIS]); // AND from the planner
plan_set_e_position(current_position[E_AXIS]); // AND from the planner retract(!retracted[active_extruder]);
retract(!retracted[active_extruder]); return;
return;
}
} }
} }
#endif //FWRETRACT #endif //FWRETRACT
prepare_move(); prepare_move();
//ClearToSend(); //ok_to_send();
}
}
/**
* Plan an arc in 2 dimensions
*
* The arc is approximated by generating many small linear segments.
* The length of each segment is configured in MM_PER_ARC_SEGMENT (Default 1mm)
* Arcs should only be made relatively large (over 5mm), as larger arcs with
* larger segments will tend to be more efficient. Your slicer should have
* options for G2/G3 arc generation. In future these options may be GCode tunable.
*/
void plan_arc(
float *target, // Destination position
float *offset, // Center of rotation relative to current_position
uint8_t clockwise // Clockwise?
) {
float radius = hypot(offset[X_AXIS], offset[Y_AXIS]),
center_axis0 = current_position[X_AXIS] + offset[X_AXIS],
center_axis1 = current_position[Y_AXIS] + offset[Y_AXIS],
linear_travel = target[Z_AXIS] - current_position[Z_AXIS],
extruder_travel = target[E_AXIS] - current_position[E_AXIS],
r_axis0 = -offset[X_AXIS], // Radius vector from center to current location
r_axis1 = -offset[Y_AXIS],
rt_axis0 = target[X_AXIS] - center_axis0,
rt_axis1 = target[Y_AXIS] - center_axis1;
// CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required.
float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
if (angular_travel < 0) { angular_travel += RADIANS(360); }
if (clockwise) { angular_travel -= RADIANS(360); }
// Make a circle if the angular rotation is 0
if (current_position[X_AXIS] == target[X_AXIS] && current_position[Y_AXIS] == target[Y_AXIS] && angular_travel == 0)
angular_travel += RADIANS(360);
float mm_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
if (mm_of_travel < 0.001) { return; }
uint16_t segments = floor(mm_of_travel / MM_PER_ARC_SEGMENT);
if (segments == 0) segments = 1;
float theta_per_segment = angular_travel/segments;
float linear_per_segment = linear_travel/segments;
float extruder_per_segment = extruder_travel/segments;
/* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
r_T = [cos(phi) -sin(phi);
sin(phi) cos(phi] * r ;
For arc generation, the center of the circle is the axis of rotation and the radius vector is
defined from the circle center to the initial position. Each line segment is formed by successive
vector rotations. This requires only two cos() and sin() computations to form the rotation
matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
all double numbers are single precision on the Arduino. (True double precision will not have
round off issues for CNC applications.) Single precision error can accumulate to be greater than
tool precision in some cases. Therefore, arc path correction is implemented.
Small angle approximation may be used to reduce computation overhead further. This approximation
holds for everything, but very small circles and large MM_PER_ARC_SEGMENT values. In other words,
theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large
to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for
numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an
issue for CNC machines with the single precision Arduino calculations.
This approximation also allows plan_arc to immediately insert a line segment into the planner
without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
a correction, the planner should have caught up to the lag caused by the initial plan_arc overhead.
This is important when there are successive arc motions.
*/
// Vector rotation matrix values
float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
float sin_T = theta_per_segment;
float arc_target[4];
float sin_Ti;
float cos_Ti;
float r_axisi;
uint16_t i;
int8_t count = 0;
// Initialize the linear axis
arc_target[Z_AXIS] = current_position[Z_AXIS];
// Initialize the extruder axis
arc_target[E_AXIS] = current_position[E_AXIS];
float feed_rate = feedrate*feedrate_multiplier/60/100.0;
for (i = 1; i < segments; i++) { // Increment (segments-1)
if (count < N_ARC_CORRECTION) {
// Apply vector rotation matrix to previous r_axis0 / 1
r_axisi = r_axis0*sin_T + r_axis1*cos_T;
r_axis0 = r_axis0*cos_T - r_axis1*sin_T;
r_axis1 = r_axisi;
count++;
}
else {
// Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
// Compute exact location by applying transformation matrix from initial radius vector(=-offset).
cos_Ti = cos(i*theta_per_segment);
sin_Ti = sin(i*theta_per_segment);
r_axis0 = -offset[X_AXIS]*cos_Ti + offset[Y_AXIS]*sin_Ti;
r_axis1 = -offset[X_AXIS]*sin_Ti - offset[Y_AXIS]*cos_Ti;
count = 0;
}
// Update arc_target location
arc_target[X_AXIS] = center_axis0 + r_axis0;
arc_target[Y_AXIS] = center_axis1 + r_axis1;
arc_target[Z_AXIS] += linear_per_segment;
arc_target[E_AXIS] += extruder_per_segment;
clamp_to_software_endstops(arc_target);
plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], feed_rate, active_extruder, active_driver);
} }
// Ensure last segment arrives at target location.
plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate, active_extruder, active_driver);
// As far as the parser is concerned, the position is now == target. In reality the
// motion control system might still be processing the action and the real tool position
// in any intermediate location.
set_current_to_destination();
} }
/** /**
...@@ -2560,8 +2709,27 @@ inline void gcode_G0_G1() { ...@@ -2560,8 +2709,27 @@ inline void gcode_G0_G1() {
*/ */
inline void gcode_G2_G3(bool clockwise) { inline void gcode_G2_G3(bool clockwise) {
if (IsRunning()) { if (IsRunning()) {
get_arc_coordinates(); #ifdef SF_ARC_FIX
prepare_arc_move(clockwise); bool relative_mode_backup = relative_mode;
relative_mode = true;
#endif
gcode_get_destination();
#ifdef SF_ARC_FIX
relative_mode = relative_mode_backup;
#endif
// Center of arc as offset from current_position
float arc_offset[2] = {
code_seen('I') ? code_value() : 0,
code_seen('J') ? code_value() : 0
};
// Send an arc to the planner
plan_arc(destination, arc_offset, clockwise);
refresh_cmd_timeout();
} }
} }
...@@ -2571,14 +2739,15 @@ inline void gcode_G2_G3(bool clockwise) { ...@@ -2571,14 +2739,15 @@ inline void gcode_G2_G3(bool clockwise) {
inline void gcode_G4() { inline void gcode_G4() {
millis_t codenum = 0; millis_t codenum = 0;
LCD_MESSAGEPGM(MSG_DWELL);
if (code_seen('P')) codenum = code_value_long(); // milliseconds to wait if (code_seen('P')) codenum = code_value_long(); // milliseconds to wait
if (code_seen('S')) codenum = code_value_long() * 1000; // seconds to wait if (code_seen('S')) codenum = code_value() * 1000; // seconds to wait
st_synchronize(); st_synchronize();
refresh_cmd_timeout(); refresh_cmd_timeout();
codenum += previous_cmd_ms; // keep track of when we started waiting codenum += previous_cmd_ms; // keep track of when we started waiting
if (!lcd_hasstatus()) LCD_MESSAGEPGM(MSG_DWELL);
while (millis() < codenum) { while (millis() < codenum) {
manage_heater(); manage_heater();
manage_inactivity(); manage_inactivity();
...@@ -2624,17 +2793,15 @@ inline void gcode_G4() { ...@@ -2624,17 +2793,15 @@ inline void gcode_G4() {
*/ */
inline void gcode_G28(boolean home_x = false, boolean home_y = false) { inline void gcode_G28(boolean home_x = false, boolean home_y = false) {
// Wait for planner moves to finish!
st_synchronize();
// For auto bed leveling, clear the level matrix // For auto bed leveling, clear the level matrix
#ifdef ENABLE_AUTO_BED_LEVELING #ifdef ENABLE_AUTO_BED_LEVELING
plan_bed_level_matrix.set_to_identity(); plan_bed_level_matrix.set_to_identity();
#endif #endif
saved_feedrate = feedrate; setup_for_endstop_move();
saved_feedrate_multiplier = feedrate_multiplier;
feedrate_multiplier = 100;
refresh_cmd_timeout();
enable_endstops(true);
set_destination_to_current(); set_destination_to_current();
...@@ -2905,6 +3072,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) { ...@@ -2905,6 +3072,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) {
// Set current X, Y is the Z_SAFE_HOMING_POINT minus PROBE_OFFSET_FROM_EXTRUDER // Set current X, Y is the Z_SAFE_HOMING_POINT minus PROBE_OFFSET_FROM_EXTRUDER
current_position[X_AXIS] = destination[X_AXIS]; current_position[X_AXIS] = destination[X_AXIS];
current_position[Y_AXIS] = destination[Y_AXIS]; current_position[Y_AXIS] = destination[Y_AXIS];
HOMEAXIS(Z); HOMEAXIS(Z);
} }
else if (homeZ) { // Don't need to Home Z twice else if (homeZ) { // Don't need to Home Z twice
...@@ -3054,7 +3222,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) { ...@@ -3054,7 +3222,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) {
if (dryrun) ECHO_LM(DB,"Running in DRY-RUN mode"); if (dryrun) ECHO_LM(DB,"Running in DRY-RUN mode");
} }
int auto_bed_leveling_grid_points = code_seen('P') ? code_value_long() : AUTO_BED_LEVELING_GRID_POINTS; int auto_bed_leveling_grid_points = code_seen('P') ? code_value_short() : AUTO_BED_LEVELING_GRID_POINTS;
if (auto_bed_leveling_grid_points < 2) { if (auto_bed_leveling_grid_points < 2) {
ECHO_LM(ER, "?Number of probed (P)oints is implausible (2 minimum).\n"); ECHO_LM(ER, "?Number of probed (P)oints is implausible (2 minimum).\n");
return; return;
...@@ -3333,6 +3501,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) { ...@@ -3333,6 +3501,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) {
// G30: Delta AutoCalibration // G30: Delta AutoCalibration
inline void gcode_G30() { inline void gcode_G30() {
st_synchronize();
int iterations = 100; // Maximum number of iterations int iterations = 100; // Maximum number of iterations
//Zero the bed level array //Zero the bed level array
...@@ -3345,7 +3514,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) { ...@@ -3345,7 +3514,7 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) {
if (code_seen('C')) { if (code_seen('C')) {
//Show carriage positions //Show carriage positions
ECHO_LM(DB, "Carriage Positions for last scan: "); ECHO_LM(DB, "Carriage Positions for last scan: ");
for(int8_t i=0; i < 7; i++) { for(int8_t i = 0; i < 7; i++) {
ECHO_SMV(DB, "[", saved_positions[i][X_AXIS]); ECHO_SMV(DB, "[", saved_positions[i][X_AXIS]);
ECHO_MV(", ", saved_positions[i][Y_AXIS]); ECHO_MV(", ", saved_positions[i][Y_AXIS]);
ECHO_MV(", ", saved_positions[i][Z_AXIS]); ECHO_MV(", ", saved_positions[i][Z_AXIS]);
...@@ -3399,6 +3568,9 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) { ...@@ -3399,6 +3568,9 @@ inline void gcode_G28(boolean home_x = false, boolean home_y = false) {
retract_z_probe(); retract_z_probe();
//reset LCD alert message
lcd_reset_alert_level();
//Restore saved variables //Restore saved variables
feedrate = saved_feedrate; feedrate = saved_feedrate;
feedrate_multiplier = saved_feedrate_multiplier; feedrate_multiplier = saved_feedrate_multiplier;
...@@ -3430,7 +3602,7 @@ inline void gcode_G61() { ...@@ -3430,7 +3602,7 @@ inline void gcode_G61() {
//ECHO_EMV(" Move to E: ", destination[E_AXIS]); //ECHO_EMV(" Move to E: ", destination[E_AXIS]);
if(code_seen('F')) { if(code_seen('F')) {
next_feedrate = code_value(); float next_feedrate = code_value();
if(next_feedrate > 0.0) feedrate = next_feedrate; if(next_feedrate > 0.0) feedrate = next_feedrate;
} }
//finish moves //finish moves
...@@ -4135,7 +4307,7 @@ inline void gcode_M104() { ...@@ -4135,7 +4307,7 @@ inline void gcode_M104() {
setTargetHotend1(temp == 0.0 ? 0.0 : temp + duplicate_extruder_temp_offset); setTargetHotend1(temp == 0.0 ? 0.0 : temp + duplicate_extruder_temp_offset);
#endif #endif
#ifdef WATCH_TEMP_PERIOD #ifdef THERMAL_PROTECTION_HOTENDS
start_watching_heater(target_extruder); start_watching_heater(target_extruder);
#endif #endif
} }
...@@ -4983,14 +5155,14 @@ inline void gcode_M303() { ...@@ -4983,14 +5155,14 @@ inline void gcode_M303() {
//SoftEndsEnabled = false; // Ignore soft endstops during calibration //SoftEndsEnabled = false; // Ignore soft endstops during calibration
//ECHO_LM(DB, " Soft endstops disabled "); //ECHO_LM(DB, " Soft endstops disabled ");
if (IsRunning()) { if (IsRunning()) {
//get_coordinates(); // For X Y Z E F //gcode_get_destination(); // For X Y Z E F
delta[X_AXIS] = delta_x; delta[X_AXIS] = delta_x;
delta[Y_AXIS] = delta_y; delta[Y_AXIS] = delta_y;
calculate_SCARA_forward_Transform(delta); calculate_SCARA_forward_Transform(delta);
destination[X_AXIS] = delta[X_AXIS]/axis_scaling[X_AXIS]; destination[X_AXIS] = delta[X_AXIS]/axis_scaling[X_AXIS];
destination[Y_AXIS] = delta[Y_AXIS]/axis_scaling[Y_AXIS]; destination[Y_AXIS] = delta[Y_AXIS]/axis_scaling[Y_AXIS];
prepare_move(); prepare_move();
//ClearToSend(); //ok_to_send();
return true; return true;
} }
return false; return false;
...@@ -5101,16 +5273,36 @@ inline void gcode_M303() { ...@@ -5101,16 +5273,36 @@ inline void gcode_M303() {
*/ */
inline void gcode_M400() { st_synchronize(); } inline void gcode_M400() { st_synchronize(); }
#if SERVO_LEVELING #if defined(ENABLE_AUTO_BED_LEVELING) && !defined(Z_PROBE_SLED) && SERVO_LEVELING
#if SERVO_LEVELING
void raise_z_for_servo() {
float zpos = current_position[Z_AXIS], z_dest = Z_RAISE_BEFORE_HOMING;
z_dest += axis_known_position[Z_AXIS] ? -zprobe_zoffset : zpos;
if (zpos < z_dest)
do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_dest); // also updates current_position
}
#endif
/** /**
* M401: Engage Z Servo endstop if available * M401: Engage Z Servo endstop if available
*/ */
inline void gcode_M401() { deploy_z_probe(); } inline void gcode_M401() {
#if SERVO_LEVELING
raise_z_for_servo();
#endif
deploy_z_probe();
}
/** /**
* M402: Retract Z Servo endstop if enabled * M402: Retract Z Servo endstop if enabled
*/ */
inline void gcode_M402() { stow_z_probe(); } inline void gcode_M402() {
#if SERVO_LEVELING
raise_z_for_servo();
#endif
stow_z_probe(false);
}
#endif #endif
...@@ -5511,33 +5703,38 @@ inline void gcode_M503() { ...@@ -5511,33 +5703,38 @@ inline void gcode_M503() {
set_delta_constants(); set_delta_constants();
} }
if (code_seen('P')) { if (code_seen('P')) {
float pz = code_value(); boolean axis_done = false;
if (!(code_seen(axis_codes[0]) || code_seen(axis_codes[1]) || code_seen(axis_codes[2]))) { // Allow direct set of Z offset without an axis code float p_val = code_value();
z_probe_offset[Z_AXIS]= pz; for (int8_t i = 0; i < 3; i++) {
} if (code_seen(axis_codes[i])) {
else { z_probe_offset[i] = code_value();
for(int8_t i=0; i < 3; i++) { axis_done = true;
if (code_seen(axis_codes[i])) z_probe_offset[i] = code_value();
} }
} }
if (axis_done == false) z_probe_offset[Z_AXIS] = p_val;
}
else {
for(int8_t i = 0; i < 3; i++) {
if (code_seen(axis_codes[i])) endstop_adj[i] = code_value();
}
} }
if (code_seen('L')) { if (code_seen('L')) {
ECHO_LM(DB, "Current Delta geometry values:"); ECHO_LM(DB, "Current Delta geometry values:");
ECHO_LMV(DB, "X (Endstop Adj): ",endstop_adj[0]); ECHO_LMV(DB, "X (Endstop Adj): ",endstop_adj[0], 3);
ECHO_LMV(DB, "Y (Endstop Adj): ",endstop_adj[1]); ECHO_LMV(DB, "Y (Endstop Adj): ",endstop_adj[1], 3);
ECHO_LMV(DB, "Z (Endstop Adj): ",endstop_adj[2]); ECHO_LMV(DB, "Z (Endstop Adj): ",endstop_adj[2], 3);
ECHO_SMV(DB, "P (Z-Probe Offset): X", z_probe_offset[0]); ECHO_SMV(DB, "P (Z-Probe Offset): X", z_probe_offset[0]);
ECHO_MV(" Y", z_probe_offset[1]); ECHO_MV(" Y", z_probe_offset[1]);
ECHO_EMV(" Z", z_probe_offset[2]); ECHO_EMV(" Z", z_probe_offset[2]);
ECHO_LMV(DB, "A (Tower A Position Correction): ",tower_adj[0]); ECHO_LMV(DB, "A (Tower A Position Correction): ",tower_adj[0], 3);
ECHO_LMV(DB, "B (Tower B Position Correction): ",tower_adj[1]); ECHO_LMV(DB, "B (Tower B Position Correction): ",tower_adj[1], 3);
ECHO_LMV(DB, "C (Tower C Position Correction): ",tower_adj[2]); ECHO_LMV(DB, "C (Tower C Position Correction): ",tower_adj[2], 3);
ECHO_LMV(DB, "I (Tower A Radius Correction): ",tower_adj[3]); ECHO_LMV(DB, "I (Tower A Radius Correction): ",tower_adj[3], 3);
ECHO_LMV(DB, "J (Tower B Radius Correction): ",tower_adj[4]); ECHO_LMV(DB, "J (Tower B Radius Correction): ",tower_adj[4], 3);
ECHO_LMV(DB, "K (Tower C Radius Correction): ",tower_adj[5]); ECHO_LMV(DB, "K (Tower C Radius Correction): ",tower_adj[5], 3);
ECHO_LMV(DB, "R (Delta Radius): ",delta_radius); ECHO_LMV(DB, "R (Delta Radius): ", delta_radius);
ECHO_LMV(DB, "D (Diagonal Rod Length): ",delta_diagonal_rod); ECHO_LMV(DB, "D (Diagonal Rod Length): ", delta_diagonal_rod);
ECHO_LMV(DB, "H (Z-Height): ",max_pos[Z_AXIS]); ECHO_LMV(DB, "H (Z-Height): ", max_pos[Z_AXIS]);
} }
} }
#endif #endif
...@@ -5648,7 +5845,7 @@ inline void gcode_T() { ...@@ -5648,7 +5845,7 @@ inline void gcode_T() {
make_move = true; make_move = true;
#endif #endif
next_feedrate = code_value(); float next_feedrate = code_value();
if (next_feedrate > 0.0) feedrate = next_feedrate; if (next_feedrate > 0.0) feedrate = next_feedrate;
} }
#if EXTRUDERS > 1 #if EXTRUDERS > 1
...@@ -6270,17 +6467,17 @@ void process_commands() { ...@@ -6270,17 +6467,17 @@ void process_commands() {
ECHO_EVM(command_queue[cmd_queue_index_r], "\""); ECHO_EVM(command_queue[cmd_queue_index_r], "\"");
} }
ClearToSend(); ok_to_send();
} }
void FlushSerialRequestResend() { void FlushSerialRequestResend() {
//char command_queue[cmd_queue_index_r][100]="Resend:"; //char command_queue[cmd_queue_index_r][100]="Resend:";
MYSERIAL.flush(); MYSERIAL.flush();
ECHO_LV(RS, gcode_LastN + 1); ECHO_LV(RS, gcode_LastN + 1);
ClearToSend(); ok_to_send();
} }
void ClearToSend() { void ok_to_send() {
refresh_cmd_timeout(); refresh_cmd_timeout();
#ifdef SDSUPPORT #ifdef SDSUPPORT
if (fromsd[cmd_queue_index_r]) return; if (fromsd[cmd_queue_index_r]) return;
...@@ -6288,45 +6485,12 @@ void ClearToSend() { ...@@ -6288,45 +6485,12 @@ void ClearToSend() {
ECHO_S(OK); ECHO_S(OK);
#ifdef ADVANCED_OK #ifdef ADVANCED_OK
ECHO_MV(" N", gcode_LastN); ECHO_MV(" N", gcode_LastN);
ECHO_MV(" P", int(BLOCK_BUFFER_SIZE - movesplanned() - 1)); ECHO_MV(" P", (int)(BLOCK_BUFFER_SIZE - movesplanned() - 1));
ECHO_MV(" B", BUFSIZE - commands_in_queue); ECHO_MV(" B", BUFSIZE - commands_in_queue);
#endif #endif
ECHO_E; ECHO_E;
} }
void get_coordinates() {
for (int i = 0; i < NUM_AXIS; i++) {
if (code_seen(axis_codes[i]))
destination[i] = code_value() + (axis_relative_modes[i] || relative_mode ? current_position[i] : 0);
else
destination[i] = current_position[i];
}
if (code_seen('F')) {
next_feedrate = code_value();
if (next_feedrate > 0.0) feedrate = next_feedrate;
}
#ifdef LASERBEAM
if(code_seen('L')) {
laser_ttl_modulation = constrain(code_value(), 0, 255);
}
#endif // LASERBEAM
}
void get_arc_coordinates() {
#ifdef SF_ARC_FIX
bool relative_mode_backup = relative_mode;
relative_mode = true;
#endif
get_coordinates();
#ifdef SF_ARC_FIX
relative_mode = relative_mode_backup;
#endif
offset[0] = code_seen('I') ? code_value() : 0;
offset[1] = code_seen('J') ? code_value() : 0;
}
void clamp_to_software_endstops(float target[3]) { void clamp_to_software_endstops(float target[3]) {
if (min_software_endstops) { if (min_software_endstops) {
NOLESS(target[X_AXIS], min_pos[X_AXIS]); NOLESS(target[X_AXIS], min_pos[X_AXIS]);
...@@ -6349,93 +6513,72 @@ void clamp_to_software_endstops(float target[3]) { ...@@ -6349,93 +6513,72 @@ void clamp_to_software_endstops(float target[3]) {
#ifdef PREVENT_DANGEROUS_EXTRUDE #ifdef PREVENT_DANGEROUS_EXTRUDE
inline float prevent_dangerous_extrude(float &curr_e, float &dest_e) { inline void prevent_dangerous_extrude(float &curr_e, float &dest_e) {
float de = dest_e - curr_e; float de = dest_e - curr_e;
if (debugLevel & DEBUG_DRYRUN) return de; if (debugLevel & DEBUG_DRYRUN) return;
if (de) { if (de) {
if (degHotend(active_extruder) < extrude_min_temp) { if (degHotend(active_extruder) < extrude_min_temp) {
curr_e = dest_e; // Behave as if the move really took place, but ignore E part curr_e = dest_e; // Behave as if the move really took place, but ignore E part
ECHO_LM(ER, MSG_ERR_COLD_EXTRUDE_STOP); ECHO_LM(ER, MSG_ERR_COLD_EXTRUDE_STOP);
return 0;
} }
#ifdef PREVENT_LENGTHY_EXTRUDE #ifdef PREVENT_LENGTHY_EXTRUDE
if (labs(de) > EXTRUDE_MAXLENGTH) { if (labs(de) > EXTRUDE_MAXLENGTH) {
curr_e = dest_e; // Behave as if the move really took place, but ignore E part curr_e = dest_e; // Behave as if the move really took place, but ignore E part
ECHO_LM(ER, MSG_ERR_LONG_EXTRUDE_STOP); ECHO_LM(ER, MSG_ERR_LONG_EXTRUDE_STOP);
return 0;
} }
#endif #endif
} }
return de;
} }
#endif // PREVENT_DANGEROUS_EXTRUDE #endif // PREVENT_DANGEROUS_EXTRUDE
void prepare_move() { #if defined(DELTA) || defined(SCARA)
clamp_to_software_endstops(destination);
refresh_cmd_timeout();
#ifdef PREVENT_DANGEROUS_EXTRUDE
(void)prevent_dangerous_extrude(current_position[E_AXIS], destination[E_AXIS]);
#endif
#ifdef SCARA //for now same as delta-code
inline bool prepare_move_delta() {
float difference[NUM_AXIS]; float difference[NUM_AXIS];
for (int8_t i = 0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i]; for (int8_t i = 0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i];
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); } if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
if (cartesian_mm < 0.000001) { return; } if (cartesian_mm < 0.000001) return false;
float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier; float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier;
int steps = max(1, int(scara_segments_per_second * seconds)); int steps = max(1, int(delta_segments_per_second * seconds));
//ECHO_SMV(DB, "mm=", cartesian_mm); // ECHO_SMV(DB, "mm =", cartesian_mm);
//ECHO_MV(" seconds=", seconds); // ECHO_MV(" seconds =", seconds);
//ECHO_EMV(" steps=", steps); // ECHOEMV(" steps =", steps);
for (int s = 1; s <= steps; s++) { for (int s = 1; s <= steps; s++) {
float fraction = float(s) / float(steps);
for (int8_t i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i] + difference[i] * fraction;
calculate_delta(destination); float fraction = float(s) / float(steps);
//ECHO_SMV(DB, "destination[X_AXIS]=", destination[X_AXIS]);
//ECHO_MV("destination[Y_AXIS]=", destination[Y_AXIS]);
//ECHO_MV("destination[Z_AXIS]=", destination[Z_AXIS]);
//ECHO_MV("delta[X_AXIS]=", delta[X_AXIS]);
//ECHO_MV("delta[Y_AXIS]=", delta[Y_AXIS]);
//ECHO_EMV("delta[Z_AXIS]=", delta[Z_AXIS]);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate*feedrate_multiplier/60/100.0, active_extruder, active_driver); for (int8_t i = 0; i < NUM_AXIS; i++)
} destination[i] = current_position[i] + difference[i] * fraction;
#endif // SCARA calculate_delta(destination);
adjust_delta(destination);
#ifdef DELTA //ECHO_LMV(DB, "destination[X_AXIS]=", destination[X_AXIS]);
float difference[NUM_AXIS]; //ECHO_LMV(DB, "destination[Y_AXIS]="); SERIAL_ECHOLN(destination[Y_AXIS]);
for (int8_t i=0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i]; //ECHO_LMV(DB, "destination[Z_AXIS]="); SERIAL_ECHOLN(destination[Z_AXIS]);
//ECHO_LMV(DB, "delta[X_AXIS]=", delta[X_AXIS]);
//ECHO_LMV(DB, "delta[Y_AXIS]=", delta[Y_AXIS]);
//ECHO_LMV(DB, "delta[Z_AXIS]=", delta[Z_AXIS]);
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS])); plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder, active_driver);
if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]); }
if (cartesian_mm < 0.000001) return; return true;
float seconds = 6000 * cartesian_mm / feedrate / feedrate_multiplier; }
int steps = max(1, int(DELTA_SEGMENTS_PER_SECOND * seconds));
// ECHO_SMV(DB,"mm=", cartesian_mm); #endif // DELTA || SCARA
// ECHO_MV(" seconds=", seconds);
// ECHO_EMV(" steps=", steps);
for (int s = 1; s <= steps; s++) { #ifdef SCARA
float fraction = float(s) / float(steps); inline bool prepare_move_scara() { return prepare_move_delta(); }
for (int8_t i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i] + difference[i] * fraction; #endif
calculate_delta(destination);
adjust_delta(destination);
plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate*feedrate_multiplier/60/100.0, active_extruder, active_driver);
}
#endif // DELTA #ifdef DUAL_X_CARRIAGE
#ifdef DUAL_X_CARRIAGE inline bool prepare_move_dual_x_carriage() {
if (active_extruder_parked) { if (active_extruder_parked) {
if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) { if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) {
// move duplicate extruder into correct duplication position. // move duplicate extruder into correct duplication position.
...@@ -6455,82 +6598,101 @@ void prepare_move() { ...@@ -6455,82 +6598,101 @@ void prepare_move() {
set_current_to_destination(); set_current_to_destination();
NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]); NOLESS(raised_parked_position[Z_AXIS], destination[Z_AXIS]);
delayed_move_time = millis(); delayed_move_time = millis();
return; return false;
} }
} }
delayed_move_time = 0; delayed_move_time = 0;
// unpark extruder: 1) raise, 2) move into starting XY position, 3) lower // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
plan_buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver); plan_buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], min(max_feedrate[X_AXIS],max_feedrate[Y_AXIS]), active_extruder, active_driver); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS], current_position[E_AXIS], min(max_feedrate[X_AXIS], max_feedrate[Y_AXIS]), active_extruder, active_driver);
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver); plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder, active_driver);
active_extruder_parked = false; active_extruder_parked = false;
} }
} }
#endif //DUAL_X_CARRIAGE return true;
}
#endif // DUAL_X_CARRIAGE
#if defined(CARTESIAN) || defined(COREXY)
#if !defined(DELTA) && !defined(SCARA) inline bool prepare_move_cartesian() {
// Do not use feedrate_multiplier for E or Z only moves // Do not use feedrate_multiplier for E or Z only moves
if ((current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) { if (current_position[X_AXIS] == destination[X_AXIS] && current_position[Y_AXIS] == destination[Y_AXIS]) {
line_to_destination(); line_to_destination();
} }
else { else {
line_to_destination(feedrate * feedrate_multiplier / 100.0); line_to_destination(feedrate * feedrate_multiplier / 100.0);
} }
#endif // !defined(DELTA) && !defined(SCARA) return true;
}
#ifdef IDLE_OOZING_PREVENT || EXTRUDER_RUNOUT_PREVENT #endif // CARTESIAN || COREXY
axis_last_activity = millis();
axis_is_moving = false; /**
* Prepare a single move and get ready for the next one
*/
void prepare_move() {
clamp_to_software_endstops(destination);
refresh_cmd_timeout();
#ifdef PREVENT_DANGEROUS_EXTRUDE
prevent_dangerous_extrude(current_position[E_AXIS], destination[E_AXIS]);
#endif #endif
set_current_to_destination(); #ifdef SCARA
} if (!prepare_move_scara()) return;
#elif defined(DELTA)
if (!prepare_move_delta()) return;
#endif
void prepare_arc_move(char isclockwise) { #ifdef DUAL_X_CARRIAGE
float r = hypot(offset[X_AXIS], offset[Y_AXIS]); // Compute arc radius for mc_arc if (!prepare_move_dual_x_carriage()) return;
#endif
// Trace the arc #if defined(CARTESIAN) || defined(COREXY)
mc_arc(current_position, destination, offset, X_AXIS, Y_AXIS, Z_AXIS, feedrate*feedrate_multiplier/60/100.0, r, isclockwise, active_extruder, active_driver); if (!prepare_move_cartesian()) return;
#endif
#ifdef IDLE_OOZING_PREVENT || EXTRUDER_RUNOUT_PREVENT
axis_last_activity = millis();
axis_is_moving = false;
#endif
// As far as the parser is concerned, the position is now == target. In reality the
// motion control system might still be processing the action and the real tool position
// in any intermediate location.
set_current_to_destination(); set_current_to_destination();
refresh_cmd_timeout();
} }
#if HAS_CONTROLLERFAN #if HAS_CONTROLLERFAN
millis_t lastMotor = 0; // Last time a motor was turned on void controllerFan() {
millis_t lastMotorCheck = 0; // Last time the state was checked static millis_t lastMotor = 0; // Last time a motor was turned on
static millis_t lastMotorCheck = 0; // Last time the state was checked
void controllerFan() { millis_t ms = millis();
millis_t ms = millis(); if (ms >= lastMotorCheck + 2500) { // Not a time critical function, so we only check every 2500ms
if (ms >= lastMotorCheck + 2500) { // Not a time critical function, so we only check every 2500ms lastMotorCheck = ms;
lastMotorCheck = ms; if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON || soft_pwm_bed > 0
if (X_ENABLE_READ == X_ENABLE_ON || Y_ENABLE_READ == Y_ENABLE_ON || Z_ENABLE_READ == Z_ENABLE_ON || soft_pwm_bed > 0 || E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled...
|| E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled... #if EXTRUDERS > 1
#if EXTRUDERS > 1 || E1_ENABLE_READ == E_ENABLE_ON
|| E1_ENABLE_READ == E_ENABLE_ON #if HAS_X2_ENABLE
#if HAS_X2_ENABLE || X2_ENABLE_READ == X_ENABLE_ON
|| X2_ENABLE_READ == X_ENABLE_ON #endif
#endif #if EXTRUDERS > 2
#if EXTRUDERS > 2 || E2_ENABLE_READ == E_ENABLE_ON
|| E2_ENABLE_READ == E_ENABLE_ON #if EXTRUDERS > 3
#if EXTRUDERS > 3 || E3_ENABLE_READ == E_ENABLE_ON
|| E3_ENABLE_READ == E_ENABLE_ON #endif
#endif #endif
#endif #endif
#endif ) {
) { lastMotor = ms; //... set time to NOW so the fan will turn on
lastMotor = ms; //... set time to NOW so the fan will turn on }
uint8_t speed = (lastMotor == 0 || ms >= lastMotor + (CONTROLLERFAN_SECS * 1000UL)) ? 0 : CONTROLLERFAN_SPEED;
// allows digital or PWM fan output to be used (see M42 handling)
digitalWrite(CONTROLLERFAN_PIN, speed);
analogWrite(CONTROLLERFAN_PIN, speed);
} }
uint8_t speed = (lastMotor == 0 || ms >= lastMotor + (CONTROLLERFAN_SECS * 1000UL)) ? 0 : CONTROLLERFAN_SPEED;
// allows digital or PWM fan output to be used (see M42 handling)
digitalWrite(CONTROLLERFAN_PIN, speed);
analogWrite(CONTROLLERFAN_PIN, speed);
} }
}
#endif #endif
#ifdef SCARA #ifdef SCARA
...@@ -6541,7 +6703,7 @@ void calculate_SCARA_forward_Transform(float f_scara[3]) ...@@ -6541,7 +6703,7 @@ void calculate_SCARA_forward_Transform(float f_scara[3])
float x_sin, x_cos, y_sin, y_cos; float x_sin, x_cos, y_sin, y_cos;
//ECHO_SMV(DB,"f_delta x=", f_scara[X_AXIS]); //ECHO_SMV(DB, "f_delta x=", f_scara[X_AXIS]);
//ECHO_MV(" y=", f_scara[Y_AXIS]); //ECHO_MV(" y=", f_scara[Y_AXIS]);
x_sin = sin(f_scara[X_AXIS]/SCARA_RAD2DEG) * Linkage_1; x_sin = sin(f_scara[X_AXIS]/SCARA_RAD2DEG) * Linkage_1;
...@@ -6609,6 +6771,7 @@ void calculate_delta(float cartesian[3]){ ...@@ -6609,6 +6771,7 @@ void calculate_delta(float cartesian[3]){
*/ */
} }
#endif #endif
#ifdef TEMP_STAT_LEDS #ifdef TEMP_STAT_LEDS
...@@ -6686,9 +6849,6 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { ...@@ -6686,9 +6849,6 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
&& !ignore_stepper_queue && !blocks_queued()) && !ignore_stepper_queue && !blocks_queued())
disable_all_steppers(); disable_all_steppers();
// Store in EEPROM Time life and power consumation
if((ms - config_last_update) > 60000UL) save_lifetime_stats();
#ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH #ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH
if (chdkActive && ms > chdkHigh + CHDK_DELAY) { if (chdkActive && ms > chdkHigh + CHDK_DELAY) {
chdkActive = false; chdkActive = false;
......
...@@ -256,19 +256,23 @@ ...@@ -256,19 +256,23 @@
#define X_MIN_ENDSTOP_INVERTING !X_MIN_ENDSTOP_LOGIC #define X_MIN_ENDSTOP_INVERTING !X_MIN_ENDSTOP_LOGIC
#define Y_MIN_ENDSTOP_INVERTING !Y_MIN_ENDSTOP_LOGIC #define Y_MIN_ENDSTOP_INVERTING !Y_MIN_ENDSTOP_LOGIC
#define Z_MIN_ENDSTOP_INVERTING !Z_MIN_ENDSTOP_LOGIC #define Z_MIN_ENDSTOP_INVERTING !Z_MIN_ENDSTOP_LOGIC
#define Z2_MIN_ENDSTOP_INVERTING !Z2_MIN_ENDSTOP_LOGIC
#define E_MIN_ENDSTOP_INVERTING !E_MIN_ENDSTOP_LOGIC #define E_MIN_ENDSTOP_INVERTING !E_MIN_ENDSTOP_LOGIC
#define X_MAX_ENDSTOP_INVERTING !X_MAX_ENDSTOP_LOGIC #define X_MAX_ENDSTOP_INVERTING !X_MAX_ENDSTOP_LOGIC
#define Y_MAX_ENDSTOP_INVERTING !Y_MAX_ENDSTOP_LOGIC #define Y_MAX_ENDSTOP_INVERTING !Y_MAX_ENDSTOP_LOGIC
#define Z_MAX_ENDSTOP_INVERTING !Z_MAX_ENDSTOP_LOGIC #define Z_MAX_ENDSTOP_INVERTING !Z_MAX_ENDSTOP_LOGIC
#define Z2_MAX_ENDSTOP_INVERTING !Z2_MAX_ENDSTOP_LOGIC
#define Z_PROBE_ENDSTOP_INVERTING !Z_PROBE_ENDSTOP_LOGIC #define Z_PROBE_ENDSTOP_INVERTING !Z_PROBE_ENDSTOP_LOGIC
#else #else
#define X_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_LOGIC #define X_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_LOGIC
#define Y_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_LOGIC #define Y_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_LOGIC
#define Z_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_LOGIC #define Z_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_LOGIC
#define Z2_MIN_ENDSTOP_INVERTING Z2_MIN_ENDSTOP_LOGIC
#define E_MIN_ENDSTOP_INVERTING E_MIN_ENDSTOP_LOGIC #define E_MIN_ENDSTOP_INVERTING E_MIN_ENDSTOP_LOGIC
#define X_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_LOGIC #define X_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_LOGIC
#define Y_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_LOGIC #define Y_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_LOGIC
#define Z_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_LOGIC #define Z_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_LOGIC
#define Z2_MAX_ENDSTOP_INVERTING Z2_MAX_ENDSTOP_LOGIC
#define Z_PROBE_ENDSTOP_INVERTING Z_PROBE_ENDSTOP_LOGIC #define Z_PROBE_ENDSTOP_INVERTING Z_PROBE_ENDSTOP_LOGIC
#endif #endif
...@@ -354,6 +358,13 @@ ...@@ -354,6 +358,13 @@
#define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER)) #define MAX_PROBE_Y (min(Y_MAX_POS, Y_MAX_POS + Y_PROBE_OFFSET_FROM_EXTRUDER))
#endif #endif
/**
* Sled Options
*/
#ifdef Z_PROBE_SLED
#define Z_SAFE_HOMING
#endif
/** /**
* Servo Leveling * Servo Leveling
*/ */
...@@ -368,8 +379,8 @@ ...@@ -368,8 +379,8 @@
#define MAX_STEP_FREQUENCY 120000 // Max step frequency for Toshiba Stepper Controllers #define MAX_STEP_FREQUENCY 120000 // Max step frequency for Toshiba Stepper Controllers
#define DOUBLE_STEP_FREQUENCY MAX_STEP_FREQUENCY #define DOUBLE_STEP_FREQUENCY MAX_STEP_FREQUENCY
#else #else
#define MAX_STEP_FREQUENCY 320000 // Max step frequency for the Due is approx. 330kHz #define MAX_STEP_FREQUENCY 500000 // Max step frequency for the Due is approx. 330kHz
#define DOUBLE_STEP_FREQUENCY 100000 //96kHz is close to maximum for an Arduino Due #define DOUBLE_STEP_FREQUENCY 120000 //96kHz is close to maximum for an Arduino Due
#endif #endif
#else #else
#ifdef CONFIG_STEPPERS_TOSHIBA #ifdef CONFIG_STEPPERS_TOSHIBA
......
...@@ -692,37 +692,33 @@ void Config_PrintSettings(bool forReplay) { ...@@ -692,37 +692,33 @@ void Config_PrintSettings(bool forReplay) {
#endif //HOTENDS > 1 #endif //HOTENDS > 1
#ifdef DELTA #ifdef DELTA
if (!forReplay) {
ECHO_LM(DB, "Endstop adjustement (mm):");
}
ECHO_SMV(DB, " M666 X", endstop_adj[X_AXIS] );
ECHO_MV(" Y", endstop_adj[Y_AXIS] );
ECHO_EMV(" Z", endstop_adj[Z_AXIS] );
if (!forReplay) { if (!forReplay) {
ECHO_LM(DB, "Delta Geometry adjustment:"); ECHO_LM(DB, "Delta Geometry adjustment:");
} }
ECHO_SMV(DB, " M666 A", tower_adj[0]); ECHO_SMV(DB, " M666 A", tower_adj[0], 3);
ECHO_MV(" B", tower_adj[1]); ECHO_MV(" B", tower_adj[1], 3);
ECHO_MV(" C", tower_adj[2]); ECHO_MV(" C", tower_adj[2], 3);
ECHO_MV(" E", tower_adj[3]); ECHO_MV(" I", tower_adj[3], 3);
ECHO_MV(" F", tower_adj[4]); ECHO_MV(" J", tower_adj[4], 3);
ECHO_MV(" G", tower_adj[5]); ECHO_MV(" K", tower_adj[5], 3);
ECHO_MV(" R", delta_radius); ECHO_MV(" R", delta_radius);
ECHO_MV(" D", delta_diagonal_rod); ECHO_MV(" D", delta_diagonal_rod);
ECHO_MV(" H", max_pos[2]); ECHO_EMV(" H", max_pos[2]);
ECHO_EMV(" P", z_probe_offset[3]);
if (!forReplay) { if (!forReplay) {
ECHO_LM(DB, "Tower Positions:"); ECHO_LM(DB, "Endstop Offsets:");
} }
ECHO_SMV(DB, " Tower1 X:", delta_tower1_x); ECHO_SMV(DB, " M666 X", endstop_adj[X_AXIS]);
ECHO_MV(" Y:", delta_tower1_y); ECHO_MV(" Y", endstop_adj[Y_AXIS]);
ECHO_MV(" Tower2 X:", delta_tower2_x); ECHO_EMV(" Z", endstop_adj[Z_AXIS]);
ECHO_MV(" Y:", delta_tower2_y);
ECHO_MV(" Tower3 X:", delta_tower3_x); if (!forReplay) {
ECHO_EMV(" Y:", delta_tower3_y); ECHO_LM(DB, "Z-Probe Offset:");
}
ECHO_SMV(DB, " M666 P X", z_probe_offset[0]);
ECHO_MV(" Y", z_probe_offset[1]);
ECHO_EMV(" Z", z_probe_offset[2]);
#elif defined(Z_DUAL_ENDSTOPS) #elif defined(Z_DUAL_ENDSTOPS)
if (!forReplay) { if (!forReplay) {
ECHO_LM(DB, "Z2 Endstop adjustement (mm):"); ECHO_LM(DB, "Z2 Endstop adjustement (mm):");
...@@ -830,57 +826,7 @@ void Config_PrintSettings(bool forReplay) { ...@@ -830,57 +826,7 @@ void Config_PrintSettings(bool forReplay) {
} }
ECHO_LVM(DB, power_consumption_hour," W/h"); ECHO_LVM(DB, power_consumption_hour," W/h");
#endif #endif
if (!forReplay) {
ECHO_LM(DB, "Power on time:");
}
char time[30];
int hours = printer_usage_seconds / 60 / 60, minutes = (printer_usage_seconds / 60) % 60;
sprintf_P(time, PSTR("%i " MSG_END_HOUR " %i " MSG_END_MINUTE), hours, minutes);
ECHO_LV(DB, time);
} }
#endif //!DISABLE_M503 #endif //!DISABLE_M503
/**
* Lifetime on EEPROM
*
*/
void load_lifetime_stats() {
int i = LIFETIME_EEPROM_OFFSET;
char stored_magic[4];
char magic[4] = LIFETIME_MAGIC;
EEPROM_READ_VAR(i, stored_magic); // read magic
if (strncmp(magic, stored_magic, 3) != 0) {
#ifdef POWER_CONSUMPTION
power_consumption_hour = 0;
#endif
printer_usage_seconds = 0;
}
else {
EEPROM_READ_VAR(i, printer_usage_seconds);
#ifdef POWER_CONSUMPTION
EEPROM_READ_VAR(i, power_consumption_hour);
#endif
}
}
void save_lifetime_stats() {
int i = LIFETIME_EEPROM_OFFSET;
char magic[4] = "000";
EEPROM_WRITE_VAR(i, magic); // invalidate data first
EEPROM_WRITE_VAR(i, printer_usage_seconds);
#ifdef POWER_CONSUMPTION
EEPROM_WRITE_VAR(i, power_consumption_hour);
#endif
char magic2[4] = LIFETIME_MAGIC;
int j = LIFETIME_EEPROM_OFFSET;
EEPROM_WRITE_VAR(j, magic2); // validate data
config_last_update = millis();
}
...@@ -273,7 +273,6 @@ static void lcd_implementation_status_screen() { ...@@ -273,7 +273,6 @@ static void lcd_implementation_status_screen() {
u8g.drawFrame(42, 49 - TALL_FONT_CORRECTION, 10, 4); u8g.drawFrame(42, 49 - TALL_FONT_CORRECTION, 10, 4);
u8g.drawPixel(50, 43 - TALL_FONT_CORRECTION); u8g.drawPixel(50, 43 - TALL_FONT_CORRECTION);
// Progress bar frame // Progress bar frame
u8g.drawFrame(54, 49, 73, 4 - TALL_FONT_CORRECTION); u8g.drawFrame(54, 49, 73, 4 - TALL_FONT_CORRECTION);
...@@ -346,19 +345,28 @@ static void lcd_implementation_status_screen() { ...@@ -346,19 +345,28 @@ static void lcd_implementation_status_screen() {
u8g.drawPixel(8,XYZ_BASELINE - 5); u8g.drawPixel(8,XYZ_BASELINE - 5);
u8g.drawPixel(8,XYZ_BASELINE - 3); u8g.drawPixel(8,XYZ_BASELINE - 3);
u8g.setPrintPos(10,XYZ_BASELINE); u8g.setPrintPos(10,XYZ_BASELINE);
lcd_print(ftostr31ns(current_position[X_AXIS])); if (axis_known_position[X_AXIS])
lcd_print(ftostr31ns(current_position[X_AXIS]));
else
lcd_printPGM(PSTR("---"));
u8g.setPrintPos(43,XYZ_BASELINE); u8g.setPrintPos(43,XYZ_BASELINE);
lcd_print('Y'); lcd_print('Y');
u8g.drawPixel(49,XYZ_BASELINE - 5); u8g.drawPixel(49,XYZ_BASELINE - 5);
u8g.drawPixel(49,XYZ_BASELINE - 3); u8g.drawPixel(49,XYZ_BASELINE - 3);
u8g.setPrintPos(51,XYZ_BASELINE); u8g.setPrintPos(51,XYZ_BASELINE);
lcd_print(ftostr31ns(current_position[Y_AXIS])); if (axis_known_position[Y_AXIS])
lcd_print(ftostr31ns(current_position[Y_AXIS]));
else
lcd_printPGM(PSTR("---"));
u8g.setPrintPos(83,XYZ_BASELINE); u8g.setPrintPos(83,XYZ_BASELINE);
lcd_print('Z'); lcd_print('Z');
u8g.drawPixel(89,XYZ_BASELINE - 5); u8g.drawPixel(89,XYZ_BASELINE - 5);
u8g.drawPixel(89,XYZ_BASELINE - 3); u8g.drawPixel(89,XYZ_BASELINE - 3);
u8g.setPrintPos(91,XYZ_BASELINE); u8g.setPrintPos(91,XYZ_BASELINE);
lcd_print(ftostr31(current_position[Z_AXIS])); if (axis_known_position[Z_AXIS])
lcd_print(ftostr32sp(current_position[Z_AXIS]));
else
lcd_printPGM(PSTR("---.--"));
u8g.setColorIndex(1); // black on white u8g.setColorIndex(1); // black on white
// Feedrate // Feedrate
......
...@@ -82,6 +82,8 @@ ...@@ -82,6 +82,8 @@
#define E1_MS2_PIN -1 #define E1_MS2_PIN -1
#define DIGIPOTSS_PIN -1 #define DIGIPOTSS_PIN -1
#define LCD_CONTRAST -1 #define LCD_CONTRAST -1
#define Z2_MIN_PIN -1
#define Z2_MAX_PIN -1
/****************************************************************************** /******************************************************************************
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
//FAN pin //FAN pin
#define FAN_PIN ORIG_FAN_PIN #define FAN_PIN ORIG_FAN_PIN
//============================================================================ //============================================================================
......
...@@ -478,7 +478,7 @@ float junction_deviation = 0.1; ...@@ -478,7 +478,7 @@ float junction_deviation = 0.1;
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
int next_buffer_head = next_block_index(block_buffer_head); int next_buffer_head = next_block_index(block_buffer_head);
...@@ -518,8 +518,7 @@ float junction_deviation = 0.1; ...@@ -518,8 +518,7 @@ float junction_deviation = 0.1;
if (degHotend(extruder) < extrude_min_temp && !(debugLevel & DEBUG_DRYRUN)) { if (degHotend(extruder) < extrude_min_temp && !(debugLevel & DEBUG_DRYRUN)) {
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
de = 0; // no difference de = 0; // no difference
ECHO_S(OK); ECHO_LM(ER, MSG_ERR_COLD_EXTRUDE_STOP);
ECHO_EM(MSG_ERR_COLD_EXTRUDE_STOP);
} }
} }
...@@ -530,8 +529,7 @@ float junction_deviation = 0.1; ...@@ -530,8 +529,7 @@ float junction_deviation = 0.1;
#endif #endif
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
de = 0; // no difference de = 0; // no difference
ECHO_S(OK); ECHO_LM(ER, MSG_ERR_LONG_EXTRUDE_STOP);
ECHO_EM(MSG_ERR_LONG_EXTRUDE_STOP);
#ifdef EASY_LOAD #ifdef EASY_LOAD
} }
allow_lengthy_extrude_once = false; allow_lengthy_extrude_once = false;
......
...@@ -114,6 +114,10 @@ FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block ...@@ -114,6 +114,10 @@ FORCE_INLINE uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block
void plan_set_e_position(const float &e); void plan_set_e_position(const float &e);
//===========================================================================
//============================= public variables ============================
//===========================================================================
extern millis_t minsegmenttime; extern millis_t 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
......
...@@ -304,4 +304,23 @@ ...@@ -304,4 +304,23 @@
#error HEATER_0_PIN not defined for this board #error HEATER_0_PIN not defined for this board
#endif #endif
/**
* Warnings for old configurations
*/
#ifdef X_HOME_RETRACT_MM
#error [XYZ]_HOME_RETRACT_MM settings have been renamed [XYZ]_HOME_BUMP_MM
#endif
#if WATCH_TEMP_PERIOD > 500
#error WATCH_TEMP_PERIOD now uses seconds instead of milliseconds
#endif
#if !defined(THERMAL_PROTECTION_HOTENDS) && (defined(WATCH_TEMP_PERIOD) || defined(THERMAL_PROTECTION_PERIOD))
#error Thermal Runaway Protection for hotends must now be enabled with THERMAL_PROTECTION_HOTENDS
#endif
#if !defined(THERMAL_PROTECTION_BED) && defined(THERMAL_PROTECTION_BED_PERIOD)
#error Thermal Runaway Protection for the bed must now be enabled with THERMAL_PROTECTION_BED
#endif
#endif //SANITYCHECK_H #endif //SANITYCHECK_H
...@@ -66,20 +66,16 @@ volatile static unsigned long step_events_completed; // The number of step event ...@@ -66,20 +66,16 @@ volatile static unsigned long step_events_completed; // The number of step event
static long acceleration_time, deceleration_time; static long acceleration_time, deceleration_time;
//static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; //static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
static unsigned short acc_step_rate; // needed for deceleration start point static unsigned short acc_step_rate; // needed for deccelaration start point
static char step_loops; static char step_loops;
static unsigned short OCR1A_nominal; static unsigned short OCR1A_nominal;
static unsigned short step_loops_nominal; static unsigned short step_loops_nominal;
volatile long endstops_trigsteps[3] = { 0 }; volatile long endstops_trigsteps[3] = { 0 };
volatile long endstops_stepsTotal, endstops_stepsDone; volatile long endstops_stepsTotal, endstops_stepsDone;
static volatile bool endstop_x_hit = false; static volatile char endstop_hit_bits = 0; // use X_MIN, Y_MIN, Z_MIN and Z_PROBE as BIT value
static volatile bool endstop_y_hit = false;
static volatile bool endstop_z_hit = false;
static volatile bool endstop_z_probe_hit = false;
#ifdef NPR2 #ifdef NPR2
static volatile bool endstop_e_hit = false;
static bool old_e_min_endstop = false; static bool old_e_min_endstop = false;
#endif #endif
...@@ -268,81 +264,36 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 }; ...@@ -268,81 +264,36 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
#define ENABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 |= BIT(OCIE1A) #define ENABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 |= BIT(OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~BIT(OCIE1A) #define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~BIT(OCIE1A)
#ifdef NPR2
void endstops_hit_on_purpose() { void endstops_hit_on_purpose() {
endstop_x_hit = endstop_y_hit = endstop_z_hit = endstop_z_probe_hit = endstop_e_hit = false; endstop_hit_bits = 0;
} }
void checkHitEndstops() { void checkHitEndstops() {
if (endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_z_probe_hit || endstop_e_hit) { if (endstop_hit_bits) {
ECHO_SM(OK, MSG_ENDSTOPS_HIT); ECHO_SM(DB, MSG_ENDSTOPS_HIT);
if(endstop_x_hit) { if (endstop_hit_bits & BIT(X_MIN)) {
ECHO_MV(MSG_ENDSTOP_X, (float)endstops_trigsteps[X_AXIS] / axis_steps_per_unit[X_AXIS]); ECHO_MV(MSG_ENDSTOP_X, (float)endstops_trigsteps[X_AXIS] / axis_steps_per_unit[X_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_XS); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_XS);
} }
if(endstop_y_hit) { if (endstop_hit_bits & BIT(Y_MIN)) {
ECHO_MV(MSG_ENDSTOP_Y, (float)endstops_trigsteps[Y_AXIS] / axis_steps_per_unit[Y_AXIS]); ECHO_MV(MSG_ENDSTOP_Y, (float)endstops_trigsteps[Y_AXIS] / axis_steps_per_unit[Y_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_YS); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_YS);
} }
if(endstop_z_hit) { if (endstop_hit_bits & BIT(Z_MIN)) {
ECHO_MV(MSG_ENDSTOP_Z, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]); ECHO_MV(MSG_ENDSTOP_Z, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZS); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZS);
} }
#ifdef Z_PROBE_ENDSTOP #ifdef Z_PROBE_ENDSTOP
if (endstop_z_probe_hit) { if (endstop_hit_bits & BIT(Z_PROBE)) {
ECHO_MV(" Z_PROBE:", (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]); ECHO_MV(MSG_ENDSTOP_ZPS, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZPS); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZPS);
} }
#endif #endif
if(endstop_e_hit) { #ifdef NPR2
if (endstop_hit_bits & BIT(E_MIN)) {
ECHO_MV(MSG_ENDSTOP_E, (float)endstops_trigsteps[E_AXIS] / axis_steps_per_unit[E_AXIS]); ECHO_MV(MSG_ENDSTOP_E, (float)endstops_trigsteps[E_AXIS] / axis_steps_per_unit[E_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ES); LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ES);
} }
ECHO_E;
endstops_hit_on_purpose();
#if defined(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && defined(SDSUPPORT)
if (abort_on_endstop_hit) {
card.sdprinting = false;
card.closeFile();
quickStop();
setTargetHotend0(0);
setTargetHotend1(0);
setTargetHotend2(0);
setTargetHotend3(0);
setTargetBed(0);
}
#endif
}
}
#else // NOT NPR2
void endstops_hit_on_purpose() {
endstop_x_hit = endstop_y_hit = endstop_z_hit = endstop_z_probe_hit = false;
}
void checkHitEndstops() {
if (endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_z_probe_hit) {
ECHO_SM(OK, MSG_ENDSTOPS_HIT);
if (endstop_x_hit) {
ECHO_MV(MSG_ENDSTOP_X, (float)endstops_trigsteps[X_AXIS] / axis_steps_per_unit[X_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_XS);
}
if (endstop_y_hit) {
ECHO_MV(MSG_ENDSTOP_Y, (float)endstops_trigsteps[Y_AXIS] / axis_steps_per_unit[Y_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_YS);
}
if (endstop_z_hit) {
ECHO_MV(MSG_ENDSTOP_Z, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZS);
}
#ifdef Z_PROBE_ENDSTOP
if (endstop_z_probe_hit) {
ECHO_MV(MSG_ENDSTOP_ZPS, (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT MSG_ENDSTOP_ZPS);
}
#endif #endif
ECHO_E; ECHO_E;
...@@ -362,7 +313,6 @@ void checkHitEndstops() { ...@@ -362,7 +313,6 @@ void checkHitEndstops() {
#endif #endif
} }
} }
#endif // NOT NPR2
void enable_endstops(bool check) { check_endstops = check; } void enable_endstops(bool check) { check_endstops = check; }
...@@ -422,9 +372,57 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { ...@@ -422,9 +372,57 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) {
return timer; return timer;
} }
// set the stepper direction of each axis
void set_stepper_direction() {
// Set the direction bits (X_AXIS=A_AXIS and Y_AXIS=B_AXIS for COREXY)
if (TEST(out_bits, X_AXIS)) {
X_APPLY_DIR(INVERT_X_DIR,0);
count_direction[X_AXIS] = -1;
}
else {
X_APPLY_DIR(!INVERT_X_DIR,0);
count_direction[X_AXIS] = 1;
}
if (TEST(out_bits, Y_AXIS)) {
Y_APPLY_DIR(INVERT_Y_DIR,0);
count_direction[Y_AXIS] = -1;
}
else {
Y_APPLY_DIR(!INVERT_Y_DIR,0);
count_direction[Y_AXIS] = 1;
}
if (TEST(out_bits, Z_AXIS)) {
Z_APPLY_DIR(INVERT_Z_DIR,0);
count_direction[Z_AXIS] = -1;
}
else {
Z_APPLY_DIR(!INVERT_Z_DIR,0);
count_direction[Z_AXIS] = 1;
}
#ifndef ADVANCE
if (TEST(out_bits, E_AXIS)) {
REV_E_DIR();
count_direction[E_AXIS] = -1;
}
else {
NORM_E_DIR();
count_direction[E_AXIS] = 1;
}
#endif
}
// Initializes the trapezoid generator from the current block. Called whenever a new // Initializes the trapezoid generator from the current block. Called whenever a new
// block begins. // block begins.
FORCE_INLINE void trapezoid_generator_reset() { FORCE_INLINE void trapezoid_generator_reset() {
// Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
out_bits = current_block->direction_bits;
set_stepper_direction();
#ifdef ADVANCE #ifdef ADVANCE
advance = current_block->initial_advance; advance = current_block->initial_advance;
final_advance = current_block->final_advance; final_advance = current_block->final_advance;
...@@ -446,8 +444,7 @@ FORCE_INLINE void trapezoid_generator_reset() { ...@@ -446,8 +444,7 @@ FORCE_INLINE void trapezoid_generator_reset() {
// It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately. // It pops blocks from the block_buffer and executes them by pulsing the stepper pins appropriately.
ISR(TIMER1_COMPA_vect) { ISR(TIMER1_COMPA_vect) {
if(cleaning_buffer_counter) if(cleaning_buffer_counter) {
{
current_block = NULL; current_block = NULL;
plan_discard_current_block(); plan_discard_current_block();
#ifdef SD_FINISHED_RELEASECOMMAND #ifdef SD_FINISHED_RELEASECOMMAND
...@@ -487,47 +484,27 @@ ISR(TIMER1_COMPA_vect) { ...@@ -487,47 +484,27 @@ ISR(TIMER1_COMPA_vect) {
} }
if (current_block != NULL) { if (current_block != NULL) {
// Set directions TO DO This should be done once during init of trapezoid. Endstops -> interrupt
out_bits = current_block->direction_bits;
// Set the direction bits (X_AXIS=A_AXIS and Y_AXIS=B_AXIS for COREXY)
if (TEST(out_bits, X_AXIS)) {
X_APPLY_DIR(INVERT_X_DIR,0);
count_direction[X_AXIS] = -1;
}
else {
X_APPLY_DIR(!INVERT_X_DIR,0);
count_direction[X_AXIS] = 1;
}
if (TEST(out_bits, Y_AXIS)) {
Y_APPLY_DIR(INVERT_Y_DIR,0);
count_direction[Y_AXIS] = -1;
}
else {
Y_APPLY_DIR(!INVERT_Y_DIR,0);
count_direction[Y_AXIS] = 1;
}
#define _ENDSTOP(axis, minmax) axis ##_## minmax ##_endstop
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
#define _OLD_ENDSTOP(axis, minmax) old_## axis ##_## minmax ##_endstop
#define _AXIS(AXIS) AXIS ##_AXIS
#define _ENDSTOP_HIT(axis) endstop_## axis ##_hit
#define UPDATE_ENDSTOP(axis,AXIS,minmax,MINMAX) \
bool _ENDSTOP(axis, minmax) = (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)); \
if (_ENDSTOP(axis, minmax) && _OLD_ENDSTOP(axis, minmax) && (current_block->steps[_AXIS(AXIS)] > 0)) { \
endstops_trigsteps[_AXIS(AXIS)] = count_position[_AXIS(AXIS)]; \
_ENDSTOP_HIT(axis) = true; \
step_events_completed = current_block->step_event_count; \
} \
_OLD_ENDSTOP(axis, minmax) = _ENDSTOP(axis, minmax);
// Check X and Y endstops // Check endstops
if (check_endstops) { if (check_endstops) {
#define _ENDSTOP(axis, minmax) axis ##_## minmax ##_endstop
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
#define _OLD_ENDSTOP(axis, minmax) old_## axis ##_## minmax ##_endstop
#define _AXIS(AXIS) AXIS ##_AXIS
#define _HIT_BIT(AXIS) AXIS ##_MIN
#define _ENDSTOP_HIT(AXIS) endstop_hit_bits |= BIT(_HIT_BIT(AXIS))
#define UPDATE_ENDSTOP(axis,AXIS,minmax,MINMAX) \
bool _ENDSTOP(axis, minmax) = (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)); \
if (_ENDSTOP(axis, minmax) && _OLD_ENDSTOP(axis, minmax) && (current_block->steps[_AXIS(AXIS)] > 0)) { \
endstops_trigsteps[_AXIS(AXIS)] = count_position[_AXIS(AXIS)]; \
_ENDSTOP_HIT(AXIS); \
step_events_completed = current_block->step_event_count; \
} \
_OLD_ENDSTOP(axis, minmax) = _ENDSTOP(axis, minmax);
#ifdef COREXY #ifdef COREXY
// 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
...@@ -580,15 +557,8 @@ ISR(TIMER1_COMPA_vect) { ...@@ -580,15 +557,8 @@ ISR(TIMER1_COMPA_vect) {
#ifdef COREXY #ifdef COREXY
} }
#endif #endif
}
if (TEST(out_bits, Z_AXIS)) { // -direction
Z_APPLY_DIR(INVERT_Z_DIR,0);
count_direction[Z_AXIS] = -1;
if (check_endstops) {
if (TEST(out_bits, Z_AXIS)) { // -direction
#if HAS_Z_MIN #if HAS_Z_MIN
#ifdef Z_DUAL_ENDSTOPS #ifdef Z_DUAL_ENDSTOPS
...@@ -606,7 +576,7 @@ ISR(TIMER1_COMPA_vect) { ...@@ -606,7 +576,7 @@ ISR(TIMER1_COMPA_vect) {
z2_min_both = z2_min_endstop && old_z2_min_endstop; z2_min_both = z2_min_endstop && old_z2_min_endstop;
if ((z_min_both || z2_min_both) && current_block->steps[Z_AXIS] > 0) { if ((z_min_both || z2_min_both) && current_block->steps[Z_AXIS] > 0) {
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_z_hit = true; endstop_hit_bits |= BIT(Z_MIN);
if (!performing_homing || (performing_homing && z_min_both && z2_min_both)) //if not performing home or if both endstops were trigged during homing... if (!performing_homing || (performing_homing && z_min_both && z2_min_both)) //if not performing home or if both endstops were trigged during homing...
step_events_completed = current_block->step_event_count; step_events_completed = current_block->step_event_count;
} }
...@@ -624,25 +594,14 @@ ISR(TIMER1_COMPA_vect) { ...@@ -624,25 +594,14 @@ ISR(TIMER1_COMPA_vect) {
#ifdef Z_PROBE_ENDSTOP #ifdef Z_PROBE_ENDSTOP
UPDATE_ENDSTOP(z, Z, probe, PROBE); UPDATE_ENDSTOP(z, Z, probe, PROBE);
z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING); z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
if (z_probe_endstop && old_z_probe_endstop) if (z_probe_endstop && old_z_probe_endstop) {
{
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_z_probe_hit = true; endstop_hit_bits |= BIT(Z_PROBE);
// if (z_probe_endstop && old_z_probe_endstop) ECHO_EV("z_probe_endstop = true");
} }
old_z_probe_endstop = z_probe_endstop; old_z_probe_endstop = z_probe_endstop;
#endif #endif
}
} // check_endstops else { // +direction
}
else { // +direction
Z_APPLY_DIR(!INVERT_Z_DIR,0);
count_direction[Z_AXIS] = 1;
if (check_endstops) {
#if HAS_Z_MAX #if HAS_Z_MAX
...@@ -661,7 +620,7 @@ ISR(TIMER1_COMPA_vect) { ...@@ -661,7 +620,7 @@ ISR(TIMER1_COMPA_vect) {
z2_max_both = z2_max_endstop && old_z2_max_endstop; z2_max_both = z2_max_endstop && old_z2_max_endstop;
if ((z_max_both || z2_max_both) && current_block->steps[Z_AXIS] > 0) { if ((z_max_both || z2_max_both) && current_block->steps[Z_AXIS] > 0) {
endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS]; endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
endstop_z_hit = true; endstop_hit_bits |= BIT(Z_MIN);
// if (z_max_both) ECHO_EV("z_max_endstop = true"); // if (z_max_both) ECHO_EV("z_max_endstop = true");
// if (z2_max_both) ECHO_EV("z2_max_endstop = true"); // if (z2_max_both) ECHO_EV("z2_max_endstop = true");
...@@ -679,34 +638,8 @@ ISR(TIMER1_COMPA_vect) { ...@@ -679,34 +638,8 @@ ISR(TIMER1_COMPA_vect) {
#endif // !Z_DUAL_ENDSTOPS #endif // !Z_DUAL_ENDSTOPS
#endif // Z_MAX_PIN #endif // Z_MAX_PIN
} // check_endstops
} // +direction
#ifndef ADVANCE
if (TEST(out_bits, E_AXIS)) { // -direction
REV_E_DIR();
count_direction[E_AXIS] = -1;
#ifdef NPR2
if (check_endstops) {
#if defined(E_MIN_PIN) && E_MIN_PIN > -1
bool e_min_endstop=(READ(E_MIN_PIN) != E_MIN_ENDSTOP_INVERTING);
if (e_min_endstop && old_e_min_endstop && (current_block->steps[E_AXIS] > 0)) {
endstops_trigsteps[E_AXIS] = count_position[E_AXIS];
endstop_e_hit = true;
step_events_completed = current_block->step_event_count;
}
old_e_min_endstop = e_min_endstop;
#endif
}
#endif
}
else { // +direction
NORM_E_DIR();
count_direction[E_AXIS] = 1;
} }
#endif //!ADVANCE }
// Take multiple steps per interrupt (For high speed moves) // Take multiple steps per interrupt (For high speed moves)
for (int8_t i = 0; i < step_loops; i++) { for (int8_t i = 0; i < step_loops; i++) {
...@@ -726,29 +659,30 @@ ISR(TIMER1_COMPA_vect) { ...@@ -726,29 +659,30 @@ ISR(TIMER1_COMPA_vect) {
#define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP #define _APPLY_STEP(AXIS) AXIS ##_APPLY_STEP
#define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN #define _INVERT_STEP_PIN(AXIS) INVERT_## AXIS ##_STEP_PIN
#define STEP_ADD(axis, AXIS) \ #define STEP_START(axis, AXIS) \
_COUNTER(axis) += current_block->steps[_AXIS(AXIS)]; \ _COUNTER(axis) += current_block->steps[_AXIS(AXIS)]; \
if (_COUNTER(axis) > 0) { _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0); } if (_COUNTER(axis) > 0) { _APPLY_STEP(AXIS)(!_INVERT_STEP_PIN(AXIS),0); }
STEP_ADD(x,X); STEP_START(x,X);
STEP_ADD(y,Y); STEP_START(y,Y);
STEP_ADD(z,Z); STEP_START(z,Z);
#ifndef ADVANCE #ifndef ADVANCE
STEP_ADD(e,E); STEP_START(e,E);
#endif #endif
#define STEP_IF_COUNTER(axis, AXIS) \
#define STEP_END(axis, AXIS) \
if (_COUNTER(axis) > 0) { \ if (_COUNTER(axis) > 0) { \
_COUNTER(axis) -= current_block->step_event_count; \ _COUNTER(axis) -= current_block->step_event_count; \
count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \ count_position[_AXIS(AXIS)] += count_direction[_AXIS(AXIS)]; \
_APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \ _APPLY_STEP(AXIS)(_INVERT_STEP_PIN(AXIS),0); \
} }
STEP_IF_COUNTER(x, X); STEP_END(x, X);
STEP_IF_COUNTER(y, Y); STEP_END(y, Y);
STEP_IF_COUNTER(z, Z); STEP_END(z, Z);
#ifndef ADVANCE #ifndef ADVANCE
STEP_IF_COUNTER(e, E); STEP_END(e, E);
#endif #endif
step_events_completed++; step_events_completed++;
...@@ -1177,14 +1111,10 @@ long st_get_position(uint8_t axis) { ...@@ -1177,14 +1111,10 @@ long st_get_position(uint8_t axis) {
return count_pos; return count_pos;
} }
#ifdef ENABLE_AUTO_BED_LEVELING float st_get_position_mm(uint8_t axis) {
float steper_position_in_steps = st_get_position(axis);
float st_get_position_mm(uint8_t axis) { return steper_position_in_steps / axis_steps_per_unit[axis];
float steper_position_in_steps = st_get_position(axis); }
return steper_position_in_steps / axis_steps_per_unit[axis];
}
#endif // ENABLE_AUTO_BED_LEVELING
void finishAndDisableSteppers() { void finishAndDisableSteppers() {
st_synchronize(); st_synchronize();
......
...@@ -70,10 +70,8 @@ void st_set_e_position(const long &e); ...@@ -70,10 +70,8 @@ void st_set_e_position(const long &e);
// Get current position in steps // Get current position in steps
long st_get_position(uint8_t axis); long st_get_position(uint8_t axis);
#ifdef ENABLE_AUTO_BED_LEVELING
// Get current position in mm // Get current position in mm
float st_get_position_mm(uint8_t axis); float st_get_position_mm(uint8_t axis);
#endif //ENABLE_AUTO_BED_LEVELING
// The stepper subsystem goes to sleep when it runs out of things to execute. Call this // The stepper subsystem goes to sleep when it runs out of things to execute. Call this
// to notify the subsystem that it is time to go to work. // to notify the subsystem that it is time to go to work.
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#if defined(PIDTEMPBED) || defined(PIDTEMP) #if defined(PIDTEMPBED) || defined(PIDTEMP)
#define PID_dT ((OVERSAMPLENR * 14.0)/(F_CPU / 64.0 / 256.0)) #define PID_dT ((OVERSAMPLENR * 14.0)/(F_CPU / 64.0 / 256.0))
#define RECI_PID_dT ( 1 / PID_dT )
#endif #endif
//=========================================================================== //===========================================================================
...@@ -73,16 +74,14 @@ unsigned char soft_pwm_bed; ...@@ -73,16 +74,14 @@ unsigned char soft_pwm_bed;
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
#endif #endif
#define HAS_HEATER_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0) #if defined(THERMAL_PROTECTION_HOTENDS) || defined(THERMAL_PROTECTION_BED)
#define HAS_BED_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_BED_PERIOD) && THERMAL_RUNAWAY_PROTECTION_BED_PERIOD > 0 && TEMP_SENSOR_BED != 0)
#if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
enum TRState { TRReset, TRInactive, TRFirstHeating, TRStable, TRRunaway }; enum TRState { TRReset, TRInactive, TRFirstHeating, TRStable, TRRunaway };
void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc); void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
#if HAS_HEATER_THERMAL_PROTECTION #ifdef THERMAL_PROTECTION_HOTENDS
static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset }; static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset };
static millis_t thermal_runaway_timer[4]; // = {0,0,0,0}; static millis_t thermal_runaway_timer[4]; // = {0,0,0,0};
#endif #endif
#if HAS_BED_THERMAL_PROTECTION #ifdef THERMAL_PROTECTION_BED
static TRState thermal_runaway_bed_state_machine = TRReset; static TRState thermal_runaway_bed_state_machine = TRReset;
static millis_t thermal_runaway_bed_timer; static millis_t thermal_runaway_bed_timer;
#endif #endif
...@@ -95,6 +94,7 @@ unsigned char soft_pwm_bed; ...@@ -95,6 +94,7 @@ unsigned char soft_pwm_bed;
//=========================================================================== //===========================================================================
//============================ private variables ============================ //============================ private variables ============================
//=========================================================================== //===========================================================================
static volatile bool temp_meas_ready = false; static volatile bool temp_meas_ready = false;
#ifdef PIDTEMP #ifdef PIDTEMP
...@@ -160,7 +160,7 @@ static float analog2temp(int raw, uint8_t e); ...@@ -160,7 +160,7 @@ static float analog2temp(int raw, uint8_t e);
static float analog2tempBed(int raw); static float analog2tempBed(int raw);
static void updateTemperaturesFromRawValues(); static void updateTemperaturesFromRawValues();
#ifdef WATCH_TEMP_PERIOD #ifdef THERMAL_PROTECTION_HOTENDS
int watch_target_temp[HOTENDS] = { 0 }; int watch_target_temp[HOTENDS] = { 0 };
millis_t watch_heater_next_ms[HOTENDS] = { 0 }; millis_t watch_heater_next_ms[HOTENDS] = { 0 };
#endif #endif
...@@ -245,8 +245,8 @@ void PID_autotune(float temp, int hotend, int ncycles) ...@@ -245,8 +245,8 @@ void PID_autotune(float temp, int hotend, int ncycles)
} }
#endif #endif
if (heating == true && input > temp) { if (heating && input > temp) {
if (ms - t2 > 5000) { if (ms > t2 + 5000) {
heating = false; heating = false;
if (hotend < 0) if (hotend < 0)
soft_pwm_bed = (bias - d) >> 1; soft_pwm_bed = (bias - d) >> 1;
...@@ -257,8 +257,9 @@ void PID_autotune(float temp, int hotend, int ncycles) ...@@ -257,8 +257,9 @@ void PID_autotune(float temp, int hotend, int ncycles)
max = temp; max = temp;
} }
} }
if (heating == false && input < temp) {
if (ms - t1 > 5000) { if (!heating && input < temp) {
if (ms > t1 + 5000) {
heating = true; heating = true;
t2 = ms; t2 = ms;
t_low = t2 - t1; t_low = t2 - t1;
...@@ -588,15 +589,15 @@ void manage_heater() { ...@@ -588,15 +589,15 @@ void manage_heater() {
if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0); if (ct < max(HEATER_0_MINTEMP, 0.01)) min_temp_error(0);
#endif #endif
#if defined(WATCH_TEMP_PERIOD) || !defined(PIDTEMPBED) || HAS_AUTO_FAN #if defined(THERMAL_PROTECTION_HOTENDS) || !defined(PIDTEMPBED) || HAS_AUTO_FAN
millis_t ms = millis(); millis_t ms = millis();
#endif #endif
// Loop through all hotends // Loop through all hotends
for (int e = 0; e < HOTENDS; e++) { for (int e = 0; e < HOTENDS; e++) {
#if HAS_HEATER_THERMAL_PROTECTION #ifdef THERMAL_PROTECTION_HOTENDS
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_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);
#endif #endif
float pid_output = get_pid_output(e); float pid_output = get_pid_output(e);
...@@ -605,21 +606,23 @@ void manage_heater() { ...@@ -605,21 +606,23 @@ void manage_heater() {
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;
// Check if the temperature is failing to increase // Check if the temperature is failing to increase
#ifdef WATCH_TEMP_PERIOD #ifdef THERMAL_PROTECTION_HOTENDS
// Is it time to check this extruder's heater? // Is it time to check this extruder's heater?
if (watch_heater_next_ms[e] && ms > watch_heater_next_ms[e]) { if (watch_heater_next_ms[e] && ms > watch_heater_next_ms[e]) {
// Has it failed to increase enough? // Has it failed to increase enough?
if (degHotend(e) < watch_target_temp[e]) { if (degHotend(e) < watch_target_temp[e]) {
// Stop! // Stop!
disable_all_heaters(); disable_all_heaters();
_temp_error(e, MSG_HEATING_FAILED, MSG_HEATING_FAILED_LCD); _temp_error(e, PSTR(MSG_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD));
} }
else { else {
// Only check once per M104/M109 // Start again if the target is still far off
watch_heater_next_ms[e] = 0; start_watching_heater(e);
} }
} }
#endif // WATCH_TEMP_PERIOD
#endif // THERMAL_PROTECTION_HOTENDS
#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) {
...@@ -659,8 +662,8 @@ void manage_heater() { ...@@ -659,8 +662,8 @@ void manage_heater() {
#if TEMP_SENSOR_BED != 0 #if TEMP_SENSOR_BED != 0
#if HAS_BED_THERMAL_PROTECTION #ifdef THERMAL_PROTECTION_BED
thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS); thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_PROTECTION_BED_PERIOD, THERMAL_PROTECTION_BED_HYSTERESIS);
#endif #endif
#ifdef PIDTEMPBED #ifdef PIDTEMPBED
...@@ -777,7 +780,6 @@ static float analog2tempBed(int raw) { ...@@ -777,7 +780,6 @@ static float analog2tempBed(int raw) {
static void updateTemperaturesFromRawValues() { static void updateTemperaturesFromRawValues() {
static millis_t last_update = millis(); static millis_t last_update = millis();
millis_t temp_last_update = millis(); millis_t temp_last_update = millis();
millis_t from_last_update = temp_last_update - last_update;
#ifdef HEATER_0_USES_MAX6675 #ifdef HEATER_0_USES_MAX6675
current_temperature_raw[0] = read_max6675(); current_temperature_raw[0] = read_max6675();
#endif #endif
...@@ -792,6 +794,7 @@ static void updateTemperaturesFromRawValues() { ...@@ -792,6 +794,7 @@ static void updateTemperaturesFromRawValues() {
filament_width_meas = analog2widthFil(); filament_width_meas = analog2widthFil();
#endif #endif
#if HAS_POWER_CONSUMPTION_SENSOR #if HAS_POWER_CONSUMPTION_SENSOR
millis_t from_last_update = temp_last_update - last_update;
static float watt_overflow = 0.0; static float watt_overflow = 0.0;
power_consumption_meas = analog2power(); power_consumption_meas = analog2power();
//MYSERIAL.println(analog2current(),3); //MYSERIAL.println(analog2current(),3);
...@@ -802,13 +805,6 @@ static void updateTemperaturesFromRawValues() { ...@@ -802,13 +805,6 @@ static void updateTemperaturesFromRawValues() {
} }
#endif #endif
static unsigned int second_overflow = 0;
second_overflow += from_last_update;
if(second_overflow >= 1000) {
printer_usage_seconds++;
second_overflow -= 1000;
}
last_update = temp_last_update;
//Reset the watchdog after we know we have a temperature measurement. //Reset the watchdog after we know we have a temperature measurement.
watchdog_reset(); watchdog_reset();
...@@ -1033,15 +1029,15 @@ void tp_init() { ...@@ -1033,15 +1029,15 @@ void tp_init() {
#endif //BED_MAXTEMP #endif //BED_MAXTEMP
} }
#ifdef WATCH_TEMP_PERIOD #ifdef THERMAL_PROTECTION_HOTENDS
/** /**
* Start Heating Sanity Check for hotends that are below * Start Heating Sanity Check for hotends that are below
* their target temperature by a configurable margin. * their target temperature by a configurable margin.
* This is called when the temperature is set. (M104, M109) * This is called when the temperature is set. (M104, M109)
*/ */
void start_watching_heater(int e) { void start_watching_heater(int e) {
millis_t ms = millis() + WATCH_TEMP_PERIOD; millis_t ms = millis() + WATCH_TEMP_PERIOD * 1000;
if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2)) { if (degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)) {
watch_target_temp[e] = degHotend(e) + WATCH_TEMP_INCREASE; watch_target_temp[e] = degHotend(e) + WATCH_TEMP_INCREASE;
watch_heater_next_ms[e] = ms; watch_heater_next_ms[e] = ms;
} }
...@@ -1050,7 +1046,7 @@ void tp_init() { ...@@ -1050,7 +1046,7 @@ void tp_init() {
} }
#endif #endif
#if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION #if defined(THERMAL_PROTECTION_HOTENDS) || defined(THERMAL_PROTECTION_BED)
void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) { void thermal_runaway_protection(TRState *state, millis_t *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
...@@ -1109,7 +1105,7 @@ void tp_init() { ...@@ -1109,7 +1105,7 @@ void tp_init() {
} }
} }
#endif // HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION #endif // THERMAL_PROTECTION_HOTENDS || THERMAL_PROTECTION_BED
void disable_all_heaters() { void disable_all_heaters() {
for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i); for (int i = 0; i < HOTENDS; i++) setTargetHotend(0, i);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "stepper.h" #include "stepper.h"
#include "configuration_store.h" #include "configuration_store.h"
int8_t encoderDiff; /* encoderDiff is updated from interrupt context and added to encoderPosition every LCD update */ int8_t encoderDiff; // updated from interrupt context and added to encoderPosition every LCD update
bool encoderRateMultiplierEnabled; bool encoderRateMultiplierEnabled;
int32_t lastEncoderMovementMillis; int32_t lastEncoderMovementMillis;
...@@ -40,7 +40,7 @@ int gumPreheatFanSpeed; ...@@ -40,7 +40,7 @@ int gumPreheatFanSpeed;
/* !Configuration settings */ /* !Configuration settings */
//Function pointer to menu functions. // Function pointer to menu functions.
typedef void (*menuFunc_t)(); typedef void (*menuFunc_t)();
uint8_t lcd_status_message_level; uint8_t lcd_status_message_level;
...@@ -239,11 +239,11 @@ static void lcd_status_screen(); ...@@ -239,11 +239,11 @@ static void lcd_status_screen();
} } while(0) } } while(0)
/** Used variables to keep track of the menu */ /** Used variables to keep track of the menu */
#ifndef REPRAPWORLD_KEYPAD volatile uint8_t buttons; //the last checked buttons in a bit array.
volatile uint8_t buttons; // Bits of the pressed buttons. #ifdef REPRAPWORLD_KEYPAD
#else volatile uint8_t buttons_reprapworld_keypad; // to store the keypad shift register values
volatile uint8_t buttons_reprapworld_keypad; // The reprapworld_keypad shift register values
#endif #endif
#ifdef LCD_HAS_SLOW_BUTTONS #ifdef LCD_HAS_SLOW_BUTTONS
volatile uint8_t slow_buttons; // Bits of the pressed buttons. volatile uint8_t slow_buttons; // Bits of the pressed buttons.
#endif #endif
...@@ -1073,10 +1073,17 @@ static void lcd_control_menu() { ...@@ -1073,10 +1073,17 @@ static void lcd_control_menu() {
* "Control" > "Temperature" submenu * "Control" > "Temperature" submenu
* *
*/ */
static void lcd_control_temperature_menu() { static void lcd_control_temperature_menu() {
START_MENU(lcd_control_menu); START_MENU(lcd_control_menu);
//
// ^ Control
//
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
//
// Nozzle, Nozzle 2, Nozzle 3, Nozzle 4
//
#if TEMP_SENSOR_0 != 0 #if TEMP_SENSOR_0 != 0
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET); MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_NOZZLE, &target_temperature[0], 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET);
#endif #endif
...@@ -1095,19 +1102,35 @@ static void lcd_control_temperature_menu() { ...@@ -1095,19 +1102,35 @@ static void lcd_control_temperature_menu() {
#endif //HOTENDS > 3 #endif //HOTENDS > 3
#endif //HOTENDS > 2 #endif //HOTENDS > 2
#endif //HOTENDS > 1 #endif //HOTENDS > 1
//
// Bed
//
#if TEMP_SENSOR_BED != 0 #if TEMP_SENSOR_BED != 0
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP + LCD_MAX_TEMP_OFFSET); MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP + LCD_MAX_TEMP_OFFSET);
#endif #endif
//
// Fan Speed
//
MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255); MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
#ifdef IDLE_OOZING_PREVENT #ifdef IDLE_OOZING_PREVENT
MENU_ITEM_EDIT(bool, MSG_IDLEOOZING, &idleoozing_enabled); MENU_ITEM_EDIT(bool, MSG_IDLEOOZING, &idleoozing_enabled);
#endif #endif
//
// Autotemp, Min, Max, Fact
//
#if defined(AUTOTEMP) && (TEMP_SENSOR_0 != 0) #if defined(AUTOTEMP) && (TEMP_SENSOR_0 != 0)
MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &autotemp_enabled); MENU_ITEM_EDIT(bool, MSG_AUTOTEMP, &autotemp_enabled);
MENU_ITEM_EDIT(float3, MSG_MIN, &autotemp_min, 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET); MENU_ITEM_EDIT(float3, MSG_MIN, &autotemp_min, 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET);
MENU_ITEM_EDIT(float3, MSG_MAX, &autotemp_max, 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET); MENU_ITEM_EDIT(float3, MSG_MAX, &autotemp_max, 0, HEATER_0_MAXTEMP + LCD_MAX_TEMP_OFFSET);
MENU_ITEM_EDIT(float32, MSG_FACTOR, &autotemp_factor, 0.0, 1.0); MENU_ITEM_EDIT(float32, MSG_FACTOR, &autotemp_factor, 0.0, 1.0);
#endif #endif
//
// PID-P, PID-I, PID-D
//
#ifdef PIDTEMP #ifdef PIDTEMP
// set up temp variables - undo the default scaling // set up temp variables - undo the default scaling
raw_Ki = unscalePID_i(PID_PARAM(Ki,0)); raw_Ki = unscalePID_i(PID_PARAM(Ki,0));
...@@ -1144,8 +1167,20 @@ static void lcd_control_temperature_menu() { ...@@ -1144,8 +1167,20 @@ static void lcd_control_temperature_menu() {
#endif //HOTENDS > 2 #endif //HOTENDS > 2
#endif //HOTENDS > 1 #endif //HOTENDS > 1
#endif //PIDTEMP #endif //PIDTEMP
//
// Preheat PLA conf
//
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);
//
// Preheat ABS conf
//
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);
//
// Preheat GUM conf
//
MENU_ITEM(submenu, MSG_PREHEAT_GUM_SETTINGS, lcd_control_temperature_preheat_gum_settings_menu); MENU_ITEM(submenu, MSG_PREHEAT_GUM_SETTINGS, lcd_control_temperature_preheat_gum_settings_menu);
END_MENU(); END_MENU();
} }
...@@ -1155,7 +1190,6 @@ static void lcd_control_temperature_menu() { ...@@ -1155,7 +1190,6 @@ static void lcd_control_temperature_menu() {
* "Temperature" > "Preheat PLA conf" submenu * "Temperature" > "Preheat PLA conf" submenu
* *
*/ */
static void lcd_control_temperature_preheat_pla_settings_menu() { static void lcd_control_temperature_preheat_pla_settings_menu() {
START_MENU(lcd_control_temperature_menu); START_MENU(lcd_control_temperature_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu); MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu);
...@@ -1177,7 +1211,6 @@ static void lcd_control_temperature_preheat_pla_settings_menu() { ...@@ -1177,7 +1211,6 @@ static void lcd_control_temperature_preheat_pla_settings_menu() {
* "Temperature" > "Preheat ABS conf" submenu * "Temperature" > "Preheat ABS conf" submenu
* *
*/ */
static void lcd_control_temperature_preheat_abs_settings_menu() { static void lcd_control_temperature_preheat_abs_settings_menu() {
START_MENU(lcd_control_temperature_menu); START_MENU(lcd_control_temperature_menu);
MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu); MENU_ITEM(back, MSG_TEMPERATURE, lcd_control_temperature_menu);
...@@ -1220,7 +1253,6 @@ static void lcd_control_temperature_preheat_gum_settings_menu() { ...@@ -1220,7 +1253,6 @@ static void lcd_control_temperature_preheat_gum_settings_menu() {
* "Control" > "Motion" submenu * "Control" > "Motion" submenu
* *
*/ */
static void lcd_control_motion_menu() { static void lcd_control_motion_menu() {
START_MENU(lcd_control_menu); START_MENU(lcd_control_menu);
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
...@@ -1271,7 +1303,6 @@ static void lcd_control_motion_menu() { ...@@ -1271,7 +1303,6 @@ static void lcd_control_motion_menu() {
* "Control" > "Filament" submenu * "Control" > "Filament" submenu
* *
*/ */
static void lcd_control_volumetric_menu() { static void lcd_control_volumetric_menu() {
START_MENU(lcd_control_menu); START_MENU(lcd_control_menu);
MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM(back, MSG_CONTROL, lcd_control_menu);
...@@ -1299,7 +1330,6 @@ static void lcd_control_volumetric_menu() { ...@@ -1299,7 +1330,6 @@ static void lcd_control_volumetric_menu() {
* "Control" > "Contrast" submenu * "Control" > "Contrast" submenu
* *
*/ */
#ifdef HAS_LCD_CONTRAST #ifdef HAS_LCD_CONTRAST
static void lcd_set_contrast() { static void lcd_set_contrast() {
if (encoderPosition != 0) { if (encoderPosition != 0) {
...@@ -1319,7 +1349,6 @@ static void lcd_control_volumetric_menu() { ...@@ -1319,7 +1349,6 @@ static void lcd_control_volumetric_menu() {
* "Control" > "Retract" submenu * "Control" > "Retract" submenu
* *
*/ */
#ifdef FWRETRACT #ifdef FWRETRACT
static void lcd_control_retract_menu() { static void lcd_control_retract_menu() {
START_MENU(lcd_control_menu); START_MENU(lcd_control_menu);
...@@ -1357,7 +1386,6 @@ static void lcd_sd_updir() { ...@@ -1357,7 +1386,6 @@ static void lcd_sd_updir() {
* "Print from SD" submenu * "Print from SD" submenu
* *
*/ */
void lcd_sdcard_menu() { void lcd_sdcard_menu() {
if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) return; // nothing to do (so don't thrash the SD card) if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) return; // nothing to do (so don't thrash the SD card)
uint16_t fileCnt = card.getnrfilenames(); uint16_t fileCnt = card.getnrfilenames();
...@@ -1483,7 +1511,7 @@ menu_edit_type(unsigned long, long5, ftostr5, 0.01) ...@@ -1483,7 +1511,7 @@ menu_edit_type(unsigned long, long5, ftostr5, 0.01)
static void reprapworld_keypad_move_home() { static void reprapworld_keypad_move_home() {
enqueuecommands_P((PSTR("G28"))); // move all axis home enqueuecommands_P((PSTR("G28"))); // move all axis home
} }
#endif //REPRAPWORLD_KEYPAD #endif // REPRAPWORLD_KEYPAD
/** /**
...@@ -1503,7 +1531,7 @@ void lcd_quick_feedback() { ...@@ -1503,7 +1531,7 @@ void lcd_quick_feedback() {
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS (1000/6) #define LCD_FEEDBACK_FREQUENCY_DURATION_MS (1000/6)
#endif #endif
lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ); lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
#elif defined(BEEPER) && BEEPER > -1 #elif defined(BEEPER) && BEEPER >= 0
#ifndef LCD_FEEDBACK_FREQUENCY_HZ #ifndef LCD_FEEDBACK_FREQUENCY_HZ
#define LCD_FEEDBACK_FREQUENCY_HZ 5000 #define LCD_FEEDBACK_FREQUENCY_HZ 5000
#endif #endif
...@@ -1753,7 +1781,7 @@ void lcd_update() { ...@@ -1753,7 +1781,7 @@ void lcd_update() {
lcd_return_to_status(); lcd_return_to_status();
lcdDrawUpdate = 2; lcdDrawUpdate = 2;
} }
#endif //ULTIPANEL #endif // ULTIPANEL
if (lcdDrawUpdate == 2) lcd_implementation_clear(); if (lcdDrawUpdate == 2) lcd_implementation_clear();
if (lcdDrawUpdate) lcdDrawUpdate--; if (lcdDrawUpdate) lcdDrawUpdate--;
...@@ -1931,13 +1959,12 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; } ...@@ -1931,13 +1959,12 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
void lcd_buzz(long duration, uint16_t freq) { void lcd_buzz(long duration, uint16_t freq) {
if (freq > 0) { if (freq > 0) {
#if BEEPER > 0 #ifdef LCD_USE_I2C_BUZZER
lcd.buzz(duration, freq);
#elif defined(BEEPER) && BEEPER >= 0
SET_OUTPUT(BEEPER); SET_OUTPUT(BEEPER);
tone(BEEPER, freq); tone(BEEPER, freq, duration);
delay(duration); delay(duration);
noTone(BEEPER);
#elif defined(LCD_USE_I2C_BUZZER)
lcd.buzz(duration, freq);
#else #else
delay(duration); delay(duration);
#endif #endif
......
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
FORCE_INLINE void lcd_setstatuspgm(const char* message, const uint8_t level=0) {} FORCE_INLINE void lcd_setstatuspgm(const char* message, const uint8_t level=0) {}
FORCE_INLINE void lcd_buttons_update() {} FORCE_INLINE void lcd_buttons_update() {}
FORCE_INLINE void lcd_reset_alert_level() {} FORCE_INLINE void lcd_reset_alert_level() {}
FORCE_INLINE void lcd_buzz(long duration,uint16_t freq) {} FORCE_INLINE void lcd_buzz(long duration, uint16_t freq) {}
FORCE_INLINE bool lcd_detected(void) { return true; } FORCE_INLINE bool lcd_detected(void) { return true; }
#define LCD_MESSAGEPGM(x) do{}while(0) #define LCD_MESSAGEPGM(x) do{}while(0)
......
...@@ -6,17 +6,17 @@ ...@@ -6,17 +6,17 @@
* When selecting the Russian language, a slightly different LCD implementation is used to handle UTF8 characters. * When selecting the Russian language, a slightly different LCD implementation is used to handle UTF8 characters.
**/ **/
#ifndef REPRAPWORLD_KEYPAD //#ifndef REPRAPWORLD_KEYPAD
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.
#else //#else
extern volatile uint16_t buttons; //an extended version of the last checked buttons in a bit array. extern volatile uint8_t buttons; //an extended version of the last checked buttons in a bit array.
#endif //#endif
//////////////////////////////////// ////////////////////////////////////
// Setup button and encode mappings for each panel (into 'buttons' variable // Setup button and encode mappings for each panel (into 'buttons' variable
// //
// This is just to map common functions (across different panels) onto the same // This is just to map common functions (across different panels) onto the same
// macro name. The mapping is independent of whether the button is directly connected or // macro name. The mapping is independent of whether the button is directly connected or
// via a shift/i2c register. // via a shift/i2c register.
#ifdef ULTIPANEL #ifdef ULTIPANEL
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
// //
#if defined(LCD_I2C_VIKI) #if defined(LCD_I2C_VIKI)
#define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C) #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C)
// button and encoder bit positions within 'buttons' // button and encoder bit positions within 'buttons'
#define B_LE (BUTTON_LEFT<<B_I2C_BTN_OFFSET) // The remaining normalized buttons are all read via I2C #define B_LE (BUTTON_LEFT<<B_I2C_BTN_OFFSET) // The remaining normalized buttons are all read via I2C
#define B_UP (BUTTON_UP<<B_I2C_BTN_OFFSET) #define B_UP (BUTTON_UP<<B_I2C_BTN_OFFSET)
...@@ -51,22 +51,22 @@ ...@@ -51,22 +51,22 @@
#define B_DW (BUTTON_DOWN<<B_I2C_BTN_OFFSET) #define B_DW (BUTTON_DOWN<<B_I2C_BTN_OFFSET)
#define B_RI (BUTTON_RIGHT<<B_I2C_BTN_OFFSET) #define B_RI (BUTTON_RIGHT<<B_I2C_BTN_OFFSET)
#if defined(BTN_ENC) && BTN_ENC > -1 #if defined(BTN_ENC) && BTN_ENC > -1
// the pause/stop/restart button is connected to BTN_ENC when used // the pause/stop/restart button is connected to BTN_ENC when used
#define B_ST (EN_C) // Map the pause/stop/resume button into its normalized functional name #define B_ST (EN_C) // Map the pause/stop/resume button into its normalized functional name
#define LCD_CLICKED (buttons&(B_MI|B_RI|B_ST)) // pause/stop button also acts as click until we implement proper pause/stop. #define LCD_CLICKED (buttons&(B_MI|B_RI|B_ST)) // pause/stop button also acts as click until we implement proper pause/stop.
#else #else
#define LCD_CLICKED (buttons&(B_MI|B_RI)) #define LCD_CLICKED (buttons&(B_MI|B_RI))
#endif #endif
// I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update
#define LCD_HAS_SLOW_BUTTONS #define LCD_HAS_SLOW_BUTTONS
#elif defined(LCD_I2C_PANELOLU2) #elif defined(LCD_I2C_PANELOLU2)
// encoder click can be read through I2C if not directly connected // encoder click can be read through I2C if not directly connected
#if BTN_ENC <= 0 #if BTN_ENC <= 0
#define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C) #define B_I2C_BTN_OFFSET 3 // (the first three bit positions reserved for EN_A, EN_B, EN_C)
#define B_MI (PANELOLU2_ENCODER_C<<B_I2C_BTN_OFFSET) // requires LiquidTWI2 library v1.2.3 or later #define B_MI (PANELOLU2_ENCODER_C<<B_I2C_BTN_OFFSET) // requires LiquidTWI2 library v1.2.3 or later
#define LCD_CLICKED (buttons&B_MI) #define LCD_CLICKED (buttons&B_MI)
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
// I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update // I2C buttons take too long to read inside an interrupt context and so we read them during lcd_update
#define LCD_HAS_SLOW_BUTTONS #define LCD_HAS_SLOW_BUTTONS
#else #else
#define LCD_CLICKED (buttons&EN_C) #define LCD_CLICKED (buttons&EN_C)
#endif #endif
#elif defined(REPRAPWORLD_KEYPAD) #elif defined(REPRAPWORLD_KEYPAD)
...@@ -82,13 +82,13 @@ ...@@ -82,13 +82,13 @@
#define BLEN_REPRAPWORLD_KEYPAD_F3 0 #define BLEN_REPRAPWORLD_KEYPAD_F3 0
#define BLEN_REPRAPWORLD_KEYPAD_F2 1 #define BLEN_REPRAPWORLD_KEYPAD_F2 1
#define BLEN_REPRAPWORLD_KEYPAD_F1 2 #define BLEN_REPRAPWORLD_KEYPAD_F1 2
#define BLEN_REPRAPWORLD_KEYPAD_UP 3 #define BLEN_REPRAPWORLD_KEYPAD_UP 6
#define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4 #define BLEN_REPRAPWORLD_KEYPAD_RIGHT 4
#define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5 #define BLEN_REPRAPWORLD_KEYPAD_MIDDLE 5
#define BLEN_REPRAPWORLD_KEYPAD_DOWN 6 #define BLEN_REPRAPWORLD_KEYPAD_DOWN 3
#define BLEN_REPRAPWORLD_KEYPAD_LEFT 7 #define BLEN_REPRAPWORLD_KEYPAD_LEFT 7
#define REPRAPWORLD_BTN_OFFSET 3 // bit offset into buttons for shift register values #define REPRAPWORLD_BTN_OFFSET 0 // bit offset into buttons for shift register values
#define EN_REPRAPWORLD_KEYPAD_F3 BIT((BLEN_REPRAPWORLD_KEYPAD_F3+REPRAPWORLD_BTN_OFFSET)) #define EN_REPRAPWORLD_KEYPAD_F3 BIT((BLEN_REPRAPWORLD_KEYPAD_F3+REPRAPWORLD_BTN_OFFSET))
#define EN_REPRAPWORLD_KEYPAD_F2 BIT((BLEN_REPRAPWORLD_KEYPAD_F2+REPRAPWORLD_BTN_OFFSET)) #define EN_REPRAPWORLD_KEYPAD_F2 BIT((BLEN_REPRAPWORLD_KEYPAD_F2+REPRAPWORLD_BTN_OFFSET))
...@@ -99,17 +99,17 @@ ...@@ -99,17 +99,17 @@
#define EN_REPRAPWORLD_KEYPAD_DOWN BIT((BLEN_REPRAPWORLD_KEYPAD_DOWN+REPRAPWORLD_BTN_OFFSET)) #define EN_REPRAPWORLD_KEYPAD_DOWN BIT((BLEN_REPRAPWORLD_KEYPAD_DOWN+REPRAPWORLD_BTN_OFFSET))
#define EN_REPRAPWORLD_KEYPAD_LEFT BIT((BLEN_REPRAPWORLD_KEYPAD_LEFT+REPRAPWORLD_BTN_OFFSET)) #define EN_REPRAPWORLD_KEYPAD_LEFT BIT((BLEN_REPRAPWORLD_KEYPAD_LEFT+REPRAPWORLD_BTN_OFFSET))
#define LCD_CLICKED ((buttons&EN_C) || (buttons&EN_REPRAPWORLD_KEYPAD_F1)) //#define LCD_CLICKED ((buttons&EN_C) || (buttons&EN_REPRAPWORLD_KEYPAD_F1))
#define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons&EN_REPRAPWORLD_KEYPAD_DOWN) //#define REPRAPWORLD_KEYPAD_MOVE_Y_DOWN (buttons&EN_REPRAPWORLD_KEYPAD_DOWN)
#define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons&EN_REPRAPWORLD_KEYPAD_UP) //#define REPRAPWORLD_KEYPAD_MOVE_Y_UP (buttons&EN_REPRAPWORLD_KEYPAD_UP)
#define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons&EN_REPRAPWORLD_KEYPAD_MIDDLE) //#define REPRAPWORLD_KEYPAD_MOVE_HOME (buttons&EN_REPRAPWORLD_KEYPAD_MIDDLE)
#elif defined(NEWPANEL) #elif defined(NEWPANEL)
#define LCD_CLICKED (buttons&EN_C) #define LCD_CLICKED (buttons&EN_C)
#if HAS_BTN_BACK #if HAS_BTN_BACK
#define LCD_BACK_CLICKED (buttons&EN_D) #define LCD_BACK_CLICKED (buttons&EN_D)
#endif #endif
#else // old style ULTIPANEL #else // old style ULTIPANEL
//bits in the shift register that carry the buttons for: //bits in the shift register that carry the buttons for:
// left up center down right red(stop) // left up center down right red(stop)
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#define LCD_CLASS LiquidCrystal_I2C #define LCD_CLASS LiquidCrystal_I2C
LCD_CLASS lcd(LCD_I2C_ADDRESS,LCD_I2C_PIN_EN,LCD_I2C_PIN_RW,LCD_I2C_PIN_RS,LCD_I2C_PIN_D4,LCD_I2C_PIN_D5,LCD_I2C_PIN_D6,LCD_I2C_PIN_D7); LCD_CLASS lcd(LCD_I2C_ADDRESS,LCD_I2C_PIN_EN,LCD_I2C_PIN_RW,LCD_I2C_PIN_RS,LCD_I2C_PIN_D4,LCD_I2C_PIN_D5,LCD_I2C_PIN_D6,LCD_I2C_PIN_D7);
#elif defined(LCD_I2C_TYPE_MCP23017) #elif defined(LCD_I2C_TYPE_MCP23017)
//for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators()) //for the LED indicators (which maybe mapped to different things in lcd_implementation_update_indicators())
#define LED_A 0x04 //100 #define LED_A 0x04 //100
...@@ -164,28 +164,28 @@ ...@@ -164,28 +164,28 @@
#include <LiquidTWI2.h> #include <LiquidTWI2.h>
#define LCD_CLASS LiquidTWI2 #define LCD_CLASS LiquidTWI2
#if defined(DETECT_DEVICE) #if defined(DETECT_DEVICE)
LCD_CLASS lcd(LCD_I2C_ADDRESS, 1); LCD_CLASS lcd(LCD_I2C_ADDRESS, 1);
#else #else
LCD_CLASS lcd(LCD_I2C_ADDRESS); LCD_CLASS lcd(LCD_I2C_ADDRESS);
#endif #endif
#elif defined(LCD_I2C_TYPE_MCP23008) #elif defined(LCD_I2C_TYPE_MCP23008)
#include <Wire.h> #include <Wire.h>
#include <LiquidTWI2.h> #include <LiquidTWI2.h>
#define LCD_CLASS LiquidTWI2 #define LCD_CLASS LiquidTWI2
#if defined(DETECT_DEVICE) #if defined(DETECT_DEVICE)
LCD_CLASS lcd(LCD_I2C_ADDRESS, 1); LCD_CLASS lcd(LCD_I2C_ADDRESS, 1);
#else #else
LCD_CLASS lcd(LCD_I2C_ADDRESS); LCD_CLASS lcd(LCD_I2C_ADDRESS);
#endif #endif
#elif defined(LCD_I2C_TYPE_PCA8574) #elif defined(LCD_I2C_TYPE_PCA8574)
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#define LCD_CLASS LiquidCrystal_I2C #define LCD_CLASS LiquidCrystal_I2C
LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT); LCD_CLASS lcd(LCD_I2C_ADDRESS, LCD_WIDTH, LCD_HEIGHT);
// 2 wire Non-latching LCD SR from: // 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection // https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
#elif defined(SR_LCD_2W_NL) #elif defined(SR_LCD_2W_NL)
extern "C" void __cxa_pure_virtual() { while (1); } extern "C" void __cxa_pure_virtual() { while (1); }
#include <LCD.h> #include <LCD.h>
...@@ -378,164 +378,158 @@ static void lcd_implementation_init( ...@@ -378,164 +378,158 @@ static void lcd_implementation_init(
#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);
lcd.begin(LCD_WIDTH, LCD_HEIGHT); lcd.begin(LCD_WIDTH, LCD_HEIGHT);
lcd.setBacklight(0); //set all the LEDs off to begin with lcd.setBacklight(0); //set all the LEDs off to begin with
#elif defined(LCD_I2C_TYPE_MCP23008) #elif defined(LCD_I2C_TYPE_MCP23008)
lcd.setMCPType(LTI_TYPE_MCP23008); lcd.setMCPType(LTI_TYPE_MCP23008);
lcd.begin(LCD_WIDTH, LCD_HEIGHT); lcd.begin(LCD_WIDTH, LCD_HEIGHT);
#elif defined(LCD_I2C_TYPE_PCA8574) #elif defined(LCD_I2C_TYPE_PCA8574)
lcd.init(); lcd.init();
lcd.backlight(); lcd.backlight();
#else #else
#if (LCD_PINS_RS != -1) && (LCD_PINS_ENABLE != -1) #if (LCD_PINS_RS != -1) && (LCD_PINS_ENABLE != -1)
// required for RAMPS-FD, but does no harm for other targets // required for RAMPS-FD, but does no harm for other targets
SET_OUTPUT(LCD_PINS_RS); SET_OUTPUT(LCD_PINS_RS);
SET_OUTPUT(LCD_PINS_ENABLE); SET_OUTPUT(LCD_PINS_ENABLE);
#endif #endif
lcd.begin(LCD_WIDTH, LCD_HEIGHT); lcd.begin(LCD_WIDTH, LCD_HEIGHT);
#endif #endif
lcd_set_custom_characters(
#ifdef LCD_PROGRESS_BAR
progress_bar_set
#endif
);
lcd.clear(); lcd_set_custom_characters(
} #ifdef LCD_PROGRESS_BAR
progress_bar_set
#endif
);
static void lcd_implementation_clear() {
lcd.clear(); lcd.clear();
} }
static void lcd_implementation_clear() { lcd.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 */
char lcd_printPGM(const char* str) { char lcd_printPGM(const char* str) {
char c; char c, n = 0;
char n = 0; while ((c = pgm_read_byte(str++))) n += charset_mapper(c);
while((c = pgm_read_byte(str++))) {
n += charset_mapper(c);
}
return n; return n;
} }
char lcd_print(char* str) { char lcd_print(char* str) {
char c, n = 0;; char c, n = 0;;
unsigned char i = 0; unsigned char i = 0;
while((c = str[i++])) { while ((c = str[i++])) n += charset_mapper(c);
n += charset_mapper(c);
}
return n; return n;
} }
unsigned lcd_print(char c) { unsigned lcd_print(char c) { return charset_mapper(c); }
return charset_mapper(c);
}
/* /*
Possible status screens: Possible status screens:
16x2 |0123456789012345| 16x2 |000/000 B000/000|
|000/000 B000/000| |0123456789012345|
|Status line.....|
16x4 |0123456789012345| 16x4 |000/000 B000/000|
|000/000 B000/000| |SD100% Z000.00 |
|SD100% Z000.0|
|F100% T--:--| |F100% T--:--|
|Status line.....| |0123456789012345|
20x2 |01234567890123456789| 20x2 |T000/000D B000/000D |
|T000/000D B000/000D | |01234567890123456789|
|Status line.........|
20x4 |01234567890123456789| 20x4 |T000/000D B000/000D |
|T000/000D B000/000D | |X000 Y000 Z000.00 |
|X000 Y000 Z000.00|
|F100% SD100% T--:--| |F100% SD100% T--:--|
|Status line.........| |01234567890123456789|
20x4 |01234567890123456789| 20x4 |T000/000D B000/000D |
|T000/000D B000/000D | |T000/000D Z000.00 |
|T000/000D Z000.0|
|F100% SD100% T--:--| |F100% SD100% T--:--|
|Status line.........| |01234567890123456789|
*/ */
static void lcd_implementation_status_screen() { static void lcd_implementation_status_screen() {
int tHotend = int(degHotend(0) + 0.5);
int tTarget = int(degTargetHotend(0) + 0.5); #define LCD_TEMP_ONLY(T1,T2) \
lcd.print(itostr3(T1 + 0.5)); \
lcd.print('/'); \
lcd.print(itostr3left(T2 + 0.5))
#define LCD_TEMP(T1,T2,PREFIX) \
lcd.print(PREFIX); \
LCD_TEMP_ONLY(T1,T2); \
lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); \
if (T2 < 10) lcd.print(' ')
//
// Line 1
//
lcd.setCursor(0, 0);
#if LCD_WIDTH < 20 #if LCD_WIDTH < 20
lcd.setCursor(0, 0); //
lcd.print(itostr3(tHotend)); // Hotend 0 Temperature
lcd.print('/'); //
lcd.print(itostr3left(tTarget)); LCD_TEMP_ONLY(degHotend(0), degTargetHotend(0));
//
// Hotend 1 or Bed Temperature
//
#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
lcd.setCursor(8, 0); lcd.setCursor(8, 0);
#if HOTENDS > 1 #if HOTENDS > 1
tHotend = int(degHotend(1) + 0.5);
tTarget = int(degTargetHotend(1) + 0.5);
lcd.print(LCD_STR_THERMOMETER[0]); lcd.print(LCD_STR_THERMOMETER[0]);
LCD_TEMP_ONLY(degHotend(1), degTargetHotend(1));
#else // Heated bed #else // Heated bed
tHotend = int(degBed() + 0.5);
tTarget = int(degTargetBed() + 0.5);
lcd.print(LCD_STR_BEDTEMP[0]); lcd.print(LCD_STR_BEDTEMP[0]);
LCD_TEMP_ONLY(degBed(), degTargetBed());
#endif #endif
lcd.print(itostr3(tHotend));
lcd.print('/');
lcd.print(itostr3left(tTarget));
#endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0
#else // LCD_WIDTH > 19 #else // LCD_WIDTH >= 20
lcd.setCursor(0, 0); //
lcd.print(LCD_STR_THERMOMETER[0]); // Hotend 0 Temperature
lcd.print(itostr3(tHotend)); //
lcd.print('/'); LCD_TEMP(degHotend(0), degTargetHotend(0), LCD_STR_THERMOMETER[0]);
lcd.print(itostr3left(tTarget));
lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
if (tTarget < 10) lcd.print(' ');
//
// Hotend 1 or Bed Temperature
//
#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
lcd.setCursor(10, 0); lcd.setCursor(10, 0);
#if HOTENDS > 1 #if HOTENDS > 1
tHotend = int(degHotend(1) + 0.5); LCD_TEMP(degHotend(1), degTargetHotend(1), LCD_STR_THERMOMETER[0]);
tTarget = int(degTargetHotend(1) + 0.5); #else
lcd.print(LCD_STR_THERMOMETER[0]); LCD_TEMP(degBed(), degTargetBed(), LCD_STR_BEDTEMP[0]);
#else // Heated bed
tHotend = int(degBed() + 0.5);
tTarget = int(degTargetBed() + 0.5);
lcd.print(LCD_STR_BEDTEMP[0]);
#endif #endif
lcd.print(itostr3(tHotend));
lcd.print('/');
lcd.print(itostr3left(tTarget));
lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
if (tTarget < 10) lcd.print(' ');
#endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0
#endif // LCD_WIDTH > 19 #endif // LCD_WIDTH >= 20
//
// Line 2
//
#if LCD_HEIGHT > 2 #if LCD_HEIGHT > 2
// Lines 2 for 4 line LCD
#if LCD_WIDTH < 20 #if LCD_WIDTH < 20
#ifdef SDSUPPORT #ifdef SDSUPPORT
lcd.setCursor(0, 2); lcd.setCursor(0, 2);
lcd_printPGM(PSTR("SD")); lcd_printPGM(PSTR("SD"));
...@@ -543,46 +537,58 @@ static void lcd_implementation_status_screen() { ...@@ -543,46 +537,58 @@ static void lcd_implementation_status_screen() {
lcd.print(itostr3(card.percentDone())); lcd.print(itostr3(card.percentDone()));
else else
lcd_printPGM(PSTR("---")); lcd_printPGM(PSTR("---"));
lcd.print('%'); lcd.print('%');
#endif // SDSUPPORT #endif // SDSUPPORT
#else // LCD_WIDTH > 19 #else // LCD_WIDTH >= 20
lcd.setCursor(0, 1);
#if HOTENDS > 1 && TEMP_SENSOR_BED != 0 #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); // If we both have a 2nd extruder and a heated bed,
lcd.print(LCD_STR_BEDTEMP[0]); // show the heated bed temp on the left,
lcd.print(itostr3(tHotend)); // since the first line is filled with extruder temps
lcd.print('/'); LCD_TEMP(degBed(), degTargetBed(), LCD_STR_BEDTEMP[0]);
lcd.print(itostr3left(tTarget));
lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
if (tTarget < 10) lcd.print(' ');
#else #else
lcd.setCursor(0,1);
lcd.print('X');
if (axis_known_position[X_AXIS])
#ifdef DELTA #ifdef DELTA
lcd.print('X');
lcd.print(ftostr30(current_position[X_AXIS])); lcd.print(ftostr30(current_position[X_AXIS]));
lcd_printPGM(PSTR(" Y"));
lcd.print(ftostr30(current_position[Y_AXIS]));
#else #else
lcd.print('X');
lcd.print(ftostr3(current_position[X_AXIS])); lcd.print(ftostr3(current_position[X_AXIS]));
lcd_printPGM(PSTR(" Y")); #endif
else
lcd_printPGM(PSTR("---"));
lcd_printPGM(PSTR(" Y"));
if (axis_known_position[Y_AXIS])
#ifdef DELTA
lcd.print(ftostr30(current_position[Y_AXIS]));
#else
lcd.print(ftostr3(current_position[Y_AXIS])); lcd.print(ftostr3(current_position[Y_AXIS]));
#endif // DELTA #endif
else
lcd_printPGM(PSTR("---"));
#endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0 #endif // HOTENDS > 1 || TEMP_SENSOR_BED != 0
#endif // LCD_WIDTH > 19 #endif // LCD_WIDTH >= 20
lcd.setCursor(LCD_WIDTH - 8, 1); lcd.setCursor(LCD_WIDTH - 8, 1);
lcd.print('Z'); lcd.print('Z');
lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001)); if (axis_known_position[Z_AXIS])
lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001));
else
lcd_printPGM(PSTR("---.--"));
#endif // LCD_HEIGHT > 2 #endif // LCD_HEIGHT > 2
//
// Line 3
//
#if LCD_HEIGHT > 3 #if LCD_HEIGHT > 3
lcd.setCursor(0, 2); lcd.setCursor(0, 2);
...@@ -630,9 +636,10 @@ static void lcd_implementation_status_screen() { ...@@ -630,9 +636,10 @@ static void lcd_implementation_status_screen() {
#endif // LCD_HEIGHT > 3 #endif // LCD_HEIGHT > 3
/** //
* Display Progress Bar, Filament display, and/or Status Message on the last line // Last Line
*/ // Status Message (which may be a Progress Bar or Filament display)
//
lcd.setCursor(0, LCD_HEIGHT - 1); lcd.setCursor(0, LCD_HEIGHT - 1);
...@@ -797,7 +804,7 @@ static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const ...@@ -797,7 +804,7 @@ static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const
static void lcd_implementation_update_indicators() { static void lcd_implementation_update_indicators() {
#if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI) #if defined(LCD_I2C_PANELOLU2) || defined(LCD_I2C_VIKI)
//set the LEDS - referred to as backlights by the LiquidTWI2 library // Set the LEDS - referred to as backlights by the LiquidTWI2 library
static uint8_t ledsprev = 0; static uint8_t ledsprev = 0;
uint8_t leds = 0; uint8_t leds = 0;
if (target_temperature_bed > 0) leds |= LED_A; if (target_temperature_bed > 0) leds |= LED_A;
...@@ -835,4 +842,4 @@ static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const ...@@ -835,4 +842,4 @@ static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const
#endif // LCD_HAS_SLOW_BUTTONS #endif // LCD_HAS_SLOW_BUTTONS
#endif //__ULTRALCD_IMPLEMENTATION_HITACHI_HD44780_H #endif // ULTRALCD_IMPLEMENTATION_HITACHI_HD44780_H
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
//#define PAGE_HEIGHT 16 //256 byte framebuffer //#define PAGE_HEIGHT 16 //256 byte framebuffer
#define PAGE_HEIGHT 32 //512 byte framebuffer #define PAGE_HEIGHT 32 //512 byte framebuffer
#define WIDTH 128 #define LCD_PIXEL_WIDTH 128
#define HEIGHT 64 #define LCD_PIXEL_HEIGHT 64
#include <U8glib.h> #include <U8glib.h>
...@@ -64,12 +64,12 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo ...@@ -64,12 +64,12 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo
ST7920_WRITE_BYTE(0x01); //clear CGRAM ram ST7920_WRITE_BYTE(0x01); //clear CGRAM ram
u8g_Delay(15); //delay for CGRAM clear u8g_Delay(15); //delay for CGRAM clear
ST7920_WRITE_BYTE(0x3E); //extended mode + GDRAM active ST7920_WRITE_BYTE(0x3E); //extended mode + GDRAM active
for(y=0;y<HEIGHT/2;y++) //clear GDRAM for(y = 0; y < LCD_PIXEL_HEIGHT / 2; y++) //clear GDRAM
{ {
ST7920_WRITE_BYTE(0x80|y); //set y ST7920_WRITE_BYTE(0x80|y); //set y
ST7920_WRITE_BYTE(0x80); //set x = 0 ST7920_WRITE_BYTE(0x80); //set x = 0
ST7920_SET_DAT(); ST7920_SET_DAT();
for(i=0;i<2*WIDTH/8;i++) //2x width clears both segments for(i = 0; i < 2 * LCD_PIXEL_WIDTH / 8; i++) //2x width clears both segments
ST7920_WRITE_BYTE(0); ST7920_WRITE_BYTE(0);
ST7920_SET_CMD(); ST7920_SET_CMD();
} }
...@@ -103,7 +103,7 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo ...@@ -103,7 +103,7 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo
} }
ST7920_SET_DAT(); ST7920_SET_DAT();
ST7920_WRITE_BYTES(ptr,WIDTH/8); //ptr is incremented inside of macro ST7920_WRITE_BYTES(ptr,LCD_PIXEL_WIDTH/8); //ptr is incremented inside of macro
y++; y++;
} }
ST7920_NCS(); ST7920_NCS();
...@@ -119,8 +119,8 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo ...@@ -119,8 +119,8 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo
#endif #endif
} }
uint8_t u8g_dev_st7920_128x64_rrd_buf[WIDTH*(PAGE_HEIGHT/8)] U8G_NOCOMMON; uint8_t u8g_dev_st7920_128x64_rrd_buf[LCD_PIXEL_WIDTH*(PAGE_HEIGHT/8)] U8G_NOCOMMON;
u8g_pb_t u8g_dev_st7920_128x64_rrd_pb = {{PAGE_HEIGHT,HEIGHT,0,0,0},WIDTH,u8g_dev_st7920_128x64_rrd_buf}; u8g_pb_t u8g_dev_st7920_128x64_rrd_pb = {{PAGE_HEIGHT,LCD_PIXEL_HEIGHT,0,0,0},LCD_PIXEL_WIDTH,u8g_dev_st7920_128x64_rrd_buf};
u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = {u8g_dev_rrd_st7920_128x64_fn,&u8g_dev_st7920_128x64_rrd_pb,&u8g_com_null_fn}; u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = {u8g_dev_rrd_st7920_128x64_fn,&u8g_dev_st7920_128x64_rrd_pb,&u8g_com_null_fn};
class U8GLIB_ST7920_128X64_RRD : public U8GLIB class U8GLIB_ST7920_128X64_RRD : public U8GLIB
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
#include "ultralcd.h" #include "ultralcd.h"
//=========================================================================== //===========================================================================
//=============================private variables ============================ //============================ private variables ============================
//=========================================================================== //===========================================================================
//=========================================================================== //===========================================================================
//=============================functinos ============================ //================================ functions ================================
//=========================================================================== //===========================================================================
...@@ -36,7 +36,7 @@ void watchdog_reset() ...@@ -36,7 +36,7 @@ void watchdog_reset()
} }
//=========================================================================== //===========================================================================
//=============================ISR ============================ //=================================== ISR ===================================
//=========================================================================== //===========================================================================
//Watchdog timer interrupt, called if main program blocks >1sec and manual reset is enabled. //Watchdog timer interrupt, called if main program blocks >1sec and manual reset is enabled.
...@@ -46,7 +46,7 @@ ISR(WDT_vect) ...@@ -46,7 +46,7 @@ ISR(WDT_vect)
//TODO: This message gets overwritten by the kill() call //TODO: This message gets overwritten by the kill() call
LCD_ALERTMESSAGEPGM("ERR:Please Reset");//16 characters so it fits on a 16x2 display LCD_ALERTMESSAGEPGM("ERR:Please Reset");//16 characters so it fits on a 16x2 display
lcd_update(); lcd_update();
ECHO_LM(MSG_WATCHDOG_RESET); ECHO_LM(ER, MSG_WATCHDOG_RESET);
kill(); //kill blocks kill(); //kill blocks
while(1); //wait for user or serial reset while(1); //wait for user or serial reset
} }
......
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