Traumflug / Teacup_Firmware

Firmware for RepRap and other 3D printers
http://forums.reprap.org/read.php?147
GNU General Public License v2.0
312 stars 199 forks source link

Z probe support #288

Open Tomin1 opened 6 years ago

Tomin1 commented 6 years ago

My printer has a probe (BLTouch clone) instead of z endstop. As far as I can see Teacup doesn't support them, but I'd like to try Teacup on my printer. Of course for Teacup to work well, it will also need compensation for non-orthogonal bed, but this would be a prerequisite for that to happen.

I'm thinking that reusing heater support would allow to add support for these probes. It would just need to be hooked up with homing code. Is this a good idea? Am I missing something obvious? Any (good) suggestions? I can and will code this, but it'll probably take some time for me to implement it, because I have other (more important) things to do and I'm not too familiar with Teacup code. The idea of clean C implementation appeals me though.

Traumflug commented 6 years ago

Does this probe change a signal from 0 to 1 or vice versa when triggered? Then Teacup does support it.

Teacup just doesn't change pin names to latest fashions all the time. Endstop is endstop, no matter whether it's called 'probe' or 'sensor' or 'touch device' or whatever.

Tomin1 commented 6 years ago

Let me explain it a little. The probe takes commands from the microcontroller. These commands are sent with PWM signal. The signal sent back is indeed digital 0 or 1 as with any endstop like you suspected. It's designed to be compatible with endstop mounted on a servo.

Before using this endstop, the probe must be pushed down by issuing a command (specific PWM duty cycle). When it is not used it must be pulled with another command (another duty cycle). There are also commands to reset the probe and to put it in self test mode. Also, if there is an error with the probe it will again use the endstop signal to tell about it. I don't know if there is a way to tell whether the probe touches the bed or if it errors (although I think Marlin devs said that there is, at least kind of), but that is the only signal it can send back to the microcontroller.

I don't say that we should start renaming things. This only requires us to add some code to enable and disable the probe when needed and use it like regular endstop in between that.

Traumflug commented 6 years ago

Apparently a pretty complex device, not a plain endstop. This makes your first comment here to appear like a good idea.

phord commented 6 years ago

The trick is that this device is a retractable z-probe. It has a servo control to deploy and retract the probe tip. Once deployed, it works like an end-stop. But it is typically used with auto-leveling, meaning several points are probed on the bed to get the leveling profile, and then the head movements are dynamically adjusted to align to the angle of the bed during the print.

Documentation is sparse for this device, but I think it is as simple as driving a PWM to deploy and retract. Maybe it even works with 100% on and 0% on? I don't know.

But once that is in place, we also need the auto-leveling code. Something I've wanted to add for years, but I never got a probe I liked. Maybe I'll try this one.

Tomin1 commented 6 years ago

@phord I recommend that you get the original BLTouch from Antclabs. At least my clone (Geetech 3DTouch) was really bad since it tended to drop the probe pin during the printing, ruin my prints and destroy the probe mount. Now I have the original BLTouch which works great. I think it'll be a bit easier to support BLTouch since it rarely needs anything special (mine hasn't failed at all) while the clone I had likes to fail once in a while and that must be cleared with an extra command.

Because it tries to emulate a servo it is controlled to "turn" to 30° and 90° with PWM. It needs to be about these because there are actually several more commands there after 90°. There is some documentation on Antclabs site: https://www.antclabs.com/manual (Smart is the current version, Classic is the older and I think they are electrically compatible)

phord commented 6 years ago

@Tomin1 I did think about getting one after reading your comments, but I saw some concerns posted about reliability on the Amazon listing. At least some of them seem to be about the real BLTouch and not one of the cheap clones. Maybe it's not an issue.

Anyway, I decided before I invested in one I would have to see how hard auto bed-leveling would be to implement, so I did that instead.

And it works! :tada: I now have 3-point bed leveling implemented in my local Teacup software.

I haven't uploaded my changes yet, but I'll get them cleaned up in a day or so and send them up.

To be clear, this change doesn't do anything with the Z-probe. I only implemented manual three-point bed-plane registration. It shouldn't be too hard to implement the BLTouch support. From there you only need a GCode script to automatically level on three points.

I don't think mesh-mapped leveling would be much more complicated than this, but I haven't really tried it yet. Since I print on glass these days, I'm pretty confident my bed will always be planar. Therefore I don't need mesh-mapping. But I do remember the first time I looked into dynamic bed-leveling many years ago; I started by measuring my bed with something similar to the BLTouch. When I saw how truly warped my bed was on the results map, I realized why I had so much trouble leveling it. That's when I built a replacement bed and put the dynamic leveler out of my mind for a while. :grin:

