Просмотр исходного кода

guaranteed BLTouch detection

To guarantee that the 5mS pulse from a BLTouch is recognized you need to
have the endstops.update() routine run twice in that 5mS period.

At 200 steps per mm, my system has problems  below a feedrate of 120 mm
per minute.

Two things were done to guarantee the two updates within 5mS:
1) In interrupt mode, a check was added to the temperature ISR.  If the
endstop interrupt flag/counter is active then it'll kick off the endstop
update routine every 1mS until the flag/counter is zero.  This
flag/counter is decremented by the temperature ISR AND by the stepper
ISR.

2) In poling mode, code was added to the stepper ISR that will make sure
the ISR runs about every 1.5mS.  The "extra" ISR runs only check the
endstops.  This was done by grabbing the intended ISR delay and, if it's
over 2.0mS, splitting the intended delay into multiple smaller delays.
The first delay can be up to 2.0mS, the next ones 1.5mS (as needed) and
the last no less than 0.5mS.

=========================================

BLTouch error state recovery

If BLTouch already active when deploying the probe then try to reset it
& clear the probe.

If that doesn't fix it then declare an error.

Also added BLTouch init routine to startup section
Bob-the-Kuhn 7 лет назад
Родитель
Сommit
0369f97ec1
4 измененных файлов: 106 добавлений и 26 удалений
  1. 23
    4
      Marlin/Marlin_main.cpp
  2. 7
    0
      Marlin/endstops.h
  3. 62
    22
      Marlin/stepper.cpp
  4. 14
    0
      Marlin/temperature.cpp

+ 23
- 4
Marlin/Marlin_main.cpp Просмотреть файл

@@ -388,7 +388,7 @@ int feedrate_percentage = 100, saved_feedrate_percentage,
388 388
     flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100);
389 389
 
390 390
 bool axis_relative_modes[] = AXIS_RELATIVE_MODES,
391
-     volumetric_enabled = 
391
+     volumetric_enabled =
392 392
       #if ENABLED(VOLUMETRIC_DEFAULT_ON)
393 393
         true
394 394
       #else
