Adaptive screen updates for all kinds of displays

The target here is to update the screens of graphical and char base
displays as fast as possible, without draining the planner buffer too much.

For that measure the time it takes to draw and transfer one
(partial) screen to the display. Build a max. value from that.
Because ther can be large differences, depending on how much the display
updates are interrupted, the max value is decreased by one ms/s. This way
it can shrink again.
On the other side we keep track on how much time it takes to empty the
planner buffer.
Now we draw the next (partial) display update only then, when we do not
drain the planner buffer to much. We draw only when the time in the
buffer is two times larger than a update takes, or the buffer is empty anyway.

When we have begun to draw a screen we do not wait until the next 100ms
time slot comes. We draw the next partial screen as fast as possible, but
give the system a chance to refill the buffers a bit.

When we see, during drawing a screen, the screen contend has changed,
we stop the current draw and begin to draw the new content from the top.
This commit is contained in:
AnHardt 2016-12-12 14:35:02 +01:00
parent 0772c8e55f
commit d0e24e0876
23 changed files with 98 additions and 644 deletions

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -760,8 +760,8 @@ inline void sync_plan_position_e() { planner.set_e_position_mm(current_position[
int freeMemory() { return SdFatUtil::FreeRam(); } int freeMemory() { return SdFatUtil::FreeRam(); }
#else #else
extern "C" { extern "C" {
extern unsigned int __bss_end; extern char __bss_end;
extern unsigned int __heap_start; extern char __heap_start;
extern void* __brkval; extern void* __brkval;
int freeMemory() { int freeMemory() {

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -520,36 +520,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -515,36 +515,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -509,36 +509,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -509,36 +509,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -509,36 +509,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -514,36 +514,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -509,36 +509,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -507,36 +507,6 @@
#define BABYSTEP_MULTIPLICATOR 1 //faster movements #define BABYSTEP_MULTIPLICATOR 1 //faster movements
#endif #endif
//
// Ensure Smooth Moves
//
// Enable this option to prevent the machine from stuttering when printing multiple short segments.
// This feature uses two strategies to eliminate stuttering:
//
// 1. During short segments a Graphical LCD update may take so much time that the planner buffer gets
// completely drained. When this happens pauses are introduced between short segments, and print moves
// will become jerky until a longer segment provides enough time for the buffer to be filled again.
// This jerkiness negatively affects print quality. The ENSURE_SMOOTH_MOVES option addresses the issue
// by pausing the LCD until there's enough time to safely update.
//
// NOTE: This will cause the Info Screen to lag and controller buttons may become unresponsive.
// Enable ALWAYS_ALLOW_MENU to keep the controller responsive.
//
// 2. No block is allowed to take less time than MIN_BLOCK_TIME. That's the time it takes in the main
// loop to add a new block to the buffer, check temperatures, etc., including all blocked time due to
// interrupts (without LCD update). By enforcing a minimum time-per-move, the buffer is prevented from
// draining.
//
//#define ENSURE_SMOOTH_MOVES
#if ENABLED(ENSURE_SMOOTH_MOVES)
//#define ALWAYS_ALLOW_MENU // If enabled, the menu will always be responsive.
// WARNING: Menu navigation during short moves may cause stuttering!
#define LCD_UPDATE_THRESHOLD 135 // (ms) Minimum duration for the current segment to allow an LCD update.
// Default value is good for graphical LCDs (e.g., REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER).
// You may try to lower this value until you printer starts stuttering again as if ENSURE_SMOOTH_MOVES is disabled.
#define MIN_BLOCK_TIME 6 // (ms) Minimum duration of a single block. You shouldn't need to modify this.
#endif
// @section extruder // @section extruder
// extruder advance constant (s2/mm3) // extruder advance constant (s2/mm3)

View file

@ -145,7 +145,7 @@ float Planner::previous_speed[NUM_AXIS],
Planner::position_float[NUM_AXIS] = { 0 }; Planner::position_float[NUM_AXIS] = { 0 };
#endif #endif
#if ENABLED(ENSURE_SMOOTH_MOVES) #if ENABLED(ULTRA_LCD)
volatile uint32_t Planner::block_buffer_runtime_us = 0; volatile uint32_t Planner::block_buffer_runtime_us = 0;
#endif #endif
@ -985,30 +985,21 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const
const uint8_t moves_queued = movesplanned(); const uint8_t moves_queued = movesplanned();
// Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill // Slow down when the buffer starts to empty, rather than wait at the corner for a buffer refill
unsigned long segment_time = lround(1000000.0 / inverse_mm_s);
#if ENABLED(SLOWDOWN) #if ENABLED(SLOWDOWN)
// Segment time im micro seconds // Segment time im micro seconds
unsigned long segment_time = lround(1000000.0 / inverse_mm_s);
if (moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE) / 2) { if (moves_queued > 1 && moves_queued < (BLOCK_BUFFER_SIZE) / 2) {
if (segment_time < min_segment_time) { if (segment_time < min_segment_time) {
// buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
inverse_mm_s = 1000000.0 / (segment_time + lround(2 * (min_segment_time - segment_time) / moves_queued)); inverse_mm_s = 1000000.0 / (segment_time + lround(2 * (min_segment_time - segment_time) / moves_queued));
#if defined(XY_FREQUENCY_LIMIT) || ENABLED(ENSURE_SMOOTH_MOVES) #if defined(XY_FREQUENCY_LIMIT) || ENABLED(ULTRA_LCD)
segment_time = lround(1000000.0 / inverse_mm_s); segment_time = lround(1000000.0 / inverse_mm_s);
#endif #endif
} }
} }
#endif #endif
#if ENABLED(ENSURE_SMOOTH_MOVES) #if ENABLED(ULTRA_LCD)
#if DISABLED(SLOWDOWN)
unsigned long segment_time = lround(1000000.0 / inverse_mm_s);
#endif
if (segment_time < (MIN_BLOCK_TIME) * 1000UL) {
// buffer will be draining, set to MIN_BLOCK_TIME.
inverse_mm_s = 1000000.0 / (1000.0 * (MIN_BLOCK_TIME));
segment_time = (MIN_BLOCK_TIME) * 1000UL;
}
block->segment_time = segment_time;
CRITICAL_SECTION_START CRITICAL_SECTION_START
block_buffer_runtime_us += segment_time; block_buffer_runtime_us += segment_time;
CRITICAL_SECTION_END CRITICAL_SECTION_END

View file

@ -124,9 +124,7 @@ typedef struct {
uint32_t valve_pressure, e_to_p_pressure; uint32_t valve_pressure, e_to_p_pressure;
#endif #endif
#if ENABLED(ENSURE_SMOOTH_MOVES)
uint32_t segment_time; uint32_t segment_time;
#endif
} block_t; } block_t;
@ -214,7 +212,7 @@ class Planner {
static float extruder_advance_k; static float extruder_advance_k;
#endif #endif
#if ENABLED(ENSURE_SMOOTH_MOVES) #if ENABLED(ULTRA_LCD)
volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs volatile static uint32_t block_buffer_runtime_us; //Theoretical block buffer runtime in µs
#endif #endif
@ -381,26 +379,27 @@ class Planner {
static block_t* get_current_block() { static block_t* get_current_block() {
if (blocks_queued()) { if (blocks_queued()) {
block_t* block = &block_buffer[block_buffer_tail]; block_t* block = &block_buffer[block_buffer_tail];
#if ENABLED(ENSURE_SMOOTH_MOVES) #if ENABLED(ULTRA_LCD)
block_buffer_runtime_us -= block->segment_time; //We can't be sure how long an active block will take, so don't count it. block_buffer_runtime_us -= block->segment_time; //We can't be sure how long an active block will take, so don't count it.
#endif #endif
SBI(block->flag, BLOCK_BIT_BUSY); SBI(block->flag, BLOCK_BIT_BUSY);
return block; return block;
} }
else { else {
#if ENABLED(ENSURE_SMOOTH_MOVES) #if ENABLED(ULTRA_LCD)
clear_block_buffer_runtime(); // paranoia. Buffer is empty now - so reset accumulated time to zero. clear_block_buffer_runtime(); // paranoia. Buffer is empty now - so reset accumulated time to zero.
#endif #endif
return NULL; return NULL;
} }
} }
#if ENABLED(ENSURE_SMOOTH_MOVES) #if ENABLED(ULTRA_LCD)
static bool long_move() {
static millis_t block_buffer_runtime() {
CRITICAL_SECTION_START CRITICAL_SECTION_START
uint32_t bbru = block_buffer_runtime_us; millis_t bbru = block_buffer_runtime_us;
CRITICAL_SECTION_END CRITICAL_SECTION_END
return !bbru || bbru > (LCD_UPDATE_THRESHOLD) * 1000UL + (MIN_BLOCK_TIME) * 3000UL; return bbru;
} }
static void clear_block_buffer_runtime(){ static void clear_block_buffer_runtime(){
@ -408,6 +407,7 @@ class Planner {
block_buffer_runtime_us = 0; block_buffer_runtime_us = 0;
CRITICAL_SECTION_END CRITICAL_SECTION_END
} }
#endif #endif
#if ENABLED(AUTOTEMP) #if ENABLED(AUTOTEMP)

View file

@ -1098,13 +1098,13 @@ void Stepper::finish_and_disable() {
void Stepper::quick_stop() { void Stepper::quick_stop() {
cleaning_buffer_counter = 5000; cleaning_buffer_counter = 5000;
#if ENABLED(ENSURE_SMOOTH_MOVES)
planner.clear_block_buffer_runtime();
#endif
DISABLE_STEPPER_DRIVER_INTERRUPT(); DISABLE_STEPPER_DRIVER_INTERRUPT();
while (planner.blocks_queued()) planner.discard_current_block(); while (planner.blocks_queued()) planner.discard_current_block();
current_block = NULL; current_block = NULL;
ENABLE_STEPPER_DRIVER_INTERRUPT(); ENABLE_STEPPER_DRIVER_INTERRUPT();
#if ENABLED(ULTRA_LCD)
planner.clear_block_buffer_runtime();
#endif
} }
void Stepper::endstop_triggered(AxisEnum axis) { void Stepper::endstop_triggered(AxisEnum axis) {

View file

@ -64,6 +64,8 @@ void lcd_status_screen();
millis_t next_lcd_update_ms; millis_t next_lcd_update_ms;
uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to draw, decrements after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to draw, decrements after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial)
millis_t max_display_update_time = 0;
#if ENABLED(DOGLCD) #if ENABLED(DOGLCD)
bool drawing_screen = false; bool drawing_screen = false;
#endif #endif
@ -2893,7 +2895,11 @@ void lcd_update() {
#endif //SDSUPPORT && SD_DETECT_PIN #endif //SDSUPPORT && SD_DETECT_PIN
millis_t ms = millis(); millis_t ms = millis();
if (ELAPSED(ms, next_lcd_update_ms)) { if (ELAPSED(ms, next_lcd_update_ms)
#if ENABLED(DOGLCD)
|| drawing_screen
#endif
) {
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL; next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
@ -2954,36 +2960,30 @@ void lcd_update() {
} }
#endif // ULTIPANEL #endif // ULTIPANEL
#if ENABLED(ENSURE_SMOOTH_MOVES) && ENABLED(ALWAYS_ALLOW_MENU)
#define STATUS_UPDATE_CONDITION planner.long_move()
#else
#define STATUS_UPDATE_CONDITION true
#endif
#if ENABLED(ENSURE_SMOOTH_MOVES) && DISABLED(ALWAYS_ALLOW_MENU)
#define LCD_HANDLER_CONDITION planner.long_move()
#else
#define LCD_HANDLER_CONDITION true
#endif
// We arrive here every ~100ms when idling often enough. // We arrive here every ~100ms when idling often enough.
// Instead of tracking the changes simply redraw the Info Screen ~1 time a second. // Instead of tracking the changes simply redraw the Info Screen ~1 time a second.
static int8_t lcd_status_update_delay = 1; // first update one loop delayed static int8_t lcd_status_update_delay = 1; // first update one loop delayed
if (STATUS_UPDATE_CONDITION && if (
#if ENABLED(ULTIPANEL) #if ENABLED(ULTIPANEL)
currentScreen == lcd_status_screen && currentScreen == lcd_status_screen &&
#endif #endif
!lcd_status_update_delay-- !lcd_status_update_delay--
) { ) {
lcd_status_update_delay = 9; lcd_status_update_delay = 9
#if ENABLED(DOGLCD)
+ 3
#endif
;
max_display_update_time--;
lcdDrawUpdate = LCDVIEW_REDRAW_NOW; lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
} }
if (LCD_HANDLER_CONDITION) { millis_t bbr = planner.block_buffer_runtime();
#if ENABLED(DOGLCD) #if ENABLED(DOGLCD)
if (lcdDrawUpdate || drawing_screen) if ((lcdDrawUpdate || drawing_screen) && (!bbr || (bbr > max_display_update_time * 2000)))
#else #else
if (lcdDrawUpdate) if (lcdDrawUpdate && (!bbr || (bbr > max_display_update_time * 2000)))
#endif #endif
{ {
#if ENABLED(DOGLCD) #if ENABLED(DOGLCD)
@ -3015,10 +3015,14 @@ void lcd_update() {
} }
lcd_setFont(FONT_MENU); lcd_setFont(FONT_MENU);
CURRENTSCREEN(); CURRENTSCREEN();
if (drawing_screen && (drawing_screen = u8g.nextPage())) return; if (drawing_screen && (drawing_screen = u8g.nextPage())) {
max_display_update_time = max(max_display_update_time, millis() - ms);
return;
}
#else #else
CURRENTSCREEN(); CURRENTSCREEN();
#endif #endif
max_display_update_time = max(max_display_update_time, millis() - ms);
} }
#if ENABLED(ULTIPANEL) #if ENABLED(ULTIPANEL)
@ -3048,7 +3052,6 @@ void lcd_update() {
break; break;
} // switch } // switch
} }
} // LCD_HANDLER_CONDITION
} // ELAPSED(ms, next_lcd_update_ms) } // ELAPSED(ms, next_lcd_update_ms)
} }