Skip to content

Per-Channel Tare Counts + Fixes & Improvements#894

Open
garethky wants to merge 4 commits into
KalicoCrew:mainfrom
garethky:pr-per-channel-tare
Open

Per-Channel Tare Counts + Fixes & Improvements#894
garethky wants to merge 4 commits into
KalicoCrew:mainfrom
garethky:pr-per-channel-tare

Conversation

@garethky

Copy link
Copy Markdown
Contributor

This little branch has turned into kind of an omnibus. Lets get into it:

Better Multichannel Sensor Support

The first commit is all about making multi-channel sensors a first-class experience. Now the tare and reference tare values are stored as arrays of values, one for each channel. Force and counts of each individual channel is also emitted to the printer object and the websocket. This allows for deeper inspection of individual channels to look for saturation errors.

When using a multichannel sensor, all of the gcode commands now display data from the individual channels as well as the summation of the force from all channels. This will help users debug issues in multichannel setups. E.g. showing what happens when weight is applied to extreme corners of a multichannel under bed setup.

There was a lot of duplicated code for displaying force and for handling column identification in the sensor data. So I refactored it to use a more object oriented and declarative approach.

There was a bug in load_cell_probe.py that was displaying force incorrectly when the safety limit was violated. This was root caused to using the wrong tare value to calculate force. The new ZeroReference enum explicit explains what reference will be used when calculating and displaying force. Everywhere that calculates or displays force now explicitly passes its zero reference.

ForceReporter now centralizes the job of printing force to the console. A 4 channel sensor might report force from LOAD_CELL_READ like this:

LOAD_CELL_READ
200g / 0.25% (12349456)
    Channel 0: 50g / 5.1% (26201)
    Channel 1: 20g / 2.03% (76323)
    Channel 2: 100g / 1.9% (275903)
    Channel 3: 30g / 5.8% (821542)

The SampleStructure Enum now describes the columns present in a load cell sample and makes finding the column index for a specific channel easy. No more magic 🪄 numbers in the code.

This is all backwards compatible with the existing interface. Everything new is being added onto the end and everything that already existed is still there. If we dont like the new structure and want to pack the channels one after another, I'm OK with making that change. Just let me know your preference in the review.

Future work

The tare value sent to the on MCU endstop is still just a single value. But we could send the tare value of each individual channel. This might help in detecting probes at the corners or edges of a bed where cantilever effects could potentially cause force cancelling between pairs of channels. Summing the absolute delta from each channel would cause these cases to be amplified. Supporting 4 channels is probably enough for our printers, so the command could have a limited size.

We just need to gather feedback for testers before prioritizing this work.


LOAD_CELL_CALIBRATE TARE=TRUE

The next commit is an update to how LOAD_CELL_CALIBRATE works. You can now run LOAD_CELL_CALIBRATE TARE=TRUE and the reference_tare_counts will be updated. This is the equivalent of "homing" the load cell.

Users can call LOAD_CELL_CALIBRATE TARE=TRUE at a point in their PRINT_START when they know that the load cell does not have any force applied to it. e.g. after a Z lift, after nozzle heating etc.

E.g here the load cell starts up at a load of 1kg:

$ LOAD_CELL_READ
// 1085.1g / 0.10% (8335)
$ LOAD_CELL_CALIBRATE TARE=TRUE
// New reference tare value: 0 = 30.5g / 0.10% (8124)
// Calibration changed by: 1084.3g / 3.44%

This solves for some persistent issues we have seen in testing:

How it's supposed to work

reference_tare_counts is the calibrated 0 of the load cell. force_safety_limit is a limit relative (+/-) to that 0 point. This is checked before probing starts. Probing at forces outside the safety limit raises an error. This is in place because we don't have any other safeguards to prevent crashes. This is the same idea as "probe triggered before movement" in other probes.

Real world ways the safety limit can be violated

  1. Moving the toolhead in X/Y before probing causes it to collide with the bed. This exerts a high force on the toolhead and probing should not continue. A common scenario would be a tilted gantry or bed, running the QUAD_GANTRY_LEVEL command and not building in enough retract height.
  2. Running the PROBE command repeatedly. The PROBE command does not retract the toolhead. This means it can leave the toolhead in contact with the bed and under load. Repeatedly probing will continue to increase this load. The dynamic tare value is reset before each probe attempt. If there was no external idea of a 0 reference value it could continue to apply force until something breaks.
  3. Load Cell Damage - some prior collision causes the reference point of the load cell to shift. This should ideally lead to a physical examination of the toolhead and a re-calibration or replacement.

What we found in testing

We see lots of false violations of the safety limit which users find frustrating:

  1. Temperature of the toolhead changes the reference value. Load cells get calibrated at ambient temperature. When heated they report a very different tare value.
  2. Extruder pressure - the reference zero changes depending on extruder pressure. With heat at the end of the print this tents to drop to 0. But it depends and certain ooze prevention routines (cold retraction) can put negative pressure on the load cell.
  3. Toohead position changes - the bowden tube and attached cable chain pull on the toolhead changing the zero value.
  4. Apparent drift over time - this is hard to pin down. It could be due to seasonal temperature variations causing ambient temperature to shift the zero point.

With all of these issues its hard to find an ideal reference value.

How this is solved elsewhere

Prusa's firmware uses stall detection to stop a probe when the toolhead crashes. That requires stall detecting stepper drivers and steppers that work well with stall detection. So that's not a universal fix for all printers.

Tradeoffs

LOAD_CELL_CALIBRATE TARE=TRUE sets the zero reference point. This has the potential to allow bad things to happen:

  • If this is run while the toolhead is already crashed
  • If this is run on a load cell that has suffered damage

In those cases you'll defeat the safety system and potentially suffer further machine damage. So by running this you are asserting that neither of those things can be true.

Future work

I know that if you give users a way to "fix" a problem they will just run it all the time and ignore the underlying issue. Adding a second safety sensor, like stall detection, would be a good solution for most users.


disable_pullback_move on gcode commands

The last commit is a small change to allow the pullback move to be selectively disabled for individual probes or other commands. e.g. you want to probe a nozzle wiper pad and leave the nozzle in contact with the pad.

Checklist

  • pr title makes sense
  • added a test case if possible
  • if new feature, added to the readme
  • ci is happy and green

@garethky
garethky force-pushed the pr-per-channel-tare branch from c61d18a to 15b128b Compare June 22, 2026 16:46
@garethky
garethky force-pushed the pr-per-channel-tare branch from 15b128b to c426428 Compare July 7, 2026 04:14
Gareth Farrington and others added 4 commits July 14, 2026 12:21
This change records tare-counts per channel for multi-channel sensors. Commands like LOAD_CELL_READ will now show a list of individual force values for each sensor channel in multi-channel setups.


Signed-off-by: Gareth Farrington <gareth@waves.ky>
* Sum the results of tare to send to the MCU
* Fix the bug with the safety limit force not bing calculated relative to the reference_tare_counts


Signed-off-by: Gareth Farrington <gareth@waves.ky>
Add a calibration mode that just updates the reference tare counts without going through the guided calibration helper.


Signed-off-by: Gareth Farrington <gareth@waves.ky>
Allow the pullback move to be disabled on individual probes or features by checking for it in gcode commands

Signed-off-by: Gareth Farrington <gareth@waves.ky>
@garethky
garethky force-pushed the pr-per-channel-tare branch from c426428 to 01a9aac Compare July 14, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant