Another weighing filament holder returns
-
I think there is maybe one other person on the planet using my filament weighing plugin (https://forum.duet3d.com/post/253602), but notwithstanding that, this updates it for firmware 3.5.1 and a fresh Bookworm DuetPi. There's also some tidying up internally.
This is the plugin file (but you will need to take the .txt off the end of this file - I'm circumventing the forum restrictions): WeighFilament.zip.txt
WARNING
This one is not as good as the old one on 3.4, because I can't get http endpoints to work on 3.5.1, so I can't put a continuously updating display on the DWC screen. However, this one sets up a global variable with the weight value in it, so you can define a macro containing e.g.
M291 P{global.filWeight^"g filament on spool"} R"Filament Weight"
and get the weight at the click of a button, so it's useful.I do intend to revert to the old functionality when I can figure it out. The problem might be that I'm jumping the gun - I'm using pre-release dsf-python-3.5.0.2rc2 with 3.5.1 RRF and DWC, and that's not a combination that's listed as compatible at https://github.com/Duet3D/dsf-python/releases.
For now, this plugin is purely DSF, no DWC component at all.
What it does
It connects a HX711 load cell amplifier direct to a Pi so you can build a load-cell into the spool holder and have a report of filament weight on the spool. The weight of filament is written into a global variable (global.filWeight, but that's configurable) for you to do whatever with.
A python3 DSF routine takes one new weight reading every three seconds (configurable), and averages over the previous 12 readings (configurable). It uses a simple IQR-based filter to disregard outliers in the data, which should eliminate the odd faulty readings. It tries to spot step-changes (e.g. lifting the spool off the holder) and if it does, it reads a whole new set of 12 readings at once, so you get a quicker update of weight (around ten seconds) and it should jump straight from previous weight to new weight without sliiiiding from one value to the next. The global variable is only updated if the weight is more than 5g different to what it last reported (threshold is configurable). The aggressiveness of the IQR filter is configurable too.
There are obvious (and explained) values in the start of /opt/dsf/plugins/WeighFilament/dsf/weighfilament.py you can change to modify all the configurable items.
There is a helper script that records tare weights and calibration values.
Hardware
Hardware is a HX711 breakout and single-point load cell. Mine is an ebay-cheap-special 3kg cell, 13x13x80, and the cheapest available green breakout. The load cell plus board is probably only £5 on ebay. Connect loadcell wires to the breakout (loads of instructions on probable colour scheme the web) and then breakout to a 3.3V pin, a 0V pin and two GPIOs on the Pi - the code assumes DAT to GPIO5 and CLK to GPIO6 (configurable). Note that the HX711 has two hardware channels - channel A can do either 128x or 64x gain and B can do 32x gain - you need to connect the cell to the correct channel for the gain you are using.
Installation and Calibration
You need some python libraries. At a command prompt:
sudo apt install python3-numpy
. The previously required python3-rpi.gpio and python3-setuptools seem to already be part of the latest DuetPi image.You need to download and install the dsf-python from https://github.com/Duet3D/dsf-python/releases. As noted above, I'm currently using dsf-python-3.5.0.2rc2 which is pre-release. I haven't tested other versions. Having downloaded and unpacked you cd into the library top folder and
sudo python3 setup.py install
.You need to download and install the HX711 library from https://github.com/tatobari/hx711py This is pure python and relatively straightforward. Having downloaded and unpacked you cd into the library top folder and
sudo python3 setup.py install
. Note that the author has done some (relatively) recent changes to the library - I'm not using the new functionality, which is mainly focussed at increasing the speed of reading - the old functionality works fast enough for this use case.To install the plugin drop the zip onto the 'Install Plugin' button in Plugins / external plugins in DWC - but DO NOT START the plugin yet.
The plugin won't create the necessary global variable, only update an existing one, so you need to add creation of the variable to config.g, e.g. with the following. The value you set here doesn't matter. You can use a different variable name, but in that case must edit the value near the start of /opt/dsf/plugins/WeighFilament/dsf/weighfilament.py to match.
if !exists(global.filWeight) global filWeight = 0
You need to calibrate the routine before use. The plugin has a helper script to do that, and it's easiest to put this into /usr/local/bin so you can run it directly. At a command prompt run
sudo cp /opt/dsf/plugins/WeighFilament/dsf/weigh /usr/local/bin
and thensudo chmod a+rx /usr/local/bin/weigh
.With nothing on the spool holder at a command prompt run
weigh zero
, this records the tare reading of the holder alone.Then you need something of a known weight not dissimilar to a spool of filament (preferably nearing the end) on the holder - I use a 200g weight - and run
weigh calib
. It will ask you what the weight is.Then preferably put an empty spool on the holder and run
weigh spool
. If you don't have an empty spool but do know what one weighs you can runweigh manual
and enter a weight value.Actually, you can abbreviate the
weigh
options to the first letter, and scatter '-' around too - instead ofweigh zero
you canweigh z
orweigh -z
orweigh --zero
orweigh zipadeedoodah
etc.Some semi-cryptic entries should now have shown up in the weighfilament_calib.txt file in the system directory.
You can re-run any of these (e.g. when you change to a spool with a different empty weight), but you must stop the plugin first. There is no locking, and the script and plugin will scramble each other's communication with the HX711 if they run simultaneously, normally resulting in a hang or garbled data. The calibration file grows forever, if you do a lot of resetting the calibration you can open it and delete older lines - the routine just uses the last of each 'zero', 'calib' and either 'spool' or 'spoolwt' lines it finds in the file.
If you get wildly varying (or complete garbage) answers or the script hangs, the plugin is probably running. Stop the plugin before running the script. Also, the plugin only reads the calibration file on startup - so you need to start the plugin after changing calibration values for it to get the new values anyway.
However, there is apparently the possibility of problems with bit ordering and byte ordering which can also lead to garbage values - if you still get garbage values see the discussion on the HX711 library github page and make changes in definitions near the top of both the helper script and the weighfilament.py file in the plugin zip file.
After all that you should be able to start the plugin. Apart from 'Status' changing to 'started' nothing visible will happen, but if you look in the object model browser or run
M291 P{global.filWeight}
you should get a weight. I have a macro as defined near the top of this posting to prettify it a bit. -
This (above) does work with dsf-python 3.5.1rc1 (as announced in https://forum.duet3d.com/post/338777).
However, I've got a slightly refined set of installation instructions for the pre-requisites:
To install dsf-python it's not necessary to download the source etc. you can just
sudo pip3 install --break-system-packages --pre dsf-python
(and this is better). It will moan about how you should be using a virtual environment instead, but should work. I haven't done any testing with virtual environments. (pip is deprecated, but setup.py is even more deprecated.)For hx711py it's not set up to use pip, but if you use
sudo python3 setup.py install --record files.txt
it will at least write the files it installs into files.txt, which will help if you want to uninstall it in future.Otherwise, same instructions as above.