Skip to content

Commit

Permalink
Develop (#12)
Browse files Browse the repository at this point in the history
* fix #11  shiftIn() timing of clock pulses (breaking change)
* update readme
* improved readability
  • Loading branch information
RobTillaart committed Nov 16, 2021
1 parent 8b04fa2 commit 7683080
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 62 deletions.
44 changes: 39 additions & 5 deletions HX711.cpp
@@ -1,7 +1,7 @@
//
// FILE: HX711.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.3.0
// PURPOSE: Library for Loadcells for UNO
// URL: https://github.com/RobTillaart/HX711
//
Expand All @@ -12,6 +12,9 @@
// 0.2.1 2020-12-28 add arduino-ci + unit test
// 0.2.2 2021-05-10 add read_median(), fix typo, add mode operandi
// 0.2.3 2021-05-26 add running_average() mode
// 0.3.0 2021-11-14 fix #11 shiftIn timing
// update build-CI, readme.md, badges



#include "HX711.h"
Expand All @@ -28,7 +31,7 @@ HX711::~HX711() {}

void HX711::begin(uint8_t dataPin, uint8_t clockPin)
{
_dataPin = dataPin;
_dataPin = dataPin;
_clockPin = clockPin;

pinMode(_dataPin, INPUT);
Expand All @@ -55,6 +58,11 @@ bool HX711::is_ready()
}


// from datasheet page 4
// When output data is not ready for retrieval,
// digital output pin DOUT is high. Serial clock
// input PD_SCK should be low. When DOUT goes
// to low, it indicates data is ready for retrieval.
float HX711::read()
{
// this waiting takes most time...
Expand All @@ -69,9 +77,12 @@ float HX711::read()
noInterrupts();

// Pulse the clock pin 24 times to read the data.
v.data[2] = shiftIn(_dataPin, _clockPin, MSBFIRST);
v.data[1] = shiftIn(_dataPin, _clockPin, MSBFIRST);
v.data[0] = shiftIn(_dataPin, _clockPin, MSBFIRST);
// v.data[2] = shiftIn(_dataPin, _clockPin, MSBFIRST);
// v.data[1] = shiftIn(_dataPin, _clockPin, MSBFIRST);
// v.data[0] = shiftIn(_dataPin, _clockPin, MSBFIRST);
v.data[2] = _shiftIn();
v.data[1] = _shiftIn();
v.data[0] = _shiftIn();

// TABLE 3 page 4 datasheet
// only default verified, so other values not supported yet
Expand Down Expand Up @@ -271,4 +282,27 @@ void HX711::power_up()
digitalWrite(_clockPin, LOW);
}


// MSB_FIRST optimized shiftIn
// see datasheet page 5 for timing
uint8_t HX711::_shiftIn()
{
uint8_t value = 0;
uint8_t mask = 0x80;
while(mask > 0)
{
digitalWrite(_clockPin, HIGH);
delayMicroseconds(1); // T2 >= 0.2 us
if (digitalRead(_dataPin) == HIGH)
{
value |= mask;
}
digitalWrite(_clockPin, LOW);
delayMicroseconds(1); // keep duty cycle ~50%
mask >>= 1;
}
return value;
}


// -- END OF FILE --
7 changes: 4 additions & 3 deletions HX711.h
Expand Up @@ -2,7 +2,7 @@
//
// FILE: HX711.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.3.0
// PURPOSE: Library for Loadcells for UNO
// URL: https://github.com/RobTillaart/HX711
//
Expand All @@ -15,7 +15,7 @@

#include "Arduino.h"

#define HX711_LIB_VERSION (F("0.2.3"))
#define HX711_LIB_VERSION (F("0.3.0"))


const uint8_t HX711_AVERAGE_MODE = 0x00;
Expand All @@ -39,7 +39,7 @@ class HX711

void reset();

// checks if loadcell is ready to read.
// checks if load cell is ready to read.
bool is_ready();

// wait until ready,
Expand Down Expand Up @@ -142,6 +142,7 @@ class HX711
uint8_t _mode = 0;

void _insertSort(float * array, uint8_t size);
uint8_t _shiftIn();
};

