Comments (22)
hey there,
since you're getting a negative number, you probably need to switch the S+, S- wires (or E+, E- on some boards) the ones that come from your load cell into your HX711 board. I would try that first...
from hx711.
Hi @alduxvm!
Would you mind testing my pull-request to see if it fixes the way your application is behaving? I expect the change to more correctly handle a range of values, and you happen to have the perfect test case.
I have a hunch that their is a bug in the datasheet about decoding the value returned by the hx711. If you could test this, it would really clear up some confusion for both @bogde and myself.
Thanks!
Zak
from hx711.
I'm going to try both next week, and let you know, thanks!
from hx711.
I wrote an Arduino sketch to make sure I understood the representation of 32-bit and 24-bit two's complement values.
There may be an error in the HX711.cpp code: it is toggling the sign-bit in the 24-bit value returned from the HX711 but it should be extending that sign bit into the top 8 bits of the 32-bit value returned to library user calling programs.
Attached is a copy of the test Arduino sketch with the output appended.
HX711_adc_conversion.txt
I changed my version of HX711.cpp from -
data[2] ^= 0x80;
return ((uint32_t) data[2] << 16) | ((uint32_t) data[1] << 8) | (uint32_t) data[0];
to -
byte datasign;
// 1 Dec 2015 - add most significant byte "datasign" to extend sign bit to 32-bit 2's complement result (from 24-bit source data from HX711 ADC)
if ((data[2] & 0x80) == 0x00)
datasign = 0x00;
else
datasign = 0xFF;
return ((uint32_t)datasign << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[1] << 8) | (uint32_t)data[0];
from hx711.
@cybermat I ran into this as well. I have a pull-request outstanding that extends the sign-bit and converts the number from two's compliment. I see you caught the padding, but you aren't converting the number from two's compliment in your pasted code. Would you mind giving it a try? Thanks!
from hx711.
@zfields, The HX711 library is fine just by extending the sign bit of each 24-bit value from the ADC into the top 8 bits of 32-bit Long (signed) integer values it produces.
The answer might be either a positive or a negative integer value (which are the two's complement of each other), and which value is correct will depend on the user's application and how they connect the HX711 ADC to their sensor.
To change the sign of a Long integer value the user can either multiply the answer by -1 or swap the leads connecting the sensor to the HX711 ADC.
I'm using the HX711 with an air pressure sensor where negative numbers represent partial vacuums and positive numbers represent pressures above atmospheric pressure, so the HX711 library can't make any assumptions about whether the user always wants a positive value returned.
"Two's complement" has 2 different meanings.
The first meaning is about converting positive numbers to negative numbers and vice versa. If your computer uses 2's complement notation then multiplying signed integers by -1 does this conversion (that is, the 2's complement of +3 is -3. The 2's complement of -3 is +3).
The second meaning is that the Arduino Uno uses this way of representing Long integers, so there's no need to convert two's complement values from the HX711 ADC to some other form, such as "one's complement" notation. They only need to be made 8 bits longer (that is, the Arduino Uno represents signed Long integer values in 32 bits stored in 2's complement notation.)
from hx711.
@cybermat Two's compliment only has one meaning, and I think you are over simplifying it. Your math (* -1) is true, but the bits behind your math are radically different. The data sheet reports it returns a two's compliment value, but the example only XOR's the highest bit. I'll use 3 bits to illustrate my observation...
bin u s | 2's u s | ^x4 u s
000 0 0 | 000 0 0 | 100 4 -4
001 1 1 | 111 7 -1 | 101 5 -3
010 2 2 | 110 6 -2 | 110 6 -2
011 3 3 | 101 5 -3 | 111 7 -1
100 4 -4 | 100 4 -4 | 000 0 0
101 5 -3 | 011 3 3 | 001 1 1
110 6 -2 | 010 2 2 | 010 2 2
111 7 -1 | 001 1 1 | 011 3 3
(Legend: bin = binary representation, 2's - two's complement conv, ^x4 - flip highest order bit, u - unsigned value, s - signed value)
As the library is now written (highest order bit flipped then left zero filled), you get the set of unsigned values from the ^x4
column. As we have both noted, the padding is important in order to preserve in the value you received from the scale. In your case (bin correctly padded), you get the set of signed values from the bin
column. The value looks correct compared to the set of signed values from the 2's
column (although negative), but the logic ultimately fails for the negative max case (results in 4 but should be -4). If the HX711 is truly returning a two's compliment value, then the result can be radically different depending whether or not the value should be signed or unsigned.
from hx711.
@alduxvm I wanted to send you a ping to see if you had an opportunity to test my pull request?
from hx711.
Ok... I tried changing E+ and E-... The thrust stand stopped working.
So, I soldered again and give it a go to @zfields version of the library and tare it using this code in setup and nothing on loop:
scale.set_scale();
scale.tare();
delay(5000); // just to have time to put the weight on it...
Serial.println(scale.get_units(10));
I got a value of -16545.00 with a weight of 40 grams... then I tested this code:
void setup() {
Serial.begin(115200);
scale.set_scale(-413.625); // -16545.00/40
scale.tare();
}
void loop() {
Serial.print("one reading:\t");
Serial.println(scale.get_units(), 1);
delay(1000);
}
And if I used the same 40 grams weight, I got this results:
one reading: -0.1
one reading: 0.0
one reading: 28.2
one reading: 39.7
one reading: 39.8
one reading: 39.6
one reading: 39.7
one reading: 39.9
one reading: 39.9
one reading: 40.1
one reading: 40.1
one reading: 40.2
one reading: 40.4
one reading: 40.6
one reading: 40.5
one reading: 40.9
one reading: 40.6
one reading: 40.8
one reading: 41.0
one reading: 40.9
one reading: 41.0
one reading: 41.1
one reading: 41.2
If I put another load like 200grams, I got this result:
one reading: -0.0
one reading: 0.0
one reading: 0.1
one reading: 198.3
one reading: 196.1
one reading: 196.1
one reading: 195.9
one reading: 196.0
one reading: 196.2
one reading: 196.0
So, I think @zfields version works!!! what do you think???
from hx711.
hello all, due to the lack of time i've been unable to look into this lately. so, unless anyone has a different opinion, i will merge @zfields changes.
from hx711.
@bogde @zfields I am using green HX711 and 4cell sensor ( body scale )
- hx711 http://www.ebay.com/itm/Weighing-Sensor-AD-Module-Dual-Channel-24-Bit-A-D-Conversion-HX711-Shieding-HPT-/201485738669?hash=item2ee97c62ad:g:jQoAAOSwHPlWcFU9
- cell http://www.ebay.com/itm/4-x-Body-Load-Scale-Weighing-Sensor-Resistance-Strain-50kg-Half-bridge-YZC-161B-/121685678462?hash=item1c5508197e:g:9kEAAOSwLVZVkU8V
Here is my test result. Ignore time, third one and few gram of variation.
with scale.set_scale(23040.f); scale.tare();
float fmeasured = scale.get_units(5) ;
measured = int(fmeasured * 1000) ;
( to send using i2c)
Same value with -.
Current ---------------------
Time(sec) measured
8.21 : 2002 : 2002
8.66 : 2011 : 2011
9.21 : 2004 : 2004
9.66 : 2000 : 2000
10.21 : 2003 : 2003
10.66 : 2005 : 2005
11.21 : 2000 : 2000
11.66 : 2003 : 2003
12.21 : 2000 : 2000
12.67 : 2000 : 2000
13.21 : 2000 : 2000
13.66 : 2003 : 2003
14.21 : 2000 : 2000
14.67 : 2003 : 2003
15.21 : 1999 : 1999
15.67 : 2001 : 2001
With https://github.com/zfields/HX711
14.66 : -2022 : -2022
15.21 : -1996 : -1996
15.67 : -1992 : -1992
16.21 : -1993 : -1993
16.67 : -1990 : -1990
17.21 : -1992 : -1992
17.67 : -1992 : -1992
18.21 : -1988 : -1988
18.67 : -2062 : -2062
19.21 : -2016 : -2016
19.67 : -2020 : -2020
20.21 : -1999 : -1999
20.67 : -1998 : -1998
21.21 : -1998 : -1998
21.67 : -1998 : -1998
22.21 : -1996 : -1996
22.67 : -1997 : -1997
23.22 : -1999 : -1999
23.67 : -1999 : -1999
24.22 : -1999 : -1999
24.67 : -2000 : -2000
from hx711.
thanks for your feedback. can you switch wiring (basically A- with A) and test zfields version again?
from hx711.
@chaeplin Also, are you recalibrating the scale to a known value when you upload each set of firmware. I would be surprised if the scale factor was the same.
from hx711.
With switching wiring, current sketch gives - value
With switching wiring, new sketch(zfields),
scale.set_scale(23.f);
scale.tare();
Serial.println(scale.get_units(5));
delay(3000);
--- 2117g is on
2123.13
2122.91
2123.78
2122.00
2123.70
***** edited *********
***** edited *******
from hx711.
Looks like recalibrating is not needed.
scale.set_scale(23.f); gives gram unit. --> 2117
scale.set_scale(231.f); gives 10 gram unit. --> 211.7
scale.set_scale(2300.f); gives 100 gram unit. --> 21.17
from hx711.
I have a test again, with my original sketch and zfields's.
2.66 : -3 : -3
3.20 : 0 : 0
3.66 : -7 : -7
4.20 : 3 : 3
4.66 : 5 : 5
5.20 : 11 : 11
5.66 : -5 : -5
6.20 : -23 : -23
6.66 : 19 : 19
7.20 : 6 : 6
7.66 : -5 : -5
8.20 : -3 : -3
8.66 : -7 : -7
9.20 : -2 : -2
9.66 : 3 : 3
10.20 : 2 : 2
10.66 : -14 : -14
11.20 : 134 : 134
11.66 : 568 : 568
12.20 : 807 : 807
12.66 : 1126 : 1126
13.20 : 1648 : 1648
13.66 : 1983 : 1983
14.20 : 2014 : 2014
14.66 : 1990 : 1990
15.20 : 1991 : 1991
15.66 : 1989 : 1989
16.20 : 1987 : 1987
16.66 : 1987 : 1987
17.20 : 1988 : 1988
17.66 : 1980 : 1980
18.20 : 1952 : 1952
18.66 : 2042 : 2042
19.20 : 2109 : 2109
19.66 : 2260 : 2260
20.20 : 2182 : 2182
20.66 : 2012 : 2012
21.21 : 2041 : 2041
21.66 : 2000 : 2000
22.20 : 1997 : 1997
22.66 : 1988 : 1988
23.20 : 1988 : 1988
23.66 : 1989 : 1989
24.21 : 1981 : 1981
24.66 : 1984 : 1984
25.21 : 2002 : 2002
25.66 : 1984 : 1984
26.20 : 1954 : 1954
26.66 : 1999 : 1999
27.21 : 2042 : 2042
27.66 : 1566 : 1566
28.21 : 114 : 114
28.66 : 5 : 5
29.20 : 5 : 5
29.66 : -11 : -11
30.21 : -9 : -9
30.66 : -3 : -3
31.21 : -3 : -3
31.66 : -2 : -2
32.21 : -7 : -7
32.66 : -12 : -12
33.20 : 1 : 1
33.66 : 5 : 5
34.21 : 4 : 4
34.66 : -4 : -4
35.21 : -2 : -2
35.66 : -1 : -1
36.20 : 0 : 0
36.66 : 0 : 0
37.21 : 2 : 2
37.66 : 0 : 0
38.21 : -1 : -1
38.66 : 0 : 0
39.21 : -2 : -2
39.66 : 1 : 1
40.21 : 1 : 1
40.66 : 0 : 0
41.21 : 1 : 1
41.66 : 3 : 3
42.21 : 0 : 0
42.66 : 0 : 0
43.21 : 0 : 0
43.66 : 0 : 0
44.21 : 4 : 4
44.66 : 0 : 0
45.21 : 1 : 1
45.66 : 0 : 0
46.21 : 0 : 0
46.66 : 0 : 0
47.21 : 0 : 0
47.66 : 0 : 0
48.21 : -10 : -10
48.66 : -51 : -51
49.21 : 4 : 4
49.66 : 381 : 381
50.21 : 113 : 113
from hx711.
@chaeplin I don't quite understand your values (x:y:z). x = time, y = ?, z = ? I am assuming that z is the value returned from my modification. What is y? (or vice versa) I don't understand the test you are running. Are you testing both versions simultaneously?
Are you adjusting the weight on the scale? I think this fix will be observed by testing a large range from negative (or tension) weight through to positive (or compression) weight.
from hx711.
@zfields time / weight / ( a function not used any more) return of weight
My scale is for dog's poop pad, so no negative test.
scale
https://raw.githubusercontent.com/chaeplin/esp8266_and_arduino/master/_03-hx711-scale/pics/2.jpg
result with your mod(moving around a lot before poop).
https://raw.githubusercontent.com/chaeplin/esp8266_and_arduino/master/_03-hx711-scale/pics/10.png
from hx711.
@chaeplin Interesting test and a pretty app!
I have a couple of questions though.
- Are you able to test the scale with a known weight, across a broad range (I think the scale is rated for 50kg)? You're dog's poop is not a known value, and will be roughly the same time after time, so it doesn't make for the best test.
- Does the noise on the scale only happen with my change set, or is it an issue with the hx711 library in general?
Thanks again for all the testing!
from hx711.
@zfields The graph is output of grafana(db : influxdb, front : grafana) :).
- tested with two known, 2117 and 2000.
- both.
I use standard deviation < 15 (10 check) for reporting, so the noise is not a problem to me.
from hx711.
@chaeplin As a final test, would you put a significant load on the scales and see how the output behaves between the two libraries?
from hx711.
@zfields done. two lib, one sketch, A- and A switched. ignore drift.
cur and new : https://raw.githubusercontent.com/chaeplin/esp8266_and_arduino/master/_03-hx711-scale/for_test/pics/all.png
from hx711.
Related Issues (20)
- Creep effect removal. Load cell storage over long time HOT 5
- Arduino 2 support
- Formula to find hx711 output of load cell voltage output HOT 1
- Arduino MKR 1010 Upload failure
- Arduino freezes after about 1 hour of continuous reading
- serial monitor freezes on arduino uno when data or clock from HX711 is connected to the arduino digital data pin
- Should function "scale.tare();" need a parameter? HOT 2
- add NRF to compatible boards list
- Verify my wiring (HX711 with four strain gauges) HOT 2
- Multiple HX711 with one clock HOT 1
- warning: this use of "defined" may not be portable [-Wexpansion-to-defined]
- Reason behind using D2 and D3 pins HOT 1
- HX711 only reads once on startup HOT 2
- How to check load cell is connected or not
- What are possible values for scale.set_scale(2280.f); HOT 2
- 71
- self-calibration of load cell
- HX711 not thread safe?
- HX711 high current consumption
- Error on `make build-all` HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hx711.