Bladeren bron

Ensure smooth print moves even with LCD enabled

lcd_update can take so much time that the block buffer gets drained if
there are only short segments. This leads to jerky printer movements for
example in circles and a bad print quality.

This change implements a simple check: Only if the block currently
executed is long enough, run lcd_update.
This also means the printer will not show actual values on the LCD nor
will it respond to buttons pressed. A option that keeps the menu
accessible is also available.
Aditionaly, slow down if a block would be so fast that adding a new
block to the buffer would take more time. In this case, the buffer would
drain until it's empty in worst case.
Sebastianv650 8 jaren geleden
bovenliggende
commit
de89dc9f04
4 gewijzigde bestanden met toevoegingen van 68 en 9 verwijderingen
  1. 20
    0
      Marlin/Configuration_adv.h
  2. 13
    1
      Marlin/planner.cpp
  3. 15
    0
      Marlin/planner.h
  4. 20
    8
      Marlin/ultralcd.cpp

+ 20
- 0
Marlin/Configuration_adv.h Bestand weergeven

496
   #define BABYSTEP_MULTIPLICATOR 1 //faster movements
496
   #define BABYSTEP_MULTIPLICATOR 1 //faster movements
497
 #endif
497
 #endif
498
 
498
 
499
+// Enabling ENSURE_SMOOTH_MOVES ensures your printer will never stutter (for example in circles with a short segments). That's done in two steps:
500
+// --1--
501
+// During short segments like in circles, the update of the LCD Display can take so long that the block buffer gets completely drained.
502
+// If that happens, the movement of the printer gets very jerky until a longer segment like a longer straight line allows the buffer
503
+// to be filled again. This small stops also effects print quality in a bad way.
504
+// Enable ENSURE_SMOOTH_MOVES to update the LCD only when there is enough time during a move to do so.
505
+// Note that this means the display will not show actual values during this time and your printer will also not react to buttons
506
+// pressed immediately, except ALWAYS_ALLOW_MENU is also enabled.
507
+// --2--
508
+// 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, checking temps,
509
+// including all interruptions due to interrupts, but without LCD update. If we would allow shorter moves, the buffer would start continously draining.
510
+//#define ENSURE_SMOOTH_MOVES
511
+#if ENABLED(ENSURE_SMOOTH_MOVES)
512
+  //#define ALWAYS_ALLOW_MENU // If enabled, the menu will be always accessible.
513
+                              // WARNING: If the menu is entered or navigated during short moves, the printer will stutter like without ENSURE_SMOOTH_MOVES!
514
+  #define LCD_UPDATE_THRESHOLD 170 // Minimum duration in ms of the current segment to allow a LCD update.
515
+                                   // Default value is valid for graphical LCDs like the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER.
516
+  #define MIN_BLOCK_TIME 6 // Minimum duration in ms a single block has to take. You shouldn't need to modify this.
517
+#endif
518
+
499
 // @section extruder
519
 // @section extruder
500
 
520
 
501
 // extruder advance constant (s2/mm3)
521
 // extruder advance constant (s2/mm3)

+ 13
- 1
Marlin/planner.cpp Bestand weergeven

937
       if (segment_time < min_segment_time) {
937
       if (segment_time < min_segment_time) {
938
         // buffer is draining, add extra time.  The amount of time added increases if the buffer is still emptied more.
938
         // buffer is draining, add extra time.  The amount of time added increases if the buffer is still emptied more.
939
         inverse_mm_s = 1000000.0 / (segment_time + lround(2 * (min_segment_time - segment_time) / moves_queued));
939
         inverse_mm_s = 1000000.0 / (segment_time + lround(2 * (min_segment_time - segment_time) / moves_queued));
940
-        #ifdef XY_FREQUENCY_LIMIT
940
+        #if defined(XY_FREQUENCY_LIMIT) || ENABLED(ENSURE_SMOOTH_MOVES)
941
           segment_time = lround(1000000.0 / inverse_mm_s);
941
           segment_time = lround(1000000.0 / inverse_mm_s);
942
         #endif
942
         #endif
943
       }
943
       }
944
     }
944
     }
945
   #endif
945
   #endif
