Skip to content
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

How to get kilogram from hx711? and the proper calibration. #70

Open
louiepaguilar opened this issue Jun 11, 2017 · 153 comments
Open

How to get kilogram from hx711? and the proper calibration. #70

louiepaguilar opened this issue Jun 11, 2017 · 153 comments

Comments

@louiepaguilar
Copy link

louiepaguilar commented Jun 11, 2017

Hi! Can someone please explain how to get kilogram from xh711? and also how to properly calibrate it. I am using arduino mega, hx711 and 4pcs of 50kg load cell (the one you see inside the bathroom scale).. please i need it for my project. and also, please do not use jargon words, for im just a beginner.. consider it like explaining to a child =D

@electrokean
Copy link

You need to just use a bit of math, so it will depend on how good your inner child is at math.
You use the standard formula for slope and intersection: y = mx + b ... or m = (y - b)/x
Here

  • y is the actual weight in whatever units you want (g, kg, oz, etc)
  • x is the raw value from the HX711 - from scale.read_average()
  • m is your slope (multiplier)
  • b is your intersection (offset) - also from scale.read_average() but with no weight, or using scale.tare()

So say you have a raw value of 10000 for 0 weight (tare) and 20000 for 1000g, and want readings in g
First, your offset (b) is 10000
To calculate your multiplier (m) just substitute into the formula
1000 = m * 20000 + 10000 ... or m = (1000 - 10000) / 20000
Thus m = -0.45

Your numbers will be completely different, but the method is the same.
You then put these values into your sketch via scale.set_scale(m) and scale.set_offset(b)
Even better if you don't hard-code them but allow them to be calculated/updated on demand, as they may change over time due to various reasons.
The example sketch that comes with the library partially shows this process.

@louiepaguilar
Copy link
Author

@electrokean thank you for answering. Ive tried your solution and here are the results (please see attached image). y is hard coded. now my question, how am i going to get kilogram from these results..
image

@electrokean
Copy link

You use those calculated values in scale.set_scale(m) and scale.set_offset(b). Then you can start using scale.get_units() to get the value in grams (or kg depending on how you did your calibration)

Note read the comments in HX711.h - it explains the difference between all the read and get functions

@louiepaguilar
Copy link
Author

louiepaguilar commented Jun 12, 2017

@electrokean heres my code for calibration
image

where should i put the scale.set_scale(m) and scale.set_offset(b)? should i put it inside the calibration() which is called by setup()? or should i put it inside the loop()? and what should be put first? the scale.set_scale(m) or scale.set_offset(b)? Sorry if i have too many questions. Im a total newbie..

@electrokean
Copy link

You only call set_scale() and set_offset() once - usually in your setup() function with some pre-calculated and saved values.
You can also just call them from the calibrate() function if you call that from setup() - although you then have to manually calibrate every time you restart the Arduino.
You don't need to call scale.tare() if using scale.set_offset() - they do basically the same thing.

Please read the code written by bogde and try to understand it! It is very small, and most is quite easy to follow.

Also, please don't include screenshots of code. You should copy and paste them inside a markdown code block (surrounded by back-quotes)

@louiepaguilar
Copy link
Author

Thank you so much @electrokean!

@DavidRTucker
Copy link

The hx711 outputs a value corresponding to the ratio of difference voltage divided by the voltage applied to the load cell. This ratio is factored by the gain. Full scale output is 800000 to 7FFFFF in hexadecimal and corresponds to 0.5 to - 0.5 difference ratio V/V. The load cell calibration certificate tells me the output at a particular voltage with a defined load applied. My certificate says 1.996 mV at 5 V with 50 kg applied. The difference ratio is then 0.0003992 V/V at 50 kg. I am using a gain of 128 so this difference ratio becomes 0.0511 V/V. This is then 10.2 % of the full scale 0.5 V and will correspond to 800000 x 10.2 % in hexadecimal. This will be a decimal value of 857275 for 50 kg. The sensitivity is therefore 17145 per kg.

@louiepaguilar
Copy link
Author

my hx711 output value is flactuating from 1000-4000 up and down, is it normal?

@DavidRTucker
Copy link

4000 is 0.047 % of full scale. So don't worry about it. Take an average over more readings if you want a steady value. I suspect that this is normal.

@DavidRTucker
Copy link

I found that was a factor of 2 out. The gain of my setup is 8573 /kgf. Does anyone know what's this is. I will let you know if I can figure it out.

@DavidRTucker
Copy link

The load cell I have has a sensitivity of 1.966 mV/V at 50kg. This is then amplified to 0.2555 V/V. This is then 0.511 of the Hx711 half scale output of 0.5 V/V. The digital output is therefore 0.511 x 800000 in hexadecimal. This will be 4286579 in decimal for 50 kg. The sensitivity is then 85731 per kg.

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

I have 2 50kg load cells and the following code,
`#include "HX711.h"

HX711 scale;

void setup() {
Serial.begin(38400);
Serial.println("HX711 Demo");

Serial.println("Initializing the scale");
// parameter "gain" is ommited; the default value 128 is used by the library
// HX711.DOUT - pin #A1
// HX711.PD_SCK - pin #A0
scale.begin(A1, A0);

Serial.println("Before setting up the scale:");
Serial.print("read: \t\t");
Serial.println(scale.read()); // print a raw reading from the ADC

Serial.print("read average: \t\t");
Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC

Serial.print("get value: \t\t");
Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight (not set yet)

Serial.print("get units: \t\t");
Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight (not set) divided
// by the SCALE parameter (not set yet)

scale.set_scale(2280.f); // this value is obtained by calibrating the scale with known weights; see the README for details
scale.tare(); // reset the scale to 0

Serial.println("After setting up the scale:");

Serial.print("read: \t\t");
Serial.println(scale.read()); // print a raw reading from the ADC

Serial.print("read average: \t\t");
Serial.println(scale.read_average(20)); // print the average of 20 readings from the ADC

Serial.print("get value: \t\t");
Serial.println(scale.get_value(5)); // print the average of 5 readings from the ADC minus the tare weight, set with tare()

Serial.print("get units: \t\t");
Serial.println(scale.get_units(5), 1); // print the average of 5 readings from the ADC minus tare weight, divided
// by the SCALE parameter set with set_scale

Serial.println("Readings:");
}

void loop() {
Serial.print("one reading:\t");
Serial.print(scale.get_units(), 1);
Serial.print("\t| average:\t");
Serial.println(scale.get_units(10), 1);

scale.power_down(); // put the ADC in sleep mode
delay(5000);
scale.power_up();
}`
I don't really understand how this code works. It gives values that are not even close to the required values.
please guide me on how to connect and use the two load cells and the hx711, my situation is desperate.
Thank you.
img_5524

@electrokean
Copy link

You need to read the README file and make use of tare() and set_scale() functions.
The value you pass to set_scale() (e.g. 2280.f in the above) will be your calibration factor to convert raw values to your units of choice (mg, g, kg, lb, etc)
Read through HX711.h, the examples, and various other open/closed issues for plenty more details.

@DavidRTucker
Copy link

The first thing I notice is that you should have four wires from each load cell. You should start by reading each load cell separately. As I explained earlier in this thread you should have a sensitivity value for the load cell. Use this to set the gain as I described. I suggest that if you want to sum up the readings you should read both cells independently and then you can add the values. Let me know if this makes sense.

@DavidRTucker
Copy link

You appear to have an apostrophe at the beginning of your #include statement. I guess that this is not in the code.
I see you are using A1 and A2. This will work but remember that the signals from the hx711 are digital so using analogue inputs is a little perverse.

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

img_20170713_133606 1

@DavidRTucker
Copy link

Okay. The two sensors are actually two half bridges that need to be measured as a pair.

