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 */
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
2013-10-30 21:52:46 +01:00
# ifdef ULTIPANEL
2013-07-30 14:33:30 +02: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
/** forward declerations **/
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
void copy_and_scalePID_i ( ) ;
void copy_and_scalePID_d ( ) ;
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 ( ) ;
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 ( ) ;
static void lcd_quick_feedback ( ) ; //Cause an LCD refresh, and give the user visual or audiable feedback that something has happend
/* Different types of actions that can be used in menuitems. */
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 ) ;
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 ) ;
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)
# define ENCODER_STEPS_PER_MENU_ITEM 5
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
# define ENCODER_STEPS_PER_MENU_ITEM 2 // VIKI LCD rotary encoder uses a different number of steps per rotation
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 { \
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 )
# 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 )
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
2013-07-14 15:35:54 +02:00
volatile uint8_t buttons_reprapworld_keypad ; // to store the reprapworld_keypad shiftregister values
2013-06-07 00:49:25 +02:00
# 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
2012-12-12 11:47:03 +01:00
# endif //ULTIPANEL
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 ;
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 atleast 1 full redraw (first redraw is partial) */
//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 ;
// placeholders for Ki and Kd edits
float raw_Ki , raw_Kd ;
2012-12-12 11:47:03 +01:00
/* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependend */
static void lcd_status_screen ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +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 */
}
# ifdef ULTIPANEL
if ( LCD_CLICKED )
{
currentMenu = lcd_main_menu ;
2013-06-07 00:49:25 +02:00
encoderPosition = 0 ;
2012-12-12 11:47:03 +01:00
lcd_quick_feedback ( ) ;
}
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 ;
encoderPosition = 0 ;
}
else if ( feedmultiply ! = 100 )
{
feedmultiply + = int ( encoderPosition ) ;
encoderPosition = 0 ;
}
2012-12-12 11:47:03 +01:00
if ( feedmultiply < 10 )
feedmultiply = 10 ;
if ( feedmultiply > 999 )
feedmultiply = 999 ;
# endif //ULTIPANEL
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
# ifdef ULTIPANEL
static void lcd_return_to_status ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
encoderPosition = 0 ;
currentMenu = lcd_status_screen ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
static void lcd_sdcard_pause ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
card . pauseSDPrint ( ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
static void lcd_sdcard_resume ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
card . startFileprint ( ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
static void lcd_sdcard_stop ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
card . sdprinting = false ;
card . closefile ( ) ;
quickStop ( ) ;
if ( SD_FINISHED_STEPPERRELEASE )
2012-02-06 12:22:44 +01:00
{
2012-12-12 11:47:03 +01:00
enquecommand_P ( PSTR ( SD_FINISHED_RELEASECOMMAND ) ) ;
2012-02-06 12:22:44 +01:00
}
2012-12-12 11:47:03 +01:00
autotempShutdown ( ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
/* Menu implementation */
static void lcd_main_menu ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
START_MENU ( ) ;
MENU_ITEM ( back , MSG_WATCH , lcd_status_screen ) ;
2013-02-20 00:54:44 +01:00
if ( movesplanned ( ) | | IS_SD_PRINTING )
2012-12-12 11:47:03 +01:00
{
MENU_ITEM ( submenu , MSG_TUNE , lcd_tune_menu ) ;
} else {
MENU_ITEM ( submenu , MSG_PREPARE , lcd_prepare_menu ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
MENU_ITEM ( submenu , MSG_CONTROL , lcd_control_menu ) ;
# ifdef SDSUPPORT
if ( card . cardOK )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
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 ) ;
2013-02-12 17:35:46 +01:00
# if SDCARDDETECT < 1
2013-06-07 00:49:25 +02:00
MENU_ITEM ( gcode , MSG_CNG_SDCARD , PSTR ( " M21 " ) ) ; // SD-card changed by user
# endif
2012-12-12 11:47:03 +01:00
}
} else {
MENU_ITEM ( submenu , MSG_NO_CARD , lcd_sdcard_menu ) ;
2013-06-07 00:49:25 +02:00
# if SDCARDDETECT < 1
MENU_ITEM ( gcode , MSG_INIT_SDCARD , PSTR ( " M21 " ) ) ; // Manually initialize the SD-card via user interface
# endif
2011-12-12 19:34:37 +01:00
}
# endif
2012-12-12 11:47:03 +01:00
END_MENU ( ) ;
2011-12-12 19:34:37 +01:00
}
2012-03-15 22:29:31 +01:00
# ifdef SDSUPPORT
2012-12-12 11:47:03 +01:00
static void lcd_autostart_sd ( )
{
card . lastnr = 0 ;
card . setroot ( ) ;
card . checkautostart ( true ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
# endif
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
void lcd_preheat_pla ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
setTargetHotend0 ( plaPreheatHotendTemp ) ;
setTargetHotend1 ( plaPreheatHotendTemp ) ;
setTargetHotend2 ( plaPreheatHotendTemp ) ;
setTargetBed ( plaPreheatHPBTemp ) ;
fanSpeed = plaPreheatFanSpeed ;
lcd_return_to_status ( ) ;
2013-06-07 00:49:25 +02:00
setWatch ( ) ; // heater sanity check timer
2012-02-07 12:58:05 +01:00
}
2012-12-12 11:47:03 +01:00
void lcd_preheat_abs ( )
2012-02-07 12:58:05 +01:00
{
2012-12-12 11:47:03 +01:00
setTargetHotend0 ( absPreheatHotendTemp ) ;
setTargetHotend1 ( absPreheatHotendTemp ) ;
setTargetHotend2 ( absPreheatHotendTemp ) ;
setTargetBed ( absPreheatHPBTemp ) ;
fanSpeed = absPreheatFanSpeed ;
lcd_return_to_status ( ) ;
2013-06-07 00:49:25 +02:00
setWatch ( ) ; // heater sanity check timer
}
static void lcd_cooldown ( )
{
setTargetHotend0 ( 0 ) ;
setTargetHotend1 ( 0 ) ;
setTargetHotend2 ( 0 ) ;
setTargetBed ( 0 ) ;
lcd_return_to_status ( ) ;
2011-12-12 19:34:37 +01: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
static void lcd_babystep_x ( )
{
if ( encoderPosition ! = 0 )
{
babystepsTodo [ X_AXIS ] + = ( int ) encoderPosition ;
encoderPosition = 0 ;
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
{
lcd_implementation_drawedit ( PSTR ( " Babystepping X " ) , " " ) ;
}
if ( LCD_CLICKED )
{
lcd_quick_feedback ( ) ;
currentMenu = lcd_tune_menu ;
encoderPosition = 0 ;
}
}
static void lcd_babystep_y ( )
{
if ( encoderPosition ! = 0 )
{
babystepsTodo [ Y_AXIS ] + = ( int ) encoderPosition ;
encoderPosition = 0 ;
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
{
lcd_implementation_drawedit ( PSTR ( " Babystepping Y " ) , " " ) ;
}
if ( LCD_CLICKED )
{
lcd_quick_feedback ( ) ;
currentMenu = lcd_tune_menu ;
encoderPosition = 0 ;
}
}
static void lcd_babystep_z ( )
{
if ( encoderPosition ! = 0 )
{
2013-10-07 09:14:04 +02:00
babystepsTodo [ Z_AXIS ] + = BABYSTEP_Z_MULTIPLICATOR * ( int ) encoderPosition ;
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
encoderPosition = 0 ;
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
{
lcd_implementation_drawedit ( PSTR ( " Babystepping Z " ) , " " ) ;
}
if ( LCD_CLICKED )
{
lcd_quick_feedback ( ) ;
currentMenu = lcd_tune_menu ;
encoderPosition = 0 ;
}
}
# endif //BABYSTEPPING
2012-12-12 11:47:03 +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 ) ;
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE , & target_temperature [ 0 ] , 0 , HEATER_0_MAXTEMP - 15 ) ;
# if TEMP_SENSOR_1 != 0
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE1 , & target_temperature [ 1 ] , 0 , HEATER_1_MAXTEMP - 15 ) ;
2011-12-12 19:34:37 +01:00
# endif
2012-12-12 11:47:03 +01:00
# if TEMP_SENSOR_2 != 0
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE2 , & target_temperature [ 2 ] , 0 , HEATER_2_MAXTEMP - 15 ) ;
2012-04-27 14:51:32 +02:00
# endif
2012-12-12 11:47:03 +01:00
# if TEMP_SENSOR_BED != 0
MENU_ITEM_EDIT ( int3 , MSG_BED , & target_temperature_bed , 0 , BED_MAXTEMP - 15 ) ;
2012-04-27 14:51:32 +02:00
# endif
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( int3 , MSG_FAN_SPEED , & fanSpeed , 0 , 255 ) ;
MENU_ITEM_EDIT ( int3 , MSG_FLOW , & extrudemultiply , 10 , 999 ) ;
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
# ifdef BABYSTEP_XY
MENU_ITEM ( submenu , " Babystep X " , lcd_babystep_x ) ;
MENU_ITEM ( submenu , " Babystep Y " , lcd_babystep_y ) ;
# endif //BABYSTEP_XY
MENU_ITEM ( submenu , " Babystep Z " , lcd_babystep_z ) ;
# endif
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
# ifdef FILAMENTCHANGEENABLE
MENU_ITEM ( gcode , MSG_FILAMENTCHANGE , PSTR ( " M600 " ) ) ;
# endif
2012-12-12 11:47:03 +01:00
END_MENU ( ) ;
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
static void lcd_prepare_menu ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
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
2012-12-12 11:47:03 +01:00
# endif
MENU_ITEM ( gcode , MSG_DISABLE_STEPPERS , PSTR ( " M84 " ) ) ;
MENU_ITEM ( gcode , MSG_AUTO_HOME , PSTR ( " G28 " ) ) ;
//MENU_ITEM(gcode, MSG_SET_ORIGIN, PSTR("G92 X0 Y0 Z0"));
MENU_ITEM ( function , MSG_PREHEAT_PLA , lcd_preheat_pla ) ;
MENU_ITEM ( function , MSG_PREHEAT_ABS , lcd_preheat_abs ) ;
2013-06-07 00:49:25 +02:00
MENU_ITEM ( function , MSG_COOLDOWN , lcd_cooldown ) ;
2013-07-23 22:28:30 +02:00
# if PS_ON_PIN > -1
2013-03-05 14:52:51 +01:00
if ( powersupply )
{
MENU_ITEM ( gcode , MSG_SWITCH_PS_OFF , PSTR ( " M81 " ) ) ;
} else {
MENU_ITEM ( gcode , MSG_SWITCH_PS_ON , PSTR ( " M80 " ) ) ;
}
2013-07-23 22:28:30 +02:00
# endif
2012-12-12 11:47:03 +01:00
MENU_ITEM ( submenu , MSG_MOVE_AXIS , lcd_move_menu ) ;
END_MENU ( ) ;
2011-12-12 19:34:37 +01:00
}
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
2012-12-12 11:47:03 +01:00
static void lcd_move_x ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
if ( encoderPosition ! = 0 )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
current_position [ X_AXIS ] + = float ( ( int ) encoderPosition ) * move_menu_scale ;
2013-06-28 14:18:00 +02:00
if ( min_software_endstops & & current_position [ X_AXIS ] < X_MIN_POS )
2012-12-12 11:47:03 +01:00
current_position [ X_AXIS ] = X_MIN_POS ;
2013-06-28 14:18:00 +02:00
if ( max_software_endstops & & current_position [ X_AXIS ] > X_MAX_POS )
2012-12-12 11:47:03 +01:00
current_position [ X_AXIS ] = X_MAX_POS ;
encoderPosition = 0 ;
2013-07-28 22:54:37 +02:00
# ifdef DELTA
calculate_delta ( current_position ) ;
2013-07-30 14:33:30 +02:00
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ X_AXIS ] / 60 , active_extruder ) ;
2013-07-28 22:54:37 +02:00
# else
2013-07-30 14:33:30 +02:00
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 ) ;
2013-07-28 22:54:37 +02:00
# endif
2012-12-12 11:47:03 +01:00
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
lcd_implementation_drawedit ( PSTR ( " X " ) , ftostr31 ( current_position [ X_AXIS ] ) ) ;
}
if ( LCD_CLICKED )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
lcd_quick_feedback ( ) ;
currentMenu = lcd_move_menu_axis ;
encoderPosition = 0 ;
}
}
static void lcd_move_y ( )
{
if ( encoderPosition ! = 0 )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
current_position [ Y_AXIS ] + = float ( ( int ) encoderPosition ) * move_menu_scale ;
2013-06-28 14:18:00 +02:00
if ( min_software_endstops & & current_position [ Y_AXIS ] < Y_MIN_POS )
2012-12-12 11:47:03 +01:00
current_position [ Y_AXIS ] = Y_MIN_POS ;
2013-06-28 14:18:00 +02:00
if ( max_software_endstops & & current_position [ Y_AXIS ] > Y_MAX_POS )
2012-12-12 11:47:03 +01:00
current_position [ Y_AXIS ] = Y_MAX_POS ;
encoderPosition = 0 ;
2013-07-28 22:54:37 +02:00
# ifdef DELTA
calculate_delta ( current_position ) ;
2013-07-30 14:33:30 +02:00
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ Y_AXIS ] / 60 , active_extruder ) ;
2013-07-28 22:54:37 +02:00
# else
2013-07-30 14:33:30 +02:00
plan_buffer_line ( current_position [ X_AXIS ] , current_position [ Y_AXIS ] , current_position [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ Y_AXIS ] / 60 , active_extruder ) ;
2013-07-28 22:54:37 +02:00
# endif
2012-12-12 11:47:03 +01:00
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
lcd_implementation_drawedit ( PSTR ( " Y " ) , ftostr31 ( current_position [ Y_AXIS ] ) ) ;
}
if ( LCD_CLICKED )
{
lcd_quick_feedback ( ) ;
currentMenu = lcd_move_menu_axis ;
encoderPosition = 0 ;
}
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
static void lcd_move_z ( )
2012-06-02 20:32:28 +02:00
{
2012-12-12 11:47:03 +01:00
if ( encoderPosition ! = 0 )
2012-06-02 20:32:28 +02:00
{
2012-12-12 11:47:03 +01:00
current_position [ Z_AXIS ] + = float ( ( int ) encoderPosition ) * move_menu_scale ;
2013-06-28 14:18:00 +02:00
if ( min_software_endstops & & current_position [ Z_AXIS ] < Z_MIN_POS )
2012-12-12 11:47:03 +01:00
current_position [ Z_AXIS ] = Z_MIN_POS ;
2013-06-28 14:18:00 +02:00
if ( max_software_endstops & & current_position [ Z_AXIS ] > Z_MAX_POS )
2012-12-12 11:47:03 +01:00
current_position [ Z_AXIS ] = Z_MAX_POS ;
encoderPosition = 0 ;
2013-07-28 22:54:37 +02:00
# ifdef DELTA
calculate_delta ( current_position ) ;
2013-07-30 14:33:30 +02:00
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ Z_AXIS ] / 60 , active_extruder ) ;
2013-07-28 22:54:37 +02:00
# else
2013-07-30 14:33:30 +02:00
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 ) ;
2013-07-28 22:54:37 +02:00
# endif
2012-12-12 11:47:03 +01:00
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
2012-06-02 20:32:28 +02:00
{
2012-12-12 11:47:03 +01:00
lcd_implementation_drawedit ( PSTR ( " Z " ) , ftostr31 ( current_position [ Z_AXIS ] ) ) ;
}
if ( LCD_CLICKED )
2012-06-02 20:32:28 +02:00
{
2012-12-12 11:47:03 +01:00
lcd_quick_feedback ( ) ;
currentMenu = lcd_move_menu_axis ;
encoderPosition = 0 ;
}
}
static void lcd_move_e ( )
{
if ( encoderPosition ! = 0 )
2012-06-02 20:32:28 +02:00
{
2012-12-12 11:47:03 +01:00
current_position [ E_AXIS ] + = float ( ( int ) encoderPosition ) * move_menu_scale ;
encoderPosition = 0 ;
2013-07-28 22:54:37 +02:00
# ifdef DELTA
calculate_delta ( current_position ) ;
2013-07-30 14:33:30 +02:00
plan_buffer_line ( delta [ X_AXIS ] , delta [ Y_AXIS ] , delta [ Z_AXIS ] , current_position [ E_AXIS ] , manual_feedrate [ E_AXIS ] / 60 , active_extruder ) ;
2013-07-28 22:54:37 +02:00
# else
2013-07-30 14:33:30 +02:00
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 ) ;
2013-07-28 22:54:37 +02:00
# endif
2012-12-12 11:47:03 +01:00
lcdDrawUpdate = 1 ;
}
if ( lcdDrawUpdate )
2012-06-02 20:32:28 +02:00
{
2012-12-12 11:47:03 +01:00
lcd_implementation_drawedit ( PSTR ( " Extruder " ) , ftostr31 ( current_position [ E_AXIS ] ) ) ;
}
if ( LCD_CLICKED )
{
lcd_quick_feedback ( ) ;
currentMenu = lcd_move_menu_axis ;
encoderPosition = 0 ;
}
}
static void lcd_move_menu_axis ( )
{
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MOVE_AXIS , lcd_move_menu ) ;
MENU_ITEM ( submenu , " Move X " , lcd_move_x ) ;
MENU_ITEM ( submenu , " Move Y " , lcd_move_y ) ;
if ( move_menu_scale < 10.0 )
{
2012-12-21 16:14:47 +01:00
MENU_ITEM ( submenu , " Move Z " , lcd_move_z ) ;
2012-12-12 11:47:03 +01:00
MENU_ITEM ( submenu , " Extruder " , lcd_move_e ) ;
}
END_MENU ( ) ;
2012-06-02 20:32:28 +02:00
}
2012-12-12 11:47:03 +01:00
static void lcd_move_menu_10mm ( )
{
move_menu_scale = 10.0 ;
lcd_move_menu_axis ( ) ;
}
static void lcd_move_menu_1mm ( )
{
move_menu_scale = 1.0 ;
lcd_move_menu_axis ( ) ;
}
static void lcd_move_menu_01mm ( )
{
move_menu_scale = 0.1 ;
lcd_move_menu_axis ( ) ;
}
2012-06-02 20:32:28 +02:00
2012-12-12 11:47:03 +01:00
static void lcd_move_menu ( )
{
START_MENU ( ) ;
MENU_ITEM ( back , MSG_PREPARE , lcd_prepare_menu ) ;
MENU_ITEM ( submenu , " Move 10mm " , lcd_move_menu_10mm ) ;
MENU_ITEM ( submenu , " Move 1mm " , lcd_move_menu_1mm ) ;
MENU_ITEM ( submenu , " Move 0.1mm " , lcd_move_menu_01mm ) ;
//TODO:X,Y,Z,E
END_MENU ( ) ;
}
2012-06-02 20:32:28 +02:00
2012-12-12 11:47:03 +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 ) ;
2013-07-14 10:28:26 +02:00
# ifdef DOGLCD
// MENU_ITEM_EDIT(int3, MSG_CONTRAST, &lcd_contrast, 0, 63);
MENU_ITEM ( submenu , MSG_CONTRAST , lcd_set_contrast ) ;
# endif
2012-06-02 20:32:28 +02:00
# ifdef FWRETRACT
2012-12-12 11:47:03 +01:00
MENU_ITEM ( submenu , MSG_RETRACT , lcd_control_retract_menu ) ;
# endif
# ifdef EEPROM_SETTINGS
MENU_ITEM ( function , MSG_STORE_EPROM , Config_StoreSettings ) ;
MENU_ITEM ( function , MSG_LOAD_EPROM , Config_RetrieveSettings ) ;
2012-06-02 20:32:28 +02:00
# endif
2012-12-12 11:47:03 +01:00
MENU_ITEM ( function , MSG_RESTORE_FAILSAFE , Config_ResetDefault ) ;
END_MENU ( ) ;
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
static void lcd_control_temperature_menu ( )
2011-12-12 19:34:37 +01:00
{
2013-06-16 02:49:18 +02:00
# ifdef PIDTEMP
2013-06-07 00:49:25 +02:00
// set up temp variables - undo the default scaling
raw_Ki = unscalePID_i ( Ki ) ;
raw_Kd = unscalePID_d ( Kd ) ;
2013-06-16 02:49:18 +02:00
# endif
2013-06-07 00:49:25 +02:00
2012-12-12 11:47:03 +01:00
START_MENU ( ) ;
MENU_ITEM ( back , MSG_CONTROL , lcd_control_menu ) ;
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE , & target_temperature [ 0 ] , 0 , HEATER_0_MAXTEMP - 15 ) ;
# if TEMP_SENSOR_1 != 0
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE1 , & target_temperature [ 1 ] , 0 , HEATER_1_MAXTEMP - 15 ) ;
2012-06-02 20:32:28 +02:00
# endif
2012-12-12 11:47:03 +01:00
# if TEMP_SENSOR_2 != 0
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE2 , & target_temperature [ 2 ] , 0 , HEATER_2_MAXTEMP - 15 ) ;
# endif
# if TEMP_SENSOR_BED != 0
MENU_ITEM_EDIT ( int3 , MSG_BED , & target_temperature_bed , 0 , BED_MAXTEMP - 15 ) ;
# endif
MENU_ITEM_EDIT ( int3 , MSG_FAN_SPEED , & fanSpeed , 0 , 255 ) ;
# ifdef AUTOTEMP
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
MENU_ITEM_EDIT ( float52 , MSG_PID_P , & Kp , 1 , 9990 ) ;
2013-06-07 00:49:25 +02:00
// i is typically a small value so allows values below 1
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
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_I , & raw_Ki , 0.01 , 9990 , copy_and_scalePID_i ) ;
MENU_ITEM_EDIT_CALLBACK ( float52 , MSG_PID_D , & raw_Kd , 1 , 9990 , copy_and_scalePID_d ) ;
2012-12-12 11:47:03 +01:00
# ifdef PID_ADD_EXTRUSION_RATE
MENU_ITEM_EDIT ( float3 , MSG_PID_C , & Kc , 1 , 9990 ) ;
# endif //PID_ADD_EXTRUSION_RATE
# 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
}
2012-12-12 11:47:03 +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 ) ;
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE , & plaPreheatHotendTemp , 0 , HEATER_0_MAXTEMP - 15 ) ;
# if TEMP_SENSOR_BED != 0
MENU_ITEM_EDIT ( int3 , MSG_BED , & plaPreheatHPBTemp , 0 , BED_MAXTEMP - 15 ) ;
# endif
2012-12-13 09:04:41 +01:00
# ifdef EEPROM_SETTINGS
2012-12-12 11:47:03 +01:00
MENU_ITEM ( function , MSG_STORE_EPROM , Config_StoreSettings ) ;
# endif
END_MENU ( ) ;
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +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 ) ;
MENU_ITEM_EDIT ( int3 , MSG_NOZZLE , & absPreheatHotendTemp , 0 , HEATER_0_MAXTEMP - 15 ) ;
# if TEMP_SENSOR_BED != 0
MENU_ITEM_EDIT ( int3 , MSG_BED , & absPreheatHPBTemp , 0 , BED_MAXTEMP - 15 ) ;
# endif
2012-12-13 09:04:41 +01:00
# ifdef EEPROM_SETTINGS
2012-12-12 11:47:03 +01:00
MENU_ITEM ( function , MSG_STORE_EPROM , Config_StoreSettings ) ;
# endif
END_MENU ( ) ;
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
static void lcd_control_motion_menu ( )
{
START_MENU ( ) ;
MENU_ITEM ( back , MSG_CONTROL , lcd_control_menu ) ;
MENU_ITEM_EDIT ( float5 , MSG_ACC , & acceleration , 500 , 99000 ) ;
MENU_ITEM_EDIT ( float3 , MSG_VXY_JERK , & max_xy_jerk , 1 , 990 ) ;
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
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 ) ;
2012-12-12 11:47:03 +01:00
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 ) ;
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
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 ) ;
2012-12-12 11:47:03 +01:00
MENU_ITEM_EDIT ( float5 , MSG_A_RETRACT , & retract_acceleration , 100 , 99000 ) ;
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 ) ;
2013-02-12 17:35:46 +01:00
# ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
MENU_ITEM_EDIT ( bool , " Endstop abort " , & abort_on_endstop_hit ) ;
# endif
2012-12-12 11:47:03 +01:00
END_MENU ( ) ;
}
2011-12-12 19:34:37 +01:00
2013-07-14 10:28:26 +02:00
# ifdef DOGLCD
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 ( " Contrast " ) , itostr2 ( lcd_contrast ) ) ;
}
if ( LCD_CLICKED )
{
lcd_quick_feedback ( ) ;
currentMenu = lcd_control_menu ;
encoderPosition = 0 ;
}
}
# endif
2012-12-12 11:47:03 +01:00
# ifdef FWRETRACT
static void lcd_control_retract_menu ( )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
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 ) ;
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 ) ;
MENU_ITEM_EDIT ( float3 , MSG_CONTROL_RETRACT_RECOVERF , & retract_recover_feedrate , 1 , 999 ) ;
END_MENU ( ) ;
}
# endif
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
# if SDCARDDETECT == -1
static void lcd_sd_refresh ( )
{
card . initsd ( ) ;
currentMenuViewOffset = 0 ;
}
2011-12-12 19:34:37 +01:00
# endif
2012-12-12 11:47:03 +01:00
static void lcd_sd_updir ( )
{
card . updir ( ) ;
currentMenuViewOffset = 0 ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
void lcd_sdcard_menu ( )
2011-12-12 19:34:37 +01:00
{
2013-07-29 11:00:29 +02:00
if ( lcdDrawUpdate = = 0 & & LCD_CLICKED = = 0 )
return ; // nothing to do (so don't thrash the SD card)
2012-12-12 11:47:03 +01:00
uint16_t fileCnt = card . getnrfilenames ( ) ;
START_MENU ( ) ;
MENU_ITEM ( back , MSG_MAIN , lcd_main_menu ) ;
card . getWorkDirName ( ) ;
if ( card . filename [ 0 ] = = ' / ' )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
# 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 ) ;
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
for ( uint16_t i = 0 ; i < fileCnt ; i + + )
2011-12-12 19:34:37 +01:00
{
2012-12-12 11:47:03 +01:00
if ( _menuItemNr = = _lineNr )
2012-07-27 07:38:33 +02:00
{
2013-10-12 13:24:55 +02:00
# ifndef SDCARD_RATHERRECENTFIRST
card . getfilename ( i ) ;
# else
card . getfilename ( fileCnt - 1 - i ) ;
# endif
2012-12-12 11:47:03 +01:00
if ( card . filenameIsDir )
2012-11-12 09:16:27 +01:00
{
2012-12-12 11:47:03 +01:00
MENU_ITEM ( sddirectory , MSG_CARD_MENU , card . filename , card . longFilename ) ;
} else {
MENU_ITEM ( sdfile , MSG_CARD_MENU , card . filename , card . longFilename ) ;
2012-11-12 09:16:27 +01:00
}
2012-12-12 11:47:03 +01:00
} else {
MENU_ITEM_DUMMY ( ) ;
}
2011-12-12 19:34:37 +01:00
}
2012-12-12 11:47:03 +01:00
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) \
void menu_edit_ # # _name ( ) \
{ \
if ( ( int32_t ) encoderPosition < minEditValue ) \
encoderPosition = minEditValue ; \
if ( ( int32_t ) encoderPosition > maxEditValue ) \
encoderPosition = maxEditValue ; \
if ( lcdDrawUpdate ) \
lcd_implementation_drawedit ( editLabel , _strFunc ( ( ( _type ) encoderPosition ) / scale ) ) ; \
if ( LCD_CLICKED ) \
{ \
* ( ( _type * ) editValue ) = ( ( _type ) encoderPosition ) / scale ; \
lcd_quick_feedback ( ) ; \
currentMenu = prevMenu ; \
encoderPosition = 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
void menu_edit_callback_ # # _name ( ) \
{ \
if ( ( int32_t ) encoderPosition < minEditValue ) \
encoderPosition = minEditValue ; \
if ( ( int32_t ) encoderPosition > maxEditValue ) \
encoderPosition = maxEditValue ; \
if ( lcdDrawUpdate ) \
lcd_implementation_drawedit ( editLabel , _strFunc ( ( ( _type ) encoderPosition ) / scale ) ) ; \
if ( LCD_CLICKED ) \
{ \
* ( ( _type * ) editValue ) = ( ( _type ) encoderPosition ) / scale ; \
lcd_quick_feedback ( ) ; \
currentMenu = prevMenu ; \
encoderPosition = prevEncoderPosition ; \
( * callbackFunc ) ( ) ; \
} \
} \
2012-12-12 11:47:03 +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 ; \
encoderPosition = ( * ptr ) * scale ; \
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_ # # _name ( const char * pstr , _type * ptr , _type minValue , _type maxValue , menuFunc_t callback ) \
{ \
prevMenu = currentMenu ; \
prevEncoderPosition = encoderPosition ; \
\
lcdDrawUpdate = 2 ; \
currentMenu = menu_edit_callback_ # # _name ; \
\
editLabel = pstr ; \
editValue = ptr ; \
minEditValue = minValue * scale ; \
maxEditValue = maxValue * scale ; \
encoderPosition = ( * ptr ) * scale ; \
callbackFunc = callback ; \
2011-12-12 19:34:37 +01:00
}
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 )
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
2013-07-14 15:35:54 +02:00
static void reprapworld_keypad_move_z_up ( ) {
encoderPosition = 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_z ( ) ;
}
static void reprapworld_keypad_move_z_down ( ) {
encoderPosition = - 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_z ( ) ;
}
static void reprapworld_keypad_move_x_left ( ) {
encoderPosition = - 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_x ( ) ;
}
static void reprapworld_keypad_move_x_right ( ) {
encoderPosition = 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_x ( ) ;
}
static void reprapworld_keypad_move_y_down ( ) {
encoderPosition = 1 ;
move_menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP ;
lcd_move_y ( ) ;
}
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 ( ) {
enquecommand_P ( ( PSTR ( " G28 " ) ) ) ; // move all axis home
}
2013-06-07 00:49:25 +02:00
# endif
2012-12-12 11:47:03 +01:00
/** End of menus **/
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
static void lcd_quick_feedback ( )
2012-08-22 00:46:10 +02:00
{
2012-12-12 11:47:03 +01:00
lcdDrawUpdate = 2 ;
blocking_enc = millis ( ) + 500 ;
lcd_implementation_quick_feedback ( ) ;
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
/** Menu action functions **/
static void menu_action_back ( menuFunc_t data )
{
currentMenu = data ;
encoderPosition = 0 ;
}
static void menu_action_submenu ( menuFunc_t data )
{
currentMenu = data ;
encoderPosition = 0 ;
}
static void menu_action_gcode ( const char * pgcode )
{
enquecommand_P ( pgcode ) ;
}
static void menu_action_function ( menuFunc_t data )
{
( * data ) ( ) ;
}
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 ) ;
enquecommand_P ( PSTR ( " M24 " ) ) ;
lcd_return_to_status ( ) ;
}
static void menu_action_sddirectory ( const char * filename , char * longFilename )
{
card . chdir ( filename ) ;
encoderPosition = 0 ;
}
static void menu_action_setting_edit_bool ( const char * pstr , bool * ptr )
{
* ptr = ! ( * ptr ) ;
}
# endif //ULTIPANEL
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
/** LCD API **/
void lcd_init ( )
{
lcd_implementation_init ( ) ;
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
# ifdef NEWPANEL
pinMode ( BTN_EN1 , INPUT ) ;
pinMode ( BTN_EN2 , INPUT ) ;
pinMode ( SDCARDDETECT , INPUT ) ;
WRITE ( BTN_EN1 , HIGH ) ;
WRITE ( BTN_EN2 , HIGH ) ;
2013-06-07 00:49:25 +02:00
# if BTN_ENC > 0
pinMode ( BTN_ENC , INPUT ) ;
2012-12-12 11:47:03 +01:00
WRITE ( BTN_ENC , HIGH ) ;
2013-06-07 00:49:25 +02:00
# endif
# ifdef REPRAPWORLD_KEYPAD
pinMode ( SHIFT_CLK , OUTPUT ) ;
pinMode ( SHIFT_LD , OUTPUT ) ;
pinMode ( SHIFT_OUT , INPUT ) ;
WRITE ( SHIFT_OUT , HIGH ) ;
WRITE ( SHIFT_LD , HIGH ) ;
# endif
2012-12-12 11:47:03 +01:00
# else
2013-10-30 11:45:32 +01:00
# ifdef SR_LCD_2W_NL
pinMode ( SR_DATA_PIN , OUTPUT ) ;
pinMode ( SR_CLK_PIN , OUTPUT ) ;
# else
pinMode ( SHIFT_CLK , OUTPUT ) ;
pinMode ( SHIFT_LD , OUTPUT ) ;
pinMode ( SHIFT_EN , OUTPUT ) ;
pinMode ( SHIFT_OUT , INPUT ) ;
WRITE ( SHIFT_OUT , HIGH ) ;
WRITE ( SHIFT_LD , HIGH ) ;
WRITE ( SHIFT_EN , LOW ) ;
# endif // SR_LCD_2W_NL
2012-12-12 11:47:03 +01:00
# endif //!NEWPANEL
2013-10-30 11:45:32 +01:00
2013-06-07 00:49:25 +02:00
# if (SDCARDDETECT > 0)
2012-12-12 11:47:03 +01:00
WRITE ( SDCARDDETECT , HIGH ) ;
lcd_oldcardstatus = IS_SD_INSERTED ;
2013-06-07 00:49:25 +02:00
# endif //(SDCARDDETECT > 0)
2012-12-21 16:14:47 +01:00
lcd_buttons_update ( ) ;
2013-06-07 00:49:25 +02:00
# ifdef ULTIPANEL
2012-12-21 16:14:47 +01:00
encoderDiff = 0 ;
2013-06-07 00:49:25 +02:00
# endif
2012-12-12 11:47:03 +01:00
}
2011-12-12 19:34:37 +01:00
2012-12-12 11:47:03 +01:00
void lcd_update ( )
{
static unsigned long timeoutToStatus = 0 ;
lcd_buttons_update ( ) ;
2013-06-07 00:49:25 +02:00
# ifdef LCD_HAS_SLOW_BUTTONS
buttons | = lcd_implementation_read_slow_buttons ( ) ; // buttons which take too long to read in interrupt context
# endif
# if (SDCARDDETECT > 0)
2012-12-12 11:47:03 +01:00
if ( ( IS_SD_INSERTED ! = lcd_oldcardstatus ) )
{
lcdDrawUpdate = 2 ;
lcd_oldcardstatus = IS_SD_INSERTED ;
lcd_implementation_init ( ) ; // to maybe revive the lcd if static electricty killed it.
2012-08-22 00:46:10 +02:00
2012-12-12 11:47:03 +01:00
if ( lcd_oldcardstatus )
2012-08-22 00:46:10 +02:00
{
2012-12-12 11:47:03 +01:00
card . initsd ( ) ;
LCD_MESSAGEPGM ( MSG_SD_INSERTED ) ;
2012-08-22 00:46:10 +02:00
}
2012-12-12 11:47:03 +01:00
else
2012-08-22 00:46:10 +02:00
{
2012-12-12 11:47:03 +01:00
card . release ( ) ;
LCD_MESSAGEPGM ( MSG_SD_REMOVED ) ;
2012-08-22 00:46:10 +02:00
}
2012-12-12 11:47:03 +01:00
}
# endif //CARDINSERTED
if ( lcd_next_update_millis < millis ( ) )
2012-08-22 00:46:10 +02:00
{
# ifdef ULTIPANEL
2013-07-14 15:35:54 +02:00
# ifdef REPRAPWORLD_KEYPAD
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 ( ) ;
}
# endif
2013-09-13 04:12:51 +02:00
if ( abs ( encoderDiff ) > = ENCODER_PULSES_PER_STEP )
2012-08-22 00:46:10 +02:00
{
2012-12-12 11:47:03 +01:00
lcdDrawUpdate = 1 ;
2013-09-13 04:12:51 +02:00
encoderPosition + = encoderDiff / ENCODER_PULSES_PER_STEP ;
2012-12-12 11:47:03 +01:00
encoderDiff = 0 ;
timeoutToStatus = millis ( ) + LCD_TIMEOUT_TO_STATUS ;
2012-08-22 00:46:10 +02:00
}
2012-12-12 11:47:03 +01:00
if ( LCD_CLICKED )
timeoutToStatus = millis ( ) + LCD_TIMEOUT_TO_STATUS ;
# endif //ULTIPANEL
2013-03-19 20:19:16 +01:00
# ifdef DOGLCD // Changes due to different driver architecture of the DOGM display
2013-06-07 00:49:25 +02:00
blink + + ; // Variable for fan animation and alive dot
u8g . firstPage ( ) ;
do
{
u8g . setFont ( u8g_font_6x10_marlin ) ;
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
( * currentMenu ) ( ) ;
if ( ! lcdDrawUpdate ) break ; // Terminate display update, when nothing new to draw. This must be done before the last dogm.next()
} while ( u8g . nextPage ( ) ) ;
2013-03-19 20:19:16 +01:00
# else
2012-12-12 11:47:03 +01:00
( * currentMenu ) ( ) ;
2013-03-19 20:19:16 +01:00
# endif
2013-06-07 00:49:25 +02:00
# ifdef LCD_HAS_STATUS_INDICATORS
lcd_implementation_update_indicators ( ) ;
# endif
2012-12-12 11:47:03 +01:00
# ifdef ULTIPANEL
if ( timeoutToStatus < millis ( ) & & currentMenu ! = lcd_status_screen )
2012-08-22 00:46:10 +02:00
{
2012-12-12 11:47:03 +01:00
lcd_return_to_status ( ) ;
lcdDrawUpdate = 2 ;
2012-08-22 00:46:10 +02:00
}
2012-12-12 11:47:03 +01:00
# endif //ULTIPANEL
if ( lcdDrawUpdate = = 2 )
lcd_implementation_clear ( ) ;
if ( lcdDrawUpdate )
lcdDrawUpdate - - ;
lcd_next_update_millis = millis ( ) + 100 ;
}
}
2012-08-22 00:46:10 +02:00
2012-12-12 11:47:03 +01:00
void lcd_setstatus ( const char * message )
{
if ( lcd_status_message_level > 0 )
return ;
strncpy ( lcd_status_message , message , LCD_WIDTH ) ;
lcdDrawUpdate = 2 ;
}
void lcd_setstatuspgm ( const char * message )
{
if ( lcd_status_message_level > 0 )
return ;
strncpy_P ( lcd_status_message , message , LCD_WIDTH ) ;
lcdDrawUpdate = 2 ;
}
void lcd_setalertstatuspgm ( const char * message )
{
lcd_setstatuspgm ( message ) ;
lcd_status_message_level = 1 ;
# ifdef ULTIPANEL
lcd_return_to_status ( ) ;
# endif //ULTIPANEL
}
void lcd_reset_alert_level ( )
{
lcd_status_message_level = 0 ;
}
2012-08-22 00:46:10 +02:00
2013-07-14 10:28:26 +02:00
# ifdef DOGLCD
void lcd_setcontrast ( uint8_t value )
{
lcd_contrast = value & 63 ;
u8g . setContrast ( lcd_contrast ) ;
}
# endif
2012-12-12 11:47:03 +01:00
# ifdef ULTIPANEL
/* Warning: This function is called from interrupt context */
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 ;
2013-06-07 00:49:25 +02:00
# if BTN_ENC > 0
2012-12-12 11:47:03 +01:00
if ( ( blocking_enc < millis ( ) ) & & ( READ ( BTN_ENC ) = = 0 ) )
newbutton | = EN_C ;
2013-06-07 00:49:25 +02:00
# endif
2012-12-12 11:47:03 +01:00
buttons = newbutton ;
2013-07-14 15:35:54 +02:00
# ifdef REPRAPWORLD_KEYPAD
// for the reprapworld_keypad
uint8_t newbutton_reprapworld_keypad = 0 ;
WRITE ( SHIFT_LD , LOW ) ;
WRITE ( SHIFT_LD , HIGH ) ;
for ( int8_t i = 0 ; i < 8 ; i + + ) {
newbutton_reprapworld_keypad = newbutton_reprapworld_keypad > > 1 ;
if ( READ ( SHIFT_OUT ) )
newbutton_reprapworld_keypad | = ( 1 < < 7 ) ;
WRITE ( SHIFT_CLK , HIGH ) ;
WRITE ( SHIFT_CLK , LOW ) ;
}
buttons_reprapworld_keypad = ~ newbutton_reprapworld_keypad ; //invert it, because a pressed switch produces a logical 0
# endif
2012-12-12 11:47:03 +01:00
# 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 = newbutton > > 1 ;
if ( READ ( SHIFT_OUT ) )
newbutton | = ( 1 < < 7 ) ;
WRITE ( SHIFT_CLK , HIGH ) ;
WRITE ( SHIFT_CLK , LOW ) ;
}
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 | = ( 1 < < 0 ) ;
if ( buttons & EN_B )
enc | = ( 1 < < 1 ) ;
if ( enc ! = lastEncoderBits )
{
switch ( enc )
2012-08-22 00:46:10 +02:00
{
2012-12-12 11:47:03 +01:00
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-08-22 00:46:10 +02:00
}
2012-12-12 11:47:03 +01:00
}
lastEncoderBits = enc ;
2012-08-22 00:46:10 +02:00
}
2013-06-07 00:49:25 +02:00
void lcd_buzz ( long duration , uint16_t freq )
{
# ifdef LCD_USE_I2C_BUZZER
lcd . buzz ( duration , freq ) ;
# endif
}
bool lcd_clicked ( )
{
return LCD_CLICKED ;
}
2012-12-12 11:47:03 +01:00
# 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 ;
}
// convert float to string with +123.4 format
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 ;
}
2013-03-19 20:13:23 +01:00
// convert float to string with 123.4 format
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 ;
}
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 ;
}
char * itostr3 ( const int & xx )
{
2012-12-12 11:47:03 +01:00
if ( xx > = 100 )
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 ;
}
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 ;
}
2011-12-12 19:34:37 +01:00
char * itostr4 ( const int & xx )
{
2012-12-12 11:47:03 +01:00
if ( xx > = 1000 )
conv [ 0 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
else
conv [ 0 ] = ' ' ;
if ( xx > = 100 )
conv [ 1 ] = ( xx / 100 ) % 10 + ' 0 ' ;
else
conv [ 1 ] = ' ' ;
if ( xx > = 10 )
conv [ 2 ] = ( xx / 10 ) % 10 + ' 0 ' ;
else
conv [ 2 ] = ' ' ;
2011-12-12 19:34:37 +01:00
conv [ 3 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 4 ] = 0 ;
return conv ;
}
2012-12-12 11:47:03 +01:00
// convert float to string with 12345 format
char * ftostr5 ( const float & x )
{
long xx = abs ( x ) ;
if ( xx > = 10000 )
conv [ 0 ] = ( xx / 10000 ) % 10 + ' 0 ' ;
else
conv [ 0 ] = ' ' ;
if ( xx > = 1000 )
conv [ 1 ] = ( xx / 1000 ) % 10 + ' 0 ' ;
else
conv [ 1 ] = ' ' ;
if ( xx > = 100 )
conv [ 2 ] = ( xx / 100 ) % 10 + ' 0 ' ;
else
conv [ 2 ] = ' ' ;
if ( xx > = 10 )
conv [ 3 ] = ( xx / 10 ) % 10 + ' 0 ' ;
else
conv [ 3 ] = ' ' ;
conv [ 4 ] = ( xx ) % 10 + ' 0 ' ;
conv [ 5 ] = 0 ;
return conv ;
}
2011-12-12 19:34:37 +01:00
// convert float to string with +1234.5 format
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 ;
}
2012-02-21 23:05:43 +01:00
// convert float to string with +123.45 format
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
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
// Callback for after editing PID i value
// grab the pid i value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_i ( )
{
2013-06-16 00:09:52 +02:00
# ifdef PIDTEMP
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
Ki = scalePID_i ( raw_Ki ) ;
updatePID ( ) ;
2013-06-16 00:09:52 +02:00
# endif
2013-06-07 00:49:25 +02:00
}
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
// Callback for after editing PID d value
// grab the pid d value out of the temp variable; scale it; then update the PID driver
void copy_and_scalePID_d ( )
{
2013-06-16 00:09:52 +02:00
# ifdef PIDTEMP
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
Kd = scalePID_d ( raw_Kd ) ;
updatePID ( ) ;
2013-06-16 00:09:52 +02:00
# endif
2013-06-07 00:49:25 +02:00
}
2011-12-12 19:34:37 +01:00
# endif //ULTRA_LCD