Strain Gauge/Load Cell based Endstops

Fyi: I just played around with my algorithm a bit in the hope to simplify it. It is currently “excessively” jumping around in Z to compensate single measurement points with a reference measurement. I once more confirmed that this is important. A single approach until the threshold is exceeded works relatively reliably but does not yield the required precision. As soon as the direction is changed, measurements become very unreliable.

Let me try to explain with an example: If I move to lower z positions until a threshold is exceeded, then try to move out until measurements go below a smaller threshold, this condition may never be fulfilled. There are hysteresis-like effects, which move the baseline when some force is applied to the system.

Maybe it is possible to fix this situation with a better hardware setup, although I do not know how. Maybe with a much faster ADC you can avoid the need for this altogether, if the precision of the first approach is already good enough (for me this is <1/100mm). In my setup currently it looks like I have to stick with this procedure…

Hi. I’m trying to integrate load cell into the bed of my Voron 2.4 printer, and I wonder if this code can be adapted to (start to try to) do it.

Basically, my plan was:

  1. Use a RPI2040 as a second MCU, and connect it to 3 XH711s at each of 3 mount points.
  2. Use the sum of the 3 XH711s readings as the input signal for knowing of when the bed was touched.
  3. Use all of the signal processing magic discussed in this thread to detect the moment of touch, to drive the QUAD_GANTRY_LEVEL method.

I don’t particularly care about the vertical probing speed - I guess it’s OK to do a rough measure at 5mm/s and then do a precise measure at say 1mm/s. As long as it works, and allows changing the magnetic sheets with impunity, it’s worth the time.

Mechanically, it would mean minimal changes to the printer, and those that don’t affect its rigidity, and wouldn’t even make anything really complex.

Can the code be adapted to the use case?

You can connect the 3 load cells in parallel to a single HX711, since you are not interested in the individual measurement signals. That way you should be able to use any algorithm designed to work with a single signal, i.e. either Garethkys or mine.

1 Like

Sorry team, I got COVID and it knocked me out for about 3 weeks. I haven’t made any progress on building a test rig other than buying all the hardware.

The only thing I can report on is the utility of the PGA in the ADS1263. For these plots I’m running the sensor at its maximum sample rate (38Khz), so no filtering is active in the sensor. The plots are sampled at 1Khz, so 1/38th of the actual sample rate. (this keeps the Pi from overheating). I’m placing a 100g weight onto a 2Kg load cell by hand. First with the PGA off (its default setting):

I cant see the event. We could find it with lots of filtering but not with my eyeballs.

Now with the PGA at its max setting of 32 V/V:

Wow! That is clear as a bell. It looks like plots at much lower sample rates (lower rates = filtered). I don’t need any filtering at all to spot that change. Better signal/noise ratio after passing a signal through an amplifier seems like dark magic to me but there you have it.

With the PGA, I don’t think I need to apply the EMA filter for individual measurements. Less filtering = faster response.

I’ll be picking back up on:

  • building the test rig
  • Testing probing with PGA but without the EMA filter.
  • diving into why there are so many “duplicate measurement” errors when the sensor runs at fast sample rates

Oh, I am sorry. I hope you fully recovered and are not getting any long term effects…

Well, you still have to deal with baseline wandering. Also, the big spikes are likely coming from “dropping” the weight on the load cell, so they won’t be there when the movement is CNC controlled. So you are more or less just around 2 sigma away of your noise floor, meaning you will hit your threshold occasionally just because of noise with a single spike. Do not underestimate the built-in filter of your eye/brain :wink:

Baseline wandering will likely appear when you start to have multiple load cells in your setup. As far as I understand you are testing with a single load cell only. In that case you cannot really get internal tensions. Attaching the hotend on a single load cell would be quite flimsy, since you have only one suspension point. Even if you can get it to work for you, it would limit the usability for other setups. My printer comes with two load cells. gsasha wants to use 3 load cells.

Replacing one of the load cells with a passive beam won’t help, since you still have the tensions. So even if I am unsure how many sensors in the end the PCB-based setup from hackady you are quoting above effectively has, it will have internal tensions and they will cause hysteresis-like baseline wandering and also amplify thermal effects.

I think your idea using the EMA filter is very interesting, but without it I fear it won’t be usable outside at most very specific setups.

Btw: The HX711 can have a gain of 128. With that gain, I have a resolution of around 300 ADC counts per Gram. The noise floor is around 0.2 Grams RMS. Still, a threshold of 100 Grams or so would be required to be really sure to never get any false triggers.

Also, your setup may be fast, but everything else seems to be quite bad… :wink: Where does all the noise come from? Your ADC as 32 bits as opposed to 24 bits of the HX711, but your noise floor is much bigger than just the additional 8 bits. Maybe you can improve this electrically somehow? What power supply do you use for the ADC?

On a second glance, you actually have clearly no room for a threshold left. You will either need filtering or improve electrically, even if you are not suffering from baseline wandering. Or you need more force :slight_smile:

Keep in mind, statistics is a bitch. You are doing 38000 measurements per second, and you shall get no false trigger over quite long periods of time (probably many hours or so, if you do not want to accept occasional incorrect results). Let’s say you are accepting 1 incorrect measurement per day of total accumulated measurement time (i.e. the time when the printer is actually paying attention to the result). This is a ratio of around 10e-9, so you need to stay 6 sigma away from your noise floor. You are currently less than 2 sigma away, it’s probably even closer to 1 sigma. So you will need a force of 600g as a threshold to reliably detect the events. You will need some headroom, so the maximum force you can apply to your printer before something might break must be a lot bigger, say 2kg at least.

At least with such high thresholds you likely won’t have any issues with baseline wandering :wink:

I am not saying this is not doable, I am actually using similar values, but my printer is quite sturdy and I have two 5kg load cells.

Still, you might see one big downside with such high thresholds: Printers are never really stiff. When applying 600g of force, you will see a significant bending and movement of the relevant parts. I am talking about several 1/10mm. The stiffness is likely not identical at all places on the bed surface. This will spoil your measurement - unless you are using some smart algorithm to compensate for that :wink: (In case it doesn’t ring a bell: that’s exactly what I am doing in my load cell probe module…)

Has anyone looked into the anycubic vyper strain gauge?

I’ve been looking into implementing something but was in research mode and came across this thread.

My initial thought was strain gauge > hx711 > pi

Then write python and define a probe with the python file. But again I just started and have about 60 more pages to read in this thread :joy:.

Looks like this: it’s for v6 hotends
US $8.80 30% Off | For Anycubic 3D Printer accessories for Vyper for Kobra Max Automatic leveling sensor for hot end mounting block of extruder
https://a.aliexpress.com/_msv3Jcq

Can you find the code they are using to run that?

All I’ve found were hints from replacement videos. From what I can tell they have an adc and mcu in the toolhead. There were led’s that lit up when the sensor was strained. My guess is they just have this mcu then provide an end stop signal on the output which runs to the main board.

I’ve bought one, and also found a 3D printed version with a full bridge strain gauge. I bought some of the 350ohm as suggested and will be testing as parts come in.

Can someone explain what the hx711 driver in klipper will do? Will it allow us to just input into the hx711 and then connect that to our pi’s that will then allow us to calibrate and use as an end stop?

if you have the board they are using, can you see what chips are on it?

Everything I’m looking at is just from pictures. I believe the microcontroller is stm32 based. I will start seeing if I can crawl the web for someone who owns one. Is it possible to flash another mcu and clone the boot loader etc to another chip?

The more I research the more I’m coming across the drifting issues that are outlined in this thread. The same with hysteresis.

This was an interesting read about it (original poster abandoned thread but was hijacked by someone with a real problem) https://maker.pro/forums/threads/load-cell-hx711-drifting-value.279103/

Basically from what I understood the issue to be was the lead screw pitch or travel was slightly different each time, so another reason outside of temperature and noise was precision. This lead to a big deviation in reading, which might be a possible issue.

Currently I have the strain gauge being delivered today and have the hx711 connected to my pi.

I’ve also searched GitHub projects and found a lot were abandoned due to drifting. However one I found was interesting that you already found on hackaday, where they basically generically say they take the integral or derivative. I looked through the code and didn’t find any examples of discrete functions that are taking a derivative.

Also I believe bambu uses a load cell or strain gauge in the bed. I found their wiki had a page on replacing the beds “force sensor”. Unfortunately I can’t get their wiki to load. Replacing the heat bed force sensor | Bambu Lab Wiki

Whelp. I was testing the strain gauge with some python code I made. I ended up taking the last 3 and averaging them together.

I added the ability to calibrate with whatever number of inputs you had for weight. I usually did around 5 then averaged those out to get a better result.

I tried implementing a moving average as well. This made it a little bit better as it took away a lot of impulse that was occurring.

Unfortunately I busted the anycubic gauge already. I made a clamp for my standing desk, and put a kitchen weight on a table next to it. After 100 or so moves of the desk, the desk went full ham downward and just busted the strain gauge off. It doesn’t look broken but I’m pretty sure the strain gauge on it is shorting on the metal because it only now reads close to zero and if I touch it it will automatically go to 120g which was the last weight I calibrated it with. Waste of 18 dollars for science I guess :slight_smile: luckily I bought 5 strain gauges from Ali, and there is a printed version on this so I will try again, probably in a month when receive them.

I do have the hx711 but I never bothers changing sample from 10 to 80. I was going to do it, but things broke :disappointed:

I didn’t get to implement anything on the rate of change (derivative). Unfortunately on top of this I kept reverting code to make sure I didn’t just bust something in code as well.

Broken strain gauges seems to be a right of passage for this type of product.

