Using strain gauge, HX711 ADC and Arduino/Digispark for homing and automatic bed leveling (ABL) of 3D printer, with improved trigger algorithm.
I was amazed by the Creality CR6-SE ABL which use strain gauge to detect load/pressure on nozzle. This method of probing has no probe-nozzle offset and shouldn't be affected by temperature of the bed. Strain gauge probing is used in CNC touch probe before 3D printer was invented.
CNC Touch Probe
Some makers applied this concept on their design in the past
- Palmerr23 - https://www.instructables.com/Reprap-Load-Cell-Z-Probe/
- David Pilling - https://www.davidpilling.com/wiki/index.php/Zprobe#a12
- IvDm - https://github.com/IvDm/Z-probe-on-smd-resistors-2512
While I made my own strain gauge/load cell contraption, I refered to IvDm's Arduino sketch a for trigger algorithm. But soon, I realised couple of weakness with the sketch.
-
Drifting
-
The strain gauge resistance rises when temperature increase, this will change the strain gauge readings and is known as drifting. Normally strain gauge is not affected much by the hotend or bed temperature since they are isolated from them & half bridge/full bridge wheatstone compensates the effect. However, when the strain cell is constantly getting excited for readings, it will emit heat significant enough to cause drifting. If the reading is done with long interval and cut off power between interval (such as power_down in bogde's HX711 library) then this effect is very minimal.
-
But for our application the probe will read value constantly at 80Hz, drifting will cause the probe to false trigger, giving me failed homing and mesh.
-
-
Crushing bed
- In some cases drifting eventually make the probe not responding to bed touch, the hotend will crush onto build plate and damaging the nozzle, heatbreak, z rod and motor.
-
Trigger algorithm
load cell reading + change in gradients
This sketch will also read change in gradient of readings, denoted as de.if de >= threshold_de, probe is touching the bed
if de < threshold_de, probe not touching the bed or drifting occurs -
Panic mode
When a threshold value is reached, Panic mode forces trigger the output to HIGH, preventing damage to the printer.
-
Blinks
Use led to indicate the working state of the probe
-
Start working (finished setup loop)
digitalWrite(LED_out, HIGH); delay(50); digitalWrite(LED_out, LOW); delay(50); for (int j = 0; j <= 5; j++) { digitalWrite(LED_out, HIGH); delay(50); digitalWrite(LED_out, LOW); delay(50); }
-
Trigger
digitalWrite(probe_out, HIGH); digitalWrite(LED_out, HIGH); delay(100); digitalWrite(probe_out, LOW); digitalWrite(LED_out, LOW);
-
recalibrating
for (int k = 0; k < 3; k++) { digitalWrite(LED_out, HIGH); delay(20); digitalWrite(LED_out, LOW); delay(50); }
-
Youtube! : https://youtu.be/V8OPNfr5NjQ
A load cell is placed on the hotend heatsink mount. It picks up tiny warp of the mount is read by HX711 24bits ADC. The Arduino (Digispark) compared the value and change-in-value to threshold values to determine if it should fire signal to printer mainboard.
In my experience, drifting of readings occurs after the probe is powered for an amount of time. The reading climbs and hit threshold from time to time. I used change-in-value (denoted as de) as second input to see if the reading shoots suddenly (when nozzle touch the bed) or it's just rising slowly. If only readling value hits threshold but change-in-value is small, the probe will not trigger and it will recalibrate threshold after a short amount of time. After each successful trigger, the probe wait a short amount of time for the nozzle to lift back in the air and it recalibrates/tares itself before next probe. To prevent crashing into the bed if the probe is not firing, a panic value is set to trigger the probe in all instance.
Typically HX711 board is shipped with 10Hz sampling rate, some modification is needed to use 80Hz sampling rate. In my case, it's resoldering the 0ohm resistor on XFW-HX711 board.
Wiring for Digispark board.
Endstop pins | Digispark | HX711 | Remark |
---|---|---|---|
5V/V | 5V | Vcc | |
GND/G | GND | GND | |
0 | DT/DOUT | serial data | |
1 | LED pin | ||
2 | SCK | serial clock | |
3 | used in USB comm | ||
IN/S | 4 | used in USB comm | |
5 | low voltage, don't use |
Check Digistump documentation for more info
If you are using other Arduino boards such as Nano or Pro Mini, or using atmel chip for custom pcb, you will need to decide the wiring on your own.
Marlin firmware needed to be adjusted for the probe. Version of marlin I use is 2.0.X bugfix but name of some configurations might change from time to time.
Define the probe used as NOOZLE_AS_PROBE
The pin number varies for all kind of boards. Use the old z-min pin just to be safe.
this part define whether the endstop/probe is active high or active low. Since our probe sends 5v when triggered and 0v when standby, we define ENDSTOPPULLDOWN_ZMIN.
make the probe probes twice rather than once (one quick probing and one slower)
the rest are behavior of the probing action, need to experiment on your own.
I attached the M48 repeatability test and it scored as good as 0.005 deviation. Please note that is after a lot of trials and errors before I can really get it to work properly.
Since the max sampling rate of HX711 is 80Hz, we can calculate the theoritical resolution of the probe like this:
Sampling rate: 80Hz Homing feedrate: 6mm/s Z porbe speed fast: (homing feedrate)/2 Z probe speed fast: (Z porbe speed fast)/4 = 0.75mm/s Resolution of reading: 2* 0.75/80 = 0.01875mm
Therefore, 0.01875mm is the worse case scenario for the deviation of the probe, but most of the time I get around 0.004 to 0.008. If you spot mistake in my calculation please let me know. Theoritically, by lowering the probing speed we can get better resolution, but this also lower the de value. From my test, with slower probe speed, the probe cannot "feel" the hits and give worst deviatioon value (as high as 0.20).
-
Spongy bed & gantry
the Ender 3 I use has only one Z-rod on the left side, the right side is a little bit spongy
this causes a dampening effect which lower the de value, therefore probing fails occasionally at the right side of bed during ABL.
I suspect this will also happen if a spongy bed with weak spring is used
Eventually this's solved by using lower threshold_de -
Plastic on the nozzle
Plastic oozing on the nozzle also lower the de value.
Marlin and slicer is configured to perform automatic nozzle brushing before homing and probing. -
Filament tugging
With direct drive extruder and filament spool on top of printer frame, the filament will tug the extruder when extruding, or during z-axis motion. This could triggers the probe as well as messing with the accuracy of the probe. In some case, the probe homes at mid-air.
Solution: Disable or 'sleep' the probe except when homing. Use bowden tube.