diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 1bfab998..b654e97e 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -5,7 +5,7 @@ #include "Configuration_prusa.h" // Firmware version -#define FW_version "3.0.7" +#define FW_version "3.0.8" #define FW_PRUSA3D_MAGIC "PRUSA3DFW" #define FW_PRUSA3D_MAGIC_LEN 10 diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 27a4a8d6..4d9993ae 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1021,6 +1021,9 @@ void setup() // 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), + // but this times out if a blocking dialog is shown in setup(). + card.initsd(); if (eeprom_read_dword((uint32_t*)(EEPROM_TOP-4)) == 0x0ffffffff && eeprom_read_dword((uint32_t*)(EEPROM_TOP-8)) == 0x0ffffffff && @@ -1038,22 +1041,15 @@ void setup() // is being written into the EEPROM, so the update procedure will be triggered only once. lang_selected = eeprom_read_byte((uint8_t*)EEPROM_LANG); if (lang_selected >= LANG_NUM){ - lcd_mylang(); + lcd_mylang(); } if (eeprom_read_byte((uint8_t*)EEPROM_BABYSTEP_Z_SET) == 0x0ff) { // Reset the babystepping values, so the printer will not move the Z axis up when the babystepping is enabled. - // eeprom_update_byte((uint8_t*)EEPROM_BABYSTEP_X, 0x0ff); - // eeprom_update_byte((uint8_t*)EEPROM_BABYSTEP_Y, 0x0ff); - eeprom_update_byte((uint8_t*)EEPROM_BABYSTEP_Z, 0x0ff); - // Get the selected laugnage index before display update. - lang_selected = eeprom_read_byte((uint8_t*)EEPROM_LANG); - if (lang_selected >= LANG_NUM) - lang_selected = LANG_ID_DEFAULT; // Czech language + eeprom_update_word((uint16_t*)EEPROM_BABYSTEP_Z, 0); // Show the message. lcd_show_fullscreen_message_and_wait_P(MSG_BABYSTEP_Z_NOT_SET); lcd_update_enable(true); - lcd_implementation_clear(); } // Store the currently running firmware into an eeprom, @@ -2961,6 +2957,9 @@ void process_commands() bool result = sample_mesh_and_store_reference(); // if (result) babystep_apply(); } else { + // Reset the baby step value and the baby step applied flag. + eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0xFF); + eeprom_update_word((uint16_t*)EEPROM_BABYSTEP_Z, 0); // Complete XYZ calibration. BedSkewOffsetDetectionResultType result = find_bed_offset_and_skew(verbosity_level); uint8_t point_too_far_mask = 0; @@ -2991,9 +2990,6 @@ void process_commands() // Timeouted. } lcd_update_enable(true); - lcd_implementation_clear(); - // lcd_return_to_status(); - lcd_update(); break; } @@ -3057,9 +3053,6 @@ void process_commands() plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS],current_position[Z_AXIS] , current_position[E_AXIS], homing_feedrate[Z_AXIS]/40, active_extruder); st_synchronize(); lcd_update_enable(true); - lcd_implementation_clear(); - // lcd_return_to_status(); - lcd_update(); break; } #endif @@ -4824,11 +4817,7 @@ void prepare_move() // Do not use feedmultiply for E or Z only moves if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) { -#ifdef MESH_BED_LEVELING - mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); -#else plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder); -#endif } else { #ifdef MESH_BED_LEVELING diff --git a/Firmware/language_all.cpp b/Firmware/language_all.cpp index 630339e5..6ef3d194 100644 --- a/Firmware/language_all.cpp +++ b/Firmware/language_all.cpp @@ -87,11 +87,11 @@ const char * const MSG_BABYSTEP_Z_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_BABYSTEP_Z_PL }; -const char MSG_BABYSTEP_Z_NOT_SET_EN[] PROGMEM = "Printer has not been calibrated yet. Run calibration G-code to adjust Z height."; -const char MSG_BABYSTEP_Z_NOT_SET_CZ[] PROGMEM = "Tiskarna nebyla jeste zkalibrovana. Spustte kalibracni G-kod a doladte Z."; -const char MSG_BABYSTEP_Z_NOT_SET_IT[] PROGMEM = "Stampante non ancora calibrata. Eseguire il G-code di calibrazione per regolare l'altezza Z."; -const char MSG_BABYSTEP_Z_NOT_SET_ES[] PROGMEM = "Impresora aun no calibrada. Ejecutar el G-code de calibracion para ajustar la altura de Z."; -const char MSG_BABYSTEP_Z_NOT_SET_PL[] PROGMEM = "Drukarka nie byla kalibrowana. Wlaczyc kalibracyjny G-kod i dostroic Z."; +const char MSG_BABYSTEP_Z_NOT_SET_EN[] PROGMEM = "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."; +const char MSG_BABYSTEP_Z_NOT_SET_CZ[] PROGMEM = "Tiskarna nebyla jeste zkalibrovana. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Postup kalibrace."; +const char MSG_BABYSTEP_Z_NOT_SET_IT[] PROGMEM = "Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione."; +const char MSG_BABYSTEP_Z_NOT_SET_ES[] PROGMEM = "Impresora no esta calibrada todavia. Por favor usar el manual, el capitulo First steps, seleccion Calibration flow."; +const char MSG_BABYSTEP_Z_NOT_SET_PL[] PROGMEM = "Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest."; const char * const MSG_BABYSTEP_Z_NOT_SET_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_BABYSTEP_Z_NOT_SET_EN, MSG_BABYSTEP_Z_NOT_SET_CZ, @@ -652,7 +652,7 @@ const char * const MSG_FACTOR_LANG_TABLE[1] PROGMEM = { const char MSG_FAN_SPEED_EN[] PROGMEM = "Fan speed"; const char MSG_FAN_SPEED_CZ[] PROGMEM = "Rychlost vent."; -const char MSG_FAN_SPEED_IT[] PROGMEM = "Velocità ventola"; +const char MSG_FAN_SPEED_IT[] PROGMEM = "Velocita ventola"; const char MSG_FAN_SPEED_ES[] PROGMEM = "Ventilador"; const char MSG_FAN_SPEED_PL[] PROGMEM = "Predkosc went."; const char * const MSG_FAN_SPEED_LANG_TABLE[LANG_NUM] PROGMEM = { @@ -686,11 +686,11 @@ const char * const MSG_FILE_SAVED_LANG_TABLE[1] PROGMEM = { MSG_FILE_SAVED_EN }; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_EN[] PROGMEM = "Searching bed"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_CZ[] PROGMEM = "Hledam kalibracni"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_IT[] PROGMEM = "Ricerca del letto"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_ES[] PROGMEM = "Buscando cama"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_PL[] PROGMEM = "Szukam kalibracyj."; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_EN[] PROGMEM = "Searching bed calibration point"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_CZ[] PROGMEM = "Hledam kalibracni bod podlozky"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_IT[] PROGMEM = "Ricerca del letto punto di calibraz."; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_ES[] PROGMEM = "Buscando cama punto de calibracion"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_PL[] PROGMEM = "Szukam punktu kalibracyjnego podkladki"; const char * const MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_EN, MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_CZ, @@ -699,11 +699,11 @@ const char * const MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE[LANG_NUM] PROGM MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_PL }; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_EN[] PROGMEM = "calibration point"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_CZ[] PROGMEM = "bod podlozky"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_IT[] PROGMEM = "punto di calibraz."; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_ES[] PROGMEM = "punto de calibracion"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_PL[] PROGMEM = "punktu podkladki"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_EN[] PROGMEM = " of 4"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_CZ[] PROGMEM = " z 4"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_IT[] PROGMEM = " su 4"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_ES[] PROGMEM = " de 4"; +const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_PL[] PROGMEM = " z 4"; const char * const MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_EN, MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_CZ, @@ -712,19 +712,6 @@ const char * const MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE[LANG_NUM] PROGM MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_PL }; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_EN[] PROGMEM = " of 4"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_CZ[] PROGMEM = " z 4"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_IT[] PROGMEM = " su 4"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_ES[] PROGMEM = " de 4"; -const char MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_PL[] PROGMEM = " z 4"; -const char * const MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_LANG_TABLE[LANG_NUM] PROGMEM = { - MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_EN, - MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_CZ, - MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_IT, - MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_ES, - MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_PL -}; - const char MSG_FLOW_EN[] PROGMEM = "Flow"; const char MSG_FLOW_CZ[] PROGMEM = "Prutok"; const char MSG_FLOW_IT[] PROGMEM = "Flusso"; @@ -828,11 +815,11 @@ const char * const MSG_HOTEND_OFFSET_LANG_TABLE[1] PROGMEM = { MSG_HOTEND_OFFSET_EN }; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_EN[] PROGMEM = "Improving bed"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_CZ[] PROGMEM = "Zlepsuji presnost"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_IT[] PROGMEM = "Perfezion. il letto"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_ES[] PROGMEM = "Mejorando cama"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_PL[] PROGMEM = "Ulepszam dokladnosc"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_EN[] PROGMEM = "Improving bed calibration point"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_CZ[] PROGMEM = "Zlepsuji presnost kalibracniho bodu"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_IT[] PROGMEM = "Perfezion. il letto punto di calibraz."; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_ES[] PROGMEM = "Mejorando cama punto de calibracion"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_PL[] PROGMEM = "Poprawiam precyzyjnosc punktu kalibracyjnego"; const char * const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_EN, MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_CZ, @@ -841,11 +828,11 @@ const char * const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE[LANG_NUM] PR MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_PL }; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_EN[] PROGMEM = "calibration point"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_CZ[] PROGMEM = "kalibracniho bodu"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_IT[] PROGMEM = "punto di calibraz."; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_ES[] PROGMEM = "punto de calibracion"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_PL[] PROGMEM = "punktu kalibracyj."; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_EN[] PROGMEM = " of 9"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_CZ[] PROGMEM = " z 9"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_IT[] PROGMEM = " su 9"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_ES[] PROGMEM = " de 9"; +const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_PL[] PROGMEM = " z 9"; const char * const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_EN, MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_CZ, @@ -854,19 +841,6 @@ const char * const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE[LANG_NUM] PR MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_PL }; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_EN[] PROGMEM = " of 9"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_CZ[] PROGMEM = " z 9"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_IT[] PROGMEM = " su 9"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_ES[] PROGMEM = " de 9"; -const char MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_PL[] PROGMEM = " z 9"; -const char * const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_LANG_TABLE[LANG_NUM] PROGMEM = { - MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_EN, - MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_CZ, - MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_IT, - MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_ES, - MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_PL -}; - const char MSG_INIT_SDCARD_EN[] PROGMEM = "Init. SD card"; const char * const MSG_INIT_SDCARD_LANG_TABLE[1] PROGMEM = { MSG_INIT_SDCARD_EN @@ -1029,6 +1003,32 @@ const char * const MSG_MAX_LANG_TABLE[1] PROGMEM = { MSG_MAX_EN }; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_EN[] PROGMEM = "Measuring reference height of calibration point"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_CZ[] PROGMEM = "Merim referencni vysku kalibracniho bodu"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_IT[] PROGMEM = "Misurare l'altezza di riferimento del punto di calibrazione"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_ES[] PROGMEM = "Medir la altura del punto de la calibracion"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_PL[] PROGMEM = "Okreslam wysokosc odniesienia punktu kalibracyjnego"; +const char * const MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_EN, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_CZ, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_IT, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_ES, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_PL +}; + +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_EN[] PROGMEM = " of 9"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_CZ[] PROGMEM = " z 9"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_IT[] PROGMEM = " su 9"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_ES[] PROGMEM = " de 9"; +const char MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_PL[] PROGMEM = " z 9"; +const char * const MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_LANG_TABLE[LANG_NUM] PROGMEM = { + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_EN, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_CZ, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_IT, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_ES, + MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_PL +}; + const char MSG_MENU_CALIBRATION_EN[] PROGMEM = "Calibration"; const char MSG_MENU_CALIBRATION_CZ[] PROGMEM = "Kalibrace"; const char MSG_MENU_CALIBRATION_IT[] PROGMEM = "Calibrazione"; @@ -1090,11 +1090,11 @@ const char * const MSG_MOVE_AXIS_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_MOVE_AXIS_PL }; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_EN[] PROGMEM = "Calibrating XYZ. Move Z carriage up to the end stoppers. Click when done."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_CZ[] PROGMEM = "Kalibrace XYZ. Posunte prosim Z osu az k~hornimu dorazu. Potvrdte tlacitkem."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_IT[] PROGMEM = "Calibrando XYZ. Muovere Z fino altezza max, poi fare clik."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_ES[] PROGMEM = "Calibrando XYZ. Subir carro Z hasta maximo. Click cuando acabes."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_PL[] PROGMEM = "Kalibracja XYZ. Prosze przesunac os Z do gornej ramy. Potw. guzikiem."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_EN[] PROGMEM = "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_CZ[] PROGMEM = "Kalibrace XYZ. Otacenim tlacitka posunte Z osu az k~hornimu dorazu. Potvrdte tlacitkem."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_IT[] PROGMEM = "Calibrazione XYZ. Ruotare la manopola per alzare il carrello Z fino all'altezza massima. Click per terminare."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_ES[] PROGMEM = "Calibrando XYZ. Gira el boton para subir el carro Z hasta golpe piezas superioras. Despues haz clic."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_PL[] PROGMEM = "Kalibracja XYZ. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic."; const char * const MSG_MOVE_CARRIAGE_TO_THE_TOP_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_MOVE_CARRIAGE_TO_THE_TOP_EN, MSG_MOVE_CARRIAGE_TO_THE_TOP_CZ, @@ -1103,11 +1103,11 @@ const char * const MSG_MOVE_CARRIAGE_TO_THE_TOP_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_MOVE_CARRIAGE_TO_THE_TOP_PL }; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_EN[] PROGMEM = "Calibrating Z. Move Z carriage up to the end stoppers. Click when done."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_CZ[] PROGMEM = "Kalibrace Z. Posunte prosim Z osu az k~hornimu dorazu. Potvrdte tlacitkem."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_IT[] PROGMEM = "Calibrando Z. Muovere Z fino altezza max, poi fare clik."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_ES[] PROGMEM = "Calibrando Z. Subir carro Z hasta maximo. Click cuando acabes."; -const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_PL[] PROGMEM = "Kalibracja Z. Prosze przesunac os Z do gornej ramy. Potw. guzikiem."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_EN[] PROGMEM = "Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_CZ[] PROGMEM = "Kalibrace Z. Otacenim tlacitka posunte Z osu az k~hornimu dorazu. Potvrdte tlacitkem."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_IT[] PROGMEM = "Calibrazione Z. Ruotare la manopola per alzare il carrello Z fino all'altezza massima. Click per terminare."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_ES[] PROGMEM = "Calibrando Z. Gira el boton para subir el carro Z hasta golpe piezas superioras. Despues haz clic."; +const char MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_PL[] PROGMEM = "Kalibracja Z. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic."; const char * const MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_EN, MSG_MOVE_CARRIAGE_TO_THE_TOP_Z_CZ, @@ -1830,7 +1830,7 @@ const char * const MSG_SELFTEST_START_LANG_TABLE[LANG_NUM] PROGMEM = { const char MSG_SELFTEST_WIRINGERROR_EN[] PROGMEM = "Wiring error"; const char MSG_SELFTEST_WIRINGERROR_CZ[] PROGMEM = "Chyba zapojeni"; const char MSG_SELFTEST_WIRINGERROR_IT[] PROGMEM = "Errore cablaggio"; -const char MSG_SELFTEST_WIRINGERROR_ES[] PROGMEM = "Error de conexión"; +const char MSG_SELFTEST_WIRINGERROR_ES[] PROGMEM = "Error de conexion"; const char MSG_SELFTEST_WIRINGERROR_PL[] PROGMEM = "Blad polaczenia"; const char * const MSG_SELFTEST_WIRINGERROR_LANG_TABLE[LANG_NUM] PROGMEM = { MSG_SELFTEST_WIRINGERROR_EN, @@ -1914,7 +1914,7 @@ const char * const MSG_SOFTWARE_RESET_LANG_TABLE[1] PROGMEM = { const char MSG_SPEED_EN[] PROGMEM = "Speed"; const char MSG_SPEED_CZ[] PROGMEM = "Rychlost"; -const char MSG_SPEED_IT[] PROGMEM = "Velocità"; +const char MSG_SPEED_IT[] PROGMEM = "Velocita"; const char MSG_SPEED_ES[] PROGMEM = "Velocidad"; const char MSG_SPEED_PL[] PROGMEM = "Predkosc"; const char * const MSG_SPEED_LANG_TABLE[LANG_NUM] PROGMEM = { diff --git a/Firmware/language_all.h b/Firmware/language_all.h index 1b13a92e..379c1521 100644 --- a/Firmware/language_all.h +++ b/Firmware/language_all.h @@ -176,8 +176,6 @@ extern const char* const MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE[LANG_NUM] #define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 LANG_TABLE_SELECT(MSG_FIND_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE) extern const char* const MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE[LANG_NUM]; #define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 LANG_TABLE_SELECT(MSG_FIND_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE) -extern const char* const MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_LANG_TABLE[LANG_NUM]; -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE3 LANG_TABLE_SELECT(MSG_FIND_BED_OFFSET_AND_SKEW_LINE3_LANG_TABLE) extern const char* const MSG_FLOW_LANG_TABLE[LANG_NUM]; #define MSG_FLOW LANG_TABLE_SELECT(MSG_FLOW_LANG_TABLE) extern const char* const MSG_FLOW0_LANG_TABLE[1]; @@ -204,8 +202,6 @@ extern const char* const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE[LANG_N #define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 LANG_TABLE_SELECT(MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1_LANG_TABLE) extern const char* const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE[LANG_NUM]; #define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 LANG_TABLE_SELECT(MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2_LANG_TABLE) -extern const char* const MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_LANG_TABLE[LANG_NUM]; -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3 LANG_TABLE_SELECT(MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3_LANG_TABLE) extern const char* const MSG_INIT_SDCARD_LANG_TABLE[1]; #define MSG_INIT_SDCARD LANG_TABLE_SELECT_EXPLICIT(MSG_INIT_SDCARD_LANG_TABLE, 0) extern const char* const MSG_INSERT_FILAMENT_LANG_TABLE[LANG_NUM]; @@ -248,6 +244,10 @@ extern const char* const MSG_MAIN_LANG_TABLE[LANG_NUM]; #define MSG_MAIN LANG_TABLE_SELECT(MSG_MAIN_LANG_TABLE) extern const char* const MSG_MAX_LANG_TABLE[1]; #define MSG_MAX LANG_TABLE_SELECT_EXPLICIT(MSG_MAX_LANG_TABLE, 0) +extern const char* const MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_LANG_TABLE[LANG_NUM]; +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 LANG_TABLE_SELECT(MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1_LANG_TABLE) +extern const char* const MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_LANG_TABLE[LANG_NUM]; +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 LANG_TABLE_SELECT(MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2_LANG_TABLE) extern const char* const MSG_MENU_CALIBRATION_LANG_TABLE[LANG_NUM]; #define MSG_MENU_CALIBRATION LANG_TABLE_SELECT(MSG_MENU_CALIBRATION_LANG_TABLE) extern const char* const MSG_MESH_BED_LEVELING_LANG_TABLE[LANG_NUM]; diff --git a/Firmware/language_cz.h b/Firmware/language_cz.h index 27f065dc..f7641a36 100644 --- a/Firmware/language_cz.h +++ b/Firmware/language_cz.h @@ -194,18 +194,18 @@ #define MSG_CALIBRATE_BED "Kalibrace XYZ" #define MSG_CALIBRATE_BED_RESET "Reset XYZ kalibr." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Kalibrace XYZ. Posunte prosim Z osu az k~hornimu dorazu. Potvrdte tlacitkem." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Kalibrace Z. Posunte prosim Z osu az k~hornimu dorazu. Potvrdte tlacitkem." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Kalibrace XYZ. Otacenim tlacitka posunte Z osu az k~hornimu dorazu. Potvrdte tlacitkem." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Kalibrace Z. Otacenim tlacitka posunte Z osu az k~hornimu dorazu. Potvrdte tlacitkem." #define MSG_CONFIRM_NOZZLE_CLEAN "Pro uspesnou kalibraci ocistete prosim tiskovou trysku. Potvrdte tlacitkem." #define MSG_CONFIRM_CARRIAGE_AT_THE_TOP "Dojely oba Z voziky k~hornimu dorazu?" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Hledam kalibracni" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 "bod podlozky" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE3 " z 4" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Zlepsuji presnost" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 "kalibracniho bodu" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3 " z 9" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Hledam kalibracni bod podlozky" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 " z 4" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Zlepsuji presnost kalibracniho bodu" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 " z 9" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 "Merim referencni vysku kalibracniho bodu" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 " z 9" #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND "Kalibrace XYZ selhala. Kalibracni bod podlozky nenalezen." #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED "Kalibrace XYZ selhala. Nahlednete do manualu." @@ -225,7 +225,7 @@ #define MSG_NEW_FIRMWARE_AVAILABLE "Vysla nova verze firmware:" #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Prosim aktualizujte." -#define MSG_BABYSTEP_Z_NOT_SET "Tiskarna nebyla jeste zkalibrovana. Spustte kalibracni G-kod a doladte Z." +#define MSG_BABYSTEP_Z_NOT_SET "Tiskarna nebyla jeste zkalibrovana. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Postup kalibrace." #define MSG_BED_CORRECTION_MENU "Korekce podlozky" #define MSG_BED_CORRECTION_LEFT "Vlevo [um]" diff --git a/Firmware/language_en.h b/Firmware/language_en.h index 09414b92..f3354eeb 100644 --- a/Firmware/language_en.h +++ b/Firmware/language_en.h @@ -188,18 +188,18 @@ #define MSG_CALIBRATE_BED "Calibrate XYZ" #define MSG_CALIBRATE_BED_RESET "Reset XYZ calibr." -#define(length=20,lines=4) MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrating XYZ. Move Z carriage up to the end stoppers. Click when done." -#define(length=20,lines=4) MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrating Z. Move Z carriage up to the end stoppers. Click when done." +#define(length=20,lines=8) MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrating XYZ. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." +#define(length=20,lines=8) MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrating Z. Rotate the knob to move the Z carriage up to the end stoppers. Click when done." #define(length=20,lines=8) MSG_CONFIRM_NOZZLE_CLEAN "Please clean the nozzle for calibration. Click when done." #define(length=20,lines=2) MSG_CONFIRM_CARRIAGE_AT_THE_TOP "Are left and right Z~carriages all up?" -#define(length=20) MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Searching bed" -#define(length=20) MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 "calibration point" -#define(length=14) MSG_FIND_BED_OFFSET_AND_SKEW_LINE3 " of 4" -#define(length=20) MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Improving bed" -#define(length=20) MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 "calibration point" -#define(length=14) MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3 " of 9" +#define(length=60) MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Searching bed calibration point" +#define(length=14) MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 " of 4" +#define(length=60) MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Improving bed calibration point" +#define(length=14) MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 " of 9" +#define(length=60) MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 "Measuring reference height of calibration point" +#define(length=14) MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 " of 9" #define(length=20,lines=8) MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND "XYZ calibration failed. Bed calibration point was not found." #define(length=20,lines=8) MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED "XYZ calibration failed. Please consult the manual." @@ -218,9 +218,9 @@ #define(length=20,lines=4) MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED "Bed leveling failed. Sensor disconnected or cable broken. Waiting for reset." #define(length=20,lines=2) MSG_NEW_FIRMWARE_AVAILABLE "New firmware version available:" -#define(length=20) MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Please upgrade." +#define(length=20) MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Please upgrade." -#define(length=20,lines=8) MSG_BABYSTEP_Z_NOT_SET "Printer has not been calibrated yet. Run calibration G-code to adjust Z height." +#define(length=20,lines=8) MSG_BABYSTEP_Z_NOT_SET "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow." #define MSG_BED_CORRECTION_MENU "Bed level correct" #define MSG_BED_CORRECTION_LEFT "Left side um" diff --git a/Firmware/language_es.h b/Firmware/language_es.h index 2f6b15d6..212e223d 100644 --- a/Firmware/language_es.h +++ b/Firmware/language_es.h @@ -159,7 +159,7 @@ #define MSG_SELFTEST_NOTCONNECTED "No hay conexion " #define MSG_SELFTEST_HEATERTHERMISTOR "Calent./Termistor" #define MSG_SELFTEST_BEDHEATER "Cama/Calentador" -#define MSG_SELFTEST_WIRINGERROR "Error de conexión" +#define MSG_SELFTEST_WIRINGERROR "Error de conexion" #define MSG_SELFTEST_ENDSTOPS "Topes final" #define MSG_SELFTEST_MOTOR "Motor" #define MSG_SELFTEST_ENDSTOP "Tope final" @@ -188,17 +188,18 @@ #define MSG_SHOW_END_STOPS "Ensena tope final" #define MSG_CALIBRATE_BED "Calibra XYZ" #define MSG_CALIBRATE_BED_RESET "Reset XYZ calibr." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrando XYZ. Subir carro Z hasta maximo. Click cuando acabes." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrando Z. Subir carro Z hasta maximo. Click cuando acabes." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrando XYZ. Gira el boton para subir el carro Z hasta golpe piezas superioras. Despues haz clic." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrando Z. Gira el boton para subir el carro Z hasta golpe piezas superioras. Despues haz clic." #define MSG_CONFIRM_NOZZLE_CLEAN "Limpiar boquilla para calibracion. Click cuando acabes." #define MSG_CONFIRM_CARRIAGE_AT_THE_TOP "Carros Z izq./der. estan arriba maximo?" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Buscando cama" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 "punto de calibracion" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE3 " de 4" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Mejorando cama" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 "punto de calibracion" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3 " de 9" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Buscando cama punto de calibracion" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 " de 4" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Mejorando cama punto de calibracion" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 " de 9" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 "Medir la altura del punto de la calibracion" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 " de 9" + #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND "Calibracion XYZ fallada. Puntos de calibracion en la cama no encontrados." #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED "Calibracion XYZ fallada. Consultar el manual por favor." #define MSG_BED_SKEW_OFFSET_DETECTION_PERFECT "Calibracion XYZ ok. Ejes X/Y perpendiculares." @@ -215,7 +216,7 @@ #define MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED "Nivelacion fallada. Sensor desconectado o cables danados. Esperando reset." #define MSG_NEW_FIRMWARE_AVAILABLE "Nuevo firmware disponible:" #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Actualizar por favor" -#define MSG_BABYSTEP_Z_NOT_SET "Impresora aun no calibrada. Ejecutar el G-code de calibracion para ajustar la altura de Z." +#define MSG_BABYSTEP_Z_NOT_SET "Impresora no esta calibrada todavia. Por favor usar el manual, el capitulo First steps, seleccion Calibration flow." #define MSG_BED_CORRECTION_MENU "Corr. de la cama" #define MSG_BED_CORRECTION_LEFT "Izquierda [um]" #define MSG_BED_CORRECTION_RIGHT "Derecha [um]" diff --git a/Firmware/language_it.h b/Firmware/language_it.h index 6fcb71db..050f0b9c 100644 --- a/Firmware/language_it.h +++ b/Firmware/language_it.h @@ -17,17 +17,17 @@ #define MSG_MOVE_01MM "Move 0.1mm" #define MSG_MOVE_1MM "Move 1mm" #define MSG_MOVE_10MM "Move 10mm" -#define MSG_SPEED "Velocità" +#define MSG_SPEED "Velocita" #define MSG_NOZZLE "Ugello" #define MSG_NOZZLE1 "Nozzle2" #define MSG_NOZZLE2 "Nozzle3" #define MSG_BED "Letto" -#define MSG_FAN_SPEED "Velocità ventola" +#define MSG_FAN_SPEED "Velocita ventola" #define MSG_FLOW "Flusso" #define MSG_TEMPERATURE "Temperatura" #define MSG_MOTION "Motion" #define MSG_VOLUMETRIC "Filament" -#define MSG_VOLUMETRIC_ENABLED "E in mm3" +#define MSG_VOLUMETRIC_ENABLED "E in mm3" #define MSG_STORE_EPROM "Store memory" #define MSG_LOAD_EPROM "Load memory" #define MSG_RESTORE_FAILSAFE "Restore failsafe" @@ -177,18 +177,18 @@ #define MSG_CALIBRATE_BED "Calibra XYZ" #define MSG_CALIBRATE_BED_RESET "Reset XYZ calibr." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrando XYZ. Muovere Z fino altezza max, poi fare clik." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrando Z. Muovere Z fino altezza max, poi fare clik." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Calibrazione XYZ. Ruotare la manopola per alzare il carrello Z fino all'altezza massima. Click per terminare." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Calibrazione Z. Ruotare la manopola per alzare il carrello Z fino all'altezza massima. Click per terminare." #define MSG_CONFIRM_NOZZLE_CLEAN "Pulire l'ugello per la calibrazione, poi fare click." #define MSG_CONFIRM_CARRIAGE_AT_THE_TOP "I carrelli Z sin/des sono altezza max?" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Ricerca del letto" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 "punto di calibraz." -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE3 " su 4" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Perfezion. il letto" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 "punto di calibraz." -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3 " su 9" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Ricerca del letto punto di calibraz." +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 " su 4" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Perfezion. il letto punto di calibraz." +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 " su 9" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 "Misurare l'altezza di riferimento del punto di calibrazione" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 " su 9" #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND "Calibrazione XYZ fallita. Il punto di calibrazione sul letto non e' stato trovato." #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED "Calibrazione XYZ fallita. Si prega di consultare il manuale." @@ -209,7 +209,7 @@ #define MSG_NEW_FIRMWARE_AVAILABLE "Nuova versione del firmware disponibile" #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Prega aggiorna." -#define MSG_BABYSTEP_Z_NOT_SET "Stampante non ancora calibrata. Eseguire il G-code di calibrazione per regolare l'altezza Z." +#define MSG_BABYSTEP_Z_NOT_SET "Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione." #define MSG_BED_CORRECTION_MENU "Correz. liv.letto" #define MSG_BED_CORRECTION_LEFT "Lato sinistro um" diff --git a/Firmware/language_pl.h b/Firmware/language_pl.h index 6380c0d1..f16f99cd 100644 --- a/Firmware/language_pl.h +++ b/Firmware/language_pl.h @@ -194,17 +194,18 @@ #define MSG_SHOW_END_STOPS "Pokaz krancowki" #define MSG_CALIBRATE_BED "Kalibracja XYZ" #define MSG_CALIBRATE_BED_RESET "Reset kalibr. XYZ" -#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Kalibracja XYZ. Prosze przesunac os Z do gornej ramy. Potw. guzikiem." -#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Kalibracja Z. Prosze przesunac os Z do gornej ramy. Potw. guzikiem." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP "Kalibracja XYZ. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic." +#define MSG_MOVE_CARRIAGE_TO_THE_TOP_Z "Kalibracja Z. Przekrec galke, aby przesunac os Z do gornych krancowek. Nacisnij, by potwierdzic." + +#define MSG_CONFIRM_NOZZLE_CLEAN "Dla prawidl. kalibracji prosze oczyscic dysze. Potw. guzikiem." +#define MSG_CONFIRM_CARRIAGE_AT_THE_TOP "Oba wozki dojechaly do gornej ramy?" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Szukam punktu kalibracyjnego podkladki" +#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 " z 4" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Poprawiam precyzyjnosc punktu kalibracyjnego" +#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 " z 9" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1 "Okreslam wysokosc odniesienia punktu kalibracyjnego" +#define MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2 " z 9" -#define MSG_CONFIRM_NOZZLE_CLEAN "Dla prawidl. kalibracji prosze oczyscic dysze. Potw. guzikiem." -#define MSG_CONFIRM_CARRIAGE_AT_THE_TOP "Oba wozki dojechaly do gornej ramy?" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE1 "Szukam kalibracyj." -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE2 "punktu podkladki" -#define MSG_FIND_BED_OFFSET_AND_SKEW_LINE3 " z 4" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1 "Ulepszam dokladnosc" -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2 "punktu kalibracyj." -#define MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3 " z 9" #define MSG_BED_SKEW_OFFSET_DETECTION_POINT_NOT_FOUND "Kalibr. XYZ nieudana. Kalibracyjny punkt podkladki nieznaleziony." #define MSG_BED_SKEW_OFFSET_DETECTION_FITTING_FAILED "Kalibracja XYZ niepowiedziona. Sprawdzic w instrukcji." #define MSG_BED_SKEW_OFFSET_DETECTION_PERFECT "Kalibracja XYZ ok. Osie X/Y sa prostopadle." @@ -221,7 +222,7 @@ #define MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED "Kalibracja nieudana. Sensor odlaczony lub uszkodz. kabel. Czekam na reset." #define MSG_NEW_FIRMWARE_AVAILABLE "Wyszla nowa wersja firmware:" #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE "Prosze zaktualizowac" -#define MSG_BABYSTEP_Z_NOT_SET "Drukarka nie byla kalibrowana. Wlaczyc kalibracyjny G-kod i dostroic Z." +#define MSG_BABYSTEP_Z_NOT_SET "Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest." #define MSG_BED_CORRECTION_MENU "Korekta podkladki" #define MSG_BED_CORRECTION_LEFT "W lewo [um]" #define MSG_BED_CORRECTION_RIGHT "W prawo [um]" diff --git a/Firmware/mesh_bed_calibration.cpp b/Firmware/mesh_bed_calibration.cpp index a4bc9fc7..f9234563 100644 --- a/Firmware/mesh_bed_calibration.cpp +++ b/Firmware/mesh_bed_calibration.cpp @@ -1547,8 +1547,10 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level // SERIAL_ECHOPGM(""); #ifdef MESH_BED_CALIBRATION_SHOW_LCD - lcd_implementation_clear(); - lcd_print_at_PGM(0, 0, MSG_FIND_BED_OFFSET_AND_SKEW_LINE1); + uint8_t next_line; + lcd_display_message_fullscreen_P(MSG_FIND_BED_OFFSET_AND_SKEW_LINE1, next_line); + if (next_line > 3) + next_line = 3; #endif /* MESH_BED_CALIBRATION_SHOW_LCD */ // Collect the rear 2x3 points. @@ -1557,9 +1559,8 @@ BedSkewOffsetDetectionResultType find_bed_offset_and_skew(int8_t verbosity_level // Don't let the manage_inactivity() function remove power from the motors. refresh_cmd_timeout(); #ifdef MESH_BED_CALIBRATION_SHOW_LCD - lcd_print_at_PGM(0, 1, MSG_FIND_BED_OFFSET_AND_SKEW_LINE2); - lcd_implementation_print_at(0, 2, k+1); - lcd_printPGM(MSG_FIND_BED_OFFSET_AND_SKEW_LINE3); + lcd_implementation_print_at(0, next_line, k+1); + lcd_printPGM(MSG_FIND_BED_OFFSET_AND_SKEW_LINE2); #endif /* MESH_BED_CALIBRATION_SHOW_LCD */ float *pt = pts + k * 2; // Go up to z_initial. @@ -1705,8 +1706,10 @@ BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8 bool endstop_z_enabled = enable_z_endstop(false); #ifdef MESH_BED_CALIBRATION_SHOW_LCD - lcd_implementation_clear(); - lcd_print_at_PGM(0, 0, MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1); + uint8_t next_line; + lcd_display_message_fullscreen_P(MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE1, next_line); + if (next_line > 3) + next_line = 3; #endif /* MESH_BED_CALIBRATION_SHOW_LCD */ // Collect a matrix of 9x9 points. @@ -1716,9 +1719,8 @@ BedSkewOffsetDetectionResultType improve_bed_offset_and_skew(int8_t method, int8 refresh_cmd_timeout(); // Print the decrasing ID of the measurement point. #ifdef MESH_BED_CALIBRATION_SHOW_LCD - lcd_print_at_PGM(0, 1, MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2); - lcd_implementation_print_at(0, 2, mesh_point+1); - lcd_printPGM(MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE3); + lcd_implementation_print_at(0, next_line, mesh_point+1); + lcd_printPGM(MSG_IMPROVE_BED_OFFSET_AND_SKEW_LINE2); #endif /* MESH_BED_CALIBRATION_SHOW_LCD */ // Move up. @@ -1963,6 +1965,16 @@ bool sample_mesh_and_store_reference() // Don't let the manage_inactivity() function remove power from the motors. refresh_cmd_timeout(); +#ifdef MESH_BED_CALIBRATION_SHOW_LCD + uint8_t next_line; + lcd_display_message_fullscreen_P(MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE1, next_line); + if (next_line > 3) + next_line = 3; + // display "point xx of yy" + lcd_implementation_print_at(0, next_line, 1); + lcd_printPGM(MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2); +#endif /* MESH_BED_CALIBRATION_SHOW_LCD */ + // Sample Z heights for the mesh bed leveling. // In addition, store the results into an eeprom, to be used later for verification of the bed leveling process. { @@ -1981,12 +1993,20 @@ bool sample_mesh_and_store_reference() mbl.set_z(0, 0, current_position[Z_AXIS]); } for (int8_t mesh_point = 1; mesh_point != MESH_MEAS_NUM_X_POINTS * MESH_MEAS_NUM_Y_POINTS; ++ mesh_point) { + // Don't let the manage_inactivity() function remove power from the motors. + refresh_cmd_timeout(); + // Print the decrasing ID of the measurement point. current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; go_to_current(homing_feedrate[Z_AXIS]/60); current_position[X_AXIS] = pgm_read_float(bed_ref_points+2*mesh_point); current_position[Y_AXIS] = pgm_read_float(bed_ref_points+2*mesh_point+1); world2machine_clamp(current_position[X_AXIS], current_position[Y_AXIS]); go_to_current(homing_feedrate[X_AXIS]/60); +#ifdef MESH_BED_CALIBRATION_SHOW_LCD + // display "point xx of yy" + lcd_implementation_print_at(0, next_line, mesh_point+1); + lcd_printPGM(MSG_MEASURE_BED_REFERENCE_HEIGHT_LINE2); +#endif /* MESH_BED_CALIBRATION_SHOW_LCD */ find_bed_induction_sensor_point_z(); // Get cords of measuring point int8_t ix = mesh_point % MESH_MEAS_NUM_X_POINTS; @@ -2023,6 +2043,7 @@ bool sample_mesh_and_store_reference() float dif = mbl.z_values[j][i] - mbl.z_values[0][0]; int16_t dif_quantized = int16_t(floor(dif * 100.f + 0.5f)); eeprom_update_word((uint16_t*)addr, *reinterpret_cast(&dif_quantized)); + #if 0 { uint16_t z_offset_u = eeprom_read_word((uint16_t*)addr); float dif2 = *reinterpret_cast(&z_offset_u) * 0.01; @@ -2037,6 +2058,7 @@ bool sample_mesh_and_store_reference() MYSERIAL.print(dif2, 5); SERIAL_ECHOLNPGM(""); } + #endif addr += 2; } } diff --git a/Firmware/planner.cpp b/Firmware/planner.cpp index 62855f18..bdfc4ca2 100644 --- a/Firmware/planner.cpp +++ b/Firmware/planner.cpp @@ -110,6 +110,11 @@ block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion volatile unsigned char block_buffer_head; // Index of the next block to be pushed volatile unsigned char block_buffer_tail; // Index of the block to process now +#ifdef PLANNER_DIAGNOSTICS +// Diagnostic function: Minimum number of planned moves since the last +static uint8_t g_cntr_planner_queue_min = 0; +#endif /* PLANNER_DIAGNOSTICS */ + //=========================================================================== //=============================private variables ============================ //=========================================================================== @@ -171,59 +176,92 @@ FORCE_INLINE float intersection_distance(float initial_rate, float final_rate, f } } -// Calculates trapezoid parameters so that the entry- and exit-speed is compensated by the provided factors. +#define MINIMAL_STEP_RATE 120 -void calculate_trapezoid_for_block(block_t *block, float entry_factor, float exit_factor) { - unsigned long initial_rate = ceil(block->nominal_rate*entry_factor); // (step/min) - unsigned long final_rate = ceil(block->nominal_rate*exit_factor); // (step/min) +// Calculates trapezoid parameters so that the entry- and exit-speed is compensated by the provided factors. +void calculate_trapezoid_for_block(block_t *block, float entry_speed, float exit_speed) +{ + // These two lines are the only floating point calculations performed in this routine. + uint32_t initial_rate = ceil(entry_speed * block->speed_factor); // (step/min) + uint32_t final_rate = ceil(exit_speed * block->speed_factor); // (step/min) // Limit minimal step rate (Otherwise the timer will overflow.) - if(initial_rate <120) { - initial_rate=120; - } - if(final_rate < 120) { - final_rate=120; - } + if (initial_rate < MINIMAL_STEP_RATE) + initial_rate = MINIMAL_STEP_RATE; + if (initial_rate > block->nominal_rate) + initial_rate = block->nominal_rate; + if (final_rate < MINIMAL_STEP_RATE) + final_rate = MINIMAL_STEP_RATE; + if (final_rate > block->nominal_rate) + final_rate = block->nominal_rate; - long acceleration = block->acceleration_st; - int32_t accelerate_steps = - ceil(estimate_acceleration_distance(initial_rate, block->nominal_rate, acceleration)); - int32_t decelerate_steps = - floor(estimate_acceleration_distance(block->nominal_rate, final_rate, -acceleration)); - - // Calculate the size of Plateau of Nominal Rate. - int32_t plateau_steps = block->step_event_count-accelerate_steps-decelerate_steps; + uint32_t acceleration = block->acceleration_st; + if (acceleration == 0) + // Don't allow zero acceleration. + acceleration = 1; + // estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) + // (target_rate*target_rate-initial_rate*initial_rate)/(2.0*acceleration)); + uint32_t initial_rate_sqr = initial_rate*initial_rate; + //FIXME assert that this result fits a 64bit unsigned int. + uint32_t nominal_rate_sqr = block->nominal_rate*block->nominal_rate; + uint32_t final_rate_sqr = final_rate*final_rate; + uint32_t acceleration_x2 = acceleration << 1; + // ceil(estimate_acceleration_distance(initial_rate, block->nominal_rate, acceleration)); + uint32_t accelerate_steps = (nominal_rate_sqr - initial_rate_sqr + acceleration_x2 - 1) / acceleration_x2; + // floor(estimate_acceleration_distance(block->nominal_rate, final_rate, -acceleration)); + uint32_t decelerate_steps = (nominal_rate_sqr - final_rate_sqr) / acceleration_x2; + uint32_t accel_decel_steps = accelerate_steps + decelerate_steps; + // Size of Plateau of Nominal Rate. + uint32_t plateau_steps = 0; // Is the Plateau of Nominal Rate smaller than nothing? That means no cruising, and we will // have to use intersection_distance() to calculate when to abort acceleration and start braking // in order to reach the final_rate exactly at the end of this block. - if (plateau_steps < 0) { - accelerate_steps = ceil(intersection_distance(initial_rate, final_rate, acceleration, block->step_event_count)); - accelerate_steps = max(accelerate_steps,0); // Check limits due to numerical round-off - accelerate_steps = min((uint32_t)accelerate_steps,block->step_event_count);//(We can cast here to unsigned, because the above line ensures that we are above zero) - plateau_steps = 0; + if (accel_decel_steps < block->step_event_count) { + plateau_steps = block->step_event_count - accel_decel_steps; + } else { + uint32_t acceleration_x4 = acceleration << 2; + // Avoid negative numbers + if (final_rate_sqr >= initial_rate_sqr) { + // accelerate_steps = ceil(intersection_distance(initial_rate, final_rate, acceleration, block->step_event_count)); + // intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) + // (2.0*acceleration*distance-initial_rate*initial_rate+final_rate*final_rate)/(4.0*acceleration); +#if 0 + accelerate_steps = (block->step_event_count >> 1) + (final_rate_sqr - initial_rate_sqr + acceleration_x4 - 1 + (block->step_event_count & 1) * acceleration_x2) / acceleration_x4; +#else + accelerate_steps = final_rate_sqr - initial_rate_sqr + acceleration_x4 - 1; + if (block->step_event_count & 1) + accelerate_steps += acceleration_x2; + accelerate_steps /= acceleration_x4; + accelerate_steps += (block->step_event_count >> 1); +#endif + if (accelerate_steps > block->step_event_count) + accelerate_steps = block->step_event_count; + } else { +#if 0 + decelerate_steps = (block->step_event_count >> 1) + (initial_rate_sqr - final_rate_sqr + (block->step_event_count & 1) * acceleration_x2) / acceleration_x4; +#else + decelerate_steps = initial_rate_sqr - final_rate_sqr; + if (block->step_event_count & 1) + decelerate_steps += acceleration_x2; + decelerate_steps /= acceleration_x4; + decelerate_steps += (block->step_event_count >> 1); +#endif + if (decelerate_steps > block->step_event_count) + decelerate_steps = block->step_event_count; + accelerate_steps = block->step_event_count - decelerate_steps; + } } -#ifdef ADVANCE - volatile long initial_advance = block->advance*entry_factor*entry_factor; - volatile long final_advance = block->advance*exit_factor*exit_factor; -#endif // ADVANCE - - // block->accelerate_until = accelerate_steps; - // block->decelerate_after = accelerate_steps+plateau_steps; CRITICAL_SECTION_START; // Fill variables used by the stepper in a critical section if (! block->busy) { // Don't update variables if block is busy. block->accelerate_until = accelerate_steps; block->decelerate_after = accelerate_steps+plateau_steps; block->initial_rate = initial_rate; block->final_rate = final_rate; -#ifdef ADVANCE - block->initial_advance = initial_advance; - block->final_advance = final_advance; -#endif //ADVANCE } CRITICAL_SECTION_END; -} +} // Calculates the maximum allowable entry speed, when you must be able to reach target_velocity using the // decceleration within the allotted distance. @@ -249,6 +287,27 @@ FORCE_INLINE float max_allowable_entry_speed(float decceleration, float target_v // the set limit. Finally it will: // // 3. Recalculate trapezoids for all blocks. +// +//FIXME This routine is called 15x every time a new line is added to the planner, +// therefore it is a bottle neck and it shall be rewritten into a Fixed Point arithmetics, +// if the CPU is found lacking computational power. +// +// Following sources may be used to optimize the 8-bit AVR code: +// http://www.mikrocontroller.net/articles/AVR_Arithmetik +// http://darcy.rsgc.on.ca/ACES/ICE4M/FixedPoint/avrfix.pdf +// +// https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/avr/lib1funcs-fixed.S +// https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html +// https://gcc.gnu.org/onlinedocs/gccint/Fixed-point-fractional-library-routines.html +// +// https://ucexperiment.wordpress.com/2015/04/04/arduino-s15-16-fixed-point-math-routines/ +// https://mekonik.wordpress.com/2009/03/18/arduino-avr-gcc-multiplication/ +// https://github.com/rekka/avrmultiplication +// +// https://people.ece.cornell.edu/land/courses/ece4760/Math/Floating_point/ +// https://courses.cit.cornell.edu/ee476/Math/ +// https://courses.cit.cornell.edu/ee476/Math/GCC644/fixedPt/multASM.S +// void planner_recalculate(const float &safe_final_speed) { // Reverse pass @@ -291,8 +350,12 @@ void planner_recalculate(const float &safe_final_speed) // segment and the maximum acceleration allowed for this segment. // If nominal length true, max junction speed is guaranteed to be reached even if decelerating to a jerk-from-zero velocity. // Only compute for max allowable speed if block is decelerating and nominal length is false. + // entry_speed is uint16_t, 24 bits would be sufficient for block->acceleration and block->millimiteres, if scaled to um. + // therefore an optimized assembly 24bit x 24bit -> 32bit multiply would be more than sufficient + // together with an assembly 32bit->16bit sqrt function. current->entry_speed = ((current->flag & BLOCK_FLAG_NOMINAL_LENGTH) || current->max_entry_speed <= next->entry_speed) ? current->max_entry_speed : + // min(current->max_entry_speed, sqrt(next->entry_speed*next->entry_speed+2*current->acceleration*current->millimeters)); min(current->max_entry_speed, max_allowable_entry_speed(-current->acceleration,next->entry_speed,current->millimeters)); current->flag |= BLOCK_FLAG_RECALCULATE; } @@ -325,7 +388,7 @@ void planner_recalculate(const float &safe_final_speed) // Recalculate if current block entry or exit junction speed has changed. if ((prev->flag | current->flag) & BLOCK_FLAG_RECALCULATE) { // NOTE: Entry and exit factors always > 0 by all previous logic operations. - calculate_trapezoid_for_block(prev, prev->entry_speed/prev->nominal_speed, current->entry_speed/prev->nominal_speed); + calculate_trapezoid_for_block(prev, prev->entry_speed, current->entry_speed); // Reset current only to ensure next trapezoid is computed. prev->flag &= ~BLOCK_FLAG_RECALCULATE; } @@ -338,7 +401,7 @@ void planner_recalculate(const float &safe_final_speed) // Last/newest block in buffer. Exit speed is set with safe_final_speed. Always recalculated. current = block_buffer + prev_block_index(block_buffer_head); - calculate_trapezoid_for_block(current, current->entry_speed/current->nominal_speed, safe_final_speed/current->nominal_speed); + calculate_trapezoid_for_block(current, current->entry_speed, safe_final_speed); current->flag &= ~BLOCK_FLAG_RECALCULATE; // SERIAL_ECHOLNPGM("planner_recalculate - 4"); @@ -471,6 +534,15 @@ void planner_abort_soft() } */ +#ifdef PLANNER_DIAGNOSTICS +static inline void planner_update_queue_min_counter() +{ + uint8_t new_counter = moves_planned(); + if (new_counter < g_cntr_planner_queue_min) + g_cntr_planner_queue_min = new_counter; +} +#endif /* PLANNER_DIAGNOSTICS */ + void planner_abort_hard() { // Abort the stepper routine and flush the planner queue. @@ -527,11 +599,18 @@ void plan_buffer_line(float x, float y, float z, const float &e, float feed_rate manage_inactivity(false); lcd_update(); } while (block_buffer_tail == next_buffer_head); - if (waiting_inside_plan_buffer_line_print_aborted) + if (waiting_inside_plan_buffer_line_print_aborted) { // Inside the lcd_update() routine the print has been aborted. // Cancel the print, do not plan the current line this routine is waiting on. +#ifdef PLANNER_DIAGNOSTICS + planner_update_queue_min_counter(); +#endif /* PLANNER_DIAGNOSTICS */ return; + } } +#ifdef PLANNER_DIAGNOSTICS + planner_update_queue_min_counter(); +#endif /* PLANNER_DIAGNOSTICS */ #ifdef ENABLE_AUTO_BED_LEVELING apply_rotation_xyz(plan_bed_level_matrix, x, y, z); @@ -637,14 +716,20 @@ block->steps_y = labs((target[X_AXIS]-position[X_AXIS]) - (target[Y_AXIS]-positi #endif block->steps_z = labs(target[Z_AXIS]-position[Z_AXIS]); block->steps_e = labs(target[E_AXIS]-position[E_AXIS]); - block->steps_e *= volumetric_multiplier[active_extruder]; - block->steps_e *= extrudemultiply; - block->steps_e /= 100; + if (volumetric_multiplier[active_extruder] != 1.f) + block->steps_e *= volumetric_multiplier[active_extruder]; + if (extrudemultiply != 100) { + block->steps_e *= extrudemultiply; + block->steps_e /= 100; + } block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e))); // Bail if this is a zero-length block if (block->step_event_count <= dropsegments) { +#ifdef PLANNER_DIAGNOSTICS + planner_update_queue_min_counter(); +#endif /* PLANNER_DIAGNOSTICS */ return; } @@ -869,6 +954,8 @@ Having the real displacement of the head, we can calculate the total movement le } // Compute and limit the acceleration rate for the trapezoid generator. + // block->step_event_count ... event count of the fastest axis + // block->millimeters ... Euclidian length of the XYZ movement or the E length, if no XYZ movement. float steps_per_mm = block->step_event_count/block->millimeters; if(block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0) { @@ -888,49 +975,27 @@ Having the real displacement of the head, we can calculate the total movement le if(((float)block->acceleration_st * (float)block->steps_z / (float)block->step_event_count ) > axis_steps_per_sqr_second[Z_AXIS]) block->acceleration_st = axis_steps_per_sqr_second[Z_AXIS]; } + // Acceleration of the segment, in mm/sec^2 block->acceleration = block->acceleration_st / steps_per_mm; + +#if 1 + // Oversample diagonal movements by a power of 2 up to 8x + // to achieve more accurate diagonal movements. + uint8_t bresenham_oversample = 1; + for (uint8_t i = 0; i < 3; ++ i) { + if (block->nominal_rate >= 5000) // 5kHz + break; + block->nominal_rate << 1; + bresenham_oversample << 1; + block->step_event_count << 1; + } + if (bresenham_oversample > 1) + // Lower the acceleration steps/sec^2 to account for the oversampling. + block->acceleration_st = (block->acceleration_st + (bresenham_oversample >> 1)) / bresenham_oversample; +#endif + block->acceleration_rate = (long)((float)block->acceleration_st * (16777216.0 / (F_CPU / 8.0))); -#if 0 // Use old jerk for now - // Compute path unit vector - double unit_vec[3]; - - unit_vec[X_AXIS] = delta_mm[X_AXIS]*inverse_millimeters; - unit_vec[Y_AXIS] = delta_mm[Y_AXIS]*inverse_millimeters; - unit_vec[Z_AXIS] = delta_mm[Z_AXIS]*inverse_millimeters; - - // Compute maximum allowable entry speed at junction by centripetal acceleration approximation. - // Let a circle be tangent to both previous and current path line segments, where the junction - // deviation is defined as the distance from the junction to the closest edge of the circle, - // colinear with the circle center. The circular segment joining the two paths represents the - // path of centripetal acceleration. Solve for max velocity based on max acceleration about the - // radius of the circle, defined indirectly by junction deviation. This may be also viewed as - // path width or max_jerk in the previous grbl version. This approach does not actually deviate - // from path, but used as a robust way to compute cornering speeds, as it takes into account the - // nonlinearities of both the junction angle and junction velocity. - double vmax_junction = MINIMUM_PLANNER_SPEED; // Set default max junction speed - - // Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles. - if ((block_buffer_head != block_buffer_tail) && (previous_nominal_speed > 0.0)) { - // Compute cosine of angle between previous and current path. (prev_unit_vec is negative) - // NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity. - double cos_theta = - previous_unit_vec[X_AXIS] * unit_vec[X_AXIS] - - previous_unit_vec[Y_AXIS] * unit_vec[Y_AXIS] - - previous_unit_vec[Z_AXIS] * unit_vec[Z_AXIS] ; - - // Skip and use default max junction speed for 0 degree acute junction. - if (cos_theta < 0.95) { - vmax_junction = min(previous_nominal_speed,block->nominal_speed); - // Skip and avoid divide by zero for straight junctions at 180 degrees. Limit to min() of nominal speeds. - if (cos_theta > -0.95) { - // Compute maximum junction velocity based on maximum acceleration and junction deviation - double sin_theta_d2 = sqrt(0.5*(1.0-cos_theta)); // Trig half angle identity. Always positive. - vmax_junction = min(vmax_junction, - sqrt(block->acceleration * junction_deviation * sin_theta_d2/(1.0-sin_theta_d2)) ); - } - } - } -#endif // Start with a safe speed. // Safe speed is the speed, from which the machine may halt to stop immediately. float safe_speed = block->nominal_speed; @@ -1047,34 +1112,9 @@ Having the real displacement of the head, we can calculate the total movement le previous_nominal_speed = block->nominal_speed; previous_safe_speed = safe_speed; -#ifdef ADVANCE - // Calculate advance rate - if((block->steps_e == 0) || (block->steps_x == 0 && block->steps_y == 0 && block->steps_z == 0)) { - block->advance_rate = 0; - block->advance = 0; - } - else { - long acc_dist = estimate_acceleration_distance(0, block->nominal_rate, block->acceleration_st); - float advance = (STEPS_PER_CUBIC_MM_E * EXTRUDER_ADVANCE_K) * - (current_speed[E_AXIS] * current_speed[E_AXIS] * EXTRUSION_AREA * EXTRUSION_AREA)*256; - block->advance = advance; - if(acc_dist == 0) { - block->advance_rate = 0; - } - else { - block->advance_rate = advance / (float)acc_dist; - } - } - /* - SERIAL_ECHO_START; - SERIAL_ECHOPGM("advance :"); - SERIAL_ECHO(block->advance/256.0); - SERIAL_ECHOPGM("advance rate :"); - SERIAL_ECHOLN(block->advance_rate/256.0); - */ -#endif // ADVANCE - - calculate_trapezoid_for_block(block, block->entry_speed/block->nominal_speed, safe_speed/block->nominal_speed); + // Precalculate the division, so when all the trapezoids in the planner queue get recalculated, the division is not repeated. + block->speed_factor = block->nominal_rate / block->nominal_speed; + calculate_trapezoid_for_block(block, block->entry_speed, safe_speed); // Move the buffer head. From now the block may be picked up by the stepper interrupt controller. block_buffer_head = next_buffer_head; @@ -1092,6 +1132,9 @@ Having the real displacement of the head, we can calculate the total movement le // SERIAL_ECHO(int(moves_planned())); // SERIAL_ECHOLNPGM(""); +#ifdef PLANNER_DIAGNOSTICS + planner_update_queue_min_counter(); +#endif /* PLANNER_DIAGNOSTIC */ st_wake_up(); } @@ -1172,3 +1215,15 @@ void reset_acceleration_rates() axis_steps_per_sqr_second[i] = max_acceleration_units_per_sq_second[i] * axis_steps_per_unit[i]; } } + +#ifdef PLANNER_DIAGNOSTICS +uint8_t planner_queue_min() +{ + return g_cntr_planner_queue_min; +} + +void planner_queue_min_reset() +{ + g_cntr_planner_queue_min = moves_planned(); +} +#endif /* PLANNER_DIAGNOSTICS */ \ No newline at end of file diff --git a/Firmware/planner.h b/Firmware/planner.h index 58619bea..a13aa1bd 100644 --- a/Firmware/planner.h +++ b/Firmware/planner.h @@ -55,12 +55,6 @@ typedef struct { // accelerate_until and decelerate_after are set by calculate_trapezoid_for_block() and they need to be synchronized with the stepper interrupt controller. long accelerate_until; // The index of the step event on which to stop acceleration long decelerate_after; // The index of the step event on which to start decelerating - #ifdef ADVANCE - long advance_rate; - volatile long initial_advance; - volatile long final_advance; - float advance; - #endif // Fields used by the motion planner to manage acceleration // float speed_x, speed_y, speed_z, speed_e; // Nominal mm/sec for each axis @@ -82,12 +76,18 @@ typedef struct { // Settings for the trapezoid generator (runs inside an interrupt handler). // Changing the following values in the planner needs to be synchronized with the interrupt handler by disabling the interrupts. + //FIXME nominal_rate, initial_rate and final_rate are limited to uint16_t by MultiU24X24toH16 in the stepper interrupt anyway! unsigned long nominal_rate; // The nominal step rate for this block in step_events/sec unsigned long initial_rate; // The jerk-adjusted step rate at start of block unsigned long final_rate; // The minimal rate at exit unsigned long acceleration_st; // acceleration steps/sec^2 + //FIXME does it have to be unsigned long? Probably uint8_t would be just fine. unsigned long fan_speed; volatile char busy; + + + // Pre-calculated division for the calculate_trapezoid_for_block() routine to run faster. + float speed_factor; } block_t; #ifdef ENABLE_AUTO_BED_LEVELING @@ -196,3 +196,11 @@ void set_extrude_min_temp(float temp); void reset_acceleration_rates(); #endif + +// #define PLANNER_DIAGNOSTICS +#ifdef PLANNER_DIAGNOSTICS +// Diagnostic functions to display planner buffer underflow on the display. +extern uint8_t planner_queue_min(); +// Diagnostic function: Reset the minimum planner segments. +extern void planner_queue_min_reset(); +#endif /* PLANNER_DIAGNOSTICS */ diff --git a/Firmware/stepper.cpp b/Firmware/stepper.cpp index 6bfea2a6..783299b9 100644 --- a/Firmware/stepper.cpp +++ b/Firmware/stepper.cpp @@ -47,22 +47,17 @@ block_t *current_block; // A pointer to the block currently being traced // Variables used by The Stepper Driver Interrupt static unsigned char out_bits; // The next stepping-bits to be output -static long counter_x, // Counter variables for the bresenham line tracer - counter_y, - counter_z, - counter_e; -volatile static unsigned long step_events_completed; // The number of step events executed in the current block -#ifdef ADVANCE - static long advance_rate, advance, final_advance = 0; - static long old_advance = 0; - static long e_steps[3]; -#endif -static long acceleration_time, deceleration_time; +static int32_t counter_x, // Counter variables for the bresenham line tracer + counter_y, + counter_z, + counter_e; +volatile static uint32_t step_events_completed; // The number of step events executed in the current block +static int32_t acceleration_time, deceleration_time; //static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate; -static unsigned short acc_step_rate; // needed for deccelaration start point -static char step_loops; -static unsigned short OCR1A_nominal; -static unsigned short step_loops_nominal; +static uint16_t acc_step_rate; // needed for deccelaration start point +static uint8_t step_loops; +static uint16_t OCR1A_nominal; +static uint8_t step_loops_nominal; volatile long endstops_trigsteps[3]={0,0,0}; volatile long endstops_stepsTotal,endstops_stepsDone; @@ -306,13 +301,6 @@ FORCE_INLINE unsigned short calc_timer(unsigned short step_rate) { // Initializes the trapezoid generator from the current block. Called whenever a new // block begins. FORCE_INLINE void trapezoid_generator_reset() { - #ifdef ADVANCE - advance = current_block->initial_advance; - final_advance = current_block->final_advance; - // Do E steps + advance steps - e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); - old_advance = advance >>8; - #endif deceleration_time = 0; // step_rate to timer interval OCR1A_nominal = calc_timer(current_block->nominal_rate); @@ -359,10 +347,6 @@ ISR(TIMER1_COMPA_vect) return; } #endif - -// #ifdef ADVANCE -// e_steps[current_block->active_extruder] = 0; -// #endif } else { OCR1A=2000; // 1kHz. @@ -531,37 +515,20 @@ ISR(TIMER1_COMPA_vect) } #endif - #ifndef ADVANCE - if ((out_bits & (1<steps_e; - if (counter_e > 0) { - counter_e -= current_block->step_event_count; - if ((out_bits & (1<active_extruder]--; - } - else { - e_steps[current_block->active_extruder]++; - } - } - #endif //ADVANCE - counter_x += current_block->steps_x; if (counter_x > 0) { WRITE(X_STEP_PIN, !INVERT_X_STEP_PIN); @@ -604,7 +571,6 @@ ISR(TIMER1_COMPA_vect) #endif } - #ifndef ADVANCE counter_e += current_block->steps_e; if (counter_e > 0) { WRITE_E_STEP(!INVERT_E_STEP_PIN); @@ -612,7 +578,6 @@ ISR(TIMER1_COMPA_vect) count_position[E_AXIS]+=count_direction[E_AXIS]; WRITE_E_STEP(INVERT_E_STEP_PIN); } - #endif //!ADVANCE step_events_completed += 1; if(step_events_completed >= current_block->step_event_count) break; } @@ -620,7 +585,7 @@ ISR(TIMER1_COMPA_vect) unsigned short timer; unsigned short step_rate; if (step_events_completed <= (unsigned long int)current_block->accelerate_until) { - + // v = t * a -> acc_step_rate = acceleration_time * current_block->acceleration_rate MultiU24X24toH16(acc_step_rate, acceleration_time, current_block->acceleration_rate); acc_step_rate += current_block->initial_rate; @@ -632,16 +597,6 @@ ISR(TIMER1_COMPA_vect) timer = calc_timer(acc_step_rate); OCR1A = timer; acceleration_time += timer; - #ifdef ADVANCE - for(int8_t i=0; i < step_loops; i++) { - advance += advance_rate; - } - //if(advance > current_block->advance) advance = current_block->advance; - // Do E steps + advance steps - e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); - old_advance = advance >>8; - - #endif // ADVANCE } else if (step_events_completed > (unsigned long int)current_block->decelerate_after) { MultiU24X24toH16(step_rate, deceleration_time, current_block->acceleration_rate); @@ -661,15 +616,6 @@ ISR(TIMER1_COMPA_vect) timer = calc_timer(step_rate); OCR1A = timer; deceleration_time += timer; - #ifdef ADVANCE - for(int8_t i=0; i < step_loops; i++) { - advance -= advance_rate; - } - if(advance < final_advance) advance = final_advance; - // Do E steps + advance steps - e_steps[current_block->active_extruder] += ((advance >>8) - old_advance); - old_advance = advance >>8; - #endif //ADVANCE } else { OCR1A = OCR1A_nominal; @@ -685,63 +631,6 @@ ISR(TIMER1_COMPA_vect) } } -#ifdef ADVANCE - unsigned char old_OCR0A; - // Timer interrupt for E. e_steps is set in the main routine; - // Timer 0 is shared with millies - ISR(TIMER0_COMPA_vect) - { - old_OCR0A += 52; // ~10kHz interrupt (250000 / 26 = 9615kHz) - OCR0A = old_OCR0A; - // Set E direction (Depends on E direction + advance) - for(unsigned char i=0; i<4;i++) { - if (e_steps[0] != 0) { - WRITE(E0_STEP_PIN, INVERT_E_STEP_PIN); - if (e_steps[0] < 0) { - WRITE(E0_DIR_PIN, INVERT_E0_DIR); - e_steps[0]++; - WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); - } - else if (e_steps[0] > 0) { - WRITE(E0_DIR_PIN, !INVERT_E0_DIR); - e_steps[0]--; - WRITE(E0_STEP_PIN, !INVERT_E_STEP_PIN); - } - } - #if EXTRUDERS > 1 - if (e_steps[1] != 0) { - WRITE(E1_STEP_PIN, INVERT_E_STEP_PIN); - if (e_steps[1] < 0) { - WRITE(E1_DIR_PIN, INVERT_E1_DIR); - e_steps[1]++; - WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN); - } - else if (e_steps[1] > 0) { - WRITE(E1_DIR_PIN, !INVERT_E1_DIR); - e_steps[1]--; - WRITE(E1_STEP_PIN, !INVERT_E_STEP_PIN); - } - } - #endif - #if EXTRUDERS > 2 - if (e_steps[2] != 0) { - WRITE(E2_STEP_PIN, INVERT_E_STEP_PIN); - if (e_steps[2] < 0) { - WRITE(E2_DIR_PIN, INVERT_E2_DIR); - e_steps[2]++; - WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN); - } - else if (e_steps[2] > 0) { - WRITE(E2_DIR_PIN, !INVERT_E2_DIR); - e_steps[2]--; - WRITE(E2_STEP_PIN, !INVERT_E_STEP_PIN); - } - } - #endif - } - } -#endif // ADVANCE - void st_init() { digipot_init(); //Initialize Digipot Motor Current @@ -930,17 +819,6 @@ void st_init() TCNT1 = 0; ENABLE_STEPPER_DRIVER_INTERRUPT(); - #ifdef ADVANCE - #if defined(TCCR0A) && defined(WGM01) - TCCR0A &= ~(1< LCD_TIMEOUT_TO_STATUS) - goto canceled; +// if (millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS) +// goto canceled; manage_heater(); manage_inactivity(true); if (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP) { @@ -1474,6 +1472,12 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z) while (lcd_clicked()) ; break; } + if (multi_screen && millis() - previous_millis_msg > 5000) { + if (msg_next == NULL) + msg_next = msg; + msg_next = lcd_display_message_fullscreen_P(msg_next); + previous_millis_msg = millis(); + } } if (! clean_nozzle_asked) { @@ -1482,7 +1486,7 @@ bool lcd_calibrate_z_end_stop_manual(bool only_z) } // Let the user confirm, that the Z carriage is at the top end stoppers. - int8_t result = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_CONFIRM_CARRIAGE_AT_THE_TOP); + int8_t result = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_CONFIRM_CARRIAGE_AT_THE_TOP, false); if (result == -1) goto canceled; else if (result == 1) @@ -1513,24 +1517,36 @@ static inline bool pgm_is_interpunction(const char *c_addr) return c == '.' || c == ',' || c == ':'|| c == ';' || c == '?' || c == '!' || c == '/'; } -const char* lcd_display_message_fullscreen_P(const char *msg) +const char* lcd_display_message_fullscreen_P(const char *msg, uint8_t &nlines) { // Disable update of the screen by the usual lcd_update() routine. lcd_update_enable(false); lcd_implementation_clear(); lcd.setCursor(0, 0); const char *msgend = msg; - for (int8_t row = 0; row < 4; ++ row) { + uint8_t row = 0; + bool multi_screen = false; + for (; row < 4; ++ row) { while (pgm_is_whitespace(msg)) ++ msg; if (pgm_read_byte(msg) == 0) // End of the message. break; lcd.setCursor(0, row); - const char *msgend2 = msg + min(strlen_P(msg), 20); + uint8_t linelen = min(strlen_P(msg), 20); + const char *msgend2 = msg + linelen; msgend = msgend2; + if (row == 3 && linelen == 20) { + // Last line of the display, full line shall be displayed. + // Find out, whether this message will be split into multiple screens. + while (pgm_is_whitespace(msgend)) + ++ msgend; + multi_screen = pgm_read_byte(msgend) != 0; + if (multi_screen) + msgend = (msgend2 -= 2); + } if (pgm_read_byte(msgend) != 0 && ! pgm_is_whitespace(msgend) && ! pgm_is_interpunction(msgend)) { - // Splitting a word. Find the start of the current word. + // Splitting a word. Find the start of the current word. while (msgend > msg && ! pgm_is_whitespace(msgend - 1)) -- msgend; if (msgend == msg) @@ -1545,7 +1561,17 @@ const char* lcd_display_message_fullscreen_P(const char *msg) } } - return (pgm_read_byte(msgend) == 0) ? NULL : msgend; + if (multi_screen) { + // Display the "next screen" indicator character. + // lcd_set_custom_characters_arrows(); + lcd_set_custom_characters_nextpage(); + lcd.setCursor(19, 3); + // Display the down arrow. + lcd.print(char(1)); + } + + nlines = row; + return multi_screen ? msgend : NULL; } void lcd_show_fullscreen_message_and_wait_P(const char *msg) @@ -2244,9 +2270,6 @@ void lcd_mylang_drawmenu(int cursor) { } } -void lcd_set_custom_characters_arrows(); -void lcd_set_custom_characters_degree(); - void lcd_mylang_drawcursor(int cursor) { if (cursor==1) lcd.setCursor(0, 1); @@ -3290,10 +3313,36 @@ void lcd_init() //#include static volatile bool lcd_update_enabled = true; +static unsigned long lcd_timeoutToStatus = 0; void lcd_update_enable(bool enabled) { - lcd_update_enabled = enabled; + if (lcd_update_enabled != enabled) { + lcd_update_enabled = enabled; + if (enabled) { + // Reset encoder position. This is equivalent to re-entering a menu. + encoderPosition = 0; + encoderDiff = 0; + // Enabling the normal LCD update procedure. + // Reset the timeout interval. + lcd_timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; + // Force the keypad update now. + lcd_next_update_millis = millis() - 1; + // Full update. + lcd_implementation_clear(); + #if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) + lcd_set_custom_characters(currentMenu == lcd_status_screen); + #else + if (currentMenu == lcd_status_screen) + lcd_set_custom_characters_degree(); + else + lcd_set_custom_characters_arrows(); + #endif + lcd_update(2); + } else { + // Clear the LCD always, or let it to the caller? + } + } } void lcd_update(uint8_t lcdDrawUpdateOverride) @@ -3301,8 +3350,6 @@ void lcd_update(uint8_t lcdDrawUpdateOverride) if (lcdDrawUpdate < lcdDrawUpdateOverride) lcdDrawUpdate = lcdDrawUpdateOverride; - static unsigned long timeoutToStatus = 0; - if (! lcd_update_enabled) return; @@ -3364,13 +3411,14 @@ void lcd_update(uint8_t lcdDrawUpdateOverride) #endif if (abs(encoderDiff) >= ENCODER_PULSES_PER_STEP) { - lcdDrawUpdate = 1; + if (lcdDrawUpdate == 0) + lcdDrawUpdate = 1; encoderPosition += encoderDiff / ENCODER_PULSES_PER_STEP; encoderDiff = 0; - timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; + lcd_timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; } if (LCD_CLICKED) - timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; + lcd_timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; #endif//ULTIPANEL #ifdef DOGLCD // Changes due to different driver architecture of the DOGM display @@ -3395,7 +3443,7 @@ void lcd_update(uint8_t lcdDrawUpdateOverride) #endif #ifdef ULTIPANEL - if (timeoutToStatus < millis() && currentMenu != lcd_status_screen) + if (lcd_timeoutToStatus < millis() && currentMenu != lcd_status_screen) { // Exiting a menu. Let's call the menu function the last time with menuExiting flag set to true // to give it a chance to save its state. diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 19563849..ae69245b 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -40,7 +40,10 @@ void lcd_mylang(); static void lcd_selftest_error(int _error_no, const char *_error_1, const char *_error_2); static void lcd_menu_statistics(); - extern const char* lcd_display_message_fullscreen_P(const char *msg); + extern const char* lcd_display_message_fullscreen_P(const char *msg, uint8_t &nlines); + inline const char* lcd_display_message_fullscreen_P(const char *msg) + { uint8_t nlines; return lcd_display_message_fullscreen_P(msg, nlines); } + extern void lcd_wait_for_click(); extern void lcd_show_fullscreen_message_and_wait_P(const char *msg); // 0: no, 1: yes, -1: timeouted diff --git a/Firmware/ultralcd_implementation_hitachi_HD44780.h b/Firmware/ultralcd_implementation_hitachi_HD44780.h index 900ef0a5..4e5ba99c 100644 --- a/Firmware/ultralcd_implementation_hitachi_HD44780.h +++ b/Firmware/ultralcd_implementation_hitachi_HD44780.h @@ -461,6 +461,24 @@ void lcd_set_custom_characters_arrows() lcd.createChar(1, arrdown); } + +void lcd_set_custom_characters_nextpage() + { + + byte arrdown[8] = { + B00000, + B00000, + B10001, + B01010, + B00100, + B10001, + B01010, + B00100 + }; + + lcd.createChar(1, arrdown); +} + void lcd_set_custom_characters_degree() { byte degree[8] = { @@ -659,6 +677,7 @@ static void lcd_implementation_status_screen() //Print the Z coordinates lcd.setCursor(LCD_WIDTH - 8-2, 0); +#if 1 lcd_printPGM(PSTR(" Z")); if (custom_message_type == 1) { // In a bed calibration mode. @@ -667,6 +686,11 @@ static void lcd_implementation_status_screen() lcd.print(ftostr32sp(current_position[Z_AXIS] + 0.00001)); lcd.print(' '); } +#else + lcd_printPGM(PSTR(" Queue:")); + lcd.print(int(moves_planned())); + lcd.print(' '); +#endif //Print the Bedtemperature lcd.setCursor(0, 1); @@ -679,15 +703,31 @@ static void lcd_implementation_status_screen() lcd_printPGM(PSTR(LCD_STR_DEGREE " ")); lcd_printPGM(PSTR(" ")); +#if 1 //Print Feedrate lcd.setCursor(LCD_WIDTH - 8-2, 1); lcd_printPGM(PSTR(" ")); lcd.print(LCD_STR_FEEDRATE[0]); lcd.print(itostr3(feedmultiply)); - lcd.print('%'); - lcd_printPGM(PSTR(" ")); - - + lcd_printPGM(PSTR("% ")); +#else + //Print Feedrate + lcd.setCursor(LCD_WIDTH - 8-2, 1); + lcd.print(LCD_STR_FEEDRATE[0]); + lcd.print(itostr3(feedmultiply)); + lcd_printPGM(PSTR("% Q")); + { + uint8_t queue = planner_queue_min(); + if (queue < (BLOCK_BUFFER_SIZE >> 1)) { + lcd.print('!'); + } else { + lcd.print((char)(queue / 10) + '0'); + queue %= 10; + } + lcd.print((char)queue + '0'); + planner_queue_min_reset(); + } +#endif //Print SD status lcd.setCursor(0, 2);