// -- END OF FILE --
82 changes: 50 additions & 32 deletions README.md
Expand Up @@ -8,7 +8,7 @@

# HX711

Arduino library for HX711 24 bit ADC used for load cells and scales.
Arduino library for HX711 24 bit ADC used for load cells and scales.


## Description
Expand All @@ -21,6 +21,21 @@ The 23 bits mantissa of the IEE754 float matches the 24 bit ADC very well.
Furthermore it gave a smaller footprint.


### Breaking change 0.3.0

In issue #11 it became clear that the timing of the default **shiftIn()** function that
reads the value of the internal ADC was too fast on some processor boards for the HX711.
This resulted in missing the first = sign bit and value read could be a factor two
higher than should. If one calibrated the sensor this would be compensated with the
factor that is derived in the calibration process.

In 0.3.0 a dedicated **shiftIn()** function is added into this library that uses hard
coded delays to keep the timing of the clock within datasheet parameters.
This should guarantee that the sign bit is read correctly on all platforms.
Drawback is that reading the HX711 takes an ~50 extra microseconds.
How much this affects performance is to be investigated.


## Main flow

First action is to call **begin(dataPin, clockPin)** to make connection to the **HX711**.
Expand All @@ -44,11 +59,11 @@ Steps to take for calibration

#### Base

- **HX711()** constructor
- **HX711()** constructor.
- **~HX711()**
- **void begin(uint8_t dataPin, uint8_t clockPin)** sets a fixed gain 128 for now.
- **void reset()**
- **bool is_ready()** checks if load-cell is ready to read.
- **void reset()** set internal state to start condition.
- **bool is_ready()** checks if load cell is ready to read.
- **void wait_ready(uint32_t ms = 0)** wait until ready, check every ms.
- **bool wait_ready_retry(uint8_t retries = 3, uint32_t ms = 0)** wait max retries.
- **bool wait_ready_timeout(uint32_t timeout = 1000, uint32_t ms = 0)** wait max timeout.
Expand All @@ -66,7 +81,8 @@ The weight alpha can be set to any value between 0 and 1, times >= 1.
#### Gain

read datasheet - see also Connections HX711 below
- **void set_gain(uint8_t gain = 128)** values: 128 (default), 64 32 - only 128 tested & verified

- **void set_gain(uint8_t gain = 128)** values: 128 (default), 64 32 - only 128 tested & verified.
- **uint8_t get_gain()** returns set gain.


Expand All @@ -78,10 +94,10 @@ In median and medavg mode only 3..15 samples are allowed.
- **void set_median_mode()**
- **void set_medavg_mode()**
- **void set_runavg_mode()** default alpha = 0.5.
- **uint8_t get_mode()**
- **uint8_t get_mode()**


#### GET VALUES
#### Get values

get values corrected for offset and scale

Expand All @@ -93,7 +109,7 @@ get values corrected for offset and scale
- **long get_offset()** idem.


#### TARE & CALIBRATION
#### Tare & calibration

Steps to take for calibration
1. clear the scale
Expand All @@ -109,7 +125,7 @@ Steps to take for calibration
- **void calibrate_scale(uint16_t weight, uint8_t times = 10)** idem.


#### POWER MANAGEMENT
#### Power management

- **void power_down()** idem.
- **void power_up()** idem.
Expand All @@ -130,13 +146,13 @@ For weight conversion functions see https://github.com/RobTillaart/weight
## Notes


### Scale values for loadcells
### Scale values for load cells

These scale values worked pretty well with a set of load-cells,
Use calibrate to find your values.
These scale values worked pretty well with a set of load cells I have,
Use calibrate to find your favourite values.

