diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 1ea4091d0..8e248e563 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -5,7 +5,7 @@ #include "Configuration_prusa.h" // Firmware version -#define FW_version "3.0.12-3" +#define FW_version "3.0.12-7" #define FW_PRUSA3D_MAGIC "PRUSA3DFW" #define FW_PRUSA3D_MAGIC_LEN 10 @@ -463,7 +463,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/Configuration_adv.h b/Firmware/Configuration_adv.h index 9112c2a50..4f3a71c49 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. @@ -323,7 +323,7 @@ * K=0 means advance disabled. * See Marlin documentation for calibration instructions. */ -//#define LIN_ADVANCE +#define LIN_ADVANCE #ifdef LIN_ADVANCE #define LIN_ADVANCE_K 0 //Try around 45 for PLA, around 25 for ABS. diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index deda0421d..9fb70eed7 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -109,6 +109,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(); @@ -281,6 +283,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]; @@ -316,8 +322,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; @@ -350,10 +354,31 @@ 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(); void proc_commands(); -bool check_commands(); \ No newline at end of file +bool check_commands(); + +#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 \ No newline at end of file diff --git a/Firmware/MarlinSerial.cpp b/Firmware/MarlinSerial.cpp index c07ec458a..8baab6dd3 100644 --- a/Firmware/MarlinSerial.cpp +++ b/Firmware/MarlinSerial.cpp @@ -64,7 +64,7 @@ FORCE_INLINE void store_char(unsigned char c) store_char(c); } } - +#ifndef SNMM SIGNAL(USART2_RX_vect) { if (selectedSerialPort == 1) { @@ -82,6 +82,7 @@ FORCE_INLINE void store_char(unsigned char c) } } #endif +#endif // Constructors //////////////////////////////////////////////////////////////// @@ -122,7 +123,7 @@ void MarlinSerial::begin(long baud) sbi(M_UCSRxB, M_TXENx); sbi(M_UCSRxB, M_RXCIEx); - +#ifndef SNMM // set up the second serial port if (useU2X) { UCSR2A = 1 << U2X2; @@ -139,6 +140,7 @@ void MarlinSerial::begin(long baud) sbi(UCSR2B, RXEN2); sbi(UCSR2B, TXEN2); sbi(UCSR2B, RXCIE2); +#endif } void MarlinSerial::end() @@ -146,10 +148,12 @@ void MarlinSerial::end() cbi(M_UCSRxB, M_RXENx); cbi(M_UCSRxB, M_TXENx); cbi(M_UCSRxB, M_RXCIEx); - + +#ifndef SNMM cbi(UCSR2B, RXEN2); cbi(UCSR2B, TXEN2); - cbi(UCSR2B, RXCIE2); + cbi(UCSR2B, RXCIE2); +#endif } diff --git a/Firmware/MarlinSerial.h b/Firmware/MarlinSerial.h index 30f5b83db..f7d333a19 100644 --- a/Firmware/MarlinSerial.h +++ b/Firmware/MarlinSerial.h @@ -101,18 +101,56 @@ class MarlinSerial //: public Stream { return (unsigned int)(RX_BUFFER_SIZE + rx_buffer.head - rx_buffer.tail) % RX_BUFFER_SIZE; } - - FORCE_INLINE void write(uint8_t c) - { - while (!((M_UCSRxA) & (1 << M_UDREx))) - ; - M_UDRx = c; - } + void write(uint8_t c) + { +#ifdef SNMM // don't do the second serial port when multimaterialing + while (!((M_UCSRxA) & (1 << M_UDREx))) + ; + + M_UDRx = c; +#else + if (selectedSerialPort == 0) { + while (!((M_UCSRxA) & (1 << M_UDREx))) + ; + + M_UDRx = c; + } + else if (selectedSerialPort == 1) { + while (!((UCSR2A) & (1 << UDRE2))) + ; + + UDR2 = c; + } +#endif + } void checkRx(void) { + +#ifdef SNMM + if((M_UCSRxA & (1< 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 @@ -372,6 +373,16 @@ int fanSpeed=0; bool cancel_heatup = false ; +#ifdef HOST_KEEPALIVE_FEATURE + + MarlinBusyState busy_state = NOT_BUSY; + static long prev_busy_signal_ms = -1; + uint8_t host_keepalive_interval = HOST_KEEPALIVE_INTERVAL; +#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 @@ -761,10 +772,12 @@ void enquecommand(const char *cmd, bool from_progmem) strcpy_P(cmdbuffer + bufindw + 1, cmd); else strcpy(cmdbuffer + bufindw + 1, cmd); - SERIAL_ECHO_START; - SERIAL_ECHORPGM(MSG_Enqueing); - SERIAL_ECHO(cmdbuffer + bufindw + 1); - SERIAL_ECHOLNPGM("\""); + if (!farm_mode) { + SERIAL_ECHO_START; + SERIAL_ECHORPGM(MSG_Enqueing); + SERIAL_ECHO(cmdbuffer + bufindw + 1); + SERIAL_ECHOLNPGM("\""); + } bufindw += len + 2; if (bufindw == sizeof(cmdbuffer)) bufindw = 0; @@ -797,10 +810,12 @@ void enquecommand_front(const char *cmd, bool from_progmem) else strcpy(cmdbuffer + bufindr + 1, cmd); ++ buflen; - SERIAL_ECHO_START; - SERIAL_ECHOPGM("Enqueing to the front: \""); - SERIAL_ECHO(cmdbuffer + bufindr + 1); - SERIAL_ECHOLNPGM("\""); + if (!farm_mode) { + SERIAL_ECHO_START; + SERIAL_ECHOPGM("Enqueing to the front: \""); + SERIAL_ECHO(cmdbuffer + bufindr + 1); + SERIAL_ECHOLNPGM("\""); + } #ifdef CMDBUFFER_DEBUG cmdqueue_dump_to_serial(); #endif /* CMDBUFFER_DEBUG */ @@ -948,7 +963,7 @@ void factory_reset(char level, bool quiet) // Force the "Follow calibration flow" message at the next boot up. calibration_status_store(CALIBRATION_STATUS_Z_CALIBRATION); farm_no = 0; - farm_mode == false; + farm_mode = false; eeprom_update_byte((uint8_t*)EEPROM_FARM_MODE, farm_mode); EEPROM_save_B(EEPROM_FARM_NUMBER, &farm_no); @@ -1011,7 +1026,7 @@ void setup() setup_powerhold(); farm_mode = eeprom_read_byte((uint8_t*)EEPROM_FARM_MODE); EEPROM_read_B(EEPROM_FARM_NUMBER, &farm_no); - //if ((farm_mode == 0xFF && farm_no == 0) || (farm_no == 0xFFFF)) farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode + if ((farm_mode == 0xFF && farm_no == 0) || (farm_no == 0xFFFF)) farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode if (farm_no == 0xFFFF) farm_no = 0; if (farm_mode) { @@ -1026,6 +1041,7 @@ void setup() SERIAL_PROTOCOLLNPGM("start"); SERIAL_ECHO_START; + #if 0 SERIAL_ECHOLN("Reading eeprom from 0 to 100: start"); for (int i = 0; i < 4096; ++i) { @@ -1086,6 +1102,7 @@ void setup() world2machine_reset(); lcd_init(); + KEEPALIVE_STATE(PAUSED_FOR_USER); if (!READ(BTN_ENC)) { _delay_ms(1000); @@ -1107,7 +1124,7 @@ void setup() _delay_ms(2000); - + char level = reset_menu(); factory_reset(level, false); @@ -1168,17 +1185,7 @@ void setup() #if defined(Z_AXIS_ALWAYS_ON) enable_z(); #endif - farm_mode = eeprom_read_byte((uint8_t*)EEPROM_FARM_MODE); - EEPROM_read_B(EEPROM_FARM_NUMBER, &farm_no); - if ((farm_mode == 0xFF && farm_no == 0) || (farm_no == 0xFFFF)) farm_mode = false; //if farm_mode has not been stored to eeprom yet and farm number is set to zero or EEPROM is fresh, deactivate farm mode - if (farm_no == 0xFFFF) farm_no = 0; - if (farm_mode) - { - prusa_statistics(8); - no_response = true; //we need confirmation by recieving PRUSA thx - important_status = 8; - } - + // Enable Toshiba FlashAir SD card / WiFi enahanced card. card.ToshibaFlashAir_enable(eeprom_read_byte((unsigned char*)EEPROM_TOSHIBA_FLASH_AIR_COMPATIBLITY) == 1); // Force SD card update. Otherwise the SD card update is done from loop() on card.checkautostart(false), @@ -1255,6 +1262,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(); @@ -1331,6 +1339,36 @@ 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() { + if (farm_mode) return; + 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) { + 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; + } + } + prev_busy_signal_ms = ms; +} +#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() @@ -1386,6 +1424,7 @@ void loop() if (! cmdbuffer_front_already_processed) cmdqueue_pop_front(); cmdbuffer_front_already_processed = false; + host_keepalive(); } } //check heater every n milliseconds @@ -2118,6 +2157,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) @@ -2451,7 +2492,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 @@ -2484,8 +2525,7 @@ void process_commands() #endif //FWRETRACT case 28: //G28 Home all Axis one at a time homing_flag = true; - -#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 @@ -2932,6 +2972,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; @@ -3332,6 +3373,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; @@ -3476,7 +3518,9 @@ void process_commands() case 98: //activate farm mode farm_mode = 1; PingTime = millis(); + EEPROM_save_B(EEPROM_FARM_NUMBER, &farm_no); eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode); + break; case 99: //deactivate farm mode @@ -3529,29 +3573,33 @@ 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(); 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); @@ -3739,7 +3787,6 @@ void process_commands() { // Only Z calibration? bool onlyZ = code_seen('Z'); - if (!onlyZ) { setTargetBed(0); setTargetHotend(0, 0); @@ -3762,7 +3809,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(); @@ -3842,6 +3891,7 @@ void process_commands() } } else { // Timeouted. + KEEPALIVE_STATE(IN_HANDLER); } lcd_update_enable(true); break; @@ -3872,8 +3922,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. @@ -4256,6 +4308,7 @@ Sigma_Exit: }} #endif SERIAL_PROTOCOLLN(""); + KEEPALIVE_STATE(NOT_BUSY); return; break; case 109: @@ -4293,11 +4346,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); }; @@ -4325,6 +4381,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. @@ -4347,6 +4404,7 @@ Sigma_Exit: lcd_update(); } LCD_MESSAGERPGM(MSG_BED_DONE); + KEEPALIVE_STATE(IN_HANDLER); heating_status = 4; previous_millis_cmd = millis(); @@ -4490,6 +4548,18 @@ 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(""); + } + break; +#endif case 115: // M115 if (code_seen('V')) { // Report the Prusa version number. @@ -5037,7 +5107,8 @@ Sigma_Exit: temp=70; if (code_seen('S')) temp=code_value(); if (code_seen('C')) c=code_value(); - PID_autotune(temp, e, c); + + PID_autotune(temp, e, c); } break; case 400: // M400 finish all moves @@ -5314,6 +5385,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++; @@ -5350,14 +5422,17 @@ 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(); + 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; @@ -5397,7 +5472,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 @@ -5570,6 +5647,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; @@ -5601,6 +5681,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: @@ -5809,6 +5890,8 @@ case 404: //M404 Enter the nominal filament width (3mm, 1.75mm ) N<3.0> or disp SERIAL_ECHOLNPGM("\""); } + KEEPALIVE_STATE(NOT_BUSY); + ClearToSend(); } @@ -6052,7 +6135,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(); } @@ -6328,7 +6411,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/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 91b7bbb59..7d53e8bb4 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -105,7 +105,7 @@ int lcd_commands_step=0; bool isPrintPaused = false; uint8_t farm_mode = 0; int farm_no = 0; -int farm_timer = 30; +int farm_timer = 8; int farm_status = 0; unsigned long allert_timer = millis(); bool printer_connected = true; @@ -408,15 +408,15 @@ static void lcd_status_screen() farm_timer--; if (farm_timer < 1) { - farm_timer = 180; + farm_timer = 10; prusa_statistics(0); } switch (farm_timer) { - case 45: + case 8: prusa_statistics(21); break; - case 10: + case 5: if (IS_SD_PRINTING) { prusa_statistics(20); @@ -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; } } @@ -2158,7 +2166,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) { prusa_stat_printerstatus(status_number); prusa_stat_farm_number(); SERIAL_ECHOLN("}"); - farm_timer = 5; + farm_timer = 4; break; case 21: // temperatures SERIAL_ECHO("{"); @@ -2185,7 +2193,7 @@ void prusa_statistics(int _message, uint8_t _fil_nr) { SERIAL_ECHOLN("}"); break; case 92: // Error - Min temp - SERIAL_ECHOLN("{[ERR:3]"); + SERIAL_ECHO("{[ERR:3]"); prusa_stat_farm_number(); SERIAL_ECHOLN("}"); break; @@ -3001,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); @@ -3029,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() { @@ -3051,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++) { @@ -3115,6 +3123,7 @@ char choose_extruder_menu() { while (lcd_clicked()); delay(10); while (lcd_clicked()); + KEEPALIVE_STATE(IN_HANDLER); return(cursor_pos + first - 1); } @@ -3304,7 +3313,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; @@ -3318,13 +3327,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; @@ -3640,8 +3649,8 @@ unsigned char lcd_choose_color() { //----------------------------------------------------- unsigned char items_no = 2; const char *item[items_no]; - item[0] = "Black"; - item[1] = "Orange"; + item[0] = "Orange"; + item[1] = "Black"; //----------------------------------------------------- unsigned char active_rows; static int first = 0; @@ -3663,10 +3672,9 @@ unsigned char lcd_choose_color() { manage_heater(); manage_inactivity(true); - - if (abs((enc_dif - encoderDiff)) > 4) { - - if ((abs(enc_dif - encoderDiff)) > 1) { + proc_commands(); + if (abs((enc_dif - encoderDiff)) > 12) { + if (enc_dif > encoderDiff) { cursor_pos--; } @@ -3674,7 +3682,7 @@ unsigned char lcd_choose_color() { if (enc_dif < encoderDiff) { cursor_pos++; } - + if (cursor_pos > active_rows) { cursor_pos = active_rows; if (first < items_no - active_rows) { @@ -3700,7 +3708,6 @@ unsigned char lcd_choose_color() { lcd.print(">"); enc_dif = encoderDiff; delay(100); - } } @@ -3708,7 +3715,11 @@ unsigned char lcd_choose_color() { while (lcd_clicked()); delay(10); while (lcd_clicked()); - return(cursor_pos + first - 1); + switch(cursor_pos + first - 1) { + case 0: return 1; break; + case 1: return 0; break; + default: return 99; break; + } } } @@ -3723,7 +3734,7 @@ void lcd_confirm_print() int _ret = 0; int _t = 0; - + enc_dif = encoderDiff; lcd_implementation_clear(); lcd.setCursor(0, 0); @@ -3731,8 +3742,7 @@ void lcd_confirm_print() do { - - if (abs((enc_dif - encoderDiff)) > 2) { + if (abs(enc_dif - encoderDiff) > 12) { if (enc_dif > encoderDiff) { cursor_pos--; } @@ -3740,6 +3750,7 @@ void lcd_confirm_print() if (enc_dif < encoderDiff) { cursor_pos++; } + enc_dif = encoderDiff; } if (cursor_pos > 2) { cursor_pos = 2; } @@ -3784,9 +3795,10 @@ void lcd_confirm_print() NcTime = millis(); } } - + manage_heater(); manage_inactivity(); + proc_commands(); } while (_ret == 0); @@ -4186,7 +4198,8 @@ void lcd_sdcard_menu() { if (_menuItemNr == _lineNr) { - const uint16_t nr = (sdSort == SD_SORT_NONE) ? (fileCnt - 1 - i) : i; + const uint16_t nr = ((sdSort == SD_SORT_NONE) || farm_mode) ? (fileCnt - 1 - i) : i; + /* #ifdef SDCARD_RATHERRECENTFIRST #ifndef SDCARD_SORT_ALPHA fileCnt - 1 - @@ -4805,6 +4818,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) @@ -4845,7 +4859,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); diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index c0c8d67f0..216752f98 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(); diff --git a/Firmware/ultralcd_implementation_hitachi_HD44780.h b/Firmware/ultralcd_implementation_hitachi_HD44780.h index c421140f7..ec360c626 100644 --- a/Firmware/ultralcd_implementation_hitachi_HD44780.h +++ b/Firmware/ultralcd_implementation_hitachi_HD44780.h @@ -830,21 +830,20 @@ static void lcd_implementation_status_screen() // If heating in progress, set flag if (heating_status != 0) { custom_message = true; } + if (IS_SD_PRINTING) { + if (strcmp(longFilenameOLD, card.longFilename) != 0) + { + memset(longFilenameOLD, '\0', strlen(longFilenameOLD)); + sprintf_P(longFilenameOLD, PSTR("%s"), card.longFilename); + scrollstuff = 0; + } + } + // If printing from SD, show what we are printing - if (IS_SD_PRINTING) + if (IS_SD_PRINTING && !custom_message) { - - if(strcmp(longFilenameOLD, card.longFilename) != 0) - { - memset(longFilenameOLD,'\0',strlen(longFilenameOLD)); - sprintf_P(longFilenameOLD, PSTR("%s"), card.longFilename); - scrollstuff = 0; - } - if (!custom_message) { - if (strlen(card.longFilename) > LCD_WIDTH) { - int inters = 0; int gh = scrollstuff; while (((gh - scrollstuff) < LCD_WIDTH) && (inters == 0)) @@ -873,9 +872,6 @@ static void lcd_implementation_status_screen() { lcd.print(longFilenameOLD); } - } - - } // If not, check for other special events else