@DavidRTucker
Copy link

How many mV per V are they supposed give at 50 KG?

@DavidRTucker
Copy link

at 50 kg?

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

I don't exactly know how to find it. can you tell me the steps to find those values?

@DavidRTucker
Copy link

Did you have any certificate with the cells?

@DavidRTucker
Copy link

The load cell I have has a sensitivity of 1.966 mV/V at 50kg. This is then amplified to 0.2555 V/V when the 128 gain of the hx711 is applied. This is then 51.1 % of the Hx711 half scale output of 0.5 V/V. The digital output is therefore 0.511 x 800000 in hexadecimal. This will be 4286579 in decimal for 50 kg. The sensitivity is then 85731 per kg.

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

Should I use a multimeter to measure the sensitivity?

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

or is there any device or code which i can use to find the sensitivity value. I didn't get any certificate details with the product.

@DavidRTucker
Copy link

Then determine the output for a couple of weights that you trust. The values will be high. Tell me what output you get for these known weights.

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

/*
Example using the SparkFun HX711 breakout board with a scale
By: Nathan Seidle
SparkFun Electronics
Date: November 19th, 2014
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

This is the calibration sketch. Use it to determine the calibration_factor that the main example uses. It also
outputs the zero_factor useful for projects that have a permanent mass on the scale in between power cycles.

Setup your scale and start the sketch WITHOUT a weight on the scale
Once readings are displayed place the weight on the scale
Press +/- or a/z to adjust the calibration_factor until the output readings match the known weight
Use this calibration_factor on the example sketch

This example assumes pounds (lbs). If you prefer kilograms, change the Serial.print(" lbs"); line to kg. The
calibration factor will be significantly different but it will be linearly related to lbs (1 lbs = 0.453592 kg).

Your calibration factor may be very positive or very negative. It all depends on the setup of your scale system
and the direction the sensors deflect from zero state
This example code uses bogde's excellent library: https://github.com/bogde/HX711
bogde's library is released under a GNU GENERAL PUBLIC LICENSE
Arduino pin 2 -> HX711 CLK
3 -> DOUT
5V -> VCC
GND -> GND

Most any pin on the Arduino Uno will be compatible with DOUT/CLK.

The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.

*/

#include "HX711.h"

#define DOUT 8
#define CLK 7

HX711 scale(DOUT, CLK);

float calibration_factor = 8875; //-7050 worked for my 440lb max scale setup

void setup() {
Serial.begin(38400);
Serial.println("HX711 calibration sketch");
Serial.println("Remove all weight from scale");
Serial.println("After readings begin, place known weight on scale");
Serial.println("Press + or a to increase calibration factor");
Serial.println("Press - or z to decrease calibration factor");

scale.set_scale();
scale.tare(); //Reset the scale to 0

long zero_factor = scale.read_average(); //Get a baseline reading
Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
Serial.println(zero_factor);
}

void loop() {

scale.set_scale(calibration_factor); //Adjust to this calibration factor

Serial.print("Reading: ");
Serial.print(scale.get_units()*0.453592, 3);
Serial.print(" kg"); //Change this to kg and re-adjust the calibration factor if you follow SI units like a sane person
Serial.print(" calibration_factor: ");
Serial.print(calibration_factor);
Serial.println();
delay(1000);

if(Serial.available())
{
char temp = Serial.read();
if(temp == '+' || temp == 'a')
calibration_factor += 10;
else if(temp == '-' || temp == 'z')
calibration_factor -= 10;
}
}

@Dixit00
Copy link

Dixit00 commented Jul 13, 2017

I have used this code and the value that i have got for 500g is 700g and for 3.4kg the values are fluctuating between 3.4 and 4.5

@DavidRTucker
Copy link

What is the calibration factor that gave these figures?

@DavidRTucker
Copy link

Have you been pressing a and z to adjust the factor?

@DavidRTucker
Copy link

