-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add HX711 absolute weight conversion #15292
Conversation
tasmota/settings.h
Outdated
uint32_t keeloq_serial; // FC4 | ||
uint32_t keeloq_count; // FC8 | ||
//uint32_t keeloq_serial; // FC4 TODO discuss | ||
//uint32_t keeloq_count; // FC8 TODO discuss |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not finished yet. Waiting for advise how to proceed.
This new functions needs two variables in permanent memory. The absolute weight is calculated from raw value following the formula
weight = absconv_a / 1e9 * raw + absconv_b / 1e6;
Typical config values from one of my setups are:
- absconv_a = 953499
- absconv_b = 15418390
The end result of the computation is a weight with a few decimals (e.g. 0-200kg, two decimals). The size of those variables can therefore certainly be reduced.
I am not sure about other builds and configs though. Another user could end with raw_weight values in different ranges and would need to apply a and b in lower or higher ranges. How do we avoid overflows and invalid user inputs?
Any help is highly appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just made these variables available in settings.h
I think you need to find some kind of scaling to keep the values within the space of a uint32_t being 0 to 4.294.967.295 while keeping in mind results of calculation being also within this range. Using floats makes things worse as the float range is a lot smaller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Okay let me think of a reasonable scaling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having some difficulties wrapping my head around this.
weight = a * raw + b;
weight = A / 1e9 * raw + B / 1e6;
weight = absconv_a / 1e9 * raw + absconv_b / 1e6;
raw
is currently of typelong
absconv_a
andabsconv_b
are of type long as well (meaning they are signed, which contradicts uint32_t)absconv_b
can be positive or negative, therefore signed long makes sense
- the
weight
result realistically lies below 200kg and could also be negative when the setup is changed, lets say [-400..400]
Therefore, result of the calculation should always be within range, under reasonable parameters. How much sanity checking of these parameters do we need to implement?
Assuming weight
results between [-400..400]:
- we can likewise limit b to [-400..400]
- we can limit a to something around
400 / max(long)
Not sure if this is the right way forward.
For reference, some of my setup configurations:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just changed both absconv to int32_t (long)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've played around with this and I wonder why we need such an elaborate formula.
Considering my situation. I have a loadcell which, when no load is attached results in a raw value of 1253. When I load a weight of known 280grams it returns a value of 1533. So all I need is a possibility to decrease the raw value with 1253 and I have the weigth.
What am I missing here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @arendst,
Did you go through the internal calibration process prior to this experiment?
Asking because I mostly ignore this function and use standard values for all my devices. In combination with the calibration formula (like examples given above) I have a deterministic approach to build reproducible devices. I have a dozend of these devices operational, number growing.
{"Sensor34":{"WeightRef":5000,"WeightCal":22,"WeightMax":200000,"WeightItem":0.0,"WeightChange":ON,"WeightDelta":10}}
I understand that all of this could feel like a solution that is not in line with functionality that is already there. My use case is to build devices which are calibrated and produce absolute weight measurements (10-90kg) across reboots, in permanent installations over years. The approach as described works quite satisfying for allmost two years now. However, so far the y=ax+b
conversion is done in Home Assistant and I wanted to change that.
Should we discuss a different (more Tasmota integrated) approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's continue here #13983 (reply in thread)
@@ -441,6 +464,9 @@ void HxShow(bool json) | |||
} | |||
weight = (float)Hx.weight / 1000; // kilograms | |||
} | |||
if (Hx.absconv_a != 0 && Hx.absconv_b != 0) { | |||
weight = (float)Hx.absconv_a / 1e9 * Hx.raw + (float)Hx.absconv_b / 1e6; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Am I right in the conclusion that using the raw value here makes current calibration efforts useless? How do you define the absconv parameters? By trial and error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No you are correct. No offense, but I didn't find the implemented calibration combined with taring the weight upon startup useful for my use case (and wonder in which use case it is). The strategy I follow is to take a few raw weights for known masses, then run a simple linear regression, e.g. here: https://mycurvefit.com to get to the absconv parameters of y=ax+b
.
It's not as integrated but is a good deterministic process. Let me know if you believe we should have a discussion about a different path!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My implemented use case is based on a commercial kitchen scale like the Ikea one.
After power on the user adds an empty dish, selects the reset button to zero the result and then is able to weigh anything he adds to the dish. Hence the zero button in the GUI.
There are ofcourse other uses which may use your suggested solution.
As your implementation doesn't interfere with mine I'll add it now so users can get some experience with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting element you brought up!
USE_HX711_GUI
is not defined for FIRMWARE_SENSORS
. As a result I did never see this "zero button in GUI" you refered to. Maybe this should be changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arendst ping in case you missed this.
Add commands ``Sensor34 10 <valueA>`` and ``Sensor34 11 <valueB>`` to use HX711 absolute weight conversion (#15292)
Merged for testing |
- Add HX711 command ``Sensor34 10 0|1|<weight in gram>`` to set HX711 fixed tare (0 = use auto tare, 1 = use calibrated tare, Any other value is user selected tare) - HX711 removed command ``Sensor34 7`` as now active tare is persistent resulting in calculated current weight - Changed HX711 commands ``Sensor34 11 <valueA>`` and ``Sensor34 12 <valueB>`` to use HX711 absolute weight conversion (#15292)
Description:
Related issue (if applicable): fixes #13983
Implemented as discussed in issue ticket. Tested and working as expected.
Checklist:
NOTE: The code change must pass CI tests. Your PR cannot be merged unless tests pass