I may be missing something but could we not just probe at print temps? Bambu Lab X1 heats the bed and nozzle, cleans the nozzle and starts probing. This way you should not have to deal with compensating anything.
Buildplate should be fine - the hotend is hot but it’s just a quick touch.
In your deployment the load cell is in the nozzle portion of the printer?
Just curious since in my use case they are under the bed itself and I will probably need to end up setting up some average from my 4x sensors
K1/max does similar
heats bed to 80
heats nozzle to 240 → wipes → cools to 180 min → then probes
attempting implementation today.
[load_cell my_scale]
sensor_type: hx711
sclk_pin: leveling_mcu:PA5
dout_pin: leveling_mcu:PA1
gain:A-128
sample_rate:10
[load_cell_probe]
load_cell: my_scale
trigger_force_grams: 50.0
trigger_count: 1
pullback_dist: 0.1
pullback_speed: 0.4
settling_time: 0.375
pullback_extra_time: 0.3
tare_count: 16
z_offset: 0.0
speed: 5.0
samples: 1
sample_retract_dist: 2.0
lift_speed:
samples_result: average
samples_tolerance: 0.100
recieving error from klipper telling me
Internal error during connect: No module named ‘load_cell’
File “/home/biqu/klipper/klippy/extras/load_cell_probe.py”, line 9, in
which is just importing from load_cell which exists…?
I don’t know the deep why behind this but import from ‘.’ works and imports from a file in ‘.’ don’t work, but only on some peoples machines? I thought the containing directory was in the module search path. from mcu ...
works, so the directory where klippy starts is in the module search path.
Unfortunately I’m away from my test setup/printer for a couple weeks and I cant verify that this is a fix, but try replacing the line with:
from .load_cell import WebhooksApiDumpRepeater
I did some hacky stuff and commented out the call to WebHookAPI in that python file it loaded up
I will try this fix and report back on its workings
Board is a Manta M5p with CB1 module running Debian image provided by BTT
I have other funky klipper things I run into because the user directory is not /home/pi/
Looks like the gain values available are not proper for my load cell setup
A-128 yields me capacity of 299g which I think I have 29g load cells… I will keep tinkering with this since I have the PCB on my desk now and can make much faster tests
Probing temps… I think there are 2 problems:
- High temps will scar PEI. Its glass transition temp is 217C
- Ooze hurts probe quality. Ooze is a real problem at printing temps.
Looking at what others are doing for their probing temp:
- Prusa: 170C by default but its complicated. PC & PA is the first layer temp - 25C, which is something like 250. Flex is 210. PETG is 175.
- Bambu: 140C
- Voron Tap: 150C max
- K1: 140 They have a macro,
NOZZLE_CLEAR
, that I can’t find the source of that seems to be doing something with the temperature. So it seems to heat up to the 240 temp, wipe and then cool back down to 140?
Prusa is probing at higher templs but it seems that everyone else has avoided this. Prusa has a bunch of protections against repeated probes in the same spot. Klipper doesn’t have this. E.g. integration with bed mesh and quad gantry leveling would be needed. Both to protect the PEI and to stop the nozzle hitting ooze from previous bad taps. They also have their ML based bad tap detector to combat ooze polluting the tap data, which I cant really replicate yet.
For now, the simplest thing to do in klipper is to probe at a lower temp (i.e. what Bambu/Voron/K1 does) and do the thermal expansion correction. I’m using the 150C suggested by Voron Tap and the taps stay good after cleaning the nozzle off. klipper has [z_thermal_adjust], and we could make a similar module for adjusting by extruder temp.
Both Bambu and the K1 heat up the nozzle to clean it and then cool it back down. This is a great idea!
I see some signs in my test prints that they start a little bit high and end a little bit low. That might mean the toolhead is heat soaking and sill expanding a bit during the print. So we might want both kinds of compensation running for perfect results.
Yes, we will have to do something that reads 4 sensors and combines the values. The simplest thing that could possibly work is adding them together. If I do that in C, then no changes are needed for load_cell or load_cell_endstop. 4x24 buy values wont overflow a 32 bit int. I think we should try this idea first.
We should be able to validate this by placing a 100g weight all over the bed and verifying that the load cell reads 100g everywhere. (this is how bathroom scales work so I’m hopeful it will work here too)
My worry is that weight in one corner of the bed would cause the bed to rotate about the 2 adjacent corners. This might cause the load cell on the opposite corner to read a negative value. You can test this out for us now by hooking up just 1 loadcell and placing a weight on the opposite corner and telling us what happens. you can even use the websocket debugging tool to see whats going on live.
Maybe you can implement a material type one can pass via Slicer start code where you can define and react to with different probing temps.
Or per se probe with 30°C less.
I do so to enable the Nevermore filter for ABS and ASA.
I re-based my changes on top of klipper mainline and I have some work to do:
- klipper has run out of oid’s, the branch wont build without turning off support for some sensors
- Kevin shipped a refactor to the way sensors like the ADXL and Angle work that I will be able to use.
Work items for January:
- Remove support for the ADS1263 sensor. I don’t think this is commercially viable and I no longer need it as I have the new HX717 based test rig.
- Implement a
quad_hx71x_sensor
to test on the K1. I want this in before the next step because I want to have at least 2 sensors to drive reusable code architecture. - Refactor to use the new
bulk_sensor
infrastructure. This will change the config again and be a pretty major change to both Python and C. Hopefully this saves enough oid’s that all sensors can be supported. - Work on continuous taring/low frequency rejection in the
adc_endstop
to support long probing moves.
I need to source a 100g calibration weight I can probably go to some local place that sells scales and buy one there or get one from Amazon. I should be able to make this test a reality once procuring a known weight over 50g and performing this test
I should be able to let you know by the 1st weekend in Jan (shipping from amazon if i cant source local will be impacted cuz of Xmas)
I think you can just wire them smartly and you won‘t have to add them on the software side. It will be dependent on if you have four full bridges or half bridges (or even quarter bridges). I have bought some full and some half bridges and will do some tests when the printer is built.
Updare from Peopoly on their Inplementstio of load sensors for bed meshing with Klipper.
[Production Status Update】
Our production has been ongoing, but we recently paused to investigate a user-raised concern about build plate flatness post-heating. After a deep dive, we found that the nozzle pressure during bed meshing sometimes led to inaccuracies. By refining the leveling algorithm and recalibrating the load cell, we’ve significantly improved our bed mesh readings. Implementing these enhancements will cause a slight delay, but the improved leveling accuracy will be well worth the wait.
I came to the same conclusion, I wait for the previous move to finish before taring the load cell. Fast moves cause a lot of electrical noise that messes with taring. Plus you can configure additional time for physical vibrations to settle: klipper/klippy/extras/load_cell_probe.py at 42f6d6d7d7c9b919e58173c1c32c09fdd8f7a2dc · garethky/klipper · GitHub
This does cause a slight delay, but its not very noticeable. I’m saving so much time by only probing once that its still much faster overall.
You’re saying that series wiring the strain gauges and adding do the same thing. I really believe you are correct, I’m counting on it. That’s how bathroom scales work.
But:
- Creality used 4 sensors in the K1. I don’t know why they did this for sure, but one good reason is fault detection. If wiring or hardware is bad on one loadcell its easy to find with 4 sensors. With a loop of strain gauges you cant tell where the fault is. I don’t see supporting this as unreasonable, so long as adding is the same as series wiring.
- There might be “dragons” / dead spots. I hope this was caused by probing outside the polygon formed by the sensor mounts. This causes the bed to rotate and one or more sensors to go negative giving “dead spots”. (picture what happens when you push on the rim of a dinner plate).
So I’m going to build a ‘sensor’ that adds the 4 sensors on the K1 board together. We’ll test its and, if you’re right, it will work just fine. If we don’t find any “dragons” in testing I’ll do an improved version:
- Stream all 4 separate readings back to the Pi, creating 4 real
load_cell
objects. - Add the 4 readings in the Pi, creating a fifth
virtual_load_cell
used for probing. - Add the 4 signals together in the c driver and pass that to the
adc_endstop
. - Ideally this code will also works for 3 sensors in delta printers as well.
So we should get the diagnostic benefits of 3 or 4 chips with the simplicity of 1 endstop and 1 load cell to probe with.
Hello, from long time i want to implement a load cell in the toolhead, recently i had the time to do it. my approach was not to implement in klipper the code to manage the HX711 but add a MCU to do that and emulate e normal probe. no need calibration or anything. just work. i put all on github.
What you think about?
Good Job, its a fun project. I don’t see much of an algorithm in there? Are you just waiting for the reading to be outside the range 10,000 - 50,000 to trigger the probe?
I don’t see any information on what accuracy or repeatability you were able to achieve with this. Tried ‘PROBE_ACCURACY’ yet?
flashforge released their new printer guider 3 ultra a few months ago. They also install four strain gages under the hotbed and use only one HX711 chip to collect signal, not like K1. I’m not really confirm what firmware they used ,but i guess it’s klipper.
yes… is scary simple. and it work. probe happen like this: move to de position to probe, activate the HX711, reset just before to touch the bed, 32U4 wait to have analog reading more then 10000, send the “click” to klipper or any … , deactivate the HX711. done
the trick here is the mega 32u2. it is fast enough detect the touch in the right moment. i try with 328p but is not quick enough. of course with optimized code even a atinny can do it… like Duet3D did in smart effector.
i didn’t make a PROBE_ACCURACY but i can give you two bed mesh in a row
## <---------------------- SAVE_CONFIG ---------------------->
## DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
##
## [bed_mesh default]
## version = 1
## points =
## -0.019800, 0.072700, 0.140200, 0.140200, 0.050200
## -0.137300, -0.019800, 0.047700, 0.072700, -0.044800
## -0.229800, -0.042300, 0.025200, 0.025200, -0.067300
## -0.252300, -0.067300, 0.025200, 0.025200, -0.089800
## -0.207300, -0.067300, 0.072700, 0.047700, -0.067300
## x_count = 5
## y_count = 5
## mesh_x_pps = 2
## mesh_y_pps = 2
## algo = lagrange
## tension = 0.2
## min_x = 20.0
## max_x = 480.0
## min_y = 20.0
## max_y = 480.0
##
## [bed_mesh mesh1]
## version = 1
## points =
## -0.019800, 0.072700, 0.140200, 0.140200, 0.050200
## -0.137300, -0.019800, 0.047700, 0.072700, -0.044800
## -0.229800, -0.042300, 0.025200, 0.025200, -0.067300
## -0.252300, -0.067300, 0.025200, 0.025200, -0.089800
## -0.207300, -0.067300, 0.072700, 0.047700, -0.067300
## x_count = 5
## y_count = 5
## mesh_x_pps = 2
## mesh_y_pps = 2
## algo = lagrange
## tension = 0.2
## min_x = 20.0
## max_x = 480.0
## min_y = 20.0
## max_y = 480.0
not bad, right?
Try PROBE_ACCURACY. The fact that the bed mesh results are identical is a little “too good to be true”, isn’t it? With 80 samples per second and 2mm/s probing speed the best range
you can hope to get is 2mm/80 = 0.025mm. No?
If you want help, start a thread here in the developers section.
(Edit: I think you overwrote the ‘default’ profile with the second mesh. It’s always overwritten and an easy mistake to make. Look at these details: Bed Mesh - Klipper documentation)