500 g is one percent of full scale so it is not a suitable value for calibration of your load cell. The 3.4 kg is a bit better but you need to get a steady reading using average function of the hx711 library.

@DavidRTucker
Copy link

The max values of the 24 bit twos complement are 8388608 and - 8388607. 200 kg will be represented as 2147484. So your initial scale factor should be 10737/kg.

@hemanth0212
Copy link

Hi,
I have used the calibration sketch to arrive at the calibration_factor for a 5Kg loadcell. I get the correct readings for the entire range properly. Once I have this calibration_factor value, is scale.tare() necessary in the setup()?
My observation is that if the scale.tare(); is commented out, I see about 200gms less all the time through out the range.

My application (using ESP32 DEVKIT) requires to go to sleep after reading the value and wakes up at regular intervals and after each wake-up, the setup() runs with the scale.tare() and I get "0" (zero) readings- note that the object being weighed is not removed from the sclae. If I comment-out/remove the scale.tare(); , I get 200gms less.

My understanding is that once the calibration_factor is known, scale.tare(); is not required. Am I missing something?

@SerBazanis
Copy link

David
I put the number you said to me and now i get only 0 everywhere.
What voltage should i measure between cables in the load cell and what numbers i must see. As i said the wiring worked good with a cell 1kgr and calibrating factor 2280.
Should i try the readings with some very heavy object? I tried with 2kgr.

@DavidRTucker
Copy link

It is a 200 kgf load cell so you should expect 0 when it is unloaded. Check resistance from the red wire to the black and white wires. The resistance to the negative excitation wire will be about 400 ohms. Red is always the positive excitation

@SerBazanis
Copy link

I measured with HX711 off [not connected]:
RED-BLACK 285 OHM
RED-WHITE 285 OHM
RED-GREEN 347 OHM

@DavidRTucker
Copy link

Not what I expected! I guess the HX711 is influencing the result. Please measure again with all connections to the HX711 disconnected.

@SerBazanis
Copy link

Only the cell wires
RED-BLACK 390 OHM
RED-WHITE 390 OHM
RED-GREEN 347 OHM
black-white 320 OHM

@DavidRTucker
Copy link

It seems pretty clear that the output is red and green. White to black is the excitation. The only thing that doesn't make sense is the white to black resistance. I would expect this to be 390 ohms.

@DavidRTucker
Copy link

It seems pretty that the output is red and green. White to black is the excitation. The only thing that doesn't make sense is the white to black resistance. I would expect this to be 390 ohms.

@SerBazanis
Copy link

If you see my third post before, the manufacter give
Wiring
Black Power + , white Power - Red Signal + green signal -

while usually is Red[Power+or E+] Black[Power-or E-] White[Signal- or A-] and Green[Signal+ or A+]
Am i correct?

@DavidRTucker
Copy link

It is not what you would expect. Yes white and black are excitation.

@DavidRTucker
Copy link

SerBazanis

With white and black as your input are you still not getting sensible output?

David

@SerBazanis
Copy link

Here in Greece we vote today so in 2 hours i will try it...
Have a good day or night?

@DavidRTucker
Copy link

Hot day in southern Italy by the beach for me.

@SerBazanis
Copy link

Ok David
It worked but with 21000 calibration factor. By the way i put a chinese HX711 [green one].
I finished this projoct for some friends apicoltore

When you come to Athens i will give you honey from abete [elato in Greek].

Thank you again

@DavidRTucker
Copy link

Now I need to figure out why I am a factor of two out. I am glad it worked out for you.

@DavidRTucker
Copy link

Full scale for the HX711 is 20 mV for a 5 V excitation. This is 0.004 V/V. If you have a load cell sensitivity of 1.001 mV/V then this is 0.25025 of the full range of the HX711. The digital output for full range is 8388608. 25.025 % of this is 2099249.

@DavidRTucker
Copy link

One would assume that the 1.001 mV/V corresponds to the stated rating of the device. If the 1.001 mV/V of the load cell actually corresponds to 100 kgf then the scale factor is 20992.