@@ -1987,8 +1987,13 @@ static void clean_up_after_endstop_or_probe_move() {
1987 1987
   #define STOW_PROBE() set_probe_deployed(false)
1988 1988
 
1989 1989
   #if ENABLED(BLTOUCH)
1990
+    void bltouch_command(int angle) {
1991
+      servo[Z_ENDSTOP_SERVO_NR].move(angle);  // Give the BL-Touch the command and wait
1992
+      safe_delay(375);
1993
+    }
1994
+
1990 1995
     FORCE_INLINE void set_bltouch_deployed(const bool &deploy) {
1991
-      servo[Z_ENDSTOP_SERVO_NR].move(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW);
1996
+      bltouch_command(deploy ? BLTOUCH_DEPLOY : BLTOUCH_STOW);
1992 1997
       #if ENABLED(DEBUG_LEVELING_FEATURE)
1993 1998
         if (DEBUGGING(LEVELING)) {
1994 1999
           SERIAL_ECHOPAIR("set_bltouch_deployed(", deploy);
@@ -2016,7 +2021,15 @@ static void clean_up_after_endstop_or_probe_move() {
2016 2021
 
2017 2022
     // When deploying make sure BLTOUCH is not already triggered
2018 2023
     #if ENABLED(BLTOUCH)
2019
-      if (deploy && TEST_BLTOUCH()) { stop(); return true; }
2024
+      if (deploy && TEST_BLTOUCH()) {      // If BL-Touch says it's triggered
2025
+        bltouch_command(BLTOUCH_RESET);    // try to reset it.
2026
+        set_bltouch_deployed(true);        // Also needs to deploy and stow to
2027
+        set_bltouch_deployed(false);       // clear the triggered condition.
2028
+        if (TEST_BLTOUCH()) {              // If it still claims to be triggered...
2029
+          stop();                          // punt!
2030
+          return true;
2031
+        }
2032
+      }
2020 2033
     #elif ENABLED(Z_PROBE_SLED)
2021 2034
       if (axis_unhomed_error(true, false, false)) { stop(); return true; }
2022 2035
     #elif ENABLED(Z_PROBE_ALLEN_KEY)
@@ -3902,7 +3915,7 @@ inline void gcode_G28() {
3902 3915
    *  R  Set the Right limit of the probing grid
3903 3916
    *
3904 3917
    * Parameters with BILINEAR only:
3905
-   * 
3918
+   *
3906 3919
    *  Z  Supply an additional Z probe offset
3907 3920
    *
3908 3921
    * Global Parameters:
@@ -10435,6 +10448,12 @@ void setup() {
10435 10448
         mixing_virtual_tool_mix[t][i] = mixing_factor[i];
10436 10449
   #endif
10437 10450
 
10451
+  #if ENABLED(BLTOUCH)
10452
+    bltouch_command(BLTOUCH_RESET);    // Just in case the BLTouch is in the error state, try to
10453
+    set_bltouch_deployed(true);        // reset it. Also needs to deploy and stow to clear the
10454
+    set_bltouch_deployed(false);       // error condition.
10455
+  #endif
10456
+
10438 10457
   #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
10439 10458
     i2c.onReceive(i2c_on_receive);
10440 10459
     i2c.onRequest(i2c_on_request);

+ 7
- 0
Marlin/endstops.h Просмотреть файл

@@ -92,4 +92,11 @@ class Endstops {
92 92
 
93 93
 extern Endstops endstops;
94 94
 
95
+#if HAS_BED_PROBE
96
+  #define ENDSTOPS_ENABLED  (endstops.enabled || endstops.z_probe_enabled)
97
+#else
98
+  #define ENDSTOPS_ENABLED  endstops.enabled
99
+#endif
100
+
101
+
95 102
 #endif // ENDSTOPS_H

+ 62
- 22
Marlin/stepper.cpp Просмотреть файл

@@ -345,13 +345,50 @@ ISR(TIMER1_COMPA_vect) {
345 345
 void Stepper::isr() {
346 346
   #define _ENABLE_ISRs() cli(); SBI(TIMSK0, OCIE0B); ENABLE_STEPPER_DRIVER_INTERRUPT()
347 347
 
348
+  uint16_t timer, remainder, ocr_val;
349
+
350
+  static uint32_t step_remaining = 0;
351
+
352
+  #define ENDSTOP_NOMINAL_OCR_VAL 3000    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
353
+  #define OCR_VAL_TOLERANCE 1000          // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
354
+
348 355
   #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
349
-    //Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
350
-    CBI(TIMSK0, OCIE0B); //Temperature ISR
356
+    // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
357
+    CBI(TIMSK0, OCIE0B); // Temperature ISR
351 358
     DISABLE_STEPPER_DRIVER_INTERRUPT();
352 359
     sei();
353 360
   #endif
354 361
 
362
+  #define _SPLIT(L) (ocr_val = (uint16_t)L)
363
+  #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
364
+    #define SPLIT(L) _SPLIT(L)
365
+  #else                 // sample endstops in between step pulses
366
+    #define SPLIT(L) do { \
367
+      _SPLIT(L); \
368
+      if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \
369
+        remainder = (uint16_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \
370
+        ocr_val = (remainder < OCR_VAL_TOLERANCE) ? ENDSTOP_NOMINAL_OCR_VAL + remainder : ENDSTOP_NOMINAL_OCR_VAL; \
371
+        step_remaining = (uint16_t)L - ocr_val; \
372
+      } \
373
+    } while(0)
374
+
375
+    if (step_remaining && ENDSTOPS_ENABLED) {   // Just check endstops - not yet time for a step
376
+      endstops.update();
377
+      ocr_val = step_remaining;
378
+      if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) {
379
+        step_remaining = step_remaining - ENDSTOP_NOMINAL_OCR_VAL;
380
+        ocr_val = ENDSTOP_NOMINAL_OCR_VAL;
381
+      }
382
+      else step_remaining = 0;  //  last one before the ISR that does the step
383
+      _NEXT_ISR(ocr_val);  //
384
+
385
+      NOLESS(OCR1A, TCNT1 + 16);
386
+
387
+      _ENABLE_ISRs(); // re-enable ISRs
388
+      return;
389
+    }
390
+  # endif
391
+
355 392
   if (cleaning_buffer_counter) {
356 393
     --cleaning_buffer_counter;
357 394
     current_block = NULL;
@@ -407,21 +444,16 @@ void Stepper::isr() {
407 444
   }
408 445
 
409 446
   // Update endstops state, if enabled
410
-  if ((endstops.enabled
411
-    #if HAS_BED_PROBE
412
-      || endstops.z_probe_enabled
413
-    #endif
414
-    )
415
-    #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
416
-      && e_hit
417
-    #endif
418
-  ) {
419
-    endstops.update();
420 447
 
421
-    #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
448
+
449
+  #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
450
+    if (ENDSTOPS_ENABLED && e_hit) {
451
+      endstops.update();
422 452
       e_hit--;
423
-    #endif
424
-  }
453
+    }
454
+  #else
455
+    if (ENDSTOPS_ENABLED) endstops.update();
456
+  #endif
425 457
 
426 458
   // Take multiple steps per interrupt (For high speed moves)
427 459
   bool all_steps_done = false;
@@ -600,7 +632,10 @@ void Stepper::isr() {
600 632
 
601 633
     // step_rate to timer interval
602 634
     uint16_t timer = calc_timer(acc_step_rate);
603
-    _NEXT_ISR(timer);
635
+
636
+    SPLIT(timer);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
637
+    _NEXT_ISR(ocr_val);
638
+
604 639
     acceleration_time += timer;
605 640
 
606 641
     #if ENABLED(LIN_ADVANCE)
@@ -653,7 +688,10 @@ void Stepper::isr() {
653 688
 
654 689
     // step_rate to timer interval
655 690
     uint16_t timer = calc_timer(step_rate);
656
-    _NEXT_ISR(timer);
691
+
692
+    SPLIT(timer);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
693
+    _NEXT_ISR(ocr_val);
694
+
657 695
     deceleration_time += timer;
658 696
 
659 697
     #if ENABLED(LIN_ADVANCE)
@@ -702,7 +740,9 @@ void Stepper::isr() {
702 740
 
703 741
     #endif
704 742
 
705
-    _NEXT_ISR(OCR1A_nominal);
743
+    SPLIT(OCR1A_nominal);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
744
+    _NEXT_ISR(ocr_val);
745
+
706 746
     // ensure we're running at the correct step rate, even if we just came off an acceleration
707 747
     step_loops = step_loops_nominal;
708 748
   }
@@ -726,9 +766,9 @@ void Stepper::isr() {
726 766
   // Timer interrupt for E. e_steps is set in the main routine;
727 767
 
728 768
   void Stepper::advance_isr() {
729
-    
769
+
730 770
     nextAdvanceISR = eISR_Rate;
731
-    
771
+
732 772
     #define SET_E_STEP_DIR(INDEX) \
733 773
       if (e_steps[INDEX]) E## INDEX ##_DIR_WRITE(e_steps[INDEX] < 0 ? INVERT_E## INDEX ##_DIR : !INVERT_E## INDEX ##_DIR)
734 774
 
@@ -803,7 +843,7 @@ void Stepper::isr() {
803 843
 
804 844
     // Run Advance stepping ISR if flagged
805 845
     if (!nextAdvanceISR) advance_isr();
806
-  
846
+
807 847
     // Is the next advance ISR scheduled before the next main ISR?
808 848
     if (nextAdvanceISR <= nextMainISR) {
809 849
       // Set up the next interrupt
@@ -822,7 +862,7 @@ void Stepper::isr() {
822 862
       // Will call Stepper::isr on the next interrupt
823 863
       nextMainISR = 0;
824 864
     }
825
-  
865
+
826 866
     // Don't run the ISR faster than possible
827 867
     NOLESS(OCR1A, TCNT1 + 16);
828 868
 

+ 14
- 0
Marlin/temperature.cpp Просмотреть файл

@@ -33,6 +33,10 @@
33 33
   #include "stepper.h"
34 34
 #endif
35 35
 
36
+#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
37
+  #include "endstops.h"
38
+#endif
39
+
36 40
 #if ENABLED(USE_WATCHDOG)
37 41
   #include "watchdog.h"
38 42
 #endif
@@ -1944,5 +1948,15 @@ void Temperature::isr() {
1944 1948
     }
1945 1949
   #endif
1946 1950
 
1951
+  #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
1952
+
1953
+    extern volatile uint8_t e_hit;
1954
+
1955
+    if (e_hit && ENDSTOPS_ENABLED) {
1956
+      endstops.update();  // call endstop update routine
1957
+      e_hit--;
1958
+    }
1959
+  #endif
1960
+
1947 1961
   SBI(TIMSK0, OCIE0B); //re-enable Temperature ISR
1948 1962
 }

Загрузка…
Отмена
Сохранить