2012-05-08 17:18:31 +02:00
# include "temperature.h"
2011-12-12 19:34:37 +01:00
# include "ultralcd.h"
# ifdef ULTRA_LCD
2011-12-22 14:55:45 +01:00
# include "Marlin.h"
2012-05-03 14:22:43 +02:00
# include "language.h"
2012-12-12 11:47:03 +01:00
# include "cardreader.h"
2012-05-03 14:22:43 +02:00
# include "temperature.h"
2013-01-31 16:43:03 +01:00
# include "stepper.h"
2012-11-07 10:02:45 +01:00
# include "ConfigurationStore.h"
2012-11-06 12:06:41 +01:00
2013-07-14 15:35:54 +02:00
int8_t encoderDiff ; /* encoderDiff is updated from interrupt context and added to encoderPosition every LCD update */
2015-02-20 03:42:57 +01:00
bool encoderRateMultiplierEnabled ;
int32_t lastEncoderMovementMillis ;
2012-12-12 11:47:03 +01:00
/* Configuration settings */
2012-11-06 12:06:41 +01:00
int plaPreheatHotendTemp ;
int plaPreheatHPBTemp ;
int plaPreheatFanSpeed ;
int absPreheatHotendTemp ;
int absPreheatHPBTemp ;
int absPreheatFanSpeed ;
2013-07-30 14:33:30 +02:00
2014-11-11 04:43:58 +01:00
# ifdef FILAMENT_LCD_DISPLAY
2014-12-28 07:26:14 +01:00
unsigned long message_millis = 0 ;
2014-11-11 04:43:58 +01:00
# endif
2013-10-30 21:52:46 +01:00
# ifdef ULTIPANEL
2014-12-28 07:26:14 +01:00
static float manual_feedrate [ ] = MANUAL_FEEDRATE ;
2013-10-30 21:52:46 +01:00
# endif // ULTIPANEL
2012-12-12 11:47:03 +01:00
/* !Configuration settings */
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
//Function pointer to menu functions.
typedef void ( * menuFunc_t ) ( ) ;
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
uint8_t lcd_status_message_level ;
char lcd_status_message [ LCD_WIDTH + 1 ] = WELCOME_MSG ;
2011-12-12 19:34:37 +01:00
2013-03-19 20:59:21 +01:00
# ifdef DOGLCD
# include "dogm_lcd_implementation.h"
# else
2012-12-12 11:47:03 +01:00
# include "ultralcd_implementation_hitachi_HD44780.h"
2013-03-19 20:59:21 +01:00
# endif
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
/* Different menus */
static void lcd_status_screen ( ) ;
# ifdef ULTIPANEL
2013-03-05 14:52:51 +01:00
extern bool powersupply ;
2012-12-12 11:47:03 +01:00
static void lcd_main_menu ( ) ;
static void lcd_tune_menu ( ) ;
static void lcd_prepare_menu ( ) ;
static void lcd_move_menu ( ) ;
static void lcd_control_menu ( ) ;
static void lcd_control_temperature_menu ( ) ;
static void lcd_control_temperature_preheat_pla_settings_menu ( ) ;
static void lcd_control_temperature_preheat_abs_settings_menu ( ) ;
static void lcd_control_motion_menu ( ) ;
2014-12-29 02:43:14 +01:00
static void lcd_control_volumetric_menu ( ) ;
2013-07-14 10:28:26 +02:00
# ifdef DOGLCD
static void lcd_set_contrast ( ) ;
# endif
2012-12-12 11:47:03 +01:00
static void lcd_control_retract_menu ( ) ;
static void lcd_sdcard_menu ( ) ;
2014-12-29 18:19:25 +01:00
# ifdef DELTA_CALIBRATION_MENU
static void lcd_delta_calibrate_menu ( ) ;
# endif // DELTA_CALIBRATION_MENU
2015-03-15 23:18:11 +01:00
# if defined(MANUAL_BED_LEVELING)
# include "mesh_bed_leveling.h"
static void _lcd_level_bed ( ) ;
static void _lcd_level_bed_homing ( ) ;
static void lcd_level_bed ( ) ;
# endif // MANUAL_BED_LEVELING
2014-02-17 14:04:44 +01:00
static void lcd_quick_feedback ( ) ; //Cause an LCD refresh, and give the user visual or audible feedback that something has happened
2012-12-12 11:47:03 +01:00
2014-02-17 14:04:44 +01:00
/* Different types of actions that can be used in menu items. */
2012-12-12 11:47:03 +01:00
static void menu_action_back ( menuFunc_t data ) ;
static void menu_action_submenu ( menuFunc_t data ) ;
static void menu_action_gcode ( const char * pgcode ) ;
static void menu_action_function ( menuFunc_t data ) ;
static void menu_action_sdfile ( const char * filename , char * longFilename ) ;
static void menu_action_sddirectory ( const char * filename , char * longFilename ) ;
static void menu_action_setting_edit_bool ( const char * pstr , bool * ptr ) ;
static void menu_action_setting_edit_int3 ( const char * pstr , int * ptr , int minValue , int maxValue ) ;
static void menu_action_setting_edit_float3 ( const char * pstr , float * ptr , float minValue , float maxValue ) ;
static void menu_action_setting_edit_float32 ( const char * pstr , float * ptr , float minValue , float maxValue ) ;
2014-12-29 02:43:14 +01:00
static void menu_action_setting_edit_float43 ( const char * pstr , float * ptr , float minValue , float maxValue ) ;
2012-12-12 11:47:03 +01:00
static void menu_action_setting_edit_float5 ( const char * pstr , float * ptr , float minValue , float maxValue ) ;
static void menu_action_setting_edit_float51 ( const char * pstr , float * ptr , float minValue , float maxValue ) ;
static void menu_action_setting_edit_float52 ( const char * pstr , float * ptr , float minValue , float maxValue ) ;
static void menu_action_setting_edit_long5 ( const char * pstr , unsigned long * ptr , unsigned long minValue , unsigned long maxValue ) ;
Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values
Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset).
Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read.
Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks.
Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk.
Conflicts:
Marlin/language.h
2013-03-19 15:05:11 +01:00
static void menu_action_setting_edit_callback_bool ( const char * pstr , bool * ptr , menuFunc_t callbackFunc ) ;
static void menu_action_setting_edit_callback_int3 ( const char * pstr , int * ptr , int minValue , int maxValue , menuFunc_t callbackFunc ) ;
static void menu_action_setting_edit_callback_float3 ( const char * pstr , float * ptr , float minValue , float maxValue , menuFunc_t callbackFunc ) ;
static void menu_action_setting_edit_callback_float32 ( const char * pstr , float * ptr , float minValue , float maxValue , menuFunc_t callbackFunc ) ;
2014-12-29 02:43:14 +01:00
static void menu_action_setting_edit_callback_float43 ( const char * pstr , float * ptr , float minValue , float maxValue , menuFunc_t callbackFunc ) ;
Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values
Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset).
Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read.
Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks.
Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk.
Conflicts:
Marlin/language.h
2013-03-19 15:05:11 +01:00
static void menu_action_setting_edit_callback_float5 ( const char * pstr , float * ptr , float minValue , float maxValue , menuFunc_t callbackFunc ) ;
static void menu_action_setting_edit_callback_float51 ( const char * pstr , float * ptr , float minValue , float maxValue , menuFunc_t callbackFunc ) ;
static void menu_action_setting_edit_callback_float52 ( const char * pstr , float * ptr , float minValue , float maxValue , menuFunc_t callbackFunc ) ;
static void menu_action_setting_edit_callback_long5 ( const char * pstr , unsigned long * ptr , unsigned long minValue , unsigned long maxValue , menuFunc_t callbackFunc ) ;
2012-12-12 11:47:03 +01:00
2013-06-07 00:49:25 +02:00
# define ENCODER_FEEDRATE_DEADZONE 10
# if !defined(LCD_I2C_VIKI)
2013-12-08 21:34:56 +01:00
# ifndef ENCODER_STEPS_PER_MENU_ITEM
# define ENCODER_STEPS_PER_MENU_ITEM 5
# endif
2013-09-23 23:25:11 +02:00
# ifndef ENCODER_PULSES_PER_STEP
# define ENCODER_PULSES_PER_STEP 1
# endif
2013-06-07 00:49:25 +02:00
# else
2013-12-08 21:34:56 +01:00
# ifndef ENCODER_STEPS_PER_MENU_ITEM
# define ENCODER_STEPS_PER_MENU_ITEM 2 // VIKI LCD rotary encoder uses a different number of steps per rotation
# endif
2013-09-23 23:25:11 +02:00
# ifndef ENCODER_PULSES_PER_STEP
# define ENCODER_PULSES_PER_STEP 1
# endif
2013-06-07 00:49:25 +02:00
# endif
2012-12-12 11:47:03 +01:00
/* Helper macros for menus */
# define START_MENU() do { \
2015-02-20 03:42:57 +01:00
encoderRateMultiplierEnabled = false ; \
2012-12-12 11:47:03 +01:00
if ( encoderPosition > 0x8000 ) encoderPosition = 0 ; \
if ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM < currentMenuViewOffset ) currentMenuViewOffset = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ; \
uint8_t _lineNr = currentMenuViewOffset , _menuItemNr ; \
2013-10-20 10:16:46 +02:00
bool wasClicked = LCD_CLICKED ; \
2012-12-12 11:47:03 +01:00
for ( uint8_t _drawLineNr = 0 ; _drawLineNr < LCD_HEIGHT ; _drawLineNr + + , _lineNr + + ) { \
_menuItemNr = 0 ;
# define MENU_ITEM(type, label, args...) do { \
if ( _menuItemNr = = _lineNr ) { \
if ( lcdDrawUpdate ) { \
2012-12-17 11:09:09 +01:00
const char * _label_pstr = PSTR ( label ) ; \
2012-12-12 11:47:03 +01:00
if ( ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ) = = _menuItemNr ) { \
2012-12-17 11:09:09 +01:00
lcd_implementation_drawmenu_ # # type # # _selected ( _drawLineNr , _label_pstr , # # args ) ; \
2012-12-12 11:47:03 +01:00
} else { \
2012-12-17 11:09:09 +01:00
lcd_implementation_drawmenu_ # # type ( _drawLineNr , _label_pstr , # # args ) ; \
2012-12-12 11:47:03 +01:00
} \
} \
2013-07-29 10:58:09 +02:00
if ( wasClicked & & ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ) = = _menuItemNr ) { \
2012-12-12 11:47:03 +01:00
lcd_quick_feedback ( ) ; \
menu_action_ # # type ( args ) ; \
return ; \
} \
} \
_menuItemNr + + ; \
} while ( 0 )
2015-02-20 03:42:57 +01:00
# ifdef ENCODER_RATE_MULTIPLIER
2015-02-22 03:24:16 +01:00
# define MENU_MULTIPLIER_ITEM(type, label, args...) do { \
2015-02-20 03:42:57 +01:00
if ( _menuItemNr = = _lineNr ) { \
2015-02-20 11:08:41 +01:00
if ( lcdDrawUpdate ) { \
const char * _label_pstr = PSTR ( label ) ; \
if ( ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ) = = _menuItemNr ) { \
lcd_implementation_drawmenu_ # # type # # _selected ( _drawLineNr , _label_pstr , # # args ) ; \
2015-02-20 11:17:16 +01:00
} \
else { \
2015-02-20 11:08:41 +01:00
lcd_implementation_drawmenu_ # # type ( _drawLineNr , _label_pstr , # # args ) ; \
2015-02-20 11:17:16 +01:00
} \
} \
if ( wasClicked & & ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ) = = _menuItemNr ) { \
2015-02-20 11:08:41 +01:00
lcd_quick_feedback ( ) ; \
encoderRateMultiplierEnabled = true ; \
lastEncoderMovementMillis = 0 ; \
menu_action_ # # type ( args ) ; \
2015-02-20 11:17:16 +01:00
return ; \
} \
} \
_menuItemNr + + ; \
2015-02-22 03:24:16 +01:00
} while ( 0 )
# endif //ENCODER_RATE_MULTIPLIER
2012-12-12 11:47:03 +01:00
# define MENU_ITEM_DUMMY() do { _menuItemNr++; } while(0)
# define MENU_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values
Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset).
Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read.
Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks.
Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk.
Conflicts:
Marlin/language.h
2013-03-19 15:05:11 +01:00
# define MENU_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
2015-02-20 03:42:57 +01:00
# ifdef ENCODER_RATE_MULTIPLIER
2015-02-22 03:24:16 +01:00
# define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
# define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_MULTIPLIER_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
# else //!ENCODER_RATE_MULTIPLIER
# define MENU_MULTIPLIER_ITEM_EDIT(type, label, args...) MENU_ITEM(setting_edit_ ## type, label, PSTR(label) , ## args )
# define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label) , ## args )
# endif //!ENCODER_RATE_MULTIPLIER
2012-12-12 11:47:03 +01:00
# define END_MENU() \
if ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM > = _menuItemNr ) encoderPosition = _menuItemNr * ENCODER_STEPS_PER_MENU_ITEM - 1 ; \
if ( ( uint8_t ) ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ) > = currentMenuViewOffset + LCD_HEIGHT ) { currentMenuViewOffset = ( encoderPosition / ENCODER_STEPS_PER_MENU_ITEM ) - LCD_HEIGHT + 1 ; lcdDrawUpdate = 1 ; _lineNr = currentMenuViewOffset - 1 ; _drawLineNr = - 1 ; } \
} } while ( 0 )
/** Used variables to keep track of the menu */
2013-06-07 00:49:25 +02:00
# ifndef REPRAPWORLD_KEYPAD
2012-12-12 11:47:03 +01:00
volatile uint8_t buttons ; //Contains the bits of the currently pressed buttons.
2013-06-07 00:49:25 +02:00
# else
2014-02-17 14:04:44 +01:00
volatile uint8_t buttons_reprapworld_keypad ; // to store the reprapworld_keypad shift register values
2013-06-07 00:49:25 +02:00
# endif
2013-11-17 17:41:30 +01:00
# ifdef LCD_HAS_SLOW_BUTTONS
volatile uint8_t slow_buttons ; //Contains the bits of the currently pressed buttons.
# endif
2012-12-12 11:47:03 +01:00
uint8_t currentMenuViewOffset ; /* scroll offset in the current menu */
uint32_t blocking_enc ;
uint8_t lastEncoderBits ;
uint32_t encoderPosition ;
2013-06-07 00:49:25 +02:00
# if (SDCARDDETECT > 0)
2012-12-12 11:47:03 +01:00
bool lcd_oldcardstatus ;
2011-12-12 19:34:37 +01:00
# endif
2014-12-28 07:26:14 +01:00
# endif //ULTIPANEL
2012-12-12 11:47:03 +01:00
menuFunc_t currentMenu = lcd_status_screen ; /* function pointer to the currently active menu */
uint32_t lcd_next_update_millis ;
uint8_t lcd_status_update_delay ;
2014-11-25 01:56:37 +01:00
bool ignore_click = false ;
2014-11-25 02:12:08 +01:00
bool wait_for_unclick ;
2014-02-17 14:04:44 +01:00
uint8_t lcdDrawUpdate = 2 ; /* Set to none-zero when the LCD needs to draw, decreased after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) */
2012-12-12 11:47:03 +01:00
//prevMenu and prevEncoderPosition are used to store the previous menu location when editing settings.
menuFunc_t prevMenu = NULL ;
uint16_t prevEncoderPosition ;
//Variables used when editing values.
const char * editLabel ;
void * editValue ;
int32_t minEditValue , maxEditValue ;
Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values
Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset).
Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read.
Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks.
Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk.
Conflicts:
Marlin/language.h
2013-03-19 15:05:11 +01:00
menuFunc_t callbackFunc ;
2015-02-20 08:54:06 +01:00
// place-holders for Ki and Kd edits
Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values
Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset).
Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read.
Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks.
Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk.
Conflicts:
Marlin/language.h
2013-03-19 15:05:11 +01:00
float raw_Ki , raw_Kd ;
2012-12-12 11:47:03 +01:00
2014-12-18 16:30:05 +01:00
static void lcd_goto_menu ( menuFunc_t menu , const uint32_t encoder = 0 , const bool feedback = true ) {
if ( currentMenu ! = menu ) {
currentMenu = menu ;
encoderPosition = encoder ;
if ( feedback ) lcd_quick_feedback ( ) ;
2014-12-28 07:26:14 +01:00
// For LCD_PROGRESS_BAR re-initialize the custom characters
2015-01-10 03:16:56 +01:00
# if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
2014-12-28 07:26:14 +01:00
lcd_set_custom_characters ( menu = = lcd_status_screen ) ;
# endif
2014-12-18 16:30:05 +01:00
}
}
2014-02-17 14:04:44 +01:00
/* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */
2012-12-12 11:47:03 +01:00
static void lcd_status_screen ( )
2011-12-12 19:34:37 +01:00
{
2015-02-20 03:42:57 +01:00
encoderRateMultiplierEnabled = false ;
2015-01-10 03:16:56 +01:00
# if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
2014-12-28 07:26:14 +01:00
uint16_t mil = millis ( ) ;
# ifndef PROGRESS_MSG_ONCE
if ( mil > progressBarTick + PROGRESS_BAR_MSG_TIME + PROGRESS_BAR_BAR_TIME ) {
progressBarTick = mil ;
}
# endif
# if PROGRESS_MSG_EXPIRE > 0
// keep the message alive if paused, count down otherwise
if ( messageTick > 0 ) {
if ( card . isFileOpen ( ) ) {
if ( IS_SD_PRINTING ) {
if ( ( mil - messageTick ) > = PROGRESS_MSG_EXPIRE ) {
lcd_status_message [ 0 ] = ' \0 ' ;
messageTick = 0 ;
}
}
else {
messageTick + = LCD_UPDATE_INTERVAL ;
}
}
else {
messageTick = 0 ;
}
}
# endif
# endif //LCD_PROGRESS_BAR
2015-02-22 02:38:56 +01:00
if ( lcd_status_update_delay )
lcd_status_update_delay - - ;
else
lcdDrawUpdate = 1 ;
if ( lcdDrawUpdate ) {
lcd_implementation_status_screen ( ) ;
lcd_status_update_delay = 10 ; /* redraw the main screen every second. This is easier then trying keep track of all things that change on the screen */
}
2015-01-10 03:16:56 +01:00
2012-12-12 11:47:03 +01:00
# ifdef ULTIPANEL
2014-11-25 01:56:37 +01:00
2014-11-25 02:12:08 +01:00
bool current_click = LCD_CLICKED ;
if ( ignore_click ) {
if ( wait_for_unclick ) {
if ( ! current_click ) {
ignore_click = wait_for_unclick = false ;
}
else {
current_click = false ;
}
}
else if ( current_click ) {
lcd_quick_feedback ( ) ;
wait_for_unclick = true ;
current_click = false ;
}
}
if ( current_click )
2012-12-12 11:47:03 +01:00
{
2014-12-18 16:30:05 +01:00
lcd_goto_menu ( lcd_main_menu ) ;
2014-12-28 07:26:14 +01:00
lcd_implementation_init ( // to maybe revive the LCD if static electricity killed it.
2015-01-10 03:16:56 +01:00
# if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
2014-12-28 07:26:14 +01:00
currentMenu = = lcd_status_screen
# endif
) ;
# ifdef FILAMENT_LCD_DISPLAY
message_millis = millis ( ) ; // get status message to show up for a while
# endif
2012-12-12 11:47:03 +01:00
}
2013-06-07 00:49:25 +02:00
2014-03-12 23:13:50 +01:00
# ifdef ULTIPANEL_FEEDMULTIPLY
2013-06-07 00:49:25 +02:00
// Dead zone at 100% feedrate
2013-06-29 13:25:11 +02:00
if ( ( feedmultiply < 100 & & ( feedmultiply + int ( encoderPosition ) ) > 100 ) | |
( feedmultiply > 100 & & ( feedmultiply + int ( encoderPosition ) ) < 100 ) )
2013-06-07 00:49:25 +02:00
{
encoderPosition = 0 ;
feedmultiply = 100 ;
}
if ( feedmultiply = = 100 & & int ( encoderPosition ) > ENCODER_FEEDRATE_DEADZONE )
{
feedmultiply + = int ( encoderPosition ) - ENCODER_FEEDRATE_DEADZONE ;
encoderPosition = 0 ;
}
else if ( feedmultiply = = 100 & & int ( encoderPosition ) < - ENCODER_FEEDRATE_DEADZONE )
{
feedmultiply + = int ( encoderPosition ) + ENCODER_FEEDRATE_DEADZONE ;
2013-12-08 21:34:56 +01:00
encoderPosition = 0 ;
2013-06-07 00:49:25 +02:00
}
else if ( feedmultiply ! = 100 )
{
feedmultiply + = int ( encoderPosition ) ;
encoderPosition = 0 ;
}
2014-12-28 07:26:14 +01:00
# endif //ULTIPANEL_FEEDMULTIPLY
2013-06-07 00:49:25 +02:00
2012-12-12 11:47:03 +01:00
if ( feedmultiply < 10 )
feedmultiply = 10 ;
2014-12-18 16:49:16 +01:00
else if ( feedmultiply > 999 )
2012-12-12 11:47:03 +01:00
feedmultiply = 999 ;
2014-12-28 07:26:14 +01:00
# endif //ULTIPANEL
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
# ifdef ULTIPANEL
2014-12-28 07:26:14 +01:00
static void lcd_return_to_status ( ) { lcd_goto_menu ( lcd_status_screen , 0 , false ) ; }
static void lcd_sdcard_pause ( ) { card . pauseSDPrint ( ) ; }
static void lcd_sdcard_resume ( ) { card . startFileprint ( ) ; }
2011-12-12 19:34:37 +01:00
2015-02-22 02:38:56 +01:00
static void lcd_sdcard_stop ( ) {
card . sdprinting = false ;
card . closefile ( ) ;
quickStop ( ) ;
if ( SD_FINISHED_STEPPERRELEASE ) {
enquecommands_P ( PSTR ( SD_FINISHED_RELEASECOMMAND ) ) ;
}
autotempShutdown ( ) ;
2014-07-20 13:49:26 +02:00
2015-02-22 02:38:56 +01:00
cancel_heatup = true ;
2014-12-01 04:56:06 +01:00
2015-02-22 02:38:56 +01:00
lcd_setstatus ( MSG_PRINT_ABORTED ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
/* Menu implementation */
2015-02-22 02:38:56 +01:00
static void lcd_main_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_WATCH , lcd_status_screen ) ;
if ( movesplanned ( ) | | IS_SD_PRINTING ) {
MENU_ITEM ( submenu , MSG_TUNE , lcd_tune_menu ) ;
}
else {
MENU_ITEM ( submenu , MSG_PREPARE , lcd_prepare_menu ) ;
# ifdef DELTA_CALIBRATION_MENU
MENU_ITEM ( submenu , MSG_DELTA_CALIBRATE , lcd_delta_calibrate_menu ) ;
# endif
}
MENU_ITEM ( submenu , MSG_CONTROL , lcd_control_menu ) ;
# ifdef SDSUPPORT
if ( card . cardOK ) {
if ( card . isFileOpen ( ) ) {
if ( card . sdprinting )
MENU_ITEM ( function , MSG_PAUSE_PRINT , lcd_sdcard_pause ) ;
else
MENU_ITEM ( function , MSG_RESUME_PRINT , lcd_sdcard_resume ) ;
MENU_ITEM ( function , MSG_STOP_PRINT , lcd_sdcard_stop ) ;
}
else {
MENU_ITEM ( submenu , MSG_CARD_MENU , lcd_sdcard_menu ) ;
# if SDCARDDETECT < 1
MENU_ITEM ( gcode , MSG_CNG_SDCARD , PSTR ( " M21 " ) ) ; // SD-card changed by user
# endif
}
2011-12-12 19:34:37 +01:00
}
2015-02-22 02:38:56 +01:00
else {
MENU_ITEM ( submenu , MSG_NO_CARD , lcd_sdcard_menu ) ;
# if SDCARDDETECT < 1
2013-06-07 00:49:25 +02:00
MENU_ITEM ( gcode , MSG_INIT_SDCARD , PSTR ( " M21 " ) ) ; // Manually initialize the SD-card via user interface
2015-02-22 02:38:56 +01:00
# endif
2011-12-12 19:34:37 +01:00
}
2015-02-22 02:38:56 +01:00
# endif //SDSUPPORT
END_MENU ( ) ;
2011-12-12 19:34:37 +01:00
}
2012-03-15 22:29:31 +01:00
# ifdef SDSUPPORT
2015-02-22 02:38:56 +01:00
static void lcd_autostart_sd ( ) {
card . autostart_index = 0 ;
2012-12-12 11:47:03 +01:00
card . setroot ( ) ;
card . checkautostart ( true ) ;
2015-02-22 02:38:56 +01:00
}
2012-12-12 11:47:03 +01:00
# endif
2011-12-12 19:34:37 +01:00
2015-02-22 02:38:56 +01:00
void lcd_set_home_offsets ( ) {
for ( int8_t i = 0 ; i < NUM_AXIS ; i + + ) {
if ( i ! = E_AXIS ) {
add_homing [ i ] - = current_position [ i ] ;
current_position [ i ] = 0.0 ;
2014-10-05 22:35:45 +02:00
}
2015-02-22 02:38:56 +01:00
}
plan_set_position ( 0.0 , 0.0 , 0.0 , current_position [ E_AXIS ] ) ;
2014-10-05 22:35:45 +02:00
2015-02-22 02:38:56 +01:00
// Audio feedback
enquecommands_P ( PSTR ( " M300 S659 P200 \n M300 S698 P200 " ) ) ;
lcd_return_to_status ( ) ;
2014-10-05 22:35:45 +02:00
}
Add the socalled "Babystepping" feature.
It is a realtime control over the head position via the LCD menu system that works _while_ printing.
Using it, one can e.g. tune the z-position in realtime, while printing the first layer.
Also, lost steps can be manually added/removed, but thats not the prime feature.
Stuff is placed into the Tune->Babystep *
It is not possible to have realtime control via gcode sending due to the buffering, so I did not include a gcode yet. However, it could be added, but it movements will not be realtime then.
Historically, a very similar thing was implemented for the "Kaamermaker" project, while Joris was babysitting his offspring, hence the name.
say goodby to fuddling around with the z-axis.
2013-10-06 21:14:51 +02:00
# ifdef BABYSTEPPING
2014-12-18 16:30:05 +01:00
static void _lcd_babystep ( int axis , const char * msg ) {
if ( encoderPosition ! = 0 ) {
babystepsTodo [ axis ] + = ( int ) encoderPosition ;
encoderPosition = 0 ;
lcdDrawUpdate = 1 ;
Add the socalled "Babystepping" feature.
It is a realtime control over the head position via the LCD menu system that works _while_ printing.
Using it, one can e.g. tune the z-position in realtime, while printing the first layer.
Also, lost steps can be manually added/removed, but thats not the prime feature.
Stuff is placed into the Tune->Babystep *
It is not possible to have realtime control via gcode sending due to the buffering, so I did not include a gcode yet. However, it could be added, but it movements will not be realtime then.
Historically, a very similar thing was implemented for the "Kaamermaker" project, while Joris was babysitting his offspring, hence the name.
say goodby to fuddling around with the z-axis.
2013-10-06 21:14:51 +02:00
}
2014-12-23 18:49:54 +01:00
if ( lcdDrawUpdate ) lcd_implementation_drawedit ( msg , " " ) ;
2014-12-18 16:30:05 +01:00
if ( LCD_CLICKED ) lcd_goto_menu ( lcd_tune_menu ) ;
}
2014-12-23 18:49:54 +01:00
static void lcd_babystep_x ( ) { _lcd_babystep ( X_AXIS , PSTR ( MSG_BABYSTEPPING_X ) ) ; }
static void lcd_babystep_y ( ) { _lcd_babystep ( Y_AXIS , PSTR ( MSG_BABYSTEPPING_Y ) ) ; }
static void lcd_babystep_z ( ) { _lcd_babystep ( Z_AXIS , PSTR ( MSG_BABYSTEPPING_Z ) ) ; }
Add the socalled "Babystepping" feature.
It is a realtime control over the head position via the LCD menu system that works _while_ printing.
Using it, one can e.g. tune the z-position in realtime, while printing the first layer.
Also, lost steps can be manually added/removed, but thats not the prime feature.
Stuff is placed into the Tune->Babystep *
It is not possible to have realtime control via gcode sending due to the buffering, so I did not include a gcode yet. However, it could be added, but it movements will not be realtime then.
Historically, a very similar thing was implemented for the "Kaamermaker" project, while Joris was babysitting his offspring, hence the name.
say goodby to fuddling around with the z-axis.
2013-10-06 21:14:51 +02:00
# endif //BABYSTEPPING
2015-02-22 02:38:56 +01:00
static void lcd_tune_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MAIN , lcd_main_menu ) ;
MENU_ITEM_EDIT ( int3 , MSG_SPEED , & feedmultiply , 10 , 999 ) ;
# if TEMP_SENSOR_0 != 0
2015-02-20 03:42:57 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE , & target_temperature [ 0 ] , 0 , HEATER_0_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# if TEMP_SENSOR_1 != 0
2015-02-22 05:18:49 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE MSG_N2 , & target_temperature [ 1 ] , 0 , HEATER_1_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# if TEMP_SENSOR_2 != 0
2015-02-22 05:18:49 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE MSG_N3 , & target_temperature [ 2 ] , 0 , HEATER_2_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# if TEMP_SENSOR_3 != 0
2015-02-22 05:18:49 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE MSG_N4 , & target_temperature [ 3 ] , 0 , HEATER_3_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# if TEMP_SENSOR_BED != 0
2015-02-20 10:22:56 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_BED , & target_temperature_bed , 0 , BED_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
2015-02-20 10:22:56 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_FAN_SPEED , & fanSpeed , 0 , 255 ) ;
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( int3 , MSG_FLOW , & extrudemultiply , 10 , 999 ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( int3 , MSG_FLOW MSG_F0 , & extruder_multiply [ 0 ] , 10 , 999 ) ;
# if TEMP_SENSOR_1 != 0
MENU_ITEM_EDIT ( int3 , MSG_FLOW MSG_F1 , & extruder_multiply [ 1 ] , 10 , 999 ) ;
# endif
# if TEMP_SENSOR_2 != 0
MENU_ITEM_EDIT ( int3 , MSG_FLOW MSG_F2 , & extruder_multiply [ 2 ] , 10 , 999 ) ;
# endif
# if TEMP_SENSOR_3 != 0
MENU_ITEM_EDIT ( int3 , MSG_FLOW MSG_F3 , & extruder_multiply [ 3 ] , 10 , 999 ) ;
# endif
2013-12-08 21:34:56 +01:00
2015-02-22 02:38:56 +01:00
# ifdef BABYSTEPPING
Add the socalled "Babystepping" feature.
It is a realtime control over the head position via the LCD menu system that works _while_ printing.
Using it, one can e.g. tune the z-position in realtime, while printing the first layer.
Also, lost steps can be manually added/removed, but thats not the prime feature.
Stuff is placed into the Tune->Babystep *
It is not possible to have realtime control via gcode sending due to the buffering, so I did not include a gcode yet. However, it could be added, but it movements will not be realtime then.
Historically, a very similar thing was implemented for the "Kaamermaker" project, while Joris was babysitting his offspring, hence the name.
say goodby to fuddling around with the z-axis.
2013-10-06 21:14:51 +02:00
# ifdef BABYSTEP_XY
2014-02-11 14:54:43 +01:00
MENU_ITEM ( submenu , MSG_BABYSTEP_X , lcd_babystep_x ) ;
MENU_ITEM ( submenu , MSG_BABYSTEP_Y , lcd_babystep_y ) ;
Add the socalled "Babystepping" feature.
It is a realtime control over the head position via the LCD menu system that works _while_ printing.
Using it, one can e.g. tune the z-position in realtime, while printing the first layer.
Also, lost steps can be manually added/removed, but thats not the prime feature.
Stuff is placed into the Tune->Babystep *
It is not possible to have realtime control via gcode sending due to the buffering, so I did not include a gcode yet. However, it could be added, but it movements will not be realtime then.
Historically, a very similar thing was implemented for the "Kaamermaker" project, while Joris was babysitting his offspring, hence the name.
say goodby to fuddling around with the z-axis.
2013-10-06 21:14:51 +02:00
# endif //BABYSTEP_XY
2014-02-11 14:54:43 +01:00
MENU_ITEM ( submenu , MSG_BABYSTEP_Z , lcd_babystep_z ) ;
2015-02-22 02:38:56 +01:00
# endif
# ifdef FILAMENTCHANGEENABLE
Added a feature to have filament change by gcode or display trigger.
[default off for now]
syntax: M600 X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
if enabled, after a M600, the printer will retract by E, lift by Z, move to XY, retract even more filament.
Oh, and it will display "remove filament" and beep like crazy.
You are then supposed to insert a new filament (other color, e.g.) and click the display to continue.
After having the nozzle cleaned manually, aided by the disabled e-steppers.
After clicking, the printer will then go back the whole shebang, and continue printing with a fancy new color.
2013-01-27 13:21:34 +01:00
MENU_ITEM ( gcode , MSG_FILAMENTCHANGE , PSTR ( " M600 " ) ) ;
2015-02-22 02:38:56 +01:00
# endif
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2015-02-22 02:38:56 +01:00
void _lcd_preheat ( int endnum , const float temph , const float tempb , const int fan ) {
if ( temph > 0 ) setTargetHotend ( temph , endnum ) ;
setTargetBed ( tempb ) ;
fanSpeed = fan ;
lcd_return_to_status ( ) ;
setWatch ( ) ; // heater sanity check timer
2014-03-17 18:37:46 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_preheat_pla0 ( ) { _lcd_preheat ( 0 , plaPreheatHotendTemp , plaPreheatHPBTemp , plaPreheatFanSpeed ) ; }
void lcd_preheat_abs0 ( ) { _lcd_preheat ( 0 , absPreheatHotendTemp , absPreheatHPBTemp , absPreheatFanSpeed ) ; }
2014-03-17 18:37:46 +01:00
# if TEMP_SENSOR_1 != 0 //2nd extruder preheat
2015-02-22 02:38:56 +01:00
void lcd_preheat_pla1 ( ) { _lcd_preheat ( 1 , plaPreheatHotendTemp , plaPreheatHPBTemp , plaPreheatFanSpeed ) ; }
void lcd_preheat_abs1 ( ) { _lcd_preheat ( 1 , absPreheatHotendTemp , absPreheatHPBTemp , absPreheatFanSpeed ) ; }
2014-03-17 18:37:46 +01:00
# endif //2nd extruder preheat
# if TEMP_SENSOR_2 != 0 //3 extruder preheat
2015-02-22 02:38:56 +01:00
void lcd_preheat_pla2 ( ) { _lcd_preheat ( 2 , plaPreheatHotendTemp , plaPreheatHPBTemp , plaPreheatFanSpeed ) ; }
void lcd_preheat_abs2 ( ) { _lcd_preheat ( 2 , absPreheatHotendTemp , absPreheatHPBTemp , absPreheatFanSpeed ) ; }
2014-03-17 18:37:46 +01:00
# endif //3 extruder preheat
2015-01-23 23:13:06 +01:00
# if TEMP_SENSOR_3 != 0 //4 extruder preheat
2015-02-22 02:38:56 +01:00
void lcd_preheat_pla3 ( ) { _lcd_preheat ( 3 , plaPreheatHotendTemp , plaPreheatHPBTemp , plaPreheatFanSpeed ) ; }
void lcd_preheat_abs3 ( ) { _lcd_preheat ( 3 , absPreheatHotendTemp , absPreheatHPBTemp , absPreheatFanSpeed ) ; }
2015-01-23 23:13:06 +01:00
# endif //4 extruder preheat
# if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 //more than one extruder present
2015-02-22 02:38:56 +01:00
void lcd_preheat_pla0123 ( ) {
2014-03-17 18:37:46 +01:00
setTargetHotend0 ( plaPreheatHotendTemp ) ;
setTargetHotend1 ( plaPreheatHotendTemp ) ;
setTargetHotend2 ( plaPreheatHotendTemp ) ;
2015-02-22 02:38:56 +01:00
_lcd_preheat ( 3 , plaPreheatHotendTemp , plaPreheatHPBTemp , plaPreheatFanSpeed ) ;
}
void lcd_preheat_abs0123 ( ) {
2014-03-17 18:37:46 +01:00
setTargetHotend0 ( absPreheatHotendTemp ) ;
setTargetHotend1 ( absPreheatHotendTemp ) ;
setTargetHotend2 ( absPreheatHotendTemp ) ;
2015-02-22 02:38:56 +01:00
_lcd_preheat ( 3 , absPreheatHotendTemp , absPreheatHPBTemp , absPreheatFanSpeed ) ;
}
2014-03-17 18:37:46 +01:00
# endif //more than one extruder present
2015-02-22 02:38:56 +01:00
void lcd_preheat_pla_bedonly ( ) { _lcd_preheat ( 0 , 0 , plaPreheatHPBTemp , plaPreheatFanSpeed ) ; }
void lcd_preheat_abs_bedonly ( ) { _lcd_preheat ( 0 , 0 , absPreheatHPBTemp , absPreheatFanSpeed ) ; }
2014-03-17 18:37:46 +01:00
2015-02-22 02:38:56 +01:00
static void lcd_preheat_pla_menu ( ) {
2015-01-23 23:13:06 +01:00
START_MENU ( ) ;
MENU_ITEM ( back , MSG_PREPARE , lcd_prepare_menu ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM ( function , MSG_PREHEAT_PLA_N MSG_H1 , lcd_preheat_pla0 ) ;
# if TEMP_SENSOR_1 != 0 //2 extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_PLA_N MSG_H2 , lcd_preheat_pla1 ) ;
# endif //2 extruder preheat
# if TEMP_SENSOR_2 != 0 //3 extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_PLA_N MSG_H3 , lcd_preheat_pla2 ) ;
# endif //3 extruder preheat
# if TEMP_SENSOR_3 != 0 //4 extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_PLA_N MSG_H4 , lcd_preheat_pla3 ) ;
# endif //4 extruder preheat
# if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 //all extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_PLA_ALL , lcd_preheat_pla0123 ) ;
# endif //all extruder preheat
# if TEMP_SENSOR_BED != 0
MENU_ITEM ( function , MSG_PREHEAT_PLA_BEDONLY , lcd_preheat_pla_bedonly ) ;
# endif
2015-01-23 23:13:06 +01:00
END_MENU ( ) ;
2014-03-17 18:37:46 +01:00
}
2015-02-22 02:38:56 +01:00
static void lcd_preheat_abs_menu ( ) {
2015-01-23 23:13:06 +01:00
START_MENU ( ) ;
MENU_ITEM ( back , MSG_PREPARE , lcd_prepare_menu ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM ( function , MSG_PREHEAT_ABS_N MSG_H1 , lcd_preheat_abs0 ) ;
# if TEMP_SENSOR_1 != 0 //2 extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_ABS_N MSG_H2 , lcd_preheat_abs1 ) ;
# endif //2 extruder preheat
# if TEMP_SENSOR_2 != 0 //3 extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_ABS_N MSG_H3 , lcd_preheat_abs2 ) ;
# endif //3 extruder preheat
# if TEMP_SENSOR_3 != 0 //4 extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_ABS_N MSG_H4 , lcd_preheat_abs3 ) ;
# endif //4 extruder preheat
# if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_3 != 0 //all extruder preheat
MENU_ITEM ( function , MSG_PREHEAT_ABS_ALL , lcd_preheat_abs0123 ) ;
# endif //all extruder preheat
# if TEMP_SENSOR_BED != 0
MENU_ITEM ( function , MSG_PREHEAT_ABS_BEDONLY , lcd_preheat_abs_bedonly ) ;
# endif
2015-01-23 23:13:06 +01:00
END_MENU ( ) ;
2014-03-17 18:37:46 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_cooldown ( ) {
setTargetHotend0 ( 0 ) ;
setTargetHotend1 ( 0 ) ;
setTargetHotend2 ( 0 ) ;
setTargetHotend3 ( 0 ) ;
setTargetBed ( 0 ) ;
fanSpeed = 0 ;
lcd_return_to_status ( ) ;
2014-03-17 18:37:46 +01:00
}
2015-02-22 02:38:56 +01:00
static void lcd_prepare_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MAIN , lcd_main_menu ) ;
# ifdef SDSUPPORT
2013-10-12 13:24:55 +02:00
# ifdef MENU_ADDAUTOSTART
MENU_ITEM ( function , MSG_AUTOSTART , lcd_autostart_sd ) ;
# endif
2014-03-17 18:37:46 +01:00
# endif
2015-02-22 02:38:56 +01:00
MENU_ITEM ( gcode , MSG_DISABLE_STEPPERS , PSTR ( " M84 " ) ) ;
MENU_ITEM ( gcode , MSG_AUTO_HOME , PSTR ( " G28 " ) ) ;
MENU_ITEM ( function , MSG_SET_HOME_OFFSETS , lcd_set_home_offsets ) ;
//MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0"));
# if TEMP_SENSOR_0 != 0
# if TEMP_SENSOR_1 != 0 || TEMP_SENSOR_2 != 0 || TEMP_SENSOR_BED != 0
MENU_ITEM ( submenu , MSG_PREHEAT_PLA , lcd_preheat_pla_menu ) ;
MENU_ITEM ( submenu , MSG_PREHEAT_ABS , lcd_preheat_abs_menu ) ;
# else
MENU_ITEM ( function , MSG_PREHEAT_PLA , lcd_preheat_pla0 ) ;
MENU_ITEM ( function , MSG_PREHEAT_ABS , lcd_preheat_abs0 ) ;
# endif
# endif
MENU_ITEM ( function , MSG_COOLDOWN , lcd_cooldown ) ;
# if defined(POWER_SUPPLY) && POWER_SUPPLY > 0 && defined(PS_ON_PIN) && PS_ON_PIN > -1
if ( powersupply ) {
MENU_ITEM ( gcode , MSG_SWITCH_PS_OFF , PSTR ( " M81 " ) ) ;
2013-03-05 14:52:51 +01:00
}
2015-02-22 02:38:56 +01:00
else {
MENU_ITEM ( gcode , MSG_SWITCH_PS_ON , PSTR ( " M80 " ) ) ;
}
# endif
MENU_ITEM ( submenu , MSG_MOVE_AXIS , lcd_move_menu ) ;
2015-03-15 23:18:11 +01:00
# if defined(MANUAL_BED_LEVELING)
MENU_ITEM ( submenu , MSG_LEVEL_BED , lcd_level_bed ) ;
# endif
2015-02-22 02:38:56 +01:00
END_MENU ( ) ;
2011-12-12 19:34:37 +01:00
}
2014-12-29 18:19:25 +01:00
# ifdef DELTA_CALIBRATION_MENU
static void lcd_delta_calibrate_menu ( )
{
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MAIN , lcd_main_menu ) ;
MENU_ITEM ( gcode , MSG_AUTO_HOME , PSTR ( " G28 " ) ) ;
MENU_ITEM ( gcode , MSG_DELTA_CALIBRATE_X , PSTR ( " G0 F8000 X-77.94 Y-45 Z0 " ) ) ;
MENU_ITEM ( gcode , MSG_DELTA_CALIBRATE_Y , PSTR ( " G0 F8000 X77.94 Y-45 Z0 " ) ) ;
MENU_ITEM ( gcode , MSG_DELTA_CALIBRATE_Z , PSTR ( " G0 F8000 X0 Y90 Z0 " ) ) ;
MENU_ITEM ( gcode , MSG_DELTA_CALIBRATE_CENTER , PSTR ( " G0 F8000 X0 Y0 Z0 " ) ) ;
END_MENU ( ) ;
}
# endif // DELTA_CALIBRATION_MENU
2012-12-12 11:47:03 +01:00
float move_menu_scale ;
static void lcd_move_menu_axis ( ) ;
2011-12-12 19:34:37 +01:00
2014-12-18 16:30:05 +01:00
static void _lcd_move ( const char * name , int axis , int min , int max ) {
if ( encoderPosition ! = 0 ) {
refresh_cmd_timeout ( ) ;
current_position [ axis ] + = float ( ( int ) encoderPosition ) * move_menu_scale ;
if ( min_software_endstops & & current_position [ axis ] < min ) current_position [ axis ] = min ;
if ( max_software_endstops & & current_position [ axis ] > max ) current_position [ axis ] = max ;
encoderPosition = 0 ;
# ifdef DELTA
calculate_delta ( current_position ) ;
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ axis ] / 60 , active_extruder ) ;
# else
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ axis ] / 60 , active_extruder ) ;
# endif
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate ) lcd_implementation_drawedit ( name , ftostr31 ( current_position [ axis ] ) ) ;
if ( LCD_CLICKED ) lcd_goto_menu ( lcd_move_menu_axis ) ;
2012-12-12 11:47:03 +01:00
}
2014-12-18 16:30:05 +01:00
static void lcd_move_x ( ) { _lcd_move ( PSTR ( " X " ) , X_AXIS , X_MIN_POS , X_MAX_POS ) ; }
static void lcd_move_y ( ) { _lcd_move ( PSTR ( " Y " ) , Y_AXIS , Y_MIN_POS , Y_MAX_POS ) ; }
static void lcd_move_z ( ) { _lcd_move ( PSTR ( " Z " ) , Z_AXIS , Z_MIN_POS , Z_MAX_POS ) ; }
2015-02-22 02:38:56 +01:00
static void lcd_move_e ( ) {
if ( encoderPosition ! = 0 ) {
current_position [ E_AXIS ] + = float ( ( int ) encoderPosition ) * move_menu_scale ;
encoderPosition = 0 ;
# ifdef DELTA
calculate_delta ( current_position ) ;
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ E_AXIS ] / 60 , active_extruder ) ;
# else
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ E_AXIS ] / 60 , active_extruder ) ;
# endif
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate ) lcd_implementation_drawedit ( PSTR ( " Extruder " ) , ftostr31 ( current_position [ E_AXIS ] ) ) ;
if ( LCD_CLICKED ) lcd_goto_menu ( lcd_move_menu_axis ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
static void lcd_move_menu_axis ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MOVE_AXIS , lcd_move_menu ) ;
MENU_ITEM ( submenu , MSG_MOVE_X , lcd_move_x ) ;
MENU_ITEM ( submenu , MSG_MOVE_Y , lcd_move_y ) ;
if ( move_menu_scale < 10.0 ) {
MENU_ITEM ( submenu , MSG_MOVE_Z , lcd_move_z ) ;
MENU_ITEM ( submenu , MSG_MOVE_E , lcd_move_e ) ;
}
END_MENU ( ) ;
2012-06-02 20:32:28 +02:00
}
2015-02-22 02:38:56 +01:00
static void lcd_move_menu_10mm ( ) {
move_menu_scale = 10.0 ;
lcd_move_menu_axis ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
static void lcd_move_menu_1mm ( ) {
move_menu_scale = 1.0 ;
lcd_move_menu_axis ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
static void lcd_move_menu_01mm ( ) {
move_menu_scale = 0.1 ;
lcd_move_menu_axis ( ) ;
2012-12-12 11:47:03 +01:00
}
2012-06-02 20:32:28 +02:00
2015-02-22 02:38:56 +01:00
static void lcd_move_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_PREPARE , lcd_prepare_menu ) ;
MENU_ITEM ( submenu , MSG_MOVE_10MM , lcd_move_menu_10mm ) ;
MENU_ITEM ( submenu , MSG_MOVE_1MM , lcd_move_menu_1mm ) ;
MENU_ITEM ( submenu , MSG_MOVE_01MM , lcd_move_menu_01mm ) ;
//TODO:X,Y,Z,E
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2012-06-02 20:32:28 +02:00
2015-02-22 02:38:56 +01:00
static void lcd_control_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MAIN , lcd_main_menu ) ;
MENU_ITEM ( submenu , MSG_TEMPERATURE , lcd_control_temperature_menu ) ;
MENU_ITEM ( submenu , MSG_MOTION , lcd_control_motion_menu ) ;
MENU_ITEM ( submenu , MSG_VOLUMETRIC , lcd_control_volumetric_menu ) ;
2014-12-29 02:43:14 +01:00
2015-02-22 02:38:56 +01:00
# ifdef DOGLCD
//MENU_ITEM_EDIT(int3, MSG_CONTRAST, &lcd_contrast, 0, 63);
2013-07-14 10:28:26 +02:00
MENU_ITEM ( submenu , MSG_CONTRAST , lcd_set_contrast ) ;
2015-02-22 02:38:56 +01:00
# endif
# ifdef FWRETRACT
2012-12-12 11:47:03 +01:00
MENU_ITEM ( submenu , MSG_RETRACT , lcd_control_retract_menu ) ;
2015-02-22 02:38:56 +01:00
# endif
# ifdef EEPROM_SETTINGS
2012-12-12 11:47:03 +01:00
MENU_ITEM ( function , MSG_STORE_EPROM , Config_StoreSettings ) ;
MENU_ITEM ( function , MSG_LOAD_EPROM , Config_RetrieveSettings ) ;
2015-02-22 02:38:56 +01:00
# endif
MENU_ITEM ( function , MSG_RESTORE_FAILSAFE , Config_ResetDefault ) ;
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2015-02-20 08:54:06 +01:00
# ifdef PIDTEMP
2015-02-20 09:00:19 +01:00
2015-02-20 08:54:06 +01:00
// Helpers for editing PID Ki & Kd values
// grab the PID value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_i ( int e ) {
PID_PARAM ( Ki , e ) = scalePID_i ( raw_Ki ) ;
updatePID ( ) ;
}
void copy_and_scalePID_d ( int e ) {
PID_PARAM ( Kd , e ) = scalePID_d ( raw_Kd ) ;
updatePID ( ) ;
}
void copy_and_scalePID_i_E1 ( ) { copy_and_scalePID_i ( 0 ) ; }
void copy_and_scalePID_d_E1 ( ) { copy_and_scalePID_d ( 0 ) ; }
2015-02-20 09:00:19 +01:00
# ifdef PID_PARAMS_PER_EXTRUDER
# if EXTRUDERS > 1
void copy_and_scalePID_i_E2 ( ) { copy_and_scalePID_i ( 1 ) ; }
void copy_and_scalePID_d_E2 ( ) { copy_and_scalePID_d ( 1 ) ; }
# if EXTRUDERS > 2
void copy_and_scalePID_i_E3 ( ) { copy_and_scalePID_i ( 2 ) ; }
void copy_and_scalePID_d_E3 ( ) { copy_and_scalePID_d ( 2 ) ; }
# if EXTRUDERS > 3
void copy_and_scalePID_i_E4 ( ) { copy_and_scalePID_i ( 3 ) ; }
2015-02-22 03:41:04 +01:00
void copy_and_scalePID_d_E4 ( ) { copy_and_scalePID_d ( 3 ) ; }
2015-02-20 09:00:19 +01:00
# endif //EXTRUDERS > 3
# endif //EXTRUDERS > 2
# endif //EXTRUDERS > 1
# endif //PID_PARAMS_PER_EXTRUDER
# endif //PIDTEMP
2015-02-20 08:54:06 +01:00
2015-02-22 02:38:56 +01:00
static void lcd_control_temperature_menu ( ) {
2015-01-23 23:13:06 +01:00
START_MENU ( ) ;
MENU_ITEM ( back , MSG_CONTROL , lcd_control_menu ) ;
2015-02-20 08:54:06 +01:00
# if TEMP_SENSOR_0 != 0
2015-02-22 03:13:31 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE , & target_temperature [ 0 ] , 0 , HEATER_0_MAXTEMP - 15 ) ;
2015-02-20 08:54:06 +01:00
# endif
# if EXTRUDERS > 1
# if TEMP_SENSOR_1 != 0
2015-02-22 05:18:49 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE MSG_N2 , & target_temperature [ 1 ] , 0 , HEATER_1_MAXTEMP - 15 ) ;
2015-02-20 08:54:06 +01:00
# endif
# if EXTRUDERS > 2
# if TEMP_SENSOR_2 != 0
2015-02-22 05:18:49 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE MSG_N3 , & target_temperature [ 2 ] , 0 , HEATER_2_MAXTEMP - 15 ) ;
2015-02-20 08:54:06 +01:00
# endif
2015-02-22 02:38:56 +01:00
# if EXTRUDERS > 3
2015-02-20 08:54:06 +01:00
# if TEMP_SENSOR_3 != 0
2015-02-22 05:18:49 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_NOZZLE MSG_N4 , & target_temperature [ 3 ] , 0 , HEATER_3_MAXTEMP - 15 ) ;
2015-02-20 08:54:06 +01:00
# endif
2015-02-22 05:18:49 +01:00
# endif // EXTRUDERS > 3
# endif // EXTRUDERS > 2
# endif // EXTRUDERS > 1
2015-02-20 08:54:06 +01:00
# if TEMP_SENSOR_BED != 0
2015-02-22 03:13:31 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_BED , & target_temperature_bed , 0 , BED_MAXTEMP - 15 ) ;
2015-02-20 08:54:06 +01:00
# endif
2015-02-20 03:42:57 +01:00
MENU_MULTIPLIER_ITEM_EDIT ( int3 , MSG_FAN_SPEED , & fanSpeed , 0 , 255 ) ;
2015-02-22 02:38:56 +01:00
# if defined(AUTOTEMP) && (TEMP_SENSOR_0 != 0)
2015-02-20 08:54:06 +01:00
MENU_ITEM_EDIT ( bool , MSG_AUTOTEMP , & autotemp_enabled ) ;
MENU_ITEM_EDIT ( float3 , MSG_MIN , & autotemp_min , 0 , HEATER_0_MAXTEMP - 15 ) ;
MENU_ITEM_EDIT ( float3 , MSG_MAX , & autotemp_max , 0 , HEATER_0_MAXTEMP - 15 ) ;
MENU_ITEM_EDIT ( float32 , MSG_FACTOR , & autotemp_factor , 0.0 , 1.0 ) ;
# endif
# ifdef PIDTEMP
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i ( PID_PARAM ( Ki , 0 ) ) ;
raw_Kd = unscalePID_d ( PID_PARAM ( Kd , 0 ) ) ;
MENU_ITEM_EDIT ( float52 , MSG_PID_P , & PID_PARAM ( Kp , 0 ) , 1 , 9990 ) ;
// i is typically a small value so allows values below 1
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_I , & raw_Ki , 0.01 , 9990 , copy_and_scalePID_i_E1 ) ;
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_D , & raw_Kd , 1 , 9990 , copy_and_scalePID_d_E1 ) ;
2015-01-11 03:50:17 +01:00
# ifdef PID_ADD_EXTRUSION_RATE
2015-02-20 08:54:06 +01:00
MENU_ITEM_EDIT ( float3 , MSG_PID_C , & PID_PARAM ( Kc , 0 ) , 1 , 9990 ) ;
2015-01-11 03:50:17 +01:00
# endif //PID_ADD_EXTRUSION_RATE
2015-02-20 08:54:06 +01:00
# ifdef PID_PARAMS_PER_EXTRUDER
# if EXTRUDERS > 1
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i ( PID_PARAM ( Ki , 1 ) ) ;
raw_Kd = unscalePID_d ( PID_PARAM ( Kd , 1 ) ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float52 , MSG_PID_P MSG_E2 , & PID_PARAM ( Kp , 1 ) , 1 , 9990 ) ;
2015-02-20 08:54:06 +01:00
// i is typically a small value so allows values below 1
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_I MSG_E2 , & raw_Ki , 0.01 , 9990 , copy_and_scalePID_i_E2 ) ;
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_D MSG_E2 , & raw_Kd , 1 , 9990 , copy_and_scalePID_d_E2 ) ;
2015-01-11 03:50:17 +01:00
# ifdef PID_ADD_EXTRUSION_RATE
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float3 , MSG_PID_C MSG_E2 , & PID_PARAM ( Kc , 1 ) , 1 , 9990 ) ;
2015-01-11 03:50:17 +01:00
# endif //PID_ADD_EXTRUSION_RATE
2015-02-20 08:54:06 +01:00
# if EXTRUDERS > 2
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i ( PID_PARAM ( Ki , 2 ) ) ;
raw_Kd = unscalePID_d ( PID_PARAM ( Kd , 2 ) ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float52 , MSG_PID_P MSG_E3 , & PID_PARAM ( Kp , 2 ) , 1 , 9990 ) ;
2015-02-20 08:54:06 +01:00
// i is typically a small value so allows values below 1
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_I MSG_E3 , & raw_Ki , 0.01 , 9990 , copy_and_scalePID_i_E3 ) ;
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_D MSG_E3 , & raw_Kd , 1 , 9990 , copy_and_scalePID_d_E3 ) ;
2015-02-20 08:54:06 +01:00
# ifdef PID_ADD_EXTRUSION_RATE
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float3 , MSG_PID_C MSG_E3 , & PID_PARAM ( Kc , 2 ) , 1 , 9990 ) ;
2015-02-20 08:54:06 +01:00
# endif //PID_ADD_EXTRUSION_RATE
# if EXTRUDERS > 3
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i ( PID_PARAM ( Ki , 3 ) ) ;
raw_Kd = unscalePID_d ( PID_PARAM ( Kd , 3 ) ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float52 , MSG_PID_P MSG_E4 , & PID_PARAM ( Kp , 3 ) , 1 , 9990 ) ;
2015-02-20 08:54:06 +01:00
// i is typically a small value so allows values below 1
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_I MSG_E4 , & raw_Ki , 0.01 , 9990 , copy_and_scalePID_i_E4 ) ;
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_D MSG_E4 , & raw_Kd , 1 , 9990 , copy_and_scalePID_d_E4 ) ;
2015-02-20 08:54:06 +01:00
# ifdef PID_ADD_EXTRUSION_RATE
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float3 , MSG_PID_C MSG_E4 , & PID_PARAM ( Kc , 3 ) , 1 , 9990 ) ;
2015-02-20 08:54:06 +01:00
# endif //PID_ADD_EXTRUSION_RATE
# endif //EXTRUDERS > 3
# endif //EXTRUDERS > 2
# endif //EXTRUDERS > 1
# endif //PID_PARAMS_PER_EXTRUDER
# endif //PIDTEMP
MENU_ITEM ( submenu , MSG_PREHEAT_PLA_SETTINGS , lcd_control_temperature_preheat_pla_settings_menu ) ;
MENU_ITEM ( submenu , MSG_PREHEAT_ABS_SETTINGS , lcd_control_temperature_preheat_abs_settings_menu ) ;
END_MENU ( ) ;
2011-12-12 19:34:37 +01:00
}
2015-02-22 02:38:56 +01:00
static void lcd_control_temperature_preheat_pla_settings_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_TEMPERATURE , lcd_control_temperature_menu ) ;
MENU_ITEM_EDIT ( int3 , MSG_FAN_SPEED , & plaPreheatFanSpeed , 0 , 255 ) ;
# if TEMP_SENSOR_0 != 0
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE , & plaPreheatHotendTemp , 0 , HEATER_0_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# if TEMP_SENSOR_BED != 0
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( int3 , MSG_BED , & plaPreheatHPBTemp , 0 , BED_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# ifdef EEPROM_SETTINGS
2012-12-12 11:47:03 +01:00
MENU_ITEM ( function , MSG_STORE_EPROM , Config_StoreSettings ) ;
2015-02-22 02:38:56 +01:00
# endif
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2015-02-22 02:38:56 +01:00
static void lcd_control_temperature_preheat_abs_settings_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_TEMPERATURE , lcd_control_temperature_menu ) ;
MENU_ITEM_EDIT ( int3 , MSG_FAN_SPEED , & absPreheatFanSpeed , 0 , 255 ) ;
# if TEMP_SENSOR_0 != 0
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE , & absPreheatHotendTemp , 0 , HEATER_0_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# if TEMP_SENSOR_BED != 0
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( int3 , MSG_BED , & absPreheatHPBTemp , 0 , BED_MAXTEMP - 15 ) ;
2015-02-22 02:38:56 +01:00
# endif
# ifdef EEPROM_SETTINGS
2012-12-12 11:47:03 +01:00
MENU_ITEM ( function , MSG_STORE_EPROM , Config_StoreSettings ) ;
2015-02-22 02:38:56 +01:00
# endif
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2015-02-22 02:38:56 +01:00
static void lcd_control_motion_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_CONTROL , lcd_control_menu ) ;
# ifdef ENABLE_AUTO_BED_LEVELING
2014-02-17 14:04:44 +01:00
MENU_ITEM_EDIT ( float32 , MSG_ZPROBE_ZOFFSET , & zprobe_zoffset , 0.5 , 50 ) ;
2015-02-22 02:38:56 +01:00
# endif
MENU_ITEM_EDIT ( float5 , MSG_ACC , & acceleration , 500 , 99000 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VXY_JERK , & max_xy_jerk , 1 , 990 ) ;
MENU_ITEM_EDIT ( float52 , MSG_VZ_JERK , & max_z_jerk , 0.1 , 990 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VE_JERK , & max_e_jerk , 1 , 990 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VMAX MSG_X , & max_feedrate [ X_AXIS ] , 1 , 999 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VMAX MSG_Y , & max_feedrate [ Y_AXIS ] , 1 , 999 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VMAX MSG_Z , & max_feedrate [ Z_AXIS ] , 1 , 999 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VMAX MSG_E , & max_feedrate [ E_AXIS ] , 1 , 999 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VMIN , & minimumfeedrate , 0 , 999 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VTRAV_MIN , & mintravelfeedrate , 0 , 999 ) ;
MENU_ITEM_EDIT_CALLBACK ( long5 , MSG_AMAX MSG_X , & max_acceleration_units_per_sq_second [ X_AXIS ] , 100 , 99000 , reset_acceleration_rates ) ;
MENU_ITEM_EDIT_CALLBACK ( long5 , MSG_AMAX MSG_Y , & max_acceleration_units_per_sq_second [ Y_AXIS ] , 100 , 99000 , reset_acceleration_rates ) ;
MENU_ITEM_EDIT_CALLBACK ( long5 , MSG_AMAX MSG_Z , & max_acceleration_units_per_sq_second [ Z_AXIS ] , 100 , 99000 , reset_acceleration_rates ) ;
MENU_ITEM_EDIT_CALLBACK ( long5 , MSG_AMAX MSG_E , & max_acceleration_units_per_sq_second [ E_AXIS ] , 100 , 99000 , reset_acceleration_rates ) ;
MENU_ITEM_EDIT ( float5 , MSG_A_RETRACT , & retract_acceleration , 100 , 99000 ) ;
2015-03-11 17:19:02 +01:00
MENU_ITEM_EDIT ( float5 , MSG_A_TRAVEL , & travel_acceleration , 100 , 99000 ) ;
2015-02-22 02:38:56 +01:00
MENU_ITEM_EDIT ( float52 , MSG_XSTEPS , & axis_steps_per_unit [ X_AXIS ] , 5 , 9999 ) ;
MENU_ITEM_EDIT ( float52 , MSG_YSTEPS , & axis_steps_per_unit [ Y_AXIS ] , 5 , 9999 ) ;
MENU_ITEM_EDIT ( float51 , MSG_ZSTEPS , & axis_steps_per_unit [ Z_AXIS ] , 5 , 9999 ) ;
MENU_ITEM_EDIT ( float51 , MSG_ESTEPS , & axis_steps_per_unit [ E_AXIS ] , 5 , 9999 ) ;
# ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
2014-02-11 14:54:43 +01:00
MENU_ITEM_EDIT ( bool , MSG_ENDSTOP_ABORT , & abort_on_endstop_hit ) ;
2015-02-22 02:38:56 +01:00
# endif
# ifdef SCARA
2014-07-20 13:49:26 +02:00
MENU_ITEM_EDIT ( float74 , MSG_XSCALE , & axis_scaling [ X_AXIS ] , 0.5 , 2 ) ;
MENU_ITEM_EDIT ( float74 , MSG_YSCALE , & axis_scaling [ Y_AXIS ] , 0.5 , 2 ) ;
2015-02-22 02:38:56 +01:00
# endif
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2015-02-22 05:18:49 +01:00
static void lcd_control_volumetric_menu ( ) {
2015-02-22 02:38:56 +01:00
START_MENU ( ) ;
MENU_ITEM ( back , MSG_CONTROL , lcd_control_menu ) ;
MENU_ITEM_EDIT_CALLBACK ( bool , MSG_VOLUMETRIC_ENABLED , & volumetric_enabled , calculate_volumetric_multipliers ) ;
if ( volumetric_enabled ) {
2015-02-20 10:22:56 +01:00
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK ( float43 , MSG_FILAMENT_SIZE_EXTRUDER_0 , & filament_size [ 0 ] , 1.5 , 3.25 , calculate_volumetric_multipliers ) ;
2015-02-22 02:38:56 +01:00
# if EXTRUDERS > 1
2015-02-20 10:22:56 +01:00
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK ( float43 , MSG_FILAMENT_SIZE_EXTRUDER_1 , & filament_size [ 1 ] , 1.5 , 3.25 , calculate_volumetric_multipliers ) ;
2015-02-22 02:38:56 +01:00
# if EXTRUDERS > 2
2015-02-20 10:22:56 +01:00
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK ( float43 , MSG_FILAMENT_SIZE_EXTRUDER_2 , & filament_size [ 2 ] , 1.5 , 3.25 , calculate_volumetric_multipliers ) ;
2015-02-22 02:38:56 +01:00
# if EXTRUDERS > 3
2015-02-20 10:22:56 +01:00
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK ( float43 , MSG_FILAMENT_SIZE_EXTRUDER_3 , & filament_size [ 3 ] , 1.5 , 3.25 , calculate_volumetric_multipliers ) ;
2015-02-22 02:38:56 +01:00
# endif //EXTRUDERS > 3
# endif //EXTRUDERS > 2
# endif //EXTRUDERS > 1
}
END_MENU ( ) ;
2014-12-29 02:43:14 +01:00
}
2015-02-22 02:38:56 +01:00
2013-07-14 10:28:26 +02:00
# ifdef DOGLCD
2015-02-22 02:38:56 +01:00
static void lcd_set_contrast ( ) {
if ( encoderPosition ! = 0 ) {
lcd_contrast - = encoderPosition ;
if ( lcd_contrast < 0 ) lcd_contrast = 0 ;
else if ( lcd_contrast > 63 ) lcd_contrast = 63 ;
encoderPosition = 0 ;
lcdDrawUpdate = 1 ;
u8g . setContrast ( lcd_contrast ) ;
}
if ( lcdDrawUpdate ) lcd_implementation_drawedit ( PSTR ( MSG_CONTRAST ) , itostr2 ( lcd_contrast ) ) ;
if ( LCD_CLICKED ) lcd_goto_menu ( lcd_control_menu ) ;
2013-07-14 10:28:26 +02:00
}
2015-02-22 02:38:56 +01:00
# endif //DOGLCD
2013-07-14 10:28:26 +02:00
2012-12-12 11:47:03 +01:00
# ifdef FWRETRACT
2015-02-22 02:38:56 +01:00
static void lcd_control_retract_menu ( ) {
START_MENU ( ) ;
MENU_ITEM ( back , MSG_CONTROL , lcd_control_menu ) ;
MENU_ITEM_EDIT ( bool , MSG_AUTORETRACT , & autoretract_enabled ) ;
MENU_ITEM_EDIT ( float52 , MSG_CONTROL_RETRACT , & retract_length , 0 , 100 ) ;
# if EXTRUDERS > 1
MENU_ITEM_EDIT ( float52 , MSG_CONTROL_RETRACT_SWAP , & retract_length_swap , 0 , 100 ) ;
# endif
MENU_ITEM_EDIT ( float3 , MSG_CONTROL_RETRACTF , & retract_feedrate , 1 , 999 ) ;
MENU_ITEM_EDIT ( float52 , MSG_CONTROL_RETRACT_ZLIFT , & retract_zlift , 0 , 999 ) ;
MENU_ITEM_EDIT ( float52 , MSG_CONTROL_RETRACT_RECOVER , & retract_recover_length , 0 , 100 ) ;
# if EXTRUDERS > 1
MENU_ITEM_EDIT ( float52 , MSG_CONTROL_RETRACT_RECOVER_SWAP , & retract_recover_length_swap , 0 , 100 ) ;
# endif
MENU_ITEM_EDIT ( float3 , MSG_CONTROL_RETRACT_RECOVERF , & retract_recover_feedrate , 1 , 999 ) ;
END_MENU ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
2014-12-18 16:30:05 +01:00
# endif //FWRETRACT
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
# if SDCARDDETECT == -1
2015-02-22 02:38:56 +01:00
static void lcd_sd_refresh ( ) {
2012-12-12 11:47:03 +01:00
card . initsd ( ) ;
currentMenuViewOffset = 0 ;
2015-02-22 02:38:56 +01:00
}
2011-12-12 19:34:37 +01:00
# endif
2015-02-22 02:38:56 +01:00
static void lcd_sd_updir ( ) {
card . updir ( ) ;
currentMenuViewOffset = 0 ;
2011-12-12 19:34:37 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_sdcard_menu ( ) {
if ( lcdDrawUpdate = = 0 & & LCD_CLICKED = = 0 ) return ; // nothing to do (so don't thrash the SD card)
uint16_t fileCnt = card . getnrfilenames ( ) ;
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MAIN , lcd_main_menu ) ;
card . getWorkDirName ( ) ;
if ( card . filename [ 0 ] = = ' / ' ) {
# if SDCARDDETECT == -1
MENU_ITEM ( function , LCD_STR_REFRESH MSG_REFRESH , lcd_sd_refresh ) ;
# endif
}
else {
MENU_ITEM ( function , LCD_STR_FOLDER " .. " , lcd_sd_updir ) ;
}
2013-12-08 21:34:56 +01:00
2015-02-22 02:38:56 +01:00
for ( uint16_t i = 0 ; i < fileCnt ; i + + ) {
if ( _menuItemNr = = _lineNr ) {
# ifndef SDCARD_RATHERRECENTFIRST
card . getfilename ( i ) ;
# else
card . getfilename ( fileCnt - 1 - i ) ;
# endif
if ( card . filenameIsDir )
MENU_ITEM ( sddirectory , MSG_CARD_MENU , card . filename , card . longFilename ) ;
else
MENU_ITEM ( sdfile , MSG_CARD_MENU , card . filename , card . longFilename ) ;
2011-12-12 19:34:37 +01:00
}
2015-02-22 02:38:56 +01:00
else {
MENU_ITEM_DUMMY ( ) ;
}
}
END_MENU ( ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
# define menu_edit_type(_type, _name, _strFunc, scale) \
2015-02-24 05:31:28 +01:00
bool _menu_edit_ # # _name ( ) { \
2015-02-24 05:11:52 +01:00
bool isClicked = LCD_CLICKED ; \
if ( ( int32_t ) encoderPosition < 0 ) encoderPosition = 0 ; \
if ( ( int32_t ) encoderPosition > maxEditValue ) encoderPosition = maxEditValue ; \
if ( lcdDrawUpdate ) \
lcd_implementation_drawedit ( editLabel , _strFunc ( ( ( _type ) ( ( int32_t ) encoderPosition + minEditValue ) ) / scale ) ) ; \
if ( isClicked ) { \
* ( ( _type * ) editValue ) = ( ( _type ) ( ( int32_t ) encoderPosition + minEditValue ) ) / scale ; \
lcd_goto_menu ( prevMenu , prevEncoderPosition ) ; \
Allow Edit menu to call fn after edit; Fix PID Ki and Kd display in menus; Actually use changed PID and Max Accel values
Add new 'callback' edit-menu types that call a function after the edit is done. Use this to display and edit Ki and Kd correctly (removing the scaling first and reapplying it after). Also use it to reset maximum stepwise acceleration rates, after updating mm/s^2 rates via menus. (Previously, changes did nothing to affect planner unless saved back to EEPROM, and the machine reset).
Add calls to updatePID() so that PID loop uses updated values whether set by gcode (it already did this), or by restoring defaults, or loading from EEPROM (it didn't do those last two). Similarly, update the maximum step/s^2 accel rates when the mm/s^2 values are changed - whether by menu edits, restore defaults, or EEPROM read.
Refactor the acceleration rate update logic, and the PID scaling logic, into new functions that can be called from wherever, including the callbacks.
Add menu items to allow the z jerk and e jerk to be viewed/edited in the Control->Motion menu, as per xy jerk.
Conflicts:
Marlin/language.h
2013-03-19 15:05:11 +01:00
} \
2015-02-24 05:11:52 +01:00
return isClicked ; \
} \
2015-02-24 05:31:28 +01:00
void menu_edit_ # # _name ( ) { _menu_edit_ # # _name ( ) ; } \
void menu_edit_callback_ # # _name ( ) { if ( _menu_edit_ # # _name ( ) ) ( * callbackFunc ) ( ) ; } \
2015-02-22 02:38:56 +01:00
static void _menu_action_setting_edit_ # # _name ( const char * pstr , _type * ptr , _type minValue , _type maxValue ) { \
prevMenu = currentMenu ; \
prevEncoderPosition = encoderPosition ; \
\
lcdDrawUpdate = 2 ; \
currentMenu = menu_edit_ # # _name ; \
\
editLabel = pstr ; \
editValue = ptr ; \
minEditValue = minValue * scale ; \
maxEditValue = maxValue * scale - minEditValue ; \
encoderPosition = ( * ptr ) * scale - minEditValue ; \
} \
static void menu_action_setting_edit_ # # _name ( const char * pstr , _type * ptr , _type minValue , _type maxValue ) { \
_menu_action_setting_edit_ # # _name ( pstr , ptr , minValue , maxValue ) ; \
currentMenu = menu_edit_ # # _name ; \
} \
static void menu_action_setting_edit_callback_ # # _name ( const char * pstr , _type * ptr , _type minValue , _type maxValue , menuFunc_t callback ) { \
_menu_action_setting_edit_ # # _name ( pstr , ptr , minValue , maxValue ) ; \
currentMenu = menu_edit_callback_ # # _name ; \
callbackFunc = callback ; \
}
2012-12-12 11:47:03 +01:00
menu_edit_type ( int , int3 , itostr3 , 1 )
menu_edit_type ( float , float3 , ftostr3 , 1 )
menu_edit_type ( float , float32 , ftostr32 , 100 )
2014-12-29 02:43:14 +01:00
menu_edit_type ( float , float43 , ftostr43 , 1000 )
2012-12-12 11:47:03 +01:00
menu_edit_type ( float , float5 , ftostr5 , 0.01 )
menu_edit_type ( float , float51 , ftostr51 , 10 )
menu_edit_type ( float , float52 , ftostr52 , 100 )
menu_edit_type ( unsigned long , long5 , ftostr5 , 0.01 )
2011-12-12 19:34:37 +01:00
2013-06-07 00:49:25 +02:00
# ifdef REPRAPWORLD_KEYPAD
2015-02-22 02:38:56 +01:00
static void reprapworld_keypad_move_z_up ( ) {
2013-07-14 15:35:54 +02:00
encoderPosition = 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
2015-02-22 02:38:56 +01:00
lcd_move_z ( ) ;
2013-07-14 15:35:54 +02:00
}
2015-02-22 02:38:56 +01:00
static void reprapworld_keypad_move_z_down ( ) {
2013-07-14 15:35:54 +02:00
encoderPosition = - 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
2015-02-22 02:38:56 +01:00
lcd_move_z ( ) ;
2013-07-14 15:35:54 +02:00
}
2015-02-22 02:38:56 +01:00
static void reprapworld_keypad_move_x_left ( ) {
2013-07-14 15:35:54 +02:00
encoderPosition = - 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
2015-02-22 02:38:56 +01:00
lcd_move_x ( ) ;
2013-07-14 15:35:54 +02:00
}
2015-02-22 02:38:56 +01:00
static void reprapworld_keypad_move_x_right ( ) {
2013-07-14 15:35:54 +02:00
encoderPosition = 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
2015-02-22 02:38:56 +01:00
lcd_move_x ( ) ;
}
static void reprapworld_keypad_move_y_down ( ) {
2013-07-14 15:35:54 +02:00
encoderPosition = 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_y ( ) ;
2015-02-22 02:38:56 +01:00
}
static void reprapworld_keypad_move_y_up ( ) {
encoderPosition = - 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_y ( ) ;
}
static void reprapworld_keypad_move_home ( ) {
enquecommands_P ( ( PSTR ( " G28 " ) ) ) ; // move all axis home
}
# endif //REPRAPWORLD_KEYPAD
2013-06-07 00:49:25 +02:00
2012-12-12 11:47:03 +01:00
/** End of menus **/
2011-12-12 19:34:37 +01:00
2015-02-22 02:38:56 +01:00
static void lcd_quick_feedback ( ) {
lcdDrawUpdate = 2 ;
blocking_enc = millis ( ) + 500 ;
lcd_implementation_quick_feedback ( ) ;
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
/** Menu action functions **/
2014-12-18 16:30:05 +01:00
static void menu_action_back ( menuFunc_t data ) { lcd_goto_menu ( data ) ; }
static void menu_action_submenu ( menuFunc_t data ) { lcd_goto_menu ( data ) ; }
2015-02-22 02:38:56 +01:00
static void menu_action_gcode ( const char * pgcode ) { enquecommands_P ( pgcode ) ; }
2014-12-18 16:30:05 +01:00
static void menu_action_function ( menuFunc_t data ) { ( * data ) ( ) ; }
2015-02-22 02:38:56 +01:00
static void menu_action_sdfile ( const char * filename , char * longFilename ) {
char cmd [ 30 ] ;
char * c ;
sprintf_P ( cmd , PSTR ( " M23 %s " ) , filename ) ;
for ( c = & cmd [ 4 ] ; * c ; c + + ) * c = tolower ( * c ) ;
enquecommand ( cmd ) ;
enquecommands_P ( PSTR ( " M24 " ) ) ;
lcd_return_to_status ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
static void menu_action_sddirectory ( const char * filename , char * longFilename ) {
card . chdir ( filename ) ;
encoderPosition = 0 ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
static void menu_action_setting_edit_bool ( const char * pstr , bool * ptr ) { * ptr = ! ( * ptr ) ; }
static void menu_action_setting_edit_callback_bool ( const char * pstr , bool * ptr , menuFunc_t callback ) {
menu_action_setting_edit_bool ( pstr , ptr ) ;
( * callback ) ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
# endif //ULTIPANEL
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
/** LCD API **/
2015-02-22 02:38:56 +01:00
void lcd_init ( ) {
lcd_implementation_init ( ) ;
# ifdef NEWPANEL
2011-12-12 19:34:37 +01:00
2014-12-28 19:54:06 +01:00
SET_INPUT ( BTN_EN1 ) ;
SET_INPUT ( BTN_EN2 ) ;
2012-12-12 11:47:03 +01:00
WRITE ( BTN_EN1 , HIGH ) ;
WRITE ( BTN_EN2 , HIGH ) ;
2013-06-07 00:49:25 +02:00
# if BTN_ENC > 0
2014-12-28 19:54:06 +01:00
SET_INPUT ( BTN_ENC ) ;
2012-12-12 11:47:03 +01:00
WRITE ( BTN_ENC , HIGH ) ;
2013-12-08 21:34:56 +01:00
# endif
2013-06-07 00:49:25 +02:00
# ifdef REPRAPWORLD_KEYPAD
pinMode ( SHIFT_CLK , OUTPUT ) ;
pinMode ( SHIFT_LD , OUTPUT ) ;
pinMode ( SHIFT_OUT , INPUT ) ;
WRITE ( SHIFT_OUT , HIGH ) ;
WRITE ( SHIFT_LD , HIGH ) ;
# endif
2014-01-17 23:00:47 +01:00
# else // Not NEWPANEL
2014-02-17 14:04:44 +01:00
# ifdef SR_LCD_2W_NL // Non latching 2 wire shift register
2013-10-30 11:45:32 +01:00
pinMode ( SR_DATA_PIN , OUTPUT ) ;
pinMode ( SR_CLK_PIN , OUTPUT ) ;
2014-11-24 15:51:16 +01:00
# elif defined(SHIFT_CLK)
2013-10-30 11:45:32 +01:00
pinMode ( SHIFT_CLK , OUTPUT ) ;
pinMode ( SHIFT_LD , OUTPUT ) ;
pinMode ( SHIFT_EN , OUTPUT ) ;
pinMode ( SHIFT_OUT , INPUT ) ;
WRITE ( SHIFT_OUT , HIGH ) ;
2013-12-08 21:34:56 +01:00
WRITE ( SHIFT_LD , HIGH ) ;
2013-10-30 11:45:32 +01:00
WRITE ( SHIFT_EN , LOW ) ;
2014-01-17 23:00:47 +01:00
# else
# ifdef ULTIPANEL
# error ULTIPANEL requires an encoder
# endif
# endif // SR_LCD_2W_NL
2012-12-12 11:47:03 +01:00
# endif //!NEWPANEL
2013-10-30 11:45:32 +01:00
2015-02-22 02:38:56 +01:00
# if defined(SDSUPPORT) && defined(SDCARDDETECT) && (SDCARDDETECT > 0)
pinMode ( SDCARDDETECT , INPUT ) ;
2012-12-12 11:47:03 +01:00
WRITE ( SDCARDDETECT , HIGH ) ;
lcd_oldcardstatus = IS_SD_INSERTED ;
2015-02-22 02:38:56 +01:00
# endif //(SDCARDDETECT > 0)
# ifdef LCD_HAS_SLOW_BUTTONS
2013-11-17 17:41:30 +01:00
slow_buttons = 0 ;
2015-02-22 02:38:56 +01:00
# endif
lcd_buttons_update ( ) ;
# ifdef ULTIPANEL
2012-12-21 16:14:47 +01:00
encoderDiff = 0 ;
2015-02-22 02:38:56 +01:00
# endif
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2015-02-16 13:53:58 +01:00
int lcd_strlen ( char * s ) {
2015-02-22 02:38:56 +01:00
int i = 0 , j = 0 ;
while ( s [ i ] ) {
if ( ( s [ i ] & 0xc0 ) ! = 0x80 ) j + + ;
i + + ;
}
return j ;
2015-02-16 13:53:58 +01:00
}
int lcd_strlen_P ( const char * s ) {
2015-02-22 02:38:56 +01:00
int j = 0 ;
while ( pgm_read_byte ( s ) ) {
if ( ( pgm_read_byte ( s ) & 0xc0 ) ! = 0x80 ) j + + ;
s + + ;
}
return j ;
2015-02-16 13:53:58 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_update ( ) {
static unsigned long timeoutToStatus = 0 ;
2015-02-16 13:53:58 +01:00
2015-02-22 02:38:56 +01:00
# ifdef LCD_HAS_SLOW_BUTTONS
2013-11-17 17:41:30 +01:00
slow_buttons = lcd_implementation_read_slow_buttons ( ) ; // buttons which take too long to read in interrupt context
2015-02-22 02:38:56 +01:00
# endif
2013-12-08 21:34:56 +01:00
2015-02-22 02:38:56 +01:00
lcd_buttons_update ( ) ;
2013-12-08 21:34:56 +01:00
2015-02-22 02:38:56 +01:00
# if (SDCARDDETECT > 0)
if ( IS_SD_INSERTED ! = lcd_oldcardstatus & & lcd_detected ( ) ) {
lcdDrawUpdate = 2 ;
lcd_oldcardstatus = IS_SD_INSERTED ;
lcd_implementation_init ( // to maybe revive the LCD if static electricity killed it.
# if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
currentMenu = = lcd_status_screen
# endif
) ;
2013-12-08 21:34:56 +01:00
2015-02-22 02:38:56 +01:00
if ( lcd_oldcardstatus ) {
card . initsd ( ) ;
LCD_MESSAGEPGM ( MSG_SD_INSERTED ) ;
}
else {
card . release ( ) ;
LCD_MESSAGEPGM ( MSG_SD_REMOVED ) ;
}
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
# endif //CARDINSERTED
2015-02-22 05:18:49 +01:00
long ms = millis ( ) ;
if ( ms > lcd_next_update_millis ) {
2015-02-22 02:38:56 +01:00
# ifdef ULTIPANEL
2015-02-22 05:18:49 +01:00
# ifdef REPRAPWORLD_KEYPAD
2015-02-22 02:38:56 +01:00
if ( REPRAPWORLD_KEYPAD_MOVE_Z_UP ) reprapworld_keypad_move_z_up ( ) ;
if ( REPRAPWORLD_KEYPAD_MOVE_Z_DOWN ) reprapworld_keypad_move_z_down ( ) ;
if ( REPRAPWORLD_KEYPAD_MOVE_X_LEFT ) reprapworld_keypad_move_x_left ( ) ;
if ( REPRAPWORLD_KEYPAD_MOVE_X_RIGHT ) reprapworld_keypad_move_x_right ( ) ;
if ( REPRAPWORLD_KEYPAD_MOVE_Y_DOWN ) reprapworld_keypad_move_y_down ( ) ;
if ( REPRAPWORLD_KEYPAD_MOVE_Y_UP ) reprapworld_keypad_move_y_up ( ) ;
if ( REPRAPWORLD_KEYPAD_MOVE_HOME ) reprapworld_keypad_move_home ( ) ;
2015-02-22 05:18:49 +01:00
# endif
2015-02-22 02:38:56 +01:00
bool encoderPastThreshold = ( abs ( encoderDiff ) > = ENCODER_PULSES_PER_STEP ) ;
if ( encoderPastThreshold | | LCD_CLICKED ) {
if ( encoderPastThreshold ) {
2015-02-22 05:18:49 +01:00
int32_t encoderMultiplier = 1 ;
# ifdef ENCODER_RATE_MULTIPLIER
if ( encoderRateMultiplierEnabled ) {
int32_t encoderMovementSteps = abs ( encoderDiff ) / ENCODER_PULSES_PER_STEP ;
if ( lastEncoderMovementMillis ! = 0 ) {
// Note that the rate is always calculated between to passes through the
// loop and that the abs of the encoderDiff value is tracked.
float encoderStepRate = ( float ) ( encoderMovementSteps ) / ( ( float ) ( ms - lastEncoderMovementMillis ) ) * 1000.0 ;
if ( encoderStepRate > = ENCODER_100X_STEPS_PER_SEC ) encoderMultiplier = 100 ;
else if ( encoderStepRate > = ENCODER_10X_STEPS_PER_SEC ) encoderMultiplier = 10 ;
# ifdef ENCODER_RATE_MULTIPLIER_DEBUG
SERIAL_ECHO_START ;
SERIAL_ECHO ( " Enc Step Rate: " ) ;
SERIAL_ECHO ( encoderStepRate ) ;
SERIAL_ECHO ( " Multiplier: " ) ;
SERIAL_ECHO ( encoderMultiplier ) ;
SERIAL_ECHO ( " ENCODER_10X_STEPS_PER_SEC: " ) ;
SERIAL_ECHO ( ENCODER_10X_STEPS_PER_SEC ) ;
SERIAL_ECHO ( " ENCODER_100X_STEPS_PER_SEC: " ) ;
SERIAL_ECHOLN ( ENCODER_100X_STEPS_PER_SEC ) ;
# endif //ENCODER_RATE_MULTIPLIER_DEBUG
}
lastEncoderMovementMillis = ms ;
}
# endif //ENCODER_RATE_MULTIPLIER
2015-02-22 02:38:56 +01:00
lcdDrawUpdate = 1 ;
2015-02-22 05:18:49 +01:00
encoderPosition + = ( encoderDiff * encoderMultiplier ) / ENCODER_PULSES_PER_STEP ;
2015-02-22 02:38:56 +01:00
encoderDiff = 0 ;
2012-08-22 00:46:10 +02:00
}
2015-02-22 05:18:49 +01:00
timeoutToStatus = ms + LCD_TIMEOUT_TO_STATUS ;
2015-02-22 02:38:56 +01:00
}
# endif //ULTIPANEL
# ifdef DOGLCD // Changes due to different driver architecture of the DOGM display
blink + + ; // Variable for fan animation and alive dot
u8g . firstPage ( ) ;
do {
u8g . setFont ( FONT_MENU ) ;
u8g . setPrintPos ( 125 , 0 ) ;
if ( blink % 2 ) u8g . setColorIndex ( 1 ) ; else u8g . setColorIndex ( 0 ) ; // Set color for the alive dot
u8g . drawPixel ( 127 , 63 ) ; // draw alive dot
u8g . setColorIndex ( 1 ) ; // black on white
2012-12-12 11:47:03 +01:00
( * currentMenu ) ( ) ;
2015-02-22 02:38:56 +01:00
if ( ! lcdDrawUpdate ) break ; // Terminate display update, when nothing new to draw. This must be done before the last dogm.next()
} while ( u8g . nextPage ( ) ) ;
# else
( * currentMenu ) ( ) ;
# endif
2013-03-19 20:19:16 +01:00
2015-02-22 02:38:56 +01:00
# ifdef LCD_HAS_STATUS_INDICATORS
lcd_implementation_update_indicators ( ) ;
# endif
2013-06-07 00:49:25 +02:00
2015-02-22 02:38:56 +01:00
# ifdef ULTIPANEL
2015-03-15 23:18:11 +01:00
if ( currentMenu ! = lcd_status_screen & &
# if defined(MANUAL_BED_LEVELING)
currentMenu ! = _lcd_level_bed & &
currentMenu ! = _lcd_level_bed_homing & &
# endif // MANUAL_BED_LEVELING
millis ( ) > timeoutToStatus ) {
2015-02-22 02:38:56 +01:00
lcd_return_to_status ( ) ;
lcdDrawUpdate = 2 ;
}
# endif //ULTIPANEL
if ( lcdDrawUpdate = = 2 ) lcd_implementation_clear ( ) ;
if ( lcdDrawUpdate ) lcdDrawUpdate - - ;
lcd_next_update_millis = millis ( ) + LCD_UPDATE_INTERVAL ;
}
2012-12-12 11:47:03 +01:00
}
2012-08-22 00:46:10 +02:00
2015-02-22 02:38:56 +01:00
void lcd_ignore_click ( bool b ) {
ignore_click = b ;
wait_for_unclick = false ;
2014-11-25 01:56:37 +01:00
}
2014-12-28 07:26:14 +01:00
void lcd_finishstatus ( ) {
2015-02-16 13:53:58 +01:00
int len = lcd_strlen ( lcd_status_message ) ;
2014-12-28 07:26:14 +01:00
if ( len > 0 ) {
while ( len < LCD_WIDTH ) {
lcd_status_message [ len + + ] = ' ' ;
}
}
lcd_status_message [ LCD_WIDTH ] = ' \0 ' ;
2015-01-10 03:16:56 +01:00
# if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT) && !defined(DOGLCD)
2014-12-28 07:26:14 +01:00
# if PROGRESS_MSG_EXPIRE > 0
messageTick =
# endif
progressBarTick = millis ( ) ;
# endif
lcdDrawUpdate = 2 ;
# ifdef FILAMENT_LCD_DISPLAY
message_millis = millis ( ) ; //get status message to show up for a while
# endif
}
2015-02-22 02:38:56 +01:00
void lcd_setstatus ( const char * message ) {
if ( lcd_status_message_level > 0 ) return ;
strncpy ( lcd_status_message , message , LCD_WIDTH ) ;
lcd_finishstatus ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_setstatuspgm ( const char * message ) {
if ( lcd_status_message_level > 0 ) return ;
strncpy_P ( lcd_status_message , message , LCD_WIDTH ) ;
lcd_finishstatus ( ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_setalertstatuspgm ( const char * message ) {
lcd_setstatuspgm ( message ) ;
lcd_status_message_level = 1 ;
# ifdef ULTIPANEL
2012-12-12 11:47:03 +01:00
lcd_return_to_status ( ) ;
2015-02-22 02:38:56 +01:00
# endif
2012-12-12 11:47:03 +01:00
}
2012-08-22 00:46:10 +02:00
2015-02-22 02:38:56 +01:00
void lcd_reset_alert_level ( ) { lcd_status_message_level = 0 ; }
2013-07-14 10:28:26 +02:00
# ifdef DOGLCD
2015-02-22 02:38:56 +01:00
void lcd_setcontrast ( uint8_t value ) {
2013-07-14 10:28:26 +02:00
lcd_contrast = value & 63 ;
2013-12-08 21:34:56 +01:00
u8g . setContrast ( lcd_contrast ) ;
2015-02-22 02:38:56 +01:00
}
2013-07-14 10:28:26 +02:00
# endif
2012-12-12 11:47:03 +01:00
# ifdef ULTIPANEL
2015-02-22 02:38:56 +01:00
2015-03-02 15:42:48 +01:00
////////////////////////
// Setup Rotary Encoder Bit Values (for two pin encoders to indicate movement)
// These values are independent of which pins are used for EN_A and EN_B indications
// The rotary encoder part is also independent to the chipset used for the LCD
# if defined(EN_A) && defined(EN_B)
# define encrot0 0
# define encrot1 2
# define encrot2 3
# define encrot3 1
# endif
2012-12-12 11:47:03 +01:00
/* Warning: This function is called from interrupt context */
2015-02-22 02:38:56 +01:00
void lcd_buttons_update ( ) {
# ifdef NEWPANEL
uint8_t newbutton = 0 ;
if ( READ ( BTN_EN1 ) = = 0 ) newbutton | = EN_A ;
if ( READ ( BTN_EN2 ) = = 0 ) newbutton | = EN_B ;
# if BTN_ENC > 0
if ( millis ( ) > blocking_enc & & READ ( BTN_ENC ) = = 0 ) newbutton | = EN_C ;
# endif
2012-12-12 11:47:03 +01:00
buttons = newbutton ;
2013-11-17 17:41:30 +01:00
# ifdef LCD_HAS_SLOW_BUTTONS
2015-02-22 02:38:56 +01:00
buttons | = slow_buttons ;
2013-11-17 17:41:30 +01:00
# endif
2013-07-14 15:35:54 +02:00
# ifdef REPRAPWORLD_KEYPAD
// for the reprapworld_keypad
uint8_t newbutton_reprapworld_keypad = 0 ;
2015-02-22 02:38:56 +01:00
WRITE ( SHIFT_LD , LOW ) ;
WRITE ( SHIFT_LD , HIGH ) ;
for ( int8_t i = 0 ; i < 8 ; i + + ) {
newbutton_reprapworld_keypad > > = 1 ;
2015-03-14 12:28:22 +01:00
if ( READ ( SHIFT_OUT ) ) newbutton_reprapworld_keypad | = BIT ( 7 ) ;
2015-02-22 02:38:56 +01:00
WRITE ( SHIFT_CLK , HIGH ) ;
WRITE ( SHIFT_CLK , LOW ) ;
2013-07-14 15:35:54 +02:00
}
buttons_reprapworld_keypad = ~ newbutton_reprapworld_keypad ; //invert it, because a pressed switch produces a logical 0
2015-02-22 02:38:56 +01:00
# endif
# else //read it from the shift register
uint8_t newbutton = 0 ;
WRITE ( SHIFT_LD , LOW ) ;
WRITE ( SHIFT_LD , HIGH ) ;
unsigned char tmp_buttons = 0 ;
for ( int8_t i = 0 ; i < 8 ; i + + ) {
newbutton > > = 1 ;
2015-03-14 12:28:22 +01:00
if ( READ ( SHIFT_OUT ) ) newbutton | = BIT ( 7 ) ;
2015-02-22 02:38:56 +01:00
WRITE ( SHIFT_CLK , HIGH ) ;
WRITE ( SHIFT_CLK , LOW ) ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
buttons = ~ newbutton ; //invert it, because a pressed switch produces a logical 0
# endif //!NEWPANEL
//manage encoder rotation
uint8_t enc = 0 ;
if ( buttons & EN_A ) enc | = B01 ;
if ( buttons & EN_B ) enc | = B10 ;
if ( enc ! = lastEncoderBits ) {
switch ( enc ) {
case encrot0 :
if ( lastEncoderBits = = encrot3 ) encoderDiff + + ;
else if ( lastEncoderBits = = encrot1 ) encoderDiff - - ;
break ;
case encrot1 :
if ( lastEncoderBits = = encrot0 ) encoderDiff + + ;
else if ( lastEncoderBits = = encrot2 ) encoderDiff - - ;
break ;
case encrot2 :
if ( lastEncoderBits = = encrot1 ) encoderDiff + + ;
else if ( lastEncoderBits = = encrot3 ) encoderDiff - - ;
break ;
case encrot3 :
if ( lastEncoderBits = = encrot2 ) encoderDiff + + ;
else if ( lastEncoderBits = = encrot0 ) encoderDiff - - ;
break ;
2012-12-12 11:47:03 +01:00
}
2015-02-22 02:38:56 +01:00
}
lastEncoderBits = enc ;
2012-08-22 00:46:10 +02:00
}
2013-06-07 00:49:25 +02:00
2015-02-22 02:38:56 +01:00
bool lcd_detected ( void ) {
# if (defined(LCD_I2C_TYPE_MCP23017) || defined(LCD_I2C_TYPE_MCP23008)) && defined(DETECT_DEVICE)
return lcd . LcdDetected ( ) = = 1 ;
# else
return true ;
# endif
2014-03-03 22:01:27 +01:00
}
2015-02-22 02:38:56 +01:00
void lcd_buzz ( long duration , uint16_t freq ) {
# ifdef LCD_USE_I2C_BUZZER
lcd . buzz ( duration , freq ) ;
# endif
2013-06-07 00:49:25 +02:00
}
2015-02-22 02:38:56 +01:00
bool lcd_clicked ( ) { return LCD_CLICKED ; }
# endif //ULTIPANEL
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
/********************************/
/** Float conversion utilities **/
/********************************/
2011-12-12 19:34:37 +01:00
// convert float to string with +123.4 format
2012-12-12 11:47:03 +01:00
char conv [ 8 ] ;
2011-12-12 19:34:37 +01:00
char * ftostr3 ( const float & x )
{
2012-12-12 11:47:03 +01:00
return itostr3 ( ( int ) x ) ;
2011-12-12 19:34:37 +01:00
}
char * itostr2 ( const uint8_t & x )
{
//sprintf(conv,"%5.1f",x);
int xx = x ;
conv [ 0 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 1 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 2 ] = 0 ;
return conv ;
}
2014-12-28 07:26:14 +01:00
// Convert float to string with 123.4 format, dropping sign
2011-12-12 19:34:37 +01:00
char * ftostr31 ( const float & x )
{
int xx = x * 10 ;
conv [ 0 ] = ( xx > = 0 ) ? ' + ' : ' - ' ;
xx = abs ( xx ) ;
conv [ 1 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 3 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 4 ] = ' . ' ;
conv [ 5 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 6 ] = 0 ;
return conv ;
}
2014-12-28 07:26:14 +01:00
// Convert float to string with 123.4 format
2013-03-19 20:13:23 +01:00
char * ftostr31ns ( const float & x )
{
int xx = x * 10 ;
//conv[0]=(xx>=0)?'+':'-';
xx = abs ( xx ) ;
conv [ 0 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
conv [ 1 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 3 ] = ' . ' ;
conv [ 4 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 5 ] = 0 ;
return conv ;
}
2011-12-12 19:34:37 +01:00
char * ftostr32 ( const float & x )
{
2013-02-12 17:35:46 +01:00
long xx = x * 100 ;
2013-01-08 11:53:18 +01:00
if ( xx > = 0 )
2013-02-12 17:35:46 +01:00
conv [ 0 ] = ( xx / 10000 ) % 10 + ' 0 ' ;
else
2013-01-08 11:53:18 +01:00
conv [ 0 ] = ' - ' ;
2011-12-12 19:34:37 +01:00
xx = abs ( xx ) ;
2013-01-08 11:53:18 +01:00
conv [ 1 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 3 ] = ' . ' ;
conv [ 4 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 5 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 6 ] = 0 ;
2011-12-12 19:34:37 +01:00
return conv ;
}
2014-12-29 02:43:14 +01:00
// Convert float to string with 1.234 format
char * ftostr43 ( const float & x )
{
long xx = x * 1000 ;
if ( xx > = 0 )
conv [ 0 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
else
conv [ 0 ] = ' - ' ;
xx = abs ( xx ) ;
conv [ 1 ] = ' . ' ;
conv [ 2 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 3 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 4 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 5 ] = 0 ;
return conv ;
}
//Float to string with 1.23 format
2014-11-11 04:43:58 +01:00
char * ftostr12ns ( const float & x )
{
long xx = x * 100 ;
xx = abs ( xx ) ;
conv [ 0 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 1 ] = ' . ' ;
conv [ 2 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 3 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 4 ] = 0 ;
return conv ;
}
2014-12-07 05:59:06 +01:00
// convert float to space-padded string with -_23.4_ format
2014-12-23 02:11:35 +01:00
char * ftostr32sp ( const float & x ) {
2014-12-08 10:43:44 +01:00
long xx = abs ( x * 100 ) ;
uint8_t dig ;
if ( x < 0 ) { // negative val = -_0
conv [ 0 ] = ' - ' ;
dig = ( xx / 1000 ) % 10 ;
conv [ 1 ] = dig ? ' 0 ' + dig : ' ' ;
}
else { // positive val = __0
dig = ( xx / 10000 ) % 10 ;
if ( dig ) {
conv [ 0 ] = ' 0 ' + dig ;
conv [ 1 ] = ' 0 ' + ( xx / 1000 ) % 10 ;
}
else {
conv [ 0 ] = ' ' ;
dig = ( xx / 1000 ) % 10 ;
conv [ 1 ] = dig ? ' 0 ' + dig : ' ' ;
}
}
conv [ 2 ] = ' 0 ' + ( xx / 100 ) % 10 ; // lsd always
dig = xx % 10 ;
if ( dig ) { // 2 decimal places
conv [ 5 ] = ' 0 ' + dig ;
2014-12-08 10:43:44 +01:00
conv [ 4 ] = ' 0 ' + ( xx / 10 ) % 10 ;
2014-12-08 10:43:44 +01:00
conv [ 3 ] = ' . ' ;
2014-12-07 05:59:06 +01:00
}
2014-12-08 10:43:44 +01:00
else { // 1 or 0 decimal place
dig = ( xx / 10 ) % 10 ;
if ( dig ) {
conv [ 4 ] = ' 0 ' + dig ;
conv [ 3 ] = ' . ' ;
}
else {
conv [ 3 ] = conv [ 4 ] = ' ' ;
}
conv [ 5 ] = ' ' ;
2014-12-07 05:59:06 +01:00
}
2014-12-08 10:43:44 +01:00
conv [ 6 ] = ' \0 ' ;
return conv ;
2014-12-07 05:59:06 +01:00
}
2011-12-12 19:34:37 +01:00
char * itostr31 ( const int & xx )
{
conv [ 0 ] = ( xx > = 0 ) ? ' + ' : ' - ' ;
conv [ 1 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 3 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 4 ] = ' . ' ;
conv [ 5 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 6 ] = 0 ;
return conv ;
}
2014-12-18 16:30:05 +01:00
// Convert int to rj string with 123 or -12 format
2014-06-24 14:31:15 +02:00
char * itostr3 ( const int & x )
2011-12-12 19:34:37 +01:00
{
2014-06-24 14:31:15 +02:00
int xx = x ;
if ( xx < 0 ) {
conv [ 0 ] = ' - ' ;
xx = - xx ;
} else if ( xx > = 100 )
2012-12-12 11:47:03 +01:00
conv [ 0 ] = ( xx / 100 ) % 10 + ' 0 ' ;
else
conv [ 0 ] = ' ' ;
if ( xx > = 10 )
conv [ 1 ] = ( xx / 10 ) % 10 + ' 0 ' ;
else
conv [ 1 ] = ' ' ;
2011-12-12 19:34:37 +01:00
conv [ 2 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 3 ] = 0 ;
return conv ;
}
2014-12-28 07:26:14 +01:00
// Convert int to lj string with 123 format
2012-12-12 11:47:03 +01:00
char * itostr3left ( const int & xx )
{
if ( xx > = 100 )
{
conv [ 0 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 1 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 3 ] = 0 ;
}
else if ( xx > = 10 )
{
conv [ 0 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 1 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 2 ] = 0 ;
}
else
{
conv [ 0 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 1 ] = 0 ;
}
return conv ;
}
2014-12-18 16:30:05 +01:00
// Convert int to rj string with 1234 format
char * itostr4 ( const int & xx ) {
conv [ 0 ] = xx > = 1000 ? ( xx / 1000 ) % 10 + ' 0 ' : ' ' ;
conv [ 1 ] = xx > = 100 ? ( xx / 100 ) % 10 + ' 0 ' : ' ' ;
conv [ 2 ] = xx > = 10 ? ( xx / 10 ) % 10 + ' 0 ' : ' ' ;
conv [ 3 ] = xx % 10 + ' 0 ' ;
conv [ 4 ] = 0 ;
2011-12-12 19:34:37 +01:00
return conv ;
}
2014-12-28 07:26:14 +01:00
// Convert float to rj string with 12345 format
2014-12-18 16:30:05 +01:00
char * ftostr5 ( const float & x ) {
long xx = abs ( x ) ;
conv [ 0 ] = xx > = 10000 ? ( xx / 10000 ) % 10 + ' 0 ' : ' ' ;
conv [ 1 ] = xx > = 1000 ? ( xx / 1000 ) % 10 + ' 0 ' : ' ' ;
conv [ 2 ] = xx > = 100 ? ( xx / 100 ) % 10 + ' 0 ' : ' ' ;
conv [ 3 ] = xx > = 10 ? ( xx / 10 ) % 10 + ' 0 ' : ' ' ;
conv [ 4 ] = xx % 10 + ' 0 ' ;
conv [ 5 ] = 0 ;
2012-12-12 11:47:03 +01:00
return conv ;
}
2014-12-28 07:26:14 +01:00
// Convert float to string with +1234.5 format
2011-12-12 19:34:37 +01:00
char * ftostr51 ( const float & x )
{
2012-08-21 16:47:39 +02:00
long xx = x * 10 ;
2011-12-12 19:34:37 +01:00
conv [ 0 ] = ( xx > = 0 ) ? ' + ' : ' - ' ;
xx = abs ( xx ) ;
conv [ 1 ] = ( xx / 10000 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
conv [ 3 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 4 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 5 ] = ' . ' ;
conv [ 6 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 7 ] = 0 ;
return conv ;
}
2014-12-28 07:26:14 +01:00
// Convert float to string with +123.45 format
2012-02-21 23:05:43 +01:00
char * ftostr52 ( const float & x )
{
2012-08-21 16:47:39 +02:00
long xx = x * 100 ;
2012-02-21 23:05:43 +01:00
conv [ 0 ] = ( xx > = 0 ) ? ' + ' : ' - ' ;
xx = abs ( xx ) ;
conv [ 1 ] = ( xx / 10000 ) % 10 + ' 0 ' ;
conv [ 2 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
conv [ 3 ] = ( xx / 100 ) % 10 + ' 0 ' ;
conv [ 4 ] = ' . ' ;
conv [ 5 ] = ( xx / 10 ) % 10 + ' 0 ' ;
conv [ 6 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 7 ] = 0 ;
return conv ;
}
2011-12-12 19:34:37 +01:00
2015-03-15 23:18:11 +01:00
# if defined(MANUAL_BED_LEVELING)
static int _lcd_level_bed_position ;
static void _lcd_level_bed ( )
{
if ( encoderPosition ! = 0 ) {
refresh_cmd_timeout ( ) ;
current_position [ Z_AXIS ] + = float ( ( int ) encoderPosition ) * 0.05 ;
if ( min_software_endstops & & current_position [ Z_AXIS ] < Z_MIN_POS ) current_position [ Z_AXIS ] = Z_MIN_POS ;
if ( max_software_endstops & & current_position [ Z_AXIS ] > Z_MAX_POS ) current_position [ Z_AXIS ] = Z_MAX_POS ;
encoderPosition = 0 ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ Z_AXIS ] / 60 , active_extruder ) ;
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate ) lcd_implementation_drawedit ( PSTR ( " Z " ) , ftostr32 ( current_position [ Z_AXIS ] ) ) ;
static bool debounce_click = false ;
if ( LCD_CLICKED ) {
if ( ! debounce_click ) {
debounce_click = true ;
int ix = _lcd_level_bed_position % MESH_NUM_X_POINTS ;
int iy = _lcd_level_bed_position / MESH_NUM_X_POINTS ;
mbl . set_z ( ix , iy , current_position [ Z_AXIS ] ) ;
_lcd_level_bed_position + + ;
if ( _lcd_level_bed_position = = MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS ) {
current_position [ Z_AXIS ] = MESH_HOME_SEARCH_Z ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ X_AXIS ] / 60 , active_extruder ) ;
mbl . active = 1 ;
enquecommands_P ( PSTR ( " G28 " ) ) ;
lcd_return_to_status ( ) ;
} else {
current_position [ Z_AXIS ] = MESH_HOME_SEARCH_Z ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ X_AXIS ] / 60 , active_extruder ) ;
ix = _lcd_level_bed_position % MESH_NUM_X_POINTS ;
iy = _lcd_level_bed_position / MESH_NUM_X_POINTS ;
if ( iy & 1 ) { // Zig zag
ix = ( MESH_NUM_X_POINTS - 1 ) - ix ;
}
current_position [ X_AXIS ] = mbl . get_x ( ix ) ;
current_position [ Y_AXIS ] = mbl . get_y ( iy ) ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ X_AXIS ] / 60 , active_extruder ) ;
lcdDrawUpdate = 1 ;
}
}
} else {
debounce_click = false ;
}
}
static void _lcd_level_bed_homing ( )
{
if ( axis_known_position [ X_AXIS ] & &
axis_known_position [ Y_AXIS ] & &
axis_known_position [ Z_AXIS ] ) {
current_position [ Z_AXIS ] = MESH_HOME_SEARCH_Z ;
plan_set_position ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] ) ;
current_position [ X_AXIS ] = MESH_MIN_X ;
current_position [ Y_AXIS ] = MESH_MIN_Y ;
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ X_AXIS ] / 60 , active_extruder ) ;
_lcd_level_bed_position = 0 ;
lcd_goto_menu ( _lcd_level_bed ) ;
}
}
static void lcd_level_bed ( )
{
axis_known_position [ X_AXIS ] = false ;
axis_known_position [ Y_AXIS ] = false ;
axis_known_position [ Z_AXIS ] = false ;
mbl . reset ( ) ;
enquecommands_P ( PSTR ( " G28 " ) ) ;
lcd_goto_menu ( _lcd_level_bed_homing ) ;
}
# endif // MANUAL_BED_LEVELING
2011-12-12 19:34:37 +01:00
# endif //ULTRA_LCD