@DavidRTucker
Copy link

The 20 mV for 5 V comes from the HX711 datasheet description. 'Channel A
can be programmed with a gain of 128 or 64, corresponding to a full-scale differential input voltage of ±20mV or ±40mV respectively, when a 5V supply is connected to AVDD analog power supply pin.'

@SerBazanis
Copy link

David
Something strange is happenning. Now when i try the read the same object [1.5kgr] i got a number 2.7kgr.
I changed the factor to 30000 and i got close to true weight.
Why? The temarature is the same in the room but the object was cold.

@DavidRTucker
Copy link

1.5 kg is just too small for a 200 kgf load cell. You will have temperature drift in the HX711 and the load cell. Try hanging your own body weight on it.

@DavidRTucker
Copy link

DavidRTucker commented Jul 7, 2019

Don't use the load cell to measure less than 20 kgf as in 10% of its rating.

@Amodpathak
Copy link

Please share a simple formula for calibration of any type of load cell

@marm496
Copy link

marm496 commented Apr 13, 2020

The max values of the 24 bit twos complement are 8388608 and - 8388607. 200 kg will be represented as 2147484. So your initial scale factor should be 10737/kg.

Hi,We are talking about 2’s complement format thus range is not 8388608 and - 8388607 but 8388608 and -16777216,so far i know.

@schef
Copy link

schef commented May 27, 2020

Hi, i was just trying to understand the formula at the beginning.
I think @electrokean replaced y with x. It should be like this:

Formula

  • y = mx + b
  • m = (y - b)/x
  • x = (y - b)/m

Explanation

  • x is the actual weight in whatever units you want (g, kg, oz, etc)
  • y is the raw value from the HX711 - from scale.read_average()
  • m is your slope (multiplier)
  • b is your intersection (offset) - also from scale.read_average() but with no weight, or using scale.tare()

Example

b = 10000 (raw value no weight)
y = 20000 (raw value with 1000g)
x = 1000 (g)
m = (20000 - 10000) / 1000 = 10

Result

So we are interested in x:

raw = 10000

x = (raw - b) / m = (10000 - 10000) / 10 = 0g

raw = 20000

x = (raw - b) / m = (20000 - 10000) / 10 = 1000g

raw = 15000

x = (raw - b) / m = (15000 - 10000) / 10 = 500g

Usage

  • scale.set_scale(m)
  • scale.set_offset(b)
  • scale.get_units() to get the value in grams

@electrokean
Copy link

@schef your explanation is very good. As you show you can rewrite the formula to solve in various ways. If you swap the definitions of x and y that just changes the effective slope (m) and intersection (b) values you get when solving. In my head I prefer to solve for y being actual weight, but the values required by the HX711 library may actually work the way you write. It has been a long time (5.5 years) since I last used this library, so I don't remember. I'm guessing so based on your results. Cheers!

@electrokean
Copy link

The max values of the 24 bit twos complement are 8388608 and - 8388607. 200 kg will be represented as 2147484. So your initial scale factor should be 10737/kg.

Hi,We are talking about 2’s complement format thus range is not 8388608 and - 8388607 but 8388608 and -16777216,so far i know.

@marm496 2^24 = 16777216 - so you can only have that many unique values in 24 bits.
With 2's complement that gives a range of -8388608 (0x800000) to 8388607 (0x7FFFFF).
@DavidRTucker was very close but he swapped the positive and negative limits.

@ba05
Copy link

ba05 commented Jul 18, 2020

Full scale for the HX711 is 20 mV for a 5 V excitation. This is 0.004 V/V. If you have a load cell sensitivity of 1.001 mV/V then this is 0.25025 of the full range of the HX711. The digital output for full range is 8388608. 25.025 % of this is 2099249.

Thanks for explaining. I will also note that the actual excitation value (AVDD from the datasheet) needs to be calculated from the schematic VBG, R1, and R2 values.

