From 12505d0f4ed588b66571ecac94b17c4e2f35a6f2 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Thu, 23 Mar 2017 15:08:11 +0100 Subject: [PATCH 1/3] button long press activates move Z axis menu, Rx buffer behavior improved when it is full (#66) --- Firmware/Configuration.h | 2 +- Firmware/Marlin_main.cpp | 68 ++++++++++++++++++++--------------- Firmware/ultralcd.cpp | 77 ++++++++++++++++++++++++++++++++-------- 3 files changed, 103 insertions(+), 44 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index b8d9c760..eba8eb67 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -5,7 +5,7 @@ #include "Configuration_prusa.h" // Firmware version -#define FW_version "3.0.10-7" +#define FW_version "3.0.10-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 2ce62193..dc00e4b7 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -429,7 +429,7 @@ static bool cmdbuffer_front_already_processed = false; // Debugging information will be sent to serial line. // #define CMDBUFFER_DEBUG -static int serial_count = 0; +static int serial_count = 0; //index of character read from serial line static boolean comment_mode = false; static char *strchr_pointer; // just a pointer to find chars in the command string like X, Y, Z, E, etc @@ -576,8 +576,8 @@ bool cmdqueue_could_enqueue_front(int len_asked) cmdqueue_pop_front(); cmdbuffer_front_already_processed = true; } - if (bufindr == bufindw && buflen > 0) - // Full buffer. + if (bufindr == bufindw && buflen > 0) + // Full buffer. return false; // Adjust the end of the write buffer based on whether a partial line is in the receive buffer. int endw = (serial_count > 0) ? (bufindw + MAX_CMD_SIZE + 1) : bufindw; @@ -615,9 +615,9 @@ bool cmdqueue_could_enqueue_back(int len_asked) if (len_asked >= MAX_CMD_SIZE) return false; - if (bufindr == bufindw && buflen > 0) - // Full buffer. - return false; + if (bufindr == bufindw && buflen > 0) + // Full buffer. + return false; if (serial_count > 0) { // If there is some data stored starting at bufindw, len_asked is certainly smaller than @@ -1028,7 +1028,7 @@ void setup() SERIAL_ECHO(freeMemory()); SERIAL_ECHORPGM(MSG_PLANNER_BUFFER_BYTES); SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE); - + lcd_update_enable(false); // loads data from EEPROM if available else uses defaults (and resets step acceleration rate) Config_RetrieveSettings(); SdFatUtil::set_stack_guard(); //writes magic number at the end of static variables to protect against overwriting static memory by stack @@ -1041,7 +1041,7 @@ void setup() // Reset the machine correction matrix. // It does not make sense to load the correction matrix until the machine is homed. world2machine_reset(); - + lcd_init(); if (!READ(BTN_ENC)) { @@ -1166,16 +1166,14 @@ void setup() eeprom_update_word((uint16_t*)EEPROM_BABYSTEP_Z, 0); // Show the message. lcd_show_fullscreen_message_and_wait_P(MSG_FOLLOW_CALIBRATION_FLOW); - lcd_update_enable(true); } else if (calibration_status() == CALIBRATION_STATUS_LIVE_ADJUST) { // Show the message. lcd_show_fullscreen_message_and_wait_P(MSG_BABYSTEP_Z_NOT_SET); - lcd_update_enable(true); } else if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION) { // Show the message. lcd_show_fullscreen_message_and_wait_P(MSG_FOLLOW_CALIBRATION_FLOW); - lcd_update_enable(true); } + lcd_update_enable(true); // 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. @@ -1323,10 +1321,16 @@ void loop() void get_command() { // Test and reserve space for the new command string. - if (! cmdqueue_could_enqueue_back(MAX_CMD_SIZE-1)) - return; + if (!cmdqueue_could_enqueue_back(MAX_CMD_SIZE - 1)) + return; + + bool rx_buffer_full = false; //flag that serial rx buffer is full while (MYSERIAL.available() > 0) { + if (MYSERIAL.available() == RX_BUFFER_SIZE - 1) { //compare number of chars buffered in rx buffer with rx buffer size + SERIAL_ECHOLNPGM("Full RX Buffer"); //if buffer was full, there is danger that reading of last gcode will not be completed + rx_buffer_full = true; //sets flag that buffer was full + } char serial_char = MYSERIAL.read(); TimeSent = millis(); TimeNow = millis(); @@ -1476,11 +1480,18 @@ void get_command() } } + //add comment + if (rx_buffer_full == true && serial_count > 0) { //if rx buffer was full and string was not properly terminated + rx_buffer_full = false; + bufindw = bufindw - serial_count; //adjust tail of the buffer to prepare buffer for writing new command + serial_count = 0; + } + #ifdef SDSUPPORT if(!card.sdprinting || serial_count!=0){ // If there is a half filled buffer from serial line, wait until return before // continuing with the serial line. - return; + return; } //'#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible @@ -2765,19 +2776,6 @@ void process_commands() } break; - /** - * G80: Mesh-based Z probe, probes a grid and produces a - * mesh to compensate for variable bed height - * - * The S0 report the points as below - * - * +----> X-axis - * | - * | - * v Y-axis - * - */ - #ifdef DIS case 77: { @@ -2808,6 +2806,18 @@ void process_commands() #endif + /** + * G80: Mesh-based Z probe, probes a grid and produces a + * mesh to compensate for variable bed height + * + * The S0 report the points as below + * + * +----> X-axis + * | + * | + * v Y-axis + * + */ case 80: case_G80: { @@ -3124,6 +3134,7 @@ void process_commands() farm_mode = 0; lcd_printer_connected(); eeprom_update_byte((unsigned char *)EEPROM_FARM_MODE, farm_mode); + lcd_update(2); break; @@ -3878,8 +3889,7 @@ Sigma_Exit: SERIAL_PROTOCOL_F(rawHotendTemp(cur_extruder)/OVERSAMPLENR,0); } #endif - - SERIAL_PROTOCOLLN(""); + SERIAL_PROTOCOLLN(""); return; break; case 109: diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 42a06902..aa22fe26 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -107,6 +107,10 @@ unsigned long allert_timer = millis(); bool printer_connected = true; +bool long_press_active = false; +long long_press_timer = millis(); +bool button_pressed = false; + bool menuExiting = false; #ifdef FILAMENT_LCD_DISPLAY @@ -265,15 +269,16 @@ volatile uint8_t buttons_reprapworld_keypad; // to store the reprapworld_keypad volatile uint8_t slow_buttons;//Contains the bits of the currently pressed buttons. #endif uint8_t currentMenuViewOffset; /* scroll offset in the current menu */ -uint32_t blocking_enc; uint8_t lastEncoderBits; uint32_t encoderPosition; +uint32_t savedEncoderPosition; #if (SDCARDDETECT > 0) bool lcd_oldcardstatus; #endif #endif //ULTIPANEL menuFunc_t currentMenu = lcd_status_screen; /* function pointer to the currently active menu */ +menuFunc_t savedMenu; uint32_t lcd_next_update_millis; uint8_t lcd_status_update_delay; bool ignore_click = false; @@ -1209,7 +1214,7 @@ void lcd_menu_statistics() static void _lcd_move(const char *name, int axis, int min, int max) { - if (encoderPosition != 0) { + if (encoderPosition != 0) { refresh_cmd_timeout(); if (! planner_queue_full()) { current_position[axis] += float((int)encoderPosition) * move_menu_scale; @@ -1222,7 +1227,8 @@ static void _lcd_move(const char *name, int axis, int min, int max) { } } if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis])); - if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis); + if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis); { + } } @@ -4269,7 +4275,7 @@ static void lcd_selftest_screen_step(int _row, int _col, int _state, const char static void lcd_quick_feedback() { lcdDrawUpdate = 2; - blocking_enc = millis() + 500; + button_pressed = false; lcd_implementation_quick_feedback(); } @@ -4320,6 +4326,7 @@ static void menu_action_setting_edit_callback_bool(const char* pstr, bool* ptr, #endif//ULTIPANEL /** LCD API **/ + void lcd_init() { lcd_implementation_init(); @@ -4413,16 +4420,17 @@ void lcd_update_enable(bool enabled) void lcd_update(uint8_t lcdDrawUpdateOverride) { - if (lcdDrawUpdate < lcdDrawUpdateOverride) - lcdDrawUpdate = lcdDrawUpdateOverride; - if (! lcd_update_enabled) - return; + if (lcdDrawUpdate < lcdDrawUpdateOverride) + lcdDrawUpdate = lcdDrawUpdateOverride; + + if (!lcd_update_enabled) + return; #ifdef LCD_HAS_SLOW_BUTTONS slow_buttons = lcd_implementation_read_slow_buttons(); // buttons which take too long to read in interrupt context #endif - + lcd_buttons_update(); #if (SDCARDDETECT > 0) @@ -4484,8 +4492,8 @@ void lcd_update(uint8_t lcdDrawUpdateOverride) encoderDiff = 0; lcd_timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; } - if (LCD_CLICKED) - lcd_timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; + + /*if (LCD_CLICKED)*/ lcd_timeoutToStatus = millis() + LCD_TIMEOUT_TO_STATUS; #endif//ULTIPANEL #ifdef DOGLCD // Changes due to different driver architecture of the DOGM display @@ -4620,9 +4628,50 @@ void lcd_buttons_update() if (READ(BTN_EN1) == 0) newbutton |= EN_A; if (READ(BTN_EN2) == 0) newbutton |= EN_B; #if BTN_ENC > 0 - if ((blocking_enc < millis()) && (READ(BTN_ENC) == 0)) - newbutton |= EN_C; -#endif + if (lcd_update_enabled == true) { //if we are in non-modal mode, long press can be used and short press triggers with button release + if (READ(BTN_ENC) == 0) { //button is pressed + + if (button_pressed == false && long_press_active == false) { + if (currentMenu != lcd_move_z) { + savedMenu = currentMenu; + savedEncoderPosition = encoderPosition; + } + long_press_timer = millis(); + button_pressed = true; + } + else { + if (millis() - long_press_timer > LONG_PRESS_TIME) { //long press activated + + long_press_active = true; + move_menu_scale = 1.0; + lcd_goto_menu(lcd_move_z); + } + } + } + else { //button not pressed + if (button_pressed) { //button was released + if (long_press_active == false) { //button released before long press gets activated + if (currentMenu == lcd_move_z) { + //return to previously active menu and previous encoder position + lcd_goto_menu(savedMenu, savedEncoderPosition); + } + else { + newbutton |= EN_C; + } + } + //button_pressed is set back to false via lcd_quick_feedback function + } + else { + long_press_active = false; + } + } + } + else { //we are in modal mode + if (READ(BTN_ENC) == 0) + newbutton |= EN_C; + } + +#endif buttons = newbutton; #ifdef LCD_HAS_SLOW_BUTTONS buttons |= slow_buttons; From 69f76e6bee74a422b5b28fce4cc84364d88d5779 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Thu, 23 Mar 2017 15:09:59 +0100 Subject: [PATCH 2/3] added timer for button long press --- Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h index a36f3c9a..852d2c62 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h @@ -328,4 +328,6 @@ THERMISTORS SETTINGS #define PING_TIME_LONG 600 //10 min; used when length of commands buffer > 0 to avoid false triggering when dealing with long gcodes #define PING_ALLERT_PERIOD 60 //time in s +#define LONG_PRESS_TIME 1000 //time in ms for button long press + #endif //__CONFIGURATION_PRUSA_H From b52e034da0fb6b347f22af621747a91a51cd5774 Mon Sep 17 00:00:00 2001 From: PavelSindler Date: Thu, 23 Mar 2017 15:10:32 +0100 Subject: [PATCH 3/3] added timer for button long press --- Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h index 3e89889a..23d612d3 100644 --- a/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h @@ -328,4 +328,6 @@ THERMISTORS SETTINGS #define PING_TIME_LONG 600 //10 min; used when length of commands buffer > 0 to avoid false triggering when dealing with long gcodes #define PING_ALLERT_PERIOD 60 //time in s +#define LONG_PRESS_TIME 1000 //time in ms for button long press + #endif //__CONFIGURATION_PRUSA_H