- 5 KG loadcell scale.set_scale(420.52);
- 20 KG loadcell scale.set_scale(127.15);
- 5 KG load cell scale.set_scale(420.52);
- 20 KG load cell scale.set_scale(127.15);


### Connections HX711
Expand All @@ -147,29 +163,30 @@ Use calibrate to find your values.

### Connections

| HX711 Pin | Color |
|:----:|:----:|
| E+ | red |
| E- | black |
| A- | white |
| A+ | green |
| B- | not connected |
| B+ | not connected |
| HX711 Pin | Colour |
|:---------:|:--------------:|
| E+ | red |
| E- | black |
| A- | white |
| A+ | green |
| B- | not connected |
| B+ | not connected |


| HX711 Pin | Color |
|:----:|:----:|
| E+ | red |
| E- | black |
| A- | blue |
| A+ | white |
| B- | not connected |
| B+ | not connected |
| HX711 Pin | Colour |
|:---------:|:--------------:|
| E+ | red |
| E- | black |
| A- | blue |
| A+ | white |
| B- | not connected |
| B+ | not connected |


### Temperature

Load-cells do have a temperature related error. (check datasheet)

Load cells do have a temperature related error. (check datasheet)
This can be reduced by doing the calibration and take the tare
at the temperature one also uses for the measurements.

Expand All @@ -187,7 +204,8 @@ See examples

- update documentation
- add examples
- test different load-cells
- test different load cells
- optimize the build-in **ShiftIn()** function to improve performance again.


#### the adding scale
Expand Down
13 changes: 9 additions & 4 deletions examples/HX_delta_scale/HX_delta_scale.ino
Expand Up @@ -9,6 +9,7 @@
// 0.1.0 2020-06-16 initial version
//


// to be tested

#include "HX711.h"
Expand All @@ -20,6 +21,7 @@ uint8_t clockPin = 7;

float w1, w2, previous = 0;


void setup()
{
Serial.begin(115200);
Expand All @@ -33,16 +35,17 @@ void setup()
Serial.print("UNITS: ");
Serial.println(scale.get_units(10));

// loadcell factor 20 KG
// load cell factor 20 KG
// scale.set_scale(127.15);
// loadcell factor 5 KG
scale.set_scale(420.0983);
// load cell factor 5 KG
scale.set_scale(420.0983); // TODO you need to calibrate this yourself.
scale.tare();

Serial.print("UNITS: ");
Serial.println(scale.get_units(10));
}


void loop()
{
// read until stable
Expand Down Expand Up @@ -71,4 +74,6 @@ void loop()
delay(100);
}

// END OF FILE

// -- END OF FILE --

6 changes: 5 additions & 1 deletion examples/HX_grocery_scale/HX_grocery_scale.ino
Expand Up @@ -9,6 +9,7 @@
// 0.1.0 2020-06-16 initial version
//


#include "HX711.h"

HX711 scale;
Expand Down Expand Up @@ -54,6 +55,7 @@ void setup()
scale.set_unit_price(0.031415); // we only have one price
}


void loop()
{
Serial.print("UNITS: ");
Expand All @@ -63,4 +65,6 @@ void loop()
delay(250);
}

// END OF FILE

// -- END OF FILE --

9 changes: 7 additions & 2 deletions examples/HX_kitchen_scale/HX_kitchen_scale.ino
Expand Up @@ -9,6 +9,7 @@
// 0.1.0 2020-06-16 initial version
//


#include "HX711.h"

HX711 scale;
Expand Down Expand Up @@ -48,16 +49,20 @@ void setup()
Serial.println(scale.get_units(10));

Serial.println("\nScale is calibrated, press a key to continue");
// Serial.println(scale.get_scale());
// Serial.println(scale.get_offset());
while(!Serial.available());
while(Serial.available()) Serial.read();

}


void loop()
{
Serial.print("UNITS: ");
Serial.println(scale.get_units(10));
delay(250);
}

// END OF FILE

// -- END OF FILE --

0 comments on commit 7683080

Please sign in to comment.