You are on page 1of 11

HX711

=====

An Arduino library to interface the Avia Semiconductor


HX711 24-Bit Analog-to-Digital Converter (ADC) for
Weight Scales.

This is my humble attempt at creating an Arduino library for this ADC:


http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf

Other libraries exist, including this very good one, which I first used and
which is the starting point for my library:
https://github.com/aguegu/ardulibs/tree/master/hx711

# Advantages of this library


Although other libraries exist, I needed a slightly different approach, so
here's how my library is different than others:

1. It provides a tare() function, which "resets" the scale to 0. Many other


implementations calculate the tare weight when the ADC is initialized
only. I needed a way to be able to set the tare weight at any time. Use
case: place an empty container on the scale, call tare() to reset the
readings to 0, fill the container and get the weight of the content.

2. It provides a power_down() function, to put the ADC into a low


power mode. According to the datasheet, "When PD_SCK pin changes
from low to high and stays at high for longer than 60μs, HX711 enters
power down mode". Use case: battery powered scales. Accordingly,
there is a power_up() function to get the chip out of the low power
mode.

3. It has a set_gain(byte gain) function that allows you to set the gain
factor and select the channel. According to the datasheet, "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.
Channel B has a fixed gain of 32.". The same function is used to select
the channel A or channel B, by passing 128 or 64 for channel A, or 32
for channel B as the parameter. The default value is 128, which means
"channel A with a gain factor of 128", so one can simply call set_gain().
Also, the function is called from the constructor.

4. The constructor has an extra parameter "gain" that allows you to set
the gain factor and channel. The constructor calls the "set_gain" function
mentioned above.
5. The "get_value" and "get_units" functions can receive an extra
parameter "times", and they will return the average of multiple readings
instead of a single reading.

# How to Calibrate Your Scale

1. Call set_scale() with no parameter.


2. Call tare() with no parameter.
3. Place a known weight on the scale and call get_units(10).
4. Divide the result in step 3 to your known weight. You should get
about the parameter you need to pass to set_scale.
5. Adjust the parameter in step 4 until you get an accurate reading.

# How to use
See the examples section for possible implementations with the different
constructors

EXAMPLE CODE:
#include "hx711.h"

Hx711 scale(A1, A0);

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println(scale.averageValue());
delay(200);
}

1. place nothing on the scale, then run the example code, which means reset your arduino that
runs the example code above.

record the output. that is the offset.


2. place a stand weight, like 1kg(1000g), record the output as w.

3. Do the math

ratio = (w - offset) / 1000

4. modify your application code to

CODE 2:

#include "hx711.h"

Hx711 scale(A1, A0);

void setup() {
Serial.begin(9600);
scale.setOffset(fill in the `offset` value here);
scale.setScale(fill in the `ratio` value here);
}

void loop() {
Serial.println(scale.getGram());
delay(200);
}

Then arduino should give you the right result in unit gram.
The init program has set the average value for the first few runs to the offset, with the
function setOffset. It is written in the lib.
My example code is supposed to work with scale that got a few seconds of zero weight when the
program start running. But we still need to do the test to calculate the ratio. It is just happen to be
742 in my setup, but it dose not fit for other setups.

If the setup got weight already when the program start running, and you do not want its getGram()
output to be zero. Then you have to setOffset() again manually with the tested value to override the
auto offset, just like the example code above.

the averageValue() basically is the raw output. It is not affected by the offest or the scale(ratio). The
offset determind your zero point. while the scale(ratio) determind what unit you want the getGram()
output to be. With different ratio value, the output can be in g, kg, oz, pound, whatever, as long as
the value in the range of the setup and makes sense to you.

0g = 0kg = 0oz = 0pound


1000g = 1kg = 35.274oz = 2.20462 pound
Just remember that the raw output and the calculated (getGram()) output, are linear related.
getGram() = (averageValue() - offset) / ratio;
Just middle school math. :)

RAW CODE: (.H FILE)

/* Arduino library for digital weight scale of hx711


*
* hardware design: syyyd
* available at http://syyyd.taobao.com
*
* library design: Weihong Guan (@aguegu)
* http://aguegu.net
*
* library host on
* https://github.com/aguegu/Arduino
*
* Created on: Oct 31, 2012
*/

