Marlin: RCBugFix's M48 broke with BLTouch

Created on 17 Nov 2016  Â·  56Comments  Â·  Source: MarlinFirmware/Marlin

RCBugFix seems to work ok on my i3 printer with a servo and Z-Probe-Leg. But it doesn't work with the BLTOUCH turned on and a BL Touch probe on my other machine.

G28 works OK. But M48 is very sick. I turned on the Debug stuff with M111 S255. The first probe by M48 looks normal. But then it moves very slow and drives the probe and nozzle into the bed. I've included the G28 log. The M48 log is at the very end. This is what came out with the debug information turned on:

Printer is now online.

>>> M111 S255
SENDING:M111 S255
echo:DEBUG:ECHO,INFO,ERRORS,DRYRUN,COMMUNICATION,LEVELING
>>> G28
SENDING:G28
echo:G28
>>> gcode_G28
Machine Type: Cartesian
Probe: BLTOUCH
Probe Offset X:12 Y:-17 Z:-1.00 (Right-Front & Below Nozzle)
Auto Bed Leveling: LINEAR
reset_bed_level
  current_position=(0.00, 0.00, 0.00) : setup_for_endstop_or_probe_move
> endstops.enable(true)
Raise Z (before homing) to 15.00
>>> do_blocking_move_to(0.00, 0.00, 15.00)
<<< do_blocking_move_to
>>> homeaxis(Y)
Home 1 Fast:
>>> do_homing_move(Y, 615.00, 0.00)
  current_position=(0.00, 0.00, 15.00) : sync_plan_position
<<< do_homing_move(Y)
Move Away:
>>> do_homing_move(Y, -5.00, 0.00)
  current_position=(0.00, 0.00, 15.00) : sync_plan_position
<<< do_homing_move(Y)
Home 2 Slow:
>>> do_homing_move(Y, 10.00, 25.00)
  current_position=(0.00, 0.00, 15.00) : sync_plan_position
<<< do_homing_move(Y)
>>> set_axis_is_at_home(Y)
For Y axis:
 home_offset = 0.00
 position_shift = 0.00
 soft_endstop_min = 0.00
 soft_endstop_max = 410.00
> home_offset[Y] = 0.00
  current_position=(0.00, 410.00, 15.00) :
<<< set_axis_is_at_home(Y)
  current_position=(0.00, 410.00, 15.00) : sync_plan_position
  current_position=(0.00, 410.00, 15.00) : > AFTER set_axis_is_at_home
<<< homeaxis(Y)
  current_position=(0.00, 410.00, 15.00) : > homeY
>>> homeaxis(X)
Home 1 Fast:
>>> do_homing_move(X, -615.00, 0.00)
  current_position=(0.00, 410.00, 15.00) : sync_plan_position
<<< do_homing_move(X)
Move Away:
>>> do_homing_move(X, 5.00, 0.00)
  current_position=(0.00, 410.00, 15.00) : sync_plan_position
<<< do_homing_move(X)
Home 2 Slow:
>>> do_homing_move(X, -10.00, 25.00)
  current_position=(0.00, 410.00, 15.00) : sync_plan_position
<<< do_homing_move(X)
>>> set_axis_is_at_home(X)
For X axis:
 home_offset = 0.00
 position_shift = 0.00
 soft_endstop_min = 0.00
 soft_endstop_max = 410.00
> home_offset[X] = 0.00
  current_position=(0.00, 410.00, 15.00) :
<<< set_axis_is_at_home(X)
  current_position=(0.00, 410.00, 15.00) : sync_plan_position
  current_position=(0.00, 410.00, 15.00) : > AFTER set_axis_is_at_home
<<< homeaxis(X)
  current_position=(0.00, 410.00, 15.00) : > homeX
Z_SAFE_HOMING >>>
  current_position=(0.00, 410.00, 15.00) : sync_plan_position
  destination=(193.00, 222.00, 15.00) : Z_SAFE_HOMING
>>> do_blocking_move_to(193.00, 222.00, 15.00)
<<< do_blocking_move_to
>>> homeaxis(Z)
  current_position=(193.00, 222.00, 15.00) : set_probe_deployed
deploy: 1
do_probe_raise(10.00)
>>> do_blocking_move_to(193.00, 222.00, 15.00)
<<< do_blocking_move_to
Home 1 Fast:
>>> do_homing_move(Z, -799.50, 0.00)
set_bltouch_deployed(1)
  current_position=(193.00, 222.00, 0.00) : sync_plan_position
set_bltouch_deployed(0)
<<< do_homing_move(Z)
Move Away:
>>> do_homing_move(Z, 6.00, 0.00)
  current_position=(193.00, 222.00, 0.00) : sync_plan_position
