BMP183 SPI sensors as bed probe
-
This is more of an announcement of a new z probe system rather than a question for help -
I've been playing with piezo sensors to detect when the nozzle touches the bed surface (mounted under the bed) when performing bed leveling and I ran into some drawbacks with that system:
- there has to be a shock of some form, like a tap, for the sensors to detect the nozzle hitting the bed. This requires the nozzle to be approaching fast enough for it to register. If it misses the impact, the increase in pressure as the nozzle drives into the bed surface never gets detected till things start to go pop or the steppers skip.
- it's not actually measuring the pressure of the nozzle down onto the bed, just the point of impact. Fine if it gets that point each and every time.
- noisy motors/mechanics trigger the sensors.
Now, I can imagine this would work better if the surface of my bed was hard like glass but it's PEI stuck to magnetic rubber pads so I can lift the surface off. I don't get the required "tap".
Putting that to one side I came up with what I think is an extremely good alternative - barometric pressure sensors with a rubber boot over the sensor chip (sealed with silicone). Surprisingly this created an incredibly sensitive sensor for any pressure down on that tiny rubber boot over the sensor. In my case I wanted three modules under the bed so had to use SPI rather than i2c as that gives me multiple assigned SPI CS pins on the Ardunio board rather than being limited to two addresses / two modules. The BMP183 from Adafruit came up as an option so went with three of those. I 3D printed a rubber boot to fit over the chip on the module using TPE and glued it down with silicone to ensure a tight seal. The Arduino code gets the current pressures on each module in a quick loop and triggers pin 3 high when any of them detect a change of 0.3 Hpa from the last measurement. With the chip sealed under this boot the smallest pressure change trips it off. Fortunately the only thing that triggers them is actual pressure, not bumps or vibrations. Compared to the raw piezo sensors they appear to be just as sensitive, without the false triggers. That seal on the rubber boot is critical as the smallest of leaks reduces the sensitivity dramatically. I can approach the bed surface as slow as I want and it will still trigger the moment there is the smallest amount of pressure. Movements in the Y axis have no effect on the sensors. However, acceleration movements in the Z axis will trigger them, so for printers with the bed moving on the z axis this would probably not be a good solution, unless that motion was very slow. In that case you could probably mount a single sensor on the hot end.
I've also tried resistor pressure pads under the hot end nozzle but these were not as sensitive to pressure as this new design.
These modified modules then get mounted into 3D printed linear bearing blocks with a slot in the top of them to allow downward pressure to directly press on the rubber boots under each Y axis mount point. All three hook up to an Arduino mini stuck on the base frame of the bed. This then has three wires back to the Duet Wifi - 5V, GND and signal.
The three modules set me back about $55 AUD in total and I already had plenty of Arduino mini's sitting about doing nothing. I thought about using a 3.3V Arduino however these run at 8MHz rather than 16 and I need the trigger to be as quick as possible. I'm going to tap into the 5V pin on the Duet to drive the Arduino for now.
What I want to know is if the Z Probe IN pin on the Duet probe connector can tolerate 5V in? Should I set up a voltage divider to drop that down to 3.3V? The write up on connecting the BLTouch suggests using a 240 ohm between the probe GND and IN pins however I would have thought an additional resistor between IN and the OUT of the 5V pin on the Arduino would complete the voltage divider. Wouldn't a -10k -|- 5k- divider be closer to the mark and still provide the amps to be detected by the Probe IN pin?
Once I get this all working nicely I'll post the 3D printed parts and a write up on Thingiverse if anyone wants to try it out. Down the track I will probably come up with an integrated PCB with connectors out to each of the three modules. There are probably more sensitive pressure sensor modules out there but these seem ok.
First test will be to create surface maps one after the other and compare the CSV's to see how consistent the probe points are.
I'll post results when I have this all mounted in the printer.
-
The revision 1.04 Duets can tolerate up to 30V on the Z probe input pin. However, an 8MHz processor will be more than fast enough to process the signal.
-
Thanks David. Ultimately it simplifies things if I can use a 3.3V Arduino for the final product as it allows me to have the one 3/4 pin connector going to the Duet Probe port. I was just concerned that the sequential reading of the three modules over SPI would pose a delay of 3 x the main loop duration so loop speed may have been an important factor. I'll probably do a debug write to EEPROM of the duration between each module read to see how quick the Adafruit libraries are and put that info out to serial after a number of loops. Tempted to output PWM to give a raw reading of the variations in pressure. This would allow the Duet to determine the trigger point. Does the mod pin allow for PWM in? I assume that is how analog values are read?
I have performed numerous G30 S-1 probes at points all over the bed and I'm getting close to 0.01mm variation between z trigger depths. Having a bubble under the PEI sheet where I set the probe point certainly makes those readings inconstant but that's hardly surprising. On the bare AL heatbed the probes were within 0.005mm of each other.
I've had to tweak the sensitivity as some z movements were triggering the modules so it's at a sweet spot now where I can perform the mesh probe at 20mm spacing and get a very accurate representation of the surface (bubbles and all).
Will fire up Eagle tomorrow and start on an integrated board with connectors.
-
Module mounted in a 3D printed bearing block (3 under the bed for the Y axis on my i3 clone) -
-
Hi David, I just tried analogWrite on the Arduino code with the pin connected to the IN probe pin. When sending a static value of 100 on analogWrite the web interface is showing a bouncing value which is all over the shop. D3 is the pin on the Pro Mini I'm using which defaults to 480Hz PWM. Does this IN pin expect a true analog input of varying voltage levels or should raw PWM work in mode 1? Currently I use M558 P1 0 R0.8 H0.75 A10 S0.02 T2000 F60 X0 Y0 Z1 for the probe. Couldn't find any write up online for this.
Also, the Duet Wifi I'm testing on is a V1.01 so I guess it's not tolerant to the 5V PWM? I can test on the newer board I have but I do need to get this one working. Might just put a 220ohm in series with D3 to see if that helps?
-
Is it possible to stick a piece of adhesive foam on top of the sensor and use that instead of a printed boot?
-
@tjb1 - I doubt it as the hole on top of the BMP sensor is tiny so the foam tape would not create the sudden increase in pressure when pressed. All it would do is seal that hole. The rubber boots I printed create a cavity of a few mm cubed which is sealed from the atmospheric pressure and spikes with the smallest of pressure down on it. It's quite critical to how this solution works.
-
One of the issues with the first LM8UU bearing block design was that I lost about 7-8mm of z depth on the printer. This new design only cuts into the z depth by a mm.
-
@jgrouse It looks like Adafruit just released this one - listed as a pressure sensor so I don't know if its sensitive enough to detect the changes here, maybe you could use one of those with a tube that goes around to all the bearing blocks and seal the end. Possibly a long silicone tube right under the bed? Clamp the bed down enough to slightly compress it and then see if it can be detected on the sensor.
-
@tjb1 - interesting. As long as the sensor in there is just as sensitive as the existing BMP sensors that would probably work. Sensitivity is the key to this working. A very narrow sealed silicone tube running through each of the three bearing blocks and then to the module would really simplify this concept. Now if the sensor could cope with a non-conductive liquid in the tube then the pressure/response would more immediate as soon as something touched the surface. Some oil?
Might order that sensor tonight and have a play with these ideas.
Thanks for letting me know about that module!
-
@jgrouse said in BMP183 SPI sensors as bed probe:
Hi David, I just tried analogWrite on the Arduino code with the pin connected to the IN probe pin. When sending a static value of 100 on analogWrite the web interface is showing a bouncing value which is all over the shop. D3 is the pin on the Pro Mini I'm using which defaults to 480Hz PWM. Does this IN pin expect a true analog input of varying voltage levels or should raw PWM work in mode 1? Currently I use M558 P1 0 R0.8 H0.75 A10 S0.02 T2000 F60 X0 Y0 Z1 for the probe. Couldn't find any write up online for this.
Also, the Duet Wifi I'm testing on is a V1.01 so I guess it's not tolerant to the 5V PWM? I can test on the newer board I have but I do need to get this one working. Might just put a 220ohm in series with D3 to see if that helps?
PWM at such a low frequency would not work because you would need to smooth it using a time constant of 10ms or more, which would delay the response too much. I suggest you use either a digital output, or a 4-level output from 2 digital pins as the IR sensor does. Use a voltage divider to reduce the output voltage to 3.3V maximum.
-
@jgrouse said in BMP183 SPI sensors as bed probe:
to see how quick the Adafruit libraries are
If you want to speed-up things, I suggest you re-write the lib. They might have implemented a lot of stuff you don't need which can slow down the reading. I did that for their PWM lib for PCA9650, and gained a factor 2 or 3 in speed.