Personally im just going to wait for Prusa to release the XL and see what they have in there. The code will be open source and we will get to see which chip they used and what the read rate is. They said the might let us run Klipper on that machine so we would need to implement support for it to get that to work. I have a pre-order in for one.

That’s a good call, I saw someone on Reddit had one but were under nda so couldn’t really talk about it much.

Are you getting one?

I haven’t entirely decided yet. I have a toolchanger that I’m working towards klipper-izing. But I think the XL has advantages:

  • The build volume is a cube, the ToolChanger is weird sized rectangle
  • I think Prusa’s tool-change mechanisim is better. They got rid of the extra stepper
  • The load cell probe solves for aligning the tools to each other, which is a big deal.
  • Its product and not a project, I could just start using it for what I want.
    I’m on the wait list, waiting on some concrete reviews.

I can understand where you are coming from them. For now since I’m waiting on strain-gauges, I’m designing another method of a contact base endstop. Where the toolhead can slide into a slot and move up and down slightly. When the tools nozzle touches the bed it will break the contact and that will then be zero.

I’m placing a magnet at the bottom to keep any premature endstop triggers. It’s not an original idea as a video came across on YouTube here:

If you look at the newest video he also has it printing at 10k accel.

The difference is I’m trying to slot the toolhead vs having another rail. If I do use a rail i don’t know if I would need an actual mg9 something that can slide or even a 3D printed rail may be sufficient, but for now I want to try a simple slot.

3 Likes

Time for me to eat some crow…

The PrusaXL is shipping and they have released the code for the firmware. They are using a HX717 chip which supports a max sample rate of only 80SPS. It is a 24 bit output and has 3 levels of gain. This looks like a souped up 24 bit version of the XH711.

I was exactly right about the 80 SPS when I analyzed the graph they showed but I didn’t believe they would use a sample rate that low! At 80 SPS your homing speed is going to be limited if you want high resolution.

Now we can look at how they are using the sensor in code: loadcell.h, loadcell.cpp

They do perform filtering on the load cell data with a “Butterworth High Pass Filter” (Butterworth filter - Wikipedia) here. Then they trigger the endstop with what looks like a simple comparison vs a threshold.

The really interesting stuff for us is in here where the analyze load cell samples. There is a lot of linear regression going on, hat tip to @mhier. The comment on this classify method is absolutely wild. All the “magic numbers” came from an ML model they have of their particular load cell. This would be an effort similar to the resonance compensation feature to build a tool to characterize new load cells to this degree.

They are using a a lot of floating point math and a big block of float storage to do all this (looks like 300 samples). I had avoided that but its likely something I should revisit if we pursue this further. I’m not sure if they are doing this on the CAN toolboard or on the main MCU.

2 Likes

Interesting. The HX711 already has 24 bit. The HX717 seems to support a higher sampling rate, 320SPS. See here: HX717 - Avia Semicon | 24Bit Analog to Digital Converter ADC 16Pin SOP | Evelta I cannot find a real data sheet in English, only in Chinese…

Prusa of course as no interest in making their algorithm work for other machines. I still think that the homing speed is not soooo critical, having a slightly slower speed is not a deal breaker. I wouldn’t trust a home-made ML model to detect the “impact” faster than a straight-forward algorithm, so I don’t think this is the way to go for us (for a company who can test this thoroughly at a large number of copies of the same printer, potentially even with a special setup to avoid breaking stuff in the process this is different of course).

1 Like

Oh, I read and linked to the wrong data sheet :man_facepalming: Thanks for catching that!

I was wondering what was going on here where it looks like they set the polling rate to 320Hz. That would fit with the sensor having a sample rate of 320SPS.

At 1mm/s and 320Hz you get 0.0031mm of motion per sample. The filter is going to steal a little bit of that but linear regression on the host would be able to sort out the exact location. I probe at 5mm/s on the Voron and that would be 0.016mm. My sample tolerance is 0.04mm. So maybe 5mm/s is achievable if the linear regression code works well.

We should be able to do the Butterworth filter and the threshold check in C. That math doesn’t look too bad, at a 320Hz rate. We can implement the filter coefficient generator (source) in Python and push the 4 values down to the MCU and run the same block of C code with custom values for that sensor’s sample rate. You just set the sample rate and filter cutoff frequency in the config.

We will need some way to characterize sensors. Their Hysteresis, settling time, noise, trigger threshold and so on. That probably has to be done the same way that Resonance Comp is done now, by moving the printer, measuring things and doing math. I do tend to agree that we cant train an ML model for everyone’s printer due to lack of sample data, but I wouldn’t rule it out, I’m not a signal processing or ML expert!

I wont have time to work on this for several months unfortunately. I have another project that I need to complete by May and then I think work is going to get busy. :weary:

SciPy can generate the Butterworth filter coefficients: scipy.signal.butter
I don’t have a problem making this a required package if you use this kind of sensor. Its probably useful for sensor characterization in other ways.