I don't know if Teacup will be interested in incorporating full automatic point selection and leveling internally, but I suppose it's possible.

phord commented 6 years ago

Here's how unlevel my bed is today. This is my 3-point registration script, as manually determined with the "business card" touch probe:

G29 S1  X20.000  Y20.000  Z-0.300
G29 S1 X220.000 Y120.000  Z-1.700
G29 S1 X120.000 Y220.000  Z-0.700

It's not usually this bad, I think. I replaced a spring yesterday, and I was intentionally not careful about making the bed level afterwards because I knew I was also working on the new feature in software. :boom:

phord commented 6 years ago

@Tomin1 Have you tried adding the BLTouch as a "heater" in the ConfigTool setup? This is how we normally set up PWM devices. If your device is setup as the 4th device, then you control it with M106 P3. You can control it with M106 P3 S25 for a 10% duty cycle. Since this uses servo position commands, and they're driven by PWM pulse-widths, you may have to do some math (or experimenting) to find the right values. Also, you will probably need to ensure you do not have FAST_PWM enabled.

If you have a 16MHz processor then you have a 61Hz PWM frequency. The S-value is a portion of 256 counts per cycle. Each "count" is about 64us. (1,000,000 us/second) / (61 cycles/second) / (256 counts/cycle) = 64.03 us/count.

The BLTouch documentation says "10 degrees" is "Push-pin Down". It also says this is a 700us pulse. 700/64 = 10.9. So, maybe try M106 P3 S11 to see if it deploys your probe. Then "Push-pin Up" should be 1500us; 1500/64 = 23.4, so try M106 P3 S23.

I did get a BLTouch this weekend, but I haven't hooked it up yet. I got distracted building a new extruder. I'll report back here if I get these commands to work on the real hardware.

Wurstnase commented 6 years ago

Hi, check also at the same time that the pin support pwm. When not, software pwm will be used, which shouldn't work.

phord commented 6 years ago

I just tried it and it didn't work for me. I used DIO11, which should be PWM-able.

Edit: I can see the blue pulse LED blinking on the BLTouch. Maybe I don't have enough current available on my 5v pin. Will update again later.

phord commented 6 years ago

Results:

DIO11 is NOT pwm-able in Teacup because it uses Timer1 which we don't do pwm on. Maybe we can document that somewhere.

Then I tried DIO6, the next set of pins on the RAMPS board. This pin does support hardware pwm, but I couldn't get it to drive the servo. After investigating I found the prescaler for this pin (on Timer4) is not set correctly when FAST_PWM is disabled.

The only RAMPS servo pin on Timer0 is DIO4. I put the BLTouch on DIO4 and it works.

DEFINE_HEATER(bltouch,  DIO4,    0,      1,     100)
#define HEATER_BLTOUCH HEATER_bltouch

Now I can extend the pin with M106 P3 S11 and retract it with M106 P3 S23.

I'm still figuring out the weird BLTouch modes. For example, since we continue to send the same signal while S11 is set, it seems the BLTouch wants to extend again after it touches the print bed and does its first retraction. Maybe I have some S-values to work out still.

phord commented 6 years ago

Continuing the BLTouch commands: The math is pulse-width * 1024 * 256 / F_CPU (F_CPU is 16MHz or 20MHz on AVRs)

BLTouch-Classic Available PWM Range 16MHz CPU 20MHz CPU
Push-pin Down 700 us ( 10° ) M106 P3 S11 M106 P3 S9
Push-pin Up 1500 us ( 90° ) M106 P3 S24 M106 P3 S20
Self-test 1800 us ( 120° ) M106 P3 S29 M106 P3 S24
Alarm Release & Push-pin UP 2200 us ( 160° ) M106 P3 S36 M106 P3 S29
Alarm Release & Touch SW Mode 1200 us ( 60° ) M106 P3 S20 M106 P3 S16

Maybe we need a SERVO_PWM setting in the heater definition that would let us give positions in degrees. Then we can do the math internally and consistently. Other firmwares use M280 to give a position in degrees. Seems unnecessary.

Wurstnase commented 6 years ago

I found this pitfall also some years ago with Marlin on a RAMPS where I want to use pwm for some LEDs and I was wondering why this don't work. Later, when starting with programming, I see this issue.

phord commented 6 years ago

I found a bug in my new bed-leveling code (incorrect movement after homing). Fixing it actually simplified the original change a bit, so I rebased and squashed them, then pushed the new commit to experimental. I cleaned up some whitespace changes in the process, too.

I'm working on adding BLTouch support directly into Teacup. It's coming along, but quite hacky right now, and not working yet.