For the module I have and when supplying 5 V to the module this is:
AVDD=VBG(R1+R2)/R2 -> AVDD = 1.25(20+8)/8) = 4.375 V.

Note the AVDD equation was incorrect on earlier HX711 datasheets. THe R1 and R2s were swapped.

The full scale differential input range is not +/- 20mV but:
+/-0.5(AVDD/GAIN)= 0.01708984375 V = 17.08984375 mV (with a GAIN of 128).

The +/- 20mV in the datasheet is a nominal value.

So if you have 2mV/V sensitivity transducer, the full scale output would be:
2mV/V*AVDD = 8.75 mV.

The ratio of the ADC range is thus:
8.75/17.08984375 = 0.512.

So 0.512*8388608 LSBs= 4294967 LSBs at full scale.

Please correct me if I am wrong.

@rkv006
Copy link

rkv006 commented Jul 22, 2020

hello there,

i'm trying to use load cell with Arduino Mega 2560 , i'm able to read the values from "HX711" but not proper values its like(335542,335543,335542,335542....)how can i change these values to weights ,

one thing i don't understand till now how calibration will be done and what is the procedure..

please give a reply...
any answers from you are appreciated

please see my code correct/give me any inputs to get proper weights

//====================load_cell data logging =====================//
#include <SD.h>
#include <SPI.h>
#include <Time.h>
File sdcard_file;
int CS_pin = 53;
unsigned long x = 0, y = 0;
unsigned long dataArray[10];
int j = 0;
void setup()
{
void clk();
Serial.begin(9600);
pinMode(A1, INPUT); //data line //input pin
pinMode(A0, OUTPUT); //SCK line //output pin
pinMode(CS_pin, OUTPUT);//declaring CS pin as output pin
if (SD.begin())
{
Serial.println("SD card is initialized and it is ready to use");
} else
{
Serial.println("SD card is not initialized");
return;
}

}
void loop()
{
unsigned long sum = 0;
sdcard_file = SD.open("data.txt", FILE_WRITE); //Looking for the data.txt in SD card
for (int j = 0; j < 10; j++)
{
digitalWrite(A0, LOW);//SCK is made LL
while (digitalRead(A1) != LOW) //wait until Data Line goes LOW
;
{
for (int i = 0; i < 24; i++) //read 24-bit data from HX711
{
clk(); //generate CLK pulse to get MSB-it at A1-pin
bitWrite(x, 0, digitalRead(A1));//Data Line
x = x << 1;
}
clk(); //25th pulse
Serial.println(x, DEC);
y = x;
x = 0;
//delay(1000);
}
dataArray[j] = y;
//}
for (j = 0; j < 10; j++)
{
sum += dataArray[j];
}
sum = sum/100;
Serial.println(sum, DEC);
sdcard_file.print(sum); //Writing to file in SD card
sdcard_file.print("\n");
sdcard_file.close(); //Closing the file in SD card
}
}

void clk()
{
digitalWrite(A0, HIGH);//SCK pin
digitalWrite(A0, LOW);//SCK pin
}

@ivanedpratama
Copy link

Hello @electrokean @DavidRTucker and everyone,

I have a case, the formula used to find the output of the hx711 module? can anyone help me ?
I use a 5 kg loadcell and a NodeMCU ESP8266 microcontroller with a load cell input voltage of 3.3 V

Loadcell Specifications:
Rated Load: 5Kg
Rated Output: 1.0mV/V±0.15mV/V
Zero Output: ±0.1mV/V
Creep: 0.03%F.S./30min
Input End: Red+(power), Black-(power)
Output End: Blue/Green+(signal), White-(signal)
Recommended operating voltage: 3 ~ 12 VDC
Maximum operating voltage: 15 VDC
Input Impedance: 1115±10%?
Output Impedance: 1000±10%?
Protection class: IP65

Thank you ...

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

No branches or pull requests