<<< do_homing_move(Z)
Home 2 Slow:
>>> do_homing_move(Z, -12.00, 3.00)
set_bltouch_deployed(1)
  current_position=(193.00, 222.00, 0.00) : sync_plan_position
set_bltouch_deployed(0)
<<< do_homing_move(Z)
>>> set_axis_is_at_home(Z)
For Z axis:
 home_offset = 0.00
 position_shift = 0.00
 soft_endstop_min = 0.00
 soft_endstop_max = 533.00
*** Z HOMED WITH PROBE (Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) ***
> zprobe_zoffset = -1.00
> home_offset[Z] = 0.00
  current_position=(193.00, 222.00, 1.00) :
<<< set_axis_is_at_home(Z)
  current_position=(193.00, 222.00, 1.00) : sync_plan_position
  current_position=(193.00, 222.00, 1.00) : > AFTER set_axis_is_at_home
  current_position=(193.00, 222.00, 1.00) : set_probe_deployed
deploy: 0
do_probe_raise(10.00)
>>> do_blocking_move_to(193.00, 222.00, 11.00)
<<< do_blocking_move_to
>>> do_blocking_move_to(193.00, 222.00, 11.00)
<<< do_blocking_move_to
<<< homeaxis(Z)
<<< Z_SAFE_HOMING
  current_position=(193.00, 222.00, 11.00) : > (home_all_axis || homeZ) > final
  current_position=(193.00, 222.00, 11.00) : sync_plan_position
  current_position=(193.00, 222.00, 11.00) : clean_up_after_endstop_or_probe_move
<<< gcode_G28



>>> M48 V4
SENDING:M48 V4
echo:M48 V4
M48 Z-Probe Repeatability Test
Positioning the probe...
reset_bed_level
  current_position=(193.00, 222.00, 11.00) : setup_for_endstop_or_probe_move
>>> probe_pt(205.00, 205.00, no stow)
  current_position=(193.00, 222.00, 11.00) :
do_probe_raise(5.00)
>>> do_blocking_move_to(193.00, 222.00, 11.00)
<<< do_blocking_move_to
  current_position=(193.00, 222.00, 11.00) : set_probe_deployed
deploy: 1
do_probe_raise(10.00)
>>> do_blocking_move_to(193.00, 222.00, 11.00)
<<< do_blocking_move_to
  current_position=(193.00, 222.00, 11.00) : >>> run_z_probe
  current_position=(193.00, 222.00, 11.00) : >>> do_probe_move
set_bltouch_deployed(1)
>>> do_blocking_move_to(193.00, 222.00, -543.00)
<<< do_blocking_move_to
set_bltouch_deployed(0)
  current_position=(193.00, 222.00, 6.66) : sync_plan_position
  current_position=(193.00, 222.00, 6.66) : <<< do_probe_move
1st Probe Z:6.66
>>> do_blocking_move_to(193.00, 222.00, 12.66)
<<< do_blocking_move_to
  current_position=(193.00, 222.00, 12.66) : >>> do_probe_move
set_bltouch_deployed(1)
>>> do_blocking_move_to(193.00, 222.00, -543.00)

At this point, the Z Axis is very slowly descending into the bed. It won't recognize that the probe is touched.

Potential ? BLTouch Calibration

All 56 comments

Does the BLTouch ever go into "error state" or start blinking? BLTouch doesn't like to be deployed too long without getting triggered. And it sounds like that second probe is going too slow. Possibly the M48 code is setting too slow a feed-rate after the first probe, or it's too far off the bed.

Is your Z_HOME_BUMP_MM set to 6? Try a smaller value, like 4.
And perhaps a faster Z_PROBE_SPEED_SLOW may also help.

I can confirm that there is something not right happening. I loaded up RCBugFix and turned on the

#define PROBE_DOUBLE_TOUCH
#define BLTOUCH

I haven't really spent a lot of time on this yet. And my debug log looks different.

But what I'm seeing is the first bump and retraction happening correctly. And I believe the 2nd bump (the actual probe of the point) is happening correctly. And then things go sour on my BL-Touch. It retracts the probe pin and immediately redeploys it. The pin strikes the bed and then the BL-Touch starts blinking Red until I power off the machine.

I'll look at it more closely tomorrow. But I think the move back up should be happening before the probe pin is re-deployed. Also... Can you tell me how long it is OK to have the BL-Touch probe deployed without it being triggered? I'm toying with the idea of doing a 'Reset' every time the probe is deployed because there is no way to check its state and see that it is not in an 'Error State'.

