From e878572b935352b50139306717c761cdb7d13380 Mon Sep 17 00:00:00 2001 From: Bjarke Istrup Pedersen Date: Mon, 7 Aug 2017 16:39:00 +0200 Subject: [PATCH 1/6] Ported MarlinFirmware/#3109 - Provide feedback to hosts when busy --- Firmware/Marlin_main.cpp | 62 +++++++++++++++++++ .../variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h | 3 + .../variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h | 3 + ...5mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h | 3 + ...5mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h | 3 + .../variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h | 3 + .../variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h | 3 + 7 files changed, 80 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a783af48a..492defe70 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -368,6 +368,26 @@ int fanSpeed=0; bool cancel_heatup = false ; +#ifdef HOST_KEEPALIVE_FEATURE + // States for managing Marlin and host communication + // Marlin sends messages if blocked or busy + enum MarlinBusyState { + NOT_BUSY, // Not in a handler + IN_HANDLER, // Processing a GCode + IN_PROCESS, // Known to be blocking command input (as in G29) + PAUSED_FOR_USER, // Blocking pending any input + PAUSED_FOR_INPUT // Blocking pending text input (concept) + }; + + static MarlinBusyState busy_state = NOT_BUSY; + static long next_busy_signal_ms = -1; + + #define KEEPALIVE_STATE(n) do { busy_state = n; } while (0) +#else + #define host_keepalive(); + #define KEEPALIVE_STATE(n); +#endif + #ifdef FILAMENT_SENSOR //Variables for Filament Sensor input float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA; //Set nominal filament width, can be changed with M404 @@ -1300,6 +1320,33 @@ int serial_read_stream() { } } +#ifdef HOST_KEEPALIVE_FEATURE +void host_keepalive() { + long ms = millis(); + if (busy_state != NOT_BUSY) { + if (ms < next_busy_signal_ms) return; + switch (busy_state) { + case NOT_BUSY: + break; + case IN_HANDLER: + case IN_PROCESS: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("busy: processing"); + break; + case PAUSED_FOR_USER: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("busy: paused for user"); + break; + case PAUSED_FOR_INPUT: + SERIAL_ECHO_START; + SERIAL_ECHOLNPGM("busy: paused for input"); + break; + } + } + next_busy_signal_ms = ms + 2000UL; +} +#endif + // The loop() function is called in an endless loop by the Arduino framework from the default main() routine. // Before loop(), the setup() function is called by the main() routine. void loop() @@ -1361,6 +1408,7 @@ void loop() manage_heater(); isPrintPaused ? manage_inactivity(true) : manage_inactivity(false); checkHitEndstops(); + host_keepalive(); lcd_update(); } @@ -2058,6 +2106,8 @@ void process_commands() float tmp_motor_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD; int8_t SilentMode; #endif + KEEPALIVE_STATE(IN_HANDLER); + if (code_seen("M117")) { //moved to highest priority place to be able to to print strings which includes "G", "PRUSA" and "^" starpos = (strchr(strchr_pointer + 5, '*')); if (starpos != NULL) @@ -2388,6 +2438,8 @@ void process_commands() case 28: //G28 Home all Axis one at a time homing_flag = true; + KEEPALIVE_STATE(IN_HANDLER); + #ifdef ENABLE_AUTO_BED_LEVELING plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data) #endif //ENABLE_AUTO_BED_LEVELING @@ -3441,20 +3493,24 @@ void process_commands() previous_millis_cmd = millis(); if (codenum > 0){ codenum += millis(); // keep track of when we started waiting + KEEPALIVE_STATE(PAUSED_FOR_USER); while(millis() < codenum && !lcd_clicked()){ manage_heater(); manage_inactivity(true); lcd_update(); } + KEEPALIVE_STATE(IN_HANDLER); lcd_ignore_click(false); }else{ if (!lcd_detected()) break; + KEEPALIVE_STATE(PAUSED_FOR_USER); while(!lcd_clicked()){ manage_heater(); manage_inactivity(true); lcd_update(); } + KEEPALIVE_STATE(IN_HANDLER); } if (IS_SD_PRINTING) LCD_MESSAGERPGM(MSG_RESUMING); @@ -4940,6 +4996,8 @@ Sigma_Exit: temp=70; if (code_seen('S')) temp=code_value(); if (code_seen('C')) c=code_value(); + + KEEPALIVE_STATE(NOT_BUSY); PID_autotune(temp, e, c); } break; @@ -5217,6 +5275,7 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp int counterBeep = 0; lcd_wait_interact(); load_filament_time = millis(); + KEEPALIVE_STATE(PAUSED_FOR_USER); while(!lcd_clicked()){ cnt++; @@ -5253,6 +5312,7 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp } } + KEEPALIVE_STATE(IN_HANDLER); WRITE(BEEPER, LOW); #ifdef SNMM display_loading(); @@ -5717,6 +5777,8 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp SERIAL_ECHOLNPGM("\""); } + KEEPALIVE_STATE(NOT_BUSY); + ClearToSend(); } diff --git a/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h index ba9f55289..0dc72e79f 100644 --- a/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h @@ -186,6 +186,9 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 +// USB host keep alive +#define HOST_KEEPALIVE_FEATURE + /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h index 1822a9d73..634c578a3 100644 --- a/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h @@ -186,6 +186,9 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 +// USB host keep alive +#define HOST_KEEPALIVE_FEATURE + /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h index 06a7410c3..eab7541a1 100644 --- a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h @@ -181,6 +181,9 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 +// USB host keep alive +#define HOST_KEEPALIVE_FEATURE + /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h index a0afa5f7f..a39519bd2 100644 --- a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h @@ -183,6 +183,9 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 +// USB host keep alive +#define HOST_KEEPALIVE_FEATURE + /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h index d7019845f..a182f9fec 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h @@ -181,6 +181,9 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 +// USB host keep alive +#define HOST_KEEPALIVE_FEATURE + /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h index 720e74f5e..ff37a14e8 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h @@ -183,6 +183,9 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 +// USB host keep alive +#define HOST_KEEPALIVE_FEATURE + /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ From 9c7de9292af1b854bdc561eee92482f3baa5b60a Mon Sep 17 00:00:00 2001 From: Bjarke Istrup Pedersen Date: Wed, 9 Aug 2017 10:24:19 +0200 Subject: [PATCH 2/6] Ported the remaining HOST_KEEPALIVE commits from Marlin --- Firmware/Configuration.h | 8 ++++- Firmware/Marlin.h | 6 ++++ Firmware/Marlin_main.cpp | 34 +++++++++++++++---- .../variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h | 3 -- .../variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h | 3 -- ...5mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h | 3 -- ...5mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h | 3 -- .../variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h | 3 -- .../variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h | 3 -- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 5a3abcd4c..ceb8ae89c 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -461,7 +461,13 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of // please keep turned on if you can. //#define EEPROM_CHITCHAT - +// Host Keepalive +// +// When enabled Marlin will send a busy status message to the host +// every couple of seconds when it can't accept commands. +// +#define HOST_KEEPALIVE_FEATURE // Disable this if your host doesn't like keepalive messages +#define HOST_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113. //LCD and SD support #define ULTRA_LCD //general LCD support, also 16x2 diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index a5c7ffa2a..1215bd468 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -108,6 +108,8 @@ FORCE_INLINE void serialprintPGM(const char *str) } } +#define NOMORE(v,n) do{ if (v > n) v = n; }while(0) + bool is_buffer_empty(); void get_command(); void process_commands(); @@ -280,6 +282,10 @@ extern float retract_length, retract_length_swap, retract_feedrate, retract_zlif extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate; #endif +#ifdef HOST_KEEPALIVE_FEATURE +extern uint8_t host_keepalive_interval; +#endif + extern unsigned long starttime; extern unsigned long stoptime; extern int bowden_length[4]; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 492defe70..a0ce4e307 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -151,6 +151,7 @@ // Rxxx Wait for extruder current temp to reach target temp. Waits when heating and cooling // IF AUTOTEMP is enabled, S B F. Exit autotemp by any M109 without F // M112 - Emergency stop +// M113 - Get or set the timeout interval for Host Keepalive "busy" messages // M114 - Output current position to serial port // M115 - Capabilities string // M117 - display message @@ -380,8 +381,8 @@ bool cancel_heatup = false ; }; static MarlinBusyState busy_state = NOT_BUSY; - static long next_busy_signal_ms = -1; - + static long prev_busy_signal_ms = -1; + uint8_t host_keepalive_interval = HOST_KEEPALIVE_INTERVAL; #define KEEPALIVE_STATE(n) do { busy_state = n; } while (0) #else #define host_keepalive(); @@ -1321,13 +1322,15 @@ int serial_read_stream() { } #ifdef HOST_KEEPALIVE_FEATURE +/** +* Output a "busy" message at regular intervals +* while the machine is not accepting commands. +*/ void host_keepalive() { long ms = millis(); - if (busy_state != NOT_BUSY) { - if (ms < next_busy_signal_ms) return; + if (host_keepalive_interval && busy_state != NOT_BUSY) { + if (ms - prev_busy_signal_ms < 1000UL * host_keepalive_interval) return; switch (busy_state) { - case NOT_BUSY: - break; case IN_HANDLER: case IN_PROCESS: SERIAL_ECHO_START; @@ -1343,7 +1346,7 @@ void host_keepalive() { break; } } - next_busy_signal_ms = ms + 2000UL; + prev_busy_signal_ms = ms; } #endif @@ -4215,6 +4218,7 @@ Sigma_Exit: }} #endif SERIAL_PROTOCOLLN(""); + KEEPALIVE_STATE(NOT_BUSY); return; break; case 109: @@ -4252,11 +4256,14 @@ Sigma_Exit: /* See if we are heating up or cooling down */ target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling + KEEPALIVE_STATE(NOT_BUSY); + cancel_heatup = false; wait_for_heater(codenum); //loops until target temperature is reached LCD_MESSAGERPGM(MSG_HEATING_COMPLETE); + KEEPALIVE_STATE(IN_HANDLER); heating_status = 2; if (farm_mode) { prusa_statistics(2); }; @@ -4284,6 +4291,7 @@ Sigma_Exit: cancel_heatup = false; target_direction = isHeatingBed(); // true if heating, false if cooling + KEEPALIVE_STATE(NOT_BUSY); while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) { if(( millis() - codenum) > 1000 ) //Print Temp Reading every 1 second while heating up. @@ -4306,6 +4314,7 @@ Sigma_Exit: lcd_update(); } LCD_MESSAGERPGM(MSG_BED_DONE); + KEEPALIVE_STATE(IN_HANDLER); heating_status = 4; previous_millis_cmd = millis(); @@ -4449,6 +4458,17 @@ Sigma_Exit: else gcode_LastN = 0; break; +#ifdef HOST_KEEPALIVE_FEATURE + case 113: // M113 - Get or set Host Keepalive interval + if (code_seen('S')) { + host_keepalive_interval = (uint8_t)code_value_short(); + NOMORE(host_keepalive_interval, 60); + } else { + SERIAL_ECHO_START; + SERIAL_ECHOPAIR("M113 S", (unsigned long)host_keepalive_interval); + SERIAL_PROTOCOLLN(""); + } +#endif case 115: // M115 if (code_seen('V')) { // Report the Prusa version number. diff --git a/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h index 0dc72e79f..ba9f55289 100644 --- a/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK1-RAMBo10a-E3Dv6full.h @@ -186,9 +186,6 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 -// USB host keep alive -#define HOST_KEEPALIVE_FEATURE - /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h index 634c578a3..1822a9d73 100644 --- a/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK1-RAMBo13a-E3Dv6full.h @@ -186,9 +186,6 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 -// USB host keep alive -#define HOST_KEEPALIVE_FEATURE - /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h index eab7541a1..06a7410c3 100644 --- a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo10a-E3Dv6full.h @@ -181,9 +181,6 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 -// USB host keep alive -#define HOST_KEEPALIVE_FEATURE - /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h index a39519bd2..a0afa5f7f 100644 --- a/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-MultiMaterial-RAMBo13a-E3Dv6full.h @@ -183,9 +183,6 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 -// USB host keep alive -#define HOST_KEEPALIVE_FEATURE - /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h index a182f9fec..d7019845f 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h @@ -181,9 +181,6 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 -// USB host keep alive -#define HOST_KEEPALIVE_FEATURE - /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ diff --git a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h index ff37a14e8..720e74f5e 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h @@ -183,9 +183,6 @@ ADDITIONAL FEATURES SETTINGS #define TEMP_RUNAWAY_EXTRUDER_HYSTERESIS 15 #define TEMP_RUNAWAY_EXTRUDER_TIMEOUT 45 -// USB host keep alive -#define HOST_KEEPALIVE_FEATURE - /*------------------------------------ MOTOR CURRENT SETTINGS *------------------------------------*/ From 9e73c96223342ab235d77b73c3038cabd3ae0a34 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Thu, 17 Aug 2017 19:07:38 +0200 Subject: [PATCH 3/6] Host keep alive messages --- Firmware/Configuration_adv.h | 2 +- Firmware/Marlin.h | 23 ++++++++++++++-- Firmware/Marlin_main.cpp | 52 ++++++++++++++++-------------------- Firmware/cardreader.cpp | 2 +- Firmware/temperature.cpp | 15 ++++++----- Firmware/ultralcd.cpp | 15 ++++++++--- 6 files changed, 66 insertions(+), 43 deletions(-) diff --git a/Firmware/Configuration_adv.h b/Firmware/Configuration_adv.h index 9112c2a50..455eb5c18 100644 --- a/Firmware/Configuration_adv.h +++ b/Firmware/Configuration_adv.h @@ -261,7 +261,7 @@ #define SD_SORT_ALPHA 1 #define SD_SORT_NONE 2 - #define SDSORT_LIMIT 40 // Maximum number of sorted items (10-256). + #define SDSORT_LIMIT 20 // Maximum number of sorted items (10-256). #define FOLDER_SORTING -1 // -1=above 0=none 1=below #define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 g-code. #define SDSORT_USES_RAM true // Pre-allocate a static array for faster pre-sorting. diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 20b9aac65..856e9a914 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -318,8 +318,6 @@ extern void digipot_i2c_set_current( int channel, float current ); extern void digipot_i2c_init(); #endif -#endif - //Long pause extern int saved_feedmultiply; extern float HotendTempBckp; @@ -352,8 +350,29 @@ float d_ReadData(); void bed_analysis(float x_dimension, float y_dimension, int x_points_num, int y_points_num, float shift_x, float shift_y); #endif + float temp_comp_interpolation(float temperature); void temp_compensation_apply(); void temp_compensation_start(); void wait_for_heater(long codenum); void serialecho_temperatures(); + +#ifdef HOST_KEEPALIVE_FEATURE + +// States for managing Marlin and host communication +// Marlin sends messages if blocked or busy +enum MarlinBusyState { + NOT_BUSY, // Not in a handler + IN_HANDLER, // Processing a GCode + IN_PROCESS, // Known to be blocking command input (as in G29) + PAUSED_FOR_USER, // Blocking pending any input + PAUSED_FOR_INPUT // Blocking pending text input (concept) +}; + +#define KEEPALIVE_STATE(n) do { busy_state = n;} while (0) +extern void host_keepalive(); +extern MarlinBusyState busy_state; + +#endif //HOST_KEEPALIVE_FEATURE + +#endif //ifndef marlin.h diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index c045eb9f5..405ff3b6d 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -372,20 +372,10 @@ int fanSpeed=0; bool cancel_heatup = false ; #ifdef HOST_KEEPALIVE_FEATURE - // States for managing Marlin and host communication - // Marlin sends messages if blocked or busy - enum MarlinBusyState { - NOT_BUSY, // Not in a handler - IN_HANDLER, // Processing a GCode - IN_PROCESS, // Known to be blocking command input (as in G29) - PAUSED_FOR_USER, // Blocking pending any input - PAUSED_FOR_INPUT // Blocking pending text input (concept) - }; - - static MarlinBusyState busy_state = NOT_BUSY; + + MarlinBusyState busy_state = NOT_BUSY; static long prev_busy_signal_ms = -1; uint8_t host_keepalive_interval = HOST_KEEPALIVE_INTERVAL; - #define KEEPALIVE_STATE(n) do { busy_state = n; } while (0) #else #define host_keepalive(); #define KEEPALIVE_STATE(n); @@ -1099,6 +1089,7 @@ void setup() world2machine_reset(); lcd_init(); + KEEPALIVE_STATE(PAUSED_FOR_USER); if (!READ(BTN_ENC)) { _delay_ms(1000); @@ -1120,7 +1111,7 @@ void setup() _delay_ms(2000); - + char level = reset_menu(); factory_reset(level, false); @@ -1266,6 +1257,7 @@ void setup() // Store the currently running firmware into an eeprom, // so the next time the firmware gets updated, it will know from which version it has been updated. update_current_firmware_version_to_eeprom(); + KEEPALIVE_STATE(NOT_BUSY); } void trace(); @@ -1351,7 +1343,7 @@ void host_keepalive() { long ms = millis(); if (host_keepalive_interval && busy_state != NOT_BUSY) { if (ms - prev_busy_signal_ms < 1000UL * host_keepalive_interval) return; - switch (busy_state) { + switch (busy_state) { case IN_HANDLER: case IN_PROCESS: SERIAL_ECHO_START; @@ -1432,7 +1424,6 @@ void loop() manage_heater(); isPrintPaused ? manage_inactivity(true) : manage_inactivity(false); checkHitEndstops(); - host_keepalive(); lcd_update(); } @@ -2460,7 +2451,7 @@ void process_commands() prepare_arc_move(false); } break; - case 4: // G4 dwell + case 4: // G4 dwell codenum = 0; if(code_seen('P')) codenum = code_value(); // milliseconds to wait if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait @@ -2493,10 +2484,7 @@ void process_commands() #endif //FWRETRACT case 28: //G28 Home all Axis one at a time homing_flag = true; - - KEEPALIVE_STATE(IN_HANDLER); - -#ifdef ENABLE_AUTO_BED_LEVELING + #ifdef ENABLE_AUTO_BED_LEVELING plan_bed_level_matrix.set_to_identity(); //Reset the plane ("erase" all leveling data) #endif //ENABLE_AUTO_BED_LEVELING @@ -2943,6 +2931,7 @@ void process_commands() enquecommand_front_P((PSTR("G28 W0"))); break; } + KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly SERIAL_ECHOLNPGM("PINDA probe calibration start"); custom_message = true; custom_message_type = 4; @@ -3540,9 +3529,9 @@ void process_commands() while (*src == ' ') ++src; if (!hasP && !hasS && *src != '\0') { lcd_setstatus(src); - } else { - LCD_MESSAGERPGM(MSG_USERWAIT); - } + } else { + LCD_MESSAGERPGM(MSG_USERWAIT); + } lcd_ignore_click(); //call lcd_ignore_click aslo for else ??? st_synchronize(); @@ -3754,7 +3743,6 @@ void process_commands() { // Only Z calibration? bool onlyZ = code_seen('Z'); - if (!onlyZ) { setTargetBed(0); setTargetHotend(0, 0); @@ -3777,7 +3765,9 @@ void process_commands() memset(axis_known_position, 0, sizeof(axis_known_position)); // Let the user move the Z axes up to the end stoppers. + KEEPALIVE_STATE(PAUSED_FOR_USER); if (lcd_calibrate_z_end_stop_manual( onlyZ )) { + KEEPALIVE_STATE(IN_HANDLER); refresh_cmd_timeout(); if (((degHotend(0) > MAX_HOTEND_TEMP_CALIBRATION) || (degBed() > MAX_BED_TEMP_CALIBRATION)) && (!onlyZ)) { lcd_wait_for_cool_down(); @@ -3857,6 +3847,7 @@ void process_commands() } } else { // Timeouted. + KEEPALIVE_STATE(IN_HANDLER); } lcd_update_enable(true); break; @@ -3887,8 +3878,10 @@ void process_commands() case 47: // M47: Prusa3D: Show end stops dialog on the display. + KEEPALIVE_STATE(PAUSED_FOR_USER); lcd_diag_show_end_stops(); - break; + KEEPALIVE_STATE(IN_HANDLER); + break; #if 0 case 48: // M48: scan the bed induction sensor points, print the sensor trigger coordinates to the serial line for visualization on the PC. @@ -5070,8 +5063,7 @@ Sigma_Exit: if (code_seen('S')) temp=code_value(); if (code_seen('C')) c=code_value(); - KEEPALIVE_STATE(NOT_BUSY); - PID_autotune(temp, e, c); + PID_autotune(temp, e, c); } break; case 400: // M400 finish all moves @@ -5433,7 +5425,9 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp lcd_loading_filament(); while ((lcd_change_fil_state == 0)||(lcd_change_fil_state != 1)){ lcd_change_fil_state = 0; + KEEPALIVE_STATE(PAUSED_FOR_USER); lcd_alright(); + KEEPALIVE_STATE(IN_HANDLER); switch(lcd_change_fil_state){ // Filament failed to load so load it again @@ -6095,7 +6089,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s static int killCount = 0; // make the inactivity button a bit less responsive const int KILL_DELAY = 10000; #endif - + if(buflen < (BUFSIZE-1)){ get_command(); } @@ -6371,7 +6365,7 @@ void calculate_volumetric_multipliers() { void delay_keep_alive(unsigned int ms) { - for (;;) { + for (;;) { manage_heater(); // Manage inactivity, but don't disable steppers on timeout. manage_inactivity(true); diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 51c02d7d9..aa1b489fb 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -705,7 +705,7 @@ void CardReader::getfilename_sorted(const uint16_t nr) { * - Most RAM: Buffer the directory and return filenames from RAM */ void CardReader::presort() { - + uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT); if (sdSort == SD_SORT_NONE) return; //sd sort is turned off diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 36ee56001..2d9c815e7 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -220,7 +220,7 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0); pid_cycle = 0; return; } - + SERIAL_ECHOLN("PID Autotune start"); disable_heater(); // switch off all heaters. @@ -336,13 +336,13 @@ unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0); p=soft_pwm_bed; SERIAL_PROTOCOLPGM("ok B:"); }else{ - p=soft_pwm[extruder]; - SERIAL_PROTOCOLPGM("ok T:"); + p=soft_pwm[extruder]; + SERIAL_PROTOCOLPGM("ok T:"); } - - SERIAL_PROTOCOL(input); - SERIAL_PROTOCOLPGM(" @:"); - SERIAL_PROTOCOLLN(p); + + SERIAL_PROTOCOL(input); + SERIAL_PROTOCOLPGM(" @:"); + SERIAL_PROTOCOLLN(p); temp_millis = millis(); } @@ -686,6 +686,7 @@ void manage_heater() volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01; } #endif + host_keepalive(); } #define PGM_RD_W(x) (short)pgm_read_word(&x) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 40e036741..5e1ffa589 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -1283,13 +1283,14 @@ void lcd_menu_statistics() lcd.print(itostr3(_days)); - + KEEPALIVE_STATE(PAUSED_FOR_USER); while (!lcd_clicked()) { manage_heater(); manage_inactivity(true); delay(100); } + KEEPALIVE_STATE(NOT_BUSY); lcd_quick_feedback(); lcd_return_to_status(); @@ -1367,6 +1368,7 @@ void lcd_service_mode_show_result() { } else lcd_print_at_PGM(11, i + 1, PSTR("N/A")); } delay_keep_alive(500); + KEEPALIVE_STATE(PAUSED_FOR_USER); while (!lcd_clicked()) { delay_keep_alive(100); } @@ -1393,6 +1395,7 @@ void lcd_service_mode_show_result() { while (!lcd_clicked()) { delay_keep_alive(100); } + KEEPALIVE_STATE(NOT_BUSY); delay_keep_alive(500); lcd_set_custom_characters_arrows(); lcd_return_to_status(); @@ -1865,6 +1868,7 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg) const char *msg_next = lcd_display_message_fullscreen_P(msg); bool multi_screen = msg_next != NULL; + KEEPALIVE_STATE(PAUSED_FOR_USER); // Until confirmed by a button click. for (;;) { // Wait for 5 seconds before displaying the next text. @@ -1874,6 +1878,7 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg) while (lcd_clicked()) ; delay(10); while (lcd_clicked()) ; + KEEPALIVE_STATE(IN_HANDLER); return; } } @@ -1887,6 +1892,7 @@ void lcd_show_fullscreen_message_and_wait_P(const char *msg) void lcd_wait_for_click() { + KEEPALIVE_STATE(PAUSED_FOR_USER); for (;;) { manage_heater(); manage_inactivity(true); @@ -1894,6 +1900,7 @@ void lcd_wait_for_click() while (lcd_clicked()) ; delay(10); while (lcd_clicked()) ; + KEEPALIVE_STATE(IN_HANDLER); return; } } @@ -1901,7 +1908,6 @@ void lcd_wait_for_click() int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting, bool default_yes) { - lcd_display_message_fullscreen_P(msg); if (default_yes) { @@ -1923,6 +1929,7 @@ int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow // Wait for user confirmation or a timeout. unsigned long previous_millis_cmd = millis(); int8_t enc_dif = encoderDiff; + KEEPALIVE_STATE(PAUSED_FOR_USER); for (;;) { if (allow_timeouting && millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS) return -1; @@ -1948,6 +1955,7 @@ int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow while (lcd_clicked()); delay(10); while (lcd_clicked()); + KEEPALIVE_STATE(IN_HANDLER); return yes; } } @@ -4800,6 +4808,7 @@ static bool lcd_selftest_fan_dialog(int _fan) lcd.setCursor(1, 3); lcd_printPGM(MSG_SELFTEST_FAN_NO); int8_t enc_dif = 0; + KEEPALIVE_STATE(PAUSED_FOR_USER); do { switch (_fan) @@ -4840,7 +4849,7 @@ static bool lcd_selftest_fan_dialog(int _fan) delay(100); } while (!lcd_clicked()); - + KEEPALIVE_STATE(IN_HANDLER); SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN); WRITE(EXTRUDER_0_AUTO_FAN_PIN, 0); SET_OUTPUT(FAN_PIN); From faeafa1100d86e03df02fd12e8cb6b58cb2074e2 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Mon, 28 Aug 2017 14:52:15 +0200 Subject: [PATCH 4/6] host keep alive multi material messages, load filament for multi material --- Firmware/Marlin_main.cpp | 9 ++++++++- Firmware/ultralcd.cpp | 15 ++++++++------- Firmware/ultralcd.h | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 405ff3b6d..d9115b6f8 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3332,6 +3332,7 @@ void process_commands() current_position[E_AXIS] += DEFAULT_RETRACTION; plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 400, active_extruder); } + KEEPALIVE_STATE(NOT_BUSY); // Restore custom message state custom_message = custom_message_old; custom_message_type = custom_message_type_old; @@ -5381,11 +5382,13 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp WRITE(BEEPER, LOW); #ifdef SNMM display_loading(); + KEEPALIVE_STATE(PAUSED_FOR_USER); do { target[E_AXIS] += 0.002; plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], 500, active_extruder); delay_keep_alive(2); - } while (!lcd_clicked()); + } while (!lcd_clicked()); + KEEPALIVE_STATE(IN_HANDLER); /*if (millis() - load_filament_time > 2) { load_filament_time = millis(); target[E_AXIS] += 0.001; @@ -5600,6 +5603,9 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp break; case 701: //M701: load filament { +#ifdef SNMM + extr_adj(snmm_extruder);//loads current extruder +#else enable_z(); custom_message = true; custom_message_type = 2; @@ -5631,6 +5637,7 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp loading_flag = false; custom_message = false; custom_message_type = 0; +#endif } break; case 702: diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 5e1ffa589..1b240c90f 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -3009,7 +3009,7 @@ static char snmm_stop_print_menu() { //menu for choosing which filaments will be lcd_print_at_PGM(1,3,MSG_CURRENT); char cursor_pos = 1; int enc_dif = 0; - + KEEPALIVE_STATE(PAUSED_FOR_USER); while (1) { manage_heater(); manage_inactivity(true); @@ -3037,10 +3037,10 @@ static char snmm_stop_print_menu() { //menu for choosing which filaments will be while (lcd_clicked()); delay(10); while (lcd_clicked()); + KEEPALIVE_STATE(IN_HANDLER); return(cursor_pos - 1); } - } - + } } char choose_extruder_menu() { @@ -3059,7 +3059,7 @@ char choose_extruder_menu() { for (int i = 0; i < 3; i++) { lcd_print_at_PGM(1, i + 1, MSG_EXTRUDER); } - + KEEPALIVE_STATE(PAUSED_FOR_USER); while (1) { for (int i = 0; i < 3; i++) { @@ -3123,6 +3123,7 @@ char choose_extruder_menu() { while (lcd_clicked()); delay(10); while (lcd_clicked()); + KEEPALIVE_STATE(IN_HANDLER); return(cursor_pos + first - 1); } @@ -3317,7 +3318,7 @@ void display_loading() { } } -static void extr_adj(int extruder) //loading filament for SNMM +void extr_adj(int extruder) //loading filament for SNMM { bool correct; max_feedrate[E_AXIS] =80; @@ -3331,13 +3332,13 @@ static void extr_adj(int extruder) //loading filament for SNMM case 3: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T3); break; default: lcd_display_message_fullscreen_P(MSG_FILAMENT_LOADING_T0); break; } - + KEEPALIVE_STATE(PAUSED_FOR_USER); do{ extr_mov(0.001,1000); delay_keep_alive(2); } while (!lcd_clicked()); //delay_keep_alive(500); - + KEEPALIVE_STATE(IN_HANDLER); st_synchronize(); //correct = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_FIL_LOADED_CHECK, false); //if (!correct) goto START; diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 99b3c4485..a89c370fb 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -211,7 +211,7 @@ extern void lcd_implementation_print_at(uint8_t x, uint8_t y, const char *str); void change_extr(int extr); static void lcd_colorprint_change(); static int get_ext_nr(); -static void extr_adj(int extruder); +void extr_adj(int extruder); static void extr_adj_0(); static void extr_adj_1(); static void extr_adj_2(); From 71b313cf269d744fb2e83551dd44a2f5fa52de9e Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Wed, 30 Aug 2017 16:18:43 +0200 Subject: [PATCH 5/6] timer reset after processing current command --- Firmware/Marlin_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index d9115b6f8..a76d5b54e 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1418,6 +1418,7 @@ void loop() if (! cmdbuffer_front_already_processed) cmdqueue_pop_front(); cmdbuffer_front_already_processed = false; + host_keepalive(); } } //check heater every n milliseconds From 0f4e08d51df4d45744bb82f45f0ff8f34de92e8d Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Wed, 30 Aug 2017 17:19:34 +0200 Subject: [PATCH 6/6] M113 updated --- Firmware/Marlin_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index a76d5b54e..1b0d04eb6 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4516,6 +4516,7 @@ Sigma_Exit: SERIAL_ECHOPAIR("M113 S", (unsigned long)host_keepalive_interval); SERIAL_PROTOCOLLN(""); } + break; #endif case 115: // M115 if (code_seen('V')) {