#ifndef HX711_H_
#define HX711_H_

#include "Arduino.h"

class Hx711
{
public:
Hx711(uint8_t pin_din, uint8_t pin_slk);
virtual ~Hx711();
long getValue();
long averageValue(byte times = 32);
void setOffset(long offset);
void setScale(float scale = 742.f);
float getGram();

private:
const uint8_t _pin_dout;
const uint8_t _pin_slk;
long _offset;
float _scale;
};

#endif /* HX711_H_ */

(.CPP FILE)

/*
* Hx711.cpp
*
* Created on: Oct 31, 2012
* Author: agu
*/

#include "hx711.h"

Hx711::Hx711(uint8_t pin_dout, uint8_t pin_slk) :


_pin_dout(pin_dout), _pin_slk(pin_slk)
{
pinMode(_pin_slk, OUTPUT);
pinMode(_pin_dout, INPUT);

digitalWrite(_pin_slk, HIGH);
delayMicroseconds(100);
digitalWrite(_pin_slk, LOW);

averageValue();
this->setOffset(averageValue());
this->setScale();
}

Hx711::~Hx711()
{

long Hx711::averageValue(byte times)


{
long sum = 0;
for (byte i = 0; i < times; i++)
{
sum += getValue();
}

return sum / times;


}

long Hx711::getValue()
{
byte data[3];

while (digitalRead(_pin_dout))
;

for (byte j = 3; j--;)


{
for (char i = 8; i--;)
{
digitalWrite(_pin_slk, HIGH);
bitWrite(data[j], i, digitalRead(_pin_dout));
digitalWrite(_pin_slk, LOW);
}
}

digitalWrite(_pin_slk, HIGH);
digitalWrite(_pin_slk, LOW);

data[2] ^= 0x80;

return ((uint32_t) data[2] << 16) | ((uint32_t) data[1] << 8)


| (uint32_t) data[0];
}

void Hx711::setOffset(long offset)


{
_offset = offset;
}

void Hx711::setScale(float scale)


{
_scale = scale;
}

float Hx711::getGram()
{
long val = (averageValue() - _offset);
return (float) val / _scale;
}

EXAMPLES(SERIAL FILE)
/* sample for digital weight scale of hx711, display with a HD44780 liquid
crtstal monitor
*
* hardware design: syyyd
* available at http://syyyd.taobao.com
*
* library design: Weihong Guan (@aguegu)
* http://aguegu.net
*
* library host on
* https://github.com/aguegu/Arduino
*/

// Hx711.DOUT - pin #A1


// Hx711.SCK - pin #A0

#include "hx711.h"

Hx711 scale(A1, A0);

void setup() {

Serial.begin(9600);

void loop() {

Serial.print(scale.getGram(), 1);
Serial.println(" g");

delay(200);
}

LCD CODE:

/* sample for digital weight scale of hx711, display with a HD44780 liquid
crtstal monitor
*
* hardware design: syyyd
* available at http://syyyd.taobao.com
*
* library design: Weihong Guan (@aguegu)
* http://aguegu.net
*
* library host on
* https://github.com/aguegu/Arduino
*/

// Hx711.DOUT - pin #A1


// Hx711.SCK - pin #A0

// LCD.RS - pin 12
// LCD.En - pin 11
// LCD.D4 - pin 5
// LCD.D5 - pin 4
// LCD.D6 - pin 3
// LCD.D7 - pin 2

#include <LiquidCrystal.h>
#include <hx711.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


Hx711 scale(A1, A0);

void setup() {

lcd.begin(16, 2);

void loop() {

lcd.setCursor(0, 0);
lcd.print(scale.getGram(), 1);
lcd.print(" g");
lcd.print(" ");

delay(200);
}

OUTPUTS:
REFERENCES:

https://forum.allaboutcircuits.com/threads/weightsensing-project-using-arduino.138691/

https://github.com/aguegu/ardulibs/tree/master/hx711

http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf
How to Calibrate Your Scale
1. Call set_scale() with no parameter.
2. Call tare() with no parameter.
3. Place a known weight on the scale and call get_units(10).
4. Divide the result in step 3 to your known weight. You should get about the
parameter you need to pass to set_scale.
5. Adjust the parameter in step 4 until you get an accurate reading.

You might also like