946
+  
947
+  #if ENABLED(ENSURE_SMOOTH_MOVES)
948
+    #if DISABLED(SLOWDOWN)
949
+      unsigned long segment_time = lround(1000000.0 / inverse_mm_s);
950
+    #endif
951
+    if (segment_time < (MIN_BLOCK_TIME) * 1000UL) {
952
+      // buffer will be draining, set to MIN_BLOCK_TIME.
953
+      inverse_mm_s = 1000000.0 / (1000.0 * (MIN_BLOCK_TIME));
954
+      segment_time = (MIN_BLOCK_TIME) * 1000UL;
955
+    }
956
+    block->segment_time = segment_time;
957
+  #endif
946
 
958
 
947
   block->nominal_speed = block->millimeters * inverse_mm_s; // (mm/sec) Always > 0
959
   block->nominal_speed = block->millimeters * inverse_mm_s; // (mm/sec) Always > 0
948
   block->nominal_rate = ceil(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0
960
   block->nominal_rate = ceil(block->step_event_count * inverse_mm_s); // (step/sec) Always > 0

+ 15
- 0
Marlin/planner.h Bestand weergeven

123
   #if ENABLED(BARICUDA)
123
   #if ENABLED(BARICUDA)
124
     uint32_t valve_pressure, e_to_p_pressure;
124
     uint32_t valve_pressure, e_to_p_pressure;
125
   #endif
125
   #endif
126
+  
127
+  #if ENABLED(ENSURE_SMOOTH_MOVES)
128
+    uint32_t segment_time;
129
+  #endif
126
 
130
 
127
 } block_t;
131
 } block_t;
128
 
132
 
366
         return NULL;
370
         return NULL;
367
     }
371
     }
368
 
372
 
373
+    #if ENABLED(ENSURE_SMOOTH_MOVES)
374
+      static bool long_move() {
375
+        if (blocks_queued()) {
376
+          block_t* block = &block_buffer[block_buffer_tail];
377
+          return (block->segment_time > (LCD_UPDATE_THRESHOLD * 1000UL));
378
+        }
379
+        else
380
+          return true;
381
+      }
382
+    #endif
383
+
369
     #if ENABLED(AUTOTEMP)
384
     #if ENABLED(AUTOTEMP)
370
       static float autotemp_max;
385
       static float autotemp_max;
371
       static float autotemp_min;
386
       static float autotemp_min;

+ 20
- 8
Marlin/ultralcd.cpp Bestand weergeven

2710
     // We arrive here every ~100ms when idling often enough.
2710
     // We arrive here every ~100ms when idling often enough.
2711
     // Instead of tracking the changes simply redraw the Info Screen ~1 time a second.
2711
     // Instead of tracking the changes simply redraw the Info Screen ~1 time a second.
2712
     static int8_t lcd_status_update_delay = 1; // first update one loop delayed
2712
     static int8_t lcd_status_update_delay = 1; // first update one loop delayed
2713
-    if (
2714
-      #if ENABLED(ULTIPANEL)
2715
-        currentScreen == lcd_status_screen &&
2716
-      #endif
2717
-        !lcd_status_update_delay--) {
2718
-      lcd_status_update_delay = 9;
2719
-      lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
2720
-    }
2713
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && ENABLED(ALWAYS_ALLOW_MENU)
2714
+      if (planner.long_move()) {
2715
+    #endif
2716
+        if (
2717
+          #if ENABLED(ULTIPANEL)
2718
+            currentScreen == lcd_status_screen &&
2719
+          #endif
2720
+            !lcd_status_update_delay--) {
2721
+          lcd_status_update_delay = 9;
2722
+          lcdDrawUpdate = LCDVIEW_REDRAW_NOW;
2723
+        }
2724
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && ENABLED(ALWAYS_ALLOW_MENU)
2725
+      }
2726
+    #endif
2721
 
2727
 
2728
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && DISABLED(ALWAYS_ALLOW_MENU)
2729
+      if (planner.long_move()) {
2730
+    #endif
2722
     if (lcdDrawUpdate) {
2731
     if (lcdDrawUpdate) {
2723
 
2732
 
2724
       switch (lcdDrawUpdate) {
2733
       switch (lcdDrawUpdate) {
2779
         break;
2788
         break;
2780
     }
2789
     }
2781
 
2790
 
2791
+    #if ENABLED(ENSURE_SMOOTH_MOVES) && DISABLED(ALWAYS_ALLOW_MENU)
2792
+      }
2793
+    #endif
2782
   }
2794
   }
2783
 }
2795
 }
2784
 
2796
 

Laden…
Annuleren
Opslaan