(Maybe this last sentence isn't true. It might return the same status (either triggered or not triggered) when ever it is in an 'Error State'. If so, we might be able to check it immediately after a deploy or a retract to see if it is reporting correctly. And if not... only do the reset at that time????)

https://github.com/MarlinFirmware/Marlin/pull/4455 (Why double touch probing is not a good thing.)
Just switch PROBE_DOUBLE_TOUCH off. It does not improve the result.

That's interesting... With the 'PROBE_DOUBLE_TOUCH' turned off, I get different errors. The first time the G28 went OK but the very first M48 probe drove the nozzle into the bed. After powering off the machine and trying again, the G28 and the first several M48 probes went OK. But then it failed to raise the nozzle before redeploying the pin (and tapping the glass) and the BL-Touch went into the 'Error State'.

I'll have to add some debug code and look at it in more detail tomorrow.

PROBE_DOUBLE_TOUCH is not used during homing. It's only used in run_z_probe().
If BLTouch needs a special handling for double touch while homing, homeaxis() has to be extended. No other kind of probe needs, or does, a stow/deploy cycle between the touches.
That also means we do not actively extend/retract the probe by purpose there - it dos that by itself.

I can't remember what thinkyhead did to integrate BLTouch but the 'E' option in G29 and M48 may help

did to integrate BLTouch but the 'E' option in G29 and M48 may help

That is worth checking! But these BL-Touch probes are not fully deterministic. I've seen it behave differently even though it is being told to do the exact same thing. And the other problem is once the probe gets into an 'Error State', I don't see (at least not yet...) any place where Marlin tries to reset it. Once it gets into an 'Error State' it is up to the user to see that and power off the machine before the nozzle gets crashed into the bed.

The main difference with BLTouch is that it always "stows" the pin immediately after probing (set_bltouch_deployed(0)), then only "deploys" the pin (set_bltouch_deployed(1)) just as it's starting the probe. This was needed to prevent it from dropping the pin too soon — while raising after probing. In do_probe_move…

// Deploy BLTouch at the start of any probe
#if ENABLED(BLTOUCH)
  set_bltouch_deployed(true);
#endif

// Move down until probe triggered
do_blocking_move_to_z(LOGICAL_Z_POSITION(z), MMM_TO_MMS(fr_mm_m));

// Retract BLTouch immediately after a probe
#if ENABLED(BLTOUCH)
  set_bltouch_deployed(false);
#endif

Same idea in do_homing_move.

PROBE_DOUBLE_TOUCH is not used during homing. It's only used in run_z_probe().
If BLTouch needs a special handling for double touch while homing, homeaxis() has to be extended.

The problem I'm seeing (both with and without PROBE_DOUBLE_TOUCH) is in run_z_probe(). As it turns out, the G28 homing is fine. I'll have to look at that closer when my machine is done doing 37 Windows Updates. But right now, I'm under the impression that G28 does not do any run_z_probe() calls.

And of course... M48 does use run_z_probe(). So that might explain why only a few people are seeing the problem. If I understand what you said about the BL-Touch probe pin in the previous post, it may be that a strategically placed:

// Retract BLTouch immediately after a probe
#if ENABLED(BLTOUCH)
  set_bltouch_deployed(false);
#endif

in run_z_probe() might cure the problem ????

UPDATE: Adding a few of those code blocks to run_z_probe() definitely helps. But I'm still getting occasional errors where the BL-Touch starts blinking Red. The good news is I think run_z_probe() isn't too far off from being 'correct'.

BLTouch doesn't like to be deployed too long without getting triggered.

I am starting to think this is not true. I have been playing with the error reset function (or setting the servo angle to 160 degrees). When in an 'Error State', the BL-Touch reports 'Triggered' to the M119.

I've been deploying the probe for several minutes at a time and not getting any errors while having it wait for me to get around to doing something with it.

The error condition takes about 1/10 second to reset with a M280 P0 S160. I wonder if it would make sense to check if the set_bltouch_deployed() function if the probe is triggered and if so, reset it?

BLTouch doesn't like to be deployed too long without getting triggered.

As far as I can tell, that's not true - you're right, Roxy. The BLTouch doesn't care how long the pin is deployed. It's entirely dumb.

When did the problem described in this thread first appear? I'm using 06f2282 and having no problems whatsoever. I guess I'll try updating to the latest and see if I have the same issue.

In any case, how it's working as of 06f2282 is perfect. Everything functions as it should, imo, and I just got a 1.8um M48 result. Doesn't get much better than that.

Will reply here after updating to the latest RCBugFix and testing.

I re-duplicated the issue on November 13 2016's RCBugFix. Part of the problem is the BL-Touch probes seem to be a little bit random. So far, I have not made it through a 10 point set of probes. But I think I can work around the finicky behavior of the BL-Touch to get it to work reliably.

@bgort Do you have a fairly fast lift of the nozzle after the probe is triggered? If so, that might explain why you are not seeing any problems.

G28, G29, M48, etc. are all working fine for me with 32247c1.

Here are my configs, in case they're of use:

@bgort Do you have a fairly fast lift of the nozzle after the probe is triggered? If so, that might explain why you are not seeing any problems.

#define HOMING_FEEDRATE_Z  (4*60)
#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)

What are you using?

Currently I'm using:

#define HOMING_FEEDRATE_Z  (12*60)
#define Z_PROBE_SPEED_FAST (HOMING_FEEDRATE_Z / 5)
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 3)

So I'm moving a bit faster. Will try slowing it down. Stand by.

Go crazy and slow it down to 10% of the current speed! :)

#define HOMING_FEEDRATE_Z  (4*6)

I just used your config values and there's no issue at all, here.

No errors/nozzle strikes and 1.6um w/M48.

Hmmmm! What if you do:

#define HOMING_FEEDRATE_Z  (4*6)

with your other settings?

That's what I had originally. I assume you mean 4*6 ?

With:

#define HOMING_FEEDRATE_Z  (4*6)
#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)

I do indeed end up with an error condition (blinking BLTouch) ..

Yes! 4*6 ! Sorry! But it is good to hear you see the same behavior.

I would be willing to bet you see the probe pin retract when the probe gets triggered, and then redeploy and hit the glass (because the nozzle isn't moving up away from the glass fast enough).
And then the probe starts blinking red.

Yes, that's exactly what's happening.

So maybe the solution is to have a minimum 'safe' height for redeploying for BLTouch users?

Agreed! But probably that can be accomplished by just not redeploying the probe until the nozzle has finished moving up to:

#define Z_CLEARANCE_DEPLOY_PROBE   10 // Z Clearance for Deploy/Stow
#define Z_CLEARANCE_BETWEEN_PROBES  5 // Z Clearance between probe points

The one trick would be to make sure Z_CLEARANCE_DEPLOY_PROBE is used between probes in the BL-Touch case.

Think I may have found the problem. Testing now...

Looking forward to finding out the cause. BLTouch behavior has always been tricky to wrangle.

Thought I'd found it, but not so lucky. Will plan on picking up where I left off in the morning, unless someone beats me to the solution.

Thought I'd found it, but not so lucky. Will plan on picking up where I left off in the morning, unless someone beats me to the solution.

@bgort Can you tell me what you thought you found? It might help me isolate the problem. Right now, I'm thinking the problem is the BL-Touch probe gets redeployed prior to the move up. But I have not confirmed that. I don't know that is true.

I have also started to add some test code to check if the BL-Touch probe is in an error state when it is deployed. If so... We need to do a 'Reset' first. I'll post that code in the morning in case you want to use it in your debug session.

I'm thinking the problem is the BL-Touch probe gets redeployed prior to the move up.

Current M48 code just uses probe_pt.

The probe_pt function does the raise, moves to the point, calls set_probe_deployed(true), and then calls run_z_probe. Unless the "stow" flag is used with M48 the BLTouch will already be "deployed," so set_probe_deployed will simply make sure it's been raised, then set the enabled flag so it will be checked.

The run_z_probe function calls do_probe_move for the actual probe of the bed.

The do_probe_move function deploys the BLTouch pin by calling set_bltouch_deployed(true), moves down until triggered, and immediately calls set_bltouch_deployed(false). The BLTouch pin should remain up until the next time do_probe_move is called.

Note that when PROBE_DOUBLE_TOUCH is enabled, the function run_z_probe uses Z_HOME_BUMP_MM as the raise value between the two probes. So be sure to have a reasonably large Z_HOME_BUMP_MM value. (The default is only 2mm because it assumes an endstop.)

This is happening for me with G28, also. It reliably happens after the second/slow homing probe. The pin is deployed, the lowering occurs, the endstop triggers, the pin is immediately retracted, then immediately redeploys->impacts the glass->error states the BLTouch.

I believe (and believed previously) this has to do with something happening in set_probe_deployed, because commenting the calls (I initially thought they were superfluous because we're actually relying on set_bltouch_deployed to do the job) causes the problem to reliably occur following the first/fast probe.

Feel like I'm on the right track, but just missing something. Hopefully will sort it out shortly.

An update: I've finally had some time for this (my days don't always go as I'd like), and am seeing that Marlin isn't actually at fault here - not as far as I can tell.

This issue (immediate pin redeployment -> 'error state'-ing) is occurring at slow z homing speeds at every point in G28. Sometimes it happens at the first/fast probe, sometimes at the second/slow probe. I haven't had a single successful G28, so haven't been able to try M48, yet.

I've put debug code in numerous places, and unless the servo position is being changed somewhere outside of Servo::move(), Marlin isn't intentionally redeploying the probe too soon at any point.

So I'm wondering if there's slow-speed-related noise, or some other issue, causing the immediate redeployment. Next step - unless anyone has any better ideas - is to put the oscilloscope on it and see what I can see.

We already know, there is a bit of jitter on the width of the servo pulses. For me not enough to see it at a real servo, but enough to feel it. We don't have an idea how to fix this. For real servos we learned to work around with DEACTIVATE_SERVOS_AFTER_MOVE. For BLTouch this is not an option.

But if it is a jitter problem, maybe centering Marlin's signal in the 'window' of BLTouch could be an option.

Try the 'original' servo angles +-1 or 2.

So I'm wondering if there's slow-speed-related noise, or some other issue, causing the immediate redeployment. Next step - unless anyone has any better ideas - is to put the oscilloscope on it and see what I can see.

Please do this!

I don't think this is an electrical noise problem. My machine is very 'clean' electrically. And remember... You didn't even see a problem until you slowed the machine down.

Do you have a multi-channel 'Storage Scope' ? Can you catch a trace of the servo pulses at the same time it goes into an error state? (Don't cringe... But if I had a storage scope I would drill a small hole so I could hook a probe onto the red error LED and use that as a trigger) Maybe there is a less invasive way to trigger the scope at the error by just taping a photo-transistor to the probe????)

I don't think this is an electrical noise problem. My machine is very 'clean' electrically. And remember... You didn't even see a problem until you slowed the machine down.

The possibility I was considering was that the noise was specifically related to the slow speed, as in something not being filtered out, or a harmonic, or something, etc. But it doesn't appear that's the case.

Do you have a multi-channel 'Storage Scope' ? Can you catch a trace of the servo pulses at the same time it goes into an error state?

Yes, after a fashion. I have a redpitaya and can screenshot or record the in-browser output. See below.

(Don't cringe... But if I had a storage scope I would drill a small hole so I could hook a probe onto the red error LED and use that as a trigger) Maybe there is a less invasive way to trigger the scope at the error by just taping a photo-transistor to the probe????)

I don't believe this is necessary. Looking at the spec sheet/timing diagram it seems that when it errors, Zmin goes high and stays that way. This is consistent with what I'm seeing with the scope.

spec sheet/timing diagram

After a few hours of tinkering, what it's looking like, to me, is that Marlin is missing the 5ms Zmin trigger signal when moving slowly. Here's the sequence of events I'm seeing w/a 'slow' homing G28 (HOMING_FEEDRATE_Z = 4*6, for me):

  • Skip X & Y - fast forward to Z
  • the probe is centered over the bed (safe homing on), all the while Marlin is sending ~1500us/90°/'UP' pulses at 50hz to keep the pin retracted (stowed state)
  • the 'UP' PWM pulses shrink to ~640us/10°/'DOWN' pulses, and the BLTouch deploys the probe pin
  • the z axis lowers itself at 'fast' speed
  • the probe pin contacts the glass but the z axis continues to descend until the trigger point (~1.5mm? after initial contact, it seems)
  • at the trigger point, the BLTouch self-retracts the pin nearly simultaneously with sending a 5ms trigger/high signal on Zmin
  • a few ms go by (however long it takes to get to the next PWM pulse time), then the pulse width increases to ~1500us/90°/'UP' (Marlin has caught the 5ms pulse and Servo::move() was called)
  • BLTouch leaves the pin retracted because it's seeing the 1500us/90°/'UP' pulses
  • the Z axis rises to the specified clearance/safe distance

...at this point, take a look at this image, which depicts the end of the above; yellow is the PWM control signal, green is Zmin:

screenshot 2016-11-20 14 00 07

...continuing on...

  • the z axis reaches the apex of the clearance move
  • the probe servo PWM pulse width again changes to 'DOWN' and the probe pin is deployed
  • the z axis lowers itself, but in 'slow' mode this time
  • at the trigger point, the BLTouch self-retracts the pin and sends its 5ms pulse (consistent with the above)
  • Marlin seems to miss the 5ms pulse and continues sending 'DOWN' pulses
  • the BLTouch receives the 'DOWN' pulses, and redeploys the pin, as it should - this results in a glass impact, and the 'could-not-properly-deploy-pin error state' a handful of PWM cycles later.

...see the following, which corresponds to the above ...

screenshot 2016-11-20 13 52 55

...and finally...

  • Marlin continues lowering the probe pin until the error state is detected, at which point it thinks it's found the bed, then it returns the Z axis to the 'finished homing' position.

screenshot 2016-11-20 14 45 49

My guess is that this whole issue is related to the timer/interrupt that's pulsing the stepper, in that at very slow speeds Marlin isn't catching the Zmin trigger because the time between interrupts/stepper pulses is larger than the time necessary to positively/reliably catch the 5ms pulse? When the steppers are moving faster, the time between pulses is much shorter, and so the odds of catching the 5ms trigger increase to the point there are no misses/failures. This would explain why the 'misses' seem to be inconsistent; i.e., sometimes the 'fast' homing probe works fine and sometimes it fails (you'd generally think if it missed once it would miss every time). I'd think this means that whether it fails depends on when the whole process started with respect to the timing of the pulsing of the steppers (and the calls to the endstop checking function). This means that everything remains happily deterministic, and that we just have a timing-sync issue.

... And, finally, some raw/un-annotated video, in case anyone is interested:

(to sort out what's going on in each, refer to the video descriptions and the scrolling logs in the upper right hand corners)

I wish I had more time to think through and fix this; have errands to run, etc. .. but I'm guessing it would be much easier for someone more familiar to fix, anyway.

For whatever it's worth, I strongly suspect the 'best' solutions are either to use an interrupt for Zmin, or to modify the BLTouch firmware (though that's probably not very practical) ...

Anyway, hope the above helps!

EDIT: corrected youtube URL - mistakenly double pasted the same one

Thanks for this detailed analysis.
Your assumption the stepper pulses are too far apart seems to be the right direction and makes perfect sense.

It's worse. To have at least a bit of debouncing, it needs two consecutive steps to detect the endstop state change.

That should be visible if you grab the probe output and the z-stepper step pulse.

The difficult part now is to find a fix, better than the advice, to be fast enough.

No problem - was fun.

Yeah, the fix doesn't seem like it would be a simple one. I think there's a reason an interrupt isn't used for the endstops - @thinkyhead mentioned this to me previously, though I don't recall what the reason was.

I suppose the stepper timer/interrupt could be run at some minimum speed, and then we could just use a simple counter to actually do the step, and run the endstop check every other time the interrupt fires. I presume some of this is already being done to keep consistent timing, as the interrupts can't trigger at every possible frequency, generally.

Something like:

void stepper_interrupt_function() {
  if(++triggers>interrupt_multiplier) {   // triggers - a global; the math for the multiplier should be trivial
    do_step_and_everything_else();
    triggers=0;
  } else check_endstops();
}

I suspect something like that might work, with fast enough minimum interrupt triggering.

BLTouch sending a longer Zmin pulse would be helpful, though obviously you lose precision, and it isn't very practical for the thousands who already have BLTouch.

I wonder how many people are operating at speeds slow enough for this to be a problem? Obviously some...

Good news is it should be relatively easy to detect the error state; if Zmin is high for longer than 5ms => error. And the reset-and-carry-on is quite simple, after that, if that's what makes the most sense.

Here we come to the root of the problem.
BLTouch is patent (or wanabe) crippled litter.
If it would be open sourced, we could take the software of the processor and increase the pulse width.

No disagreement from me... Open source is much better - for this reason and many others.

The uC is an ATTiny, I believe. I don't think it'd be too hard to clip onto the chip and overwrite it, unless they've disallowed that with the fuses (though iirc you can still fix the fuses with a HV programmer). Would just take someone writing a new bit of probably-not-very-complicated code. Though it would have been better to design for open source/overwriting, so as not to force people to disassemble it when it might cause damage. I don't recall whether the chip is on the outside or inside, and mine is installed so I can't easily check.

Perhaps we can send them this thread and see if they'll be willing to either open source or offer an update or replacement for those who have this issue.

I emailed Paris a couple of weeks ago about the possibility of upgrading
the firmware in the BLTouch, she thought it was a great idea, however there
hasn't been any update since, though I don't know what provisions or not,
have been enabled to achieve this

A brief calculation shows.
With 16MHz and a 16bit timer and prescaler, we can go as slow as ~30steps/second which is ~33ms/step.
More than 6 times longer than the BLTouch pulse.
Even if we'd drop the debouncing there is a good chance to miss the pulse.

To put 2 steps into 5ms for sure we'd have to make steps not lasting longer than ~2ms. (500steps/second)
Assuming a typical belt with ~80steps/mm - this is quite fast.

Do we already have a minimum step speed? I've seen that before - but if that was Marlin?

__Edited__ some times.

we can go as slow as ~30steps/second what is ~33ms/step.

Perhaps we can send them this thread and see if they'll be willing to either open source or offer an update or replacement for those who have this issue.

Would there be any harm to other printers if we asked for the BL-Touch to have the triggered time length be 40 ms instead of 5 ms ?

Hmm. Can't the changes being discussed in #5102 (with perhaps some slight alterations) be used to resolve this issue for almost all users? I just came across this and it seems to me that using the ISR for the endstop could solve the problem for most (I believe a lot of/most boards have interrupt capability on pins that could be used for at least Zmin), provided there's no noise on the line. Or am I missing something?

Would there be any harm to other printers if we asked for the BL-Touch to have the triggered time length be 40 ms instead of 5 ms ?

I can't imagine how it could cause a problem. I'm not as familiar other types of printers, but I can't imagine anyone/anything would need to probe faster than a 40ms trigger signal would allow.

Can't the changes being discussed in #5102 (with perhaps some slight alterations) be used to resolve this issue for almost all users?

I was thinking the same thing. And we should try to do that. But the problem is there still will be users that put a BL-Touch probe on a non-interrupt pin by accident. The other possibility is to ask them to do is provide a mode where the pin does not automatically retract until the firmware tells it to retract. And part of the special mode would be if the pin is not retracted... It keeps putting out a triggered signal. With that, we could be sure we would not miss the pulse. Something like if we tell the server to go to 45 degrees... It enters the special mode.

The other possibility is to ask them to do is provide a mode where the pin does not automatically retract until the firmware tells it to retract. And part of the special mode would be if the pin is not retracted... It keeps putting out a triggered signal. With that, we could be sure we would not miss the pulse.

I think that's a great idea. Make the BLTouch (optionally) dumber, in essence, and the problem goes away.

Though it would make it harder to detect an error condition when in that mode..

As a workaround, could we send the BLTOUCH_RESET angle to the probe just before each probe begins? Or, first check whether the raised probe is still triggered (thus in error state), then send BLTOUCH_RESET to it?

Maybe... But the BLTOUCH_RESET angle takes time to be recognized. And it takes time to wait for the possible retraction of the probe. If we are going to do something like that... How about we add an extra parameter to do_probe_move() saying whether we should do a reset or not while the move is happening. Maybe we could combine the time it takes to do the reset with what ever movement is happening prior to the move. (I'm not sure that is really do-able... But it it was... A reset might just be the ticket.)

Or, first check whether the raised probe is still triggered, then send BLTOUCH_RESET to it?

Actually... I already did this one. And it does help. But it isn't a complete solution. The problem is... Sometimes during the M48 probing the probe gets sick. But it doesn't light up the Error State blink.
I don't know the specifics yet. But some times you can tell the probe to deploy but it doesn't. And the Error Light does not come on. And what happens is you drive the nozzle into the bed.

I was thinking the same thing. And we should try to do that. But the problem is there still will be users that put a BL-Touch probe on a non-interrupt pin by accident.

Thinking out loud: that someone uses a non-interrupt pin isn't Marlin's problem, though. I mean, sure, it's better for things to be easier to use, of course, but I'm quite sure they'd put in the BLTouch instructions and wiring diagrams that an interrupt-capable pin should be used, and they can even make suggestions for each board, like they already do. As in.. "If you're using Marlin and use 'slow' Z homing/probing, be sure to use an interrupt-capable pin (pin x recommended; circled in red on the above diagram) and #define ZMIN_INTERRUPT [or whatever]."

And we can add a detailed comment somewhere(s) (config file, at least) explaining that for slow homing, or higher precision, that Zmin should be on an interrupt pin and ZMIN_INTERRUPT defined.

Chances are, unless they're moving slowly they're not even going to notice this issue and will therefore be happy with the standard config., if they do have a problem, chances are good they'll look in the config files for options to fix it.

As a workaround, could we send the BLTOUCH_RESET angle to the probe just before each probe begins? Or, first check whether the raised probe is still triggered (thus in error state), then send BLTOUCH_RESET to it?

I think the main reason not to do this is that the time between when Marlin misses the 5ms trigger pulse and when it picks up the error state (thinking it's the trigger) is potentially long enough to throw off the accuracy of the probe pretty significantly. How meaningful the 'error' is would depend on the stepper's travel per step, step speed, etc. I didn't time how long it actually takes, but I know there were more pulses between pin impact and error than would fit on the screen, even when zoomed out. Maybe 200ms? I'm guessing, but it isn't necessarily a short delay. (I need to sort out proper data logging with the thing, but haven't done that yet; I know it's possible.)

Then again, whether the user is willing to accept the potential error rather than move Zmin to an interrupt pin is their decision. I'd imagine a #define RESET_BLTOUCH_BETWEEN_PROBES, referenced/used in the appropriate function(s) - perhaps in calls to set_bltouch_deployed(false), which could simply send the 160°/'RESET' instead of the 90°/'UP'/STOW - would pretty easily do the job in a way that shouldn't necessarily require any potentially complicated waiting at any point. If someone needs longer for the reset to complete, the easy solution is to simply add a few mm to the clearance distance, no? If they're going to be waiting anyway, what's the difference if the axis is moving a little further during that time. Much easier to implement, I'd think.

How meaningful the 'error' is would depend on the stepper's travel per step, step speed, etc. I didn't time how long it actually takes, but I know there were more pulses between pin impact and error than would fit on the screen, even when zoomed out. Maybe 200ms? I'm guessing, but it isn't necessarily a short delay.

From my raw video, and in round numbers suggested by a frame-by-frame analysis, here's the timing of what happens when it's going to error for the reason we're discussing:

  • t=0: the normal 5ms trigger pulse is sent, which Marlin misses, and the probe starts the self-retract
  • t=~99.9ms (3 frames): the pin has fully self-retracted
  • t=~333ms (7 more frames; 10 total): the pin starts to redeploy
  • t=~366.3ms (+1f; 11 total): the pin impacts the glass
  • t=~1032.3ms (+20f; 31): the error state begins - Zmin goes high/error, LED begins blinking, etc.

Because this is from a frame-by-frame analysis and it's hard to account for potential 1-or-2-frame sync issues between what's captured in the video and what's captured in the browser-based oscilloscope, these numbers are necessarily rough. But at least they give us some brackets and an idea of the timing.

I'd imagine a #define RESET_BLTOUCH_BETWEEN_PROBES, referenced/used in the appropriate function(s) - perhaps in calls to set_bltouch_deployed(false), which could simply send the 160°/'RESET' instead of the 90°/'UP'/STOW - would pretty easily do the job in a way that shouldn't necessarily require any potentially complicated waiting at any point.

Disregard this - it doesn't actually reset when there's no error condition. Could check and then reset, though.

i wonder where @naive-user is in all this?

From my raw video, and in round numbers suggested by a frame-by-frame analysis, here's the timing of what happens when it's going to error for the reason we're discussing:

  • t=0: the normal 5ms trigger pulse is sent, which Marlin misses, and the probe starts the self-retract
  • t=~99.9ms (3 frames): the pin has fully self-retracted
  • t=~333ms (7 more frames; 10 total): the pin starts to redeploy
  • t=~366.3ms (+1f; 11 total): the pin impacts the glass
  • t=~1032.3ms (+20f; 31): the error state begins - Zmin goes high/error, LED begins blinking, etc.
    Because this is from a frame-by-frame analysis and it's hard to account for potential 1-or-2-frame sync issues between what's captured in the video and what's captured in the browser-based oscilloscope, these numbers are necessarily rough. But at least they give us some brackets and an idea of the timing.

@bgort I've been distracted on other things... But in the next day or two I'll be using this information to see if I can figure out a clean way to handle the situation.

@bgort I've been distracted on other things... But in the next day or two I'll be using this information to see if I can figure out a clean way to handle the situation.

No worries. I've been really busy, also. Let me know if you need additional information or if there's anything I can help with.

I've been thinking about this on and off and I'm not seeing a good solution outside of using an interrupt. Not to suggest there isn't something else..

In any case, curious to hear what you come up with!

All who still have problems with G28 or M48 gcode when using low speeds for Z probe and the bltouch please try possible fix in #5650 comment

Tested for M48 with different division value for:

define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 6)

Tested for G28 with different division value for ZAXIS:

define HOMING_BUMP_DIVISOR {2, 2, 8} // Re-Bump Speed Divisor (Divides the Homing Feedrate)

This code only works when your system can handle interrupts for endstops (#define ENDSTOP_INTERRUPTS_FEATURE in Configuration.h)

Before this change my setup only worked with a division value of 2 or lower. Now it accepts higher without the bltouch going into error state.

Let me know if this works and I will create a merge request.

Latest version in #5650 comment is now also working without interrupts. Please test if this fixes this problem.

Was this page helpful?
0 / 5 - 0 ratings