diff --git a/.gitignore b/.gitignore index 620d3dc..e66e203 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,10 @@ *.lai *.la *.a + +# IDE metadata +/.idea + +# PlatformIO virtualenv and pioenv +/.venv* +/.pioenvs diff --git a/.travis.yml b/.travis.yml index 6e17bee..39935f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,10 @@ cache: directories: - "~/.platformio" -env: - - PLATFORMIO_CI_SRC=examples/HX711Serial - - PLATFORMIO_CI_SRC=examples/HX711SerialBegin - install: - pip install -U platformio script: - - platformio ci --board=megaatmega2560 --lib="." + - platformio ci --board=megaatmega2560 --lib="." examples/HX711_full_example + - platformio ci --board=megaatmega2560 --lib="." examples/HX711_timeout_example + - platformio run diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..93af465 --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,20 @@ +# HX711 library contributors + +Listed in the order of appearance. + +- Weihong Guan: First steps +- Bogdan Necula: Making it real +- Zachary J. Fields: Performance improvements on AVR. Simplify read logic. +- Rodrigo Wirth: Support to read the current `get_offset` and `get_scale` +- Ulrich Wolf: Move pin definition out of constructor +- Alexander Wilms: Improve documentation +- David Holland-Moritz: Improve interrupt safety on AVR +- Geert Roumen et al.: ESP32 support +- Thomas O Fredericks: Support for Teensy 3.2 and non-blocking readings +- Ahmad Elbadri: Improve ESP8266 stability +- Andreas Motl: Bookkeeping, multiarch support +- The Hiveeyes Developers: Spring-cleaning 2019 +- Many bits and pieces by countless people from the community, + see also "doc/backlog.rst" in the repository. + +Thanks a bunch! diff --git a/HX711.cpp b/HX711.cpp index c3f67cc..2cfcbaa 100644 --- a/HX711.cpp +++ b/HX711.cpp @@ -1,19 +1,66 @@ +/** + * + * HX711 library for Arduino + * https://github.com/bogde/HX711 + * + * MIT License + * (c) 2018 Bogdan Necula + * +**/ #include #include -#ifndef ESP8266 - #if ARDUINO_VERSION <= 106 - // "yield" is not implemented as noop in older Arduino Core releases, so let's define it. - // See also: https://stackoverflow.com/questions/34497758/what-is-the-secret-of-the-arduino-yieldfunction/34498165#34498165 - void yield(void) {}; - #endif +// TEENSYDUINO has a port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3. +#define HAS_ATOMIC_BLOCK (defined(ARDUINO_ARCH_AVR) || defined(TEENSYDUINO)) + +// Whether we are running on either the ESP8266 or the ESP32. +#define ARCH_ESPRESSIF (defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)) + +// Whether we are actually running on FreeRTOS. +#define IS_FREE_RTOS defined(ARDUINO_ARCH_ESP32) + +// Define macro designating whether we're running on a reasonable +// fast CPU and so should slow down sampling from GPIO. +#define FAST_CPU \ + ( \ + ARCH_ESPRESSIF || \ + defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || \ + defined(ARDUINO_ARCH_STM32) || defined(TEENSYDUINO) \ + ) + +#if HAS_ATOMIC_BLOCK +// Acquire AVR-specific ATOMIC_BLOCK(ATOMIC_RESTORESTATE) macro. +#include #endif -HX711::HX711(byte dout, byte pd_sck, byte gain) { - #ifndef ESP8266 - begin(dout, pd_sck, gain); - #endif +#if FAST_CPU +// Make shiftIn() be aware of clockspeed for +// faster CPUs like ESP32, Teensy 3.x and friends. +// See also: +// - https://github.com/bogde/HX711/issues/75 +// - https://github.com/arduino/Arduino/issues/6561 +// - https://community.hiveeyes.org/t/using-bogdans-canonical-hx711-library-on-the-esp32/539 +uint8_t shiftInSlow(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) { + uint8_t value = 0; + uint8_t i; + + for(i = 0; i < 8; ++i) { + digitalWrite(clockPin, HIGH); + delayMicroseconds(1); + if(bitOrder == LSBFIRST) + value |= digitalRead(dataPin) << i; + else + value |= digitalRead(dataPin) << (7 - i); + digitalWrite(clockPin, LOW); + delayMicroseconds(1); + } + return value; } +#define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftInSlow(data,clock,order) +#else +#define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftIn(data,clock,order) +#endif + HX711::HX711() { } @@ -53,27 +100,74 @@ void HX711::set_gain(byte gain) { } long HX711::read() { - // wait for the chip to become ready - while (!is_ready()) { - // Will do nothing on Arduino but prevent resets of ESP8266 (Watchdog Issue) - yield(); - } + // Wait for the chip to become ready. + wait_ready(); + + // Define structures for reading data into. unsigned long value = 0; uint8_t data[3] = { 0 }; uint8_t filler = 0x00; - // pulse the clock pin 24 times to read the data - data[2] = shiftIn(DOUT, PD_SCK, MSBFIRST); - data[1] = shiftIn(DOUT, PD_SCK, MSBFIRST); - data[0] = shiftIn(DOUT, PD_SCK, MSBFIRST); + // Protect the read sequence from system interrupts. If an interrupt occurs during + // the time the PD_SCK signal is high it will stretch the length of the clock pulse. + // If the total pulse time exceeds 60 uSec this will cause the HX711 to enter + // power down mode during the middle of the read sequence. While the device will + // wake up when PD_SCK goes low again, the reset starts a new conversion cycle which + // forces DOUT high until that cycle is completed. + // + // The result is that all subsequent bits read by shiftIn() will read back as 1, + // corrupting the value returned by read(). The ATOMIC_BLOCK macro disables + // interrupts during the sequence and then restores the interrupt mask to its previous + // state after the sequence completes, insuring that the entire read-and-gain-set + // sequence is not interrupted. The macro has a few minor advantages over bracketing + // the sequence between `noInterrupts()` and `interrupts()` calls. + #if HAS_ATOMIC_BLOCK + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + + #elif IS_FREE_RTOS + // Begin of critical section. + // Critical sections are used as a valid protection method + // against simultaneous access in vanilla FreeRTOS. + // Disable the scheduler and call portDISABLE_INTERRUPTS. This prevents + // context switches and servicing of ISRs during a critical section. + portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL(&mux); + + #else + // Disable interrupts. + noInterrupts(); + #endif + + // Pulse the clock pin 24 times to read the data. + data[2] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); + data[1] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); + data[0] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST); - // set the channel and the gain factor for the next reading using the clock pin + // Set the channel and the gain factor for the next reading using the clock pin. for (unsigned int i = 0; i < GAIN; i++) { digitalWrite(PD_SCK, HIGH); + #if ARCH_ESPRESSIF + delayMicroseconds(1); + #endif digitalWrite(PD_SCK, LOW); + #if ARCH_ESPRESSIF + delayMicroseconds(1); + #endif } + #if IS_FREE_RTOS + // End of critical section. + portEXIT_CRITICAL(&mux); + + #elif HAS_ATOMIC_BLOCK + } + + #else + // Enable interrupts again. + interrupts(); + #endif + // Replicate the most significant bit to pad out a 32-bit signed integer if (data[2] & 0x80) { filler = 0xFF; @@ -90,11 +184,52 @@ long HX711::read() { return static_cast(value); } +void HX711::wait_ready(unsigned long delay_ms) { + // Wait for the chip to become ready. + // This is a blocking implementation and will + // halt the sketch until a load cell is connected. + while (!is_ready()) { + // Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP. + // https://github.com/bogde/HX711/issues/73 + delay(delay_ms); + } +} + +bool HX711::wait_ready_retry(int retries, unsigned long delay_ms) { + // Wait for the chip to become ready by + // retrying for a specified amount of attempts. + // https://github.com/bogde/HX711/issues/76 + int count = 0; + while (count < retries) { + if (is_ready()) { + return true; + } + delay(delay_ms); + count++; + } + return false; +} + +bool HX711::wait_ready_timeout(unsigned long timeout, unsigned long delay_ms) { + // Wait for the chip to become ready until timeout. + // https://github.com/bogde/HX711/pull/96 + unsigned long millisStarted = millis(); + while (millis() - millisStarted < timeout) { + if (is_ready()) { + return true; + } + delay(delay_ms); + } + return false; +} + long HX711::read_average(byte times) { long sum = 0; for (byte i = 0; i < times; i++) { sum += read(); - yield(); + // Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP. + // https://github.com/bogde/HX711/issues/73 + delay(0); } return sum / times; } diff --git a/HX711.h b/HX711.h index 23b2234..9814891 100644 --- a/HX711.h +++ b/HX711.h @@ -1,3 +1,12 @@ +/** + * + * HX711 library for Arduino + * https://github.com/bogde/HX711 + * + * MIT License + * (c) 2018 Bogdan Necula + * +**/ #ifndef HX711_h #define HX711_h @@ -17,23 +26,28 @@ class HX711 float SCALE = 1; // used to return weight in grams, kg, ounces, whatever public: - // define clock and data pin, channel, and gain factor - // channel selection is made by passing the appropriate gain: 128 or 64 for channel A, 32 for channel B - // gain: 128 or 64 for channel A; channel B works with 32 gain factor only - HX711(byte dout, byte pd_sck, byte gain = 128); HX711(); virtual ~HX711(); - // Allows to set the pins and gain later than in the constructor + // Initialize library with data output pin, clock input pin and gain factor. + // Channel selection is made by passing the appropriate gain: + // - With a gain factor of 64 or 128, channel A is selected + // - With a gain factor of 32, channel B is selected + // The library default is "128" (Channel A). void begin(byte dout, byte pd_sck, byte gain = 128); - // check if HX711 is ready + // Check if HX711 is ready // from the datasheet: 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. bool is_ready(); + // Wait for the HX711 to become ready + void wait_ready(unsigned long delay_ms = 0); + bool wait_ready_retry(int retries = 3, unsigned long delay_ms = 0); + bool wait_ready_timeout(unsigned long timeout = 1000, unsigned long delay_ms = 0); + // set the gain factor; takes effect only after a call to read() // channel A can be set for a 128 or 64 gain; channel B has a fixed 32 gain // depending on the parameter, the channel is also set to either A or B diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3e82788 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ +# ============ +# Main targets +# ============ + + +# ------------- +# Configuration +# ------------- + +$(eval venvpath := .venv2) +$(eval pip := $(venvpath)/bin/pip) +$(eval python := $(venvpath)/bin/python) +$(eval platformio := $(venvpath)/bin/platformio) + +# Setup Python virtualenv +setup-virtualenv: + @test -e $(python) || `command -v virtualenv` --python=python2 --no-site-packages $(venvpath) + + +# ---------- +# PlatformIO +# ---------- + +install-platformio: setup-virtualenv + @$(pip) install platformio --quiet + +build-all: install-platformio + @$(platformio) run + +build-env: install-platformio + @$(platformio) run --environment $(environment) + + +# Note: This are legacy build targets, the new ones are defined through `platformio.ini`. + +ci-all: install-platformio + # atmelavr + $(platformio) ci --board=megaatmega2560 --lib="." examples/HX711_basic_example + $(platformio) ci --board=megaatmega2560 --lib="." examples/HX711_timeout_example + $(platformio) ci --board=megaatmega2560 --lib="." examples/HX711_full_example + + # atmelavr + $(MAKE) ci-basic board=feather328p + + # espressif8266 + $(MAKE) ci-basic board=huzzah + + # espressif32 + $(MAKE) ci-basic board=lopy4 + + # atmelsam + $(MAKE) ci-basic board=adafruit_feather_m0 + $(MAKE) ci-basic board=adafruit_feather_m4 + + # bluepill + $(MAKE) ci-basic board=bluepill_f103c8 + +ci-basic: + $(platformio) ci --board=$(board) --lib="." examples/HX711_basic_example --verbose + +clean: + platformio run -t clean diff --git a/README.md b/README.md index db587f1..c384c07 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,177 @@ -HX711 -===== +# HX711 +An Arduino library to interface the [Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC)] for Weight Scales. -An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for Weight Scales. +It supports the platforms `atmelavr`, `espressif8266`, `espressif32`, +`atmelsam` and `ststm32` by corresponding [PlatformIO] build environments. -This is my humble attempt at creating an Arduino library for this ADC: -http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf +[Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC)]: http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf +[PlatformIO]: https://platformio.org/ -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: +## Synopsis +```c++ +#include "HX711.h" +HX711 loadcell; -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. +// 1. HX711 circuit wiring +const int LOADCELL_DOUT_PIN = 2; +const int LOADCELL_SCK_PIN = 3; -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. +// 2. Adjustment settings +const long LOADCELL_OFFSET = 50682624; +const long LOADCELL_DIVIDER = 5895655; -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. +// 3. Initialize library +loadcell.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); +loadcell.set_scale(LOADCELL_DIVIDER); +loadcell.set_offset(LOADCELL_OFFSET); -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. +// 4. Acquire reading +Serial.print("Weight: "); +Serial.println(loadcell.get_units(10), 2); +``` -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. +For non-blocking mode, use: +``` +// 4. Acquire reading without blocking +if (scale.wait_ready_timeout(1000)) { + long reading = loadcell.get_units(10); + Serial.print("Weight: "); + Serial.println(reading, 2); +} else { + Serial.println("HX711 not found."); +} +``` -# 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. +## More examples +See `examples` directory in this repository. + + +## HAL support +- [Arduino AVR core](https://github.com/arduino/ArduinoCore-avr) +- [Arduino core for ESP8266](https://github.com/esp8266/Arduino) +- [Arduino core for ESP32](https://github.com/espressif/arduino-esp32) +- [Arduino core for SAMD21](https://github.com/arduino/ArduinoCore-samd) (untested) +- [Arduino core for SAMD51](https://github.com/adafruit/ArduinoCore-samd) (untested) +- [Arduino core for STM32](https://github.com/stm32duino/Arduino_Core_STM32) + + +## Hardware support +The library has been tested successfully on the following hardware. Thanks, Bogdan! +- Arduino Uno ([ATmega328]) +- WeMos D1 mini ([ESP8266]) +- ESP32 DEVKIT V1 ([ESP32]) +- STM32F103C8T6 STM32 Blue Pill Board ([STM32 F1], [Cortex-M3]) + +[ATmega328]: https://en.wikipedia.org/wiki/ATmega328 +[ESP8266]: https://en.wikipedia.org/wiki/ESP8266 +[ESP32]: https://en.wikipedia.org/wiki/ESP32 +[STM32 F1]: https://en.wikipedia.org/wiki/STM32#STM32_F1 +[Cortex-M3]: https://en.wikipedia.org/wiki/ARM_Cortex-M#Cortex-M3 + + +## Features +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()`. + + This function is also called from the initializer method `begin()`. + +4. 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 load cell +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 example in examples/HX711SerialBegin. Please don't use examples/HX711Serial anymore. It is deprecated because the pin definition within the constructor -is not timing safe. (#29) + +## Deprecation warning +This library received some spring-cleaning in February 2019, removing +the pin definition within the constructor completely, as this was not +timing safe. (#29) Please use the new initialization flavor as outlined +in the example above. + + +## Build + +### All architectures +This will spawn a Python virtualenv in the current directory, +install `platformio` into it and then execute `platformio run`. +effectively running all targets defined in `platformio.ini`. + + make build-all + +#### Result +``` +Environment feather_328 [SUCCESS] +Environment atmega_2560 [SUCCESS] +Environment huzzah [SUCCESS] +Environment lopy4 [SUCCESS] +Environment teensy31 [SUCCESS] +Environment teensy36 [SUCCESS] +Environment feather_m0 [SUCCESS] +Environment arduino_due [SUCCESS] +Environment feather_m4 [SUCCESS] +Environment bluepill [SUCCESS] +``` + +#### Details +https://gist.github.com/amotl/5ed6b3eb1fcd2bc78552b218b426f6aa + + +### Specific environment + + # Build for LoPy4 + make build-env environment=lopy4 + + # Build for Feather M0 + make build-env environment=feather_m0 + + +## Credits +Thanks to Weihong Guan who started the first version of this library in 2012 +already (see [[arduino|module]Hx711 electronic scale kit](http://aguegu.net/?p=1327), +[sources](https://github.com/aguegu/ardulibs/tree/master/hx711)), Bogdan Necula +who took over in 2014 and last but not least all others who contributed to this +library over the course of the last years, see also `CONTRIBUTORS.rst` in this +repository. + +### See also +- https://item.taobao.com/item.htm?id=18121631630 +- https://item.taobao.com/item.htm?id=544769386300 + + +## Similar libraries + +There are other libraries around, enjoy: + +- https://github.com/olkal/HX711_ADC +- https://github.com/queuetue/Q2-HX711-Arduino-Library diff --git a/doc/backlog.md b/doc/backlog.md new file mode 100644 index 0000000..c6b6bfb --- /dev/null +++ b/doc/backlog.md @@ -0,0 +1,60 @@ +# HX711 library issue summary + + +## Miscellaneous +- [o] Get library into https://www.arduinolibraries.info/ and https://platformio.org/ +- [o] Maybe use constructor-based initialization again? +- [o] Unify critical sections / interrupt disabling between platforms? + https://github.com/esp8266/Arduino/issues/2218 +- [o] Q: Would `delay(1)` be better than `delay(0)`? + A: even delay(0) will work. Should be as often as you can spare, but not more than 100ms let's say + -- https://github.com/esp8266/Arduino/issues/2240#issuecomment-230874704 +- [o] Pulling all together + https://github.com/hiveeyes/HX711/tree/spring-cleaning +- [o] Drop a line at https://github.com/aguegu/ardulibs/issues/3 re. support for Arduino Due + + +## AVR +- [x] AVR interrupt safety + https://github.com/bogde/HX711/pull/62 + + + +## ARM/SAMD + +### Teensy 3.x +- [x] Thomas O Fredericks + https://github.com/bogde/HX711/pull/96 + + +## Espressif + +### ESP8266 arch pragma / yield definition woes +- [x] https://github.com/bogde/HX711/issues/119 +- [x] https://github.com/bogde/HX711/issues/114 + +### ESP8266 constructor initialization freezes +- [x] https://github.com/bogde/HX711/issues/29 +- [x] https://github.com/bogde/HX711/pull/40 +- [x] https://github.com/bogde/HX711/pull/113 +- [x] https://github.com/bogde/HX711/pull/53 +- [x] https://github.com/bogde/HX711/pull/122 +- [x] https://github.com/bogde/HX711/issues/89 + +### ESP8266 WDT +- [x] https://github.com/bogde/HX711/issues/73 +- [x] https://github.com/bogde/HX711/pull/81 +- [x] https://github.com/bogde/HX711/pull/86 +- [x] https://github.com/bogde/HX711/issues/120 +- [x] https://github.com/bogde/HX711/issues/101 + +### ESP8266 lacking pin mapping +- [x] https://github.com/bruhautomation/ESP-MQTT-JSON-Multisensor/issues/14 +- [x] https://github.com/witnessmenow/simple-arduino-crypto-display/issues/2 +- [x] https://github.com/wemos/D1_mini_Examples/issues/21 +- [x] https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h + + +### ESP32 too fast +- [x] https://github.com/lemio/HX711 +- [x] https://github.com/bogde/HX711/issues/75 diff --git a/doc/platformio-howto.md b/doc/platformio-howto.md new file mode 100644 index 0000000..7557689 --- /dev/null +++ b/doc/platformio-howto.md @@ -0,0 +1,39 @@ +# PlatformIO howto + +https://platformio.org/ + + +List installed platforms + + platformio platform list + + +List available boards + + platformio boards + + +Run specific build + + platformio ci --board=megaatmega2560 --lib="." examples/HX711_full_example + + +Run specific environment + + platformio run --environment lopy4 + + +Build all environments + + platformio run + +"Make clean" for all environments + + platformio run -t clean + + +Dump specific build environment + + platformio run --environment lopy4 --target envdump + +See slot `CPPDEFINES`. diff --git a/examples/HX711ESP8266/HX711ESP8266.ino b/examples/HX711ESP8266/HX711ESP8266.ino deleted file mode 100644 index 3d2022b..0000000 --- a/examples/HX711ESP8266/HX711ESP8266.ino +++ /dev/null @@ -1,58 +0,0 @@ -#include "HX711.h" - -// HX711.DOUT - pin #D2 -// HX711.PD_SCK - pin #D3 - -HX711 scale(D2, D3); // parameter "gain" is ommited; the default value 128 is used by the library - -void setup() { - Serial.begin(38400); - // usually the begin method is called by the class builder but in case of esp8266 must be called explicitly in the setup - scale.begin(D2,D3); //esp specific statment - Serial.println("HX711 Demo"); - - 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(); -} \ No newline at end of file diff --git a/examples/HX711_basic_example/HX711_basic_example.ino b/examples/HX711_basic_example/HX711_basic_example.ino new file mode 100644 index 0000000..3ccca60 --- /dev/null +++ b/examples/HX711_basic_example/HX711_basic_example.ino @@ -0,0 +1,26 @@ +#include "HX711.h" + +// HX711 circuit wiring +const int LOADCELL_DOUT_PIN = 2; +const int LOADCELL_SCK_PIN = 3; + +HX711 scale; + +void setup() { + Serial.begin(57600); + scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); +} + +void loop() { + + if (scale.is_ready()) { + long reading = scale.read(); + Serial.print("HX711 reading: "); + Serial.println(reading); + } else { + Serial.println("HX711 not found."); + } + + delay(1000); + +} diff --git a/examples/HX711SerialBegin/HX711SerialBegin.ino b/examples/HX711_full_example/HX711_full_example.ino similarity index 75% rename from examples/HX711SerialBegin/HX711SerialBegin.ino rename to examples/HX711_full_example/HX711_full_example.ino index 6963afa..ed39e25 100644 --- a/examples/HX711SerialBegin/HX711SerialBegin.ino +++ b/examples/HX711_full_example/HX711_full_example.ino @@ -1,5 +1,20 @@ +/** + * + * HX711 library for Arduino - example file + * https://github.com/bogde/HX711 + * + * MIT License + * (c) 2018 Bogdan Necula + * +**/ #include "HX711.h" + +// HX711 circuit wiring +const int LOADCELL_DOUT_PIN = 2; +const int LOADCELL_SCK_PIN = 3; + + HX711 scale; void setup() { @@ -7,10 +22,14 @@ void setup() { 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); + + // Initialize library with data output pin, clock input pin and gain factor. + // Channel selection is made by passing the appropriate gain: + // - With a gain factor of 64 or 128, channel A is selected + // - With a gain factor of 32, channel B is selected + // By omitting the gain factor parameter, the library + // default "128" (Channel A) is used here. + scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); Serial.println("Before setting up the scale:"); Serial.print("read: \t\t"); diff --git a/examples/HX711_retry_example/HX711_retry_example.ino b/examples/HX711_retry_example/HX711_retry_example.ino new file mode 100644 index 0000000..659a3f2 --- /dev/null +++ b/examples/HX711_retry_example/HX711_retry_example.ino @@ -0,0 +1,26 @@ +#include "HX711.h" + +// HX711 circuit wiring +const int LOADCELL_DOUT_PIN = 2; +const int LOADCELL_SCK_PIN = 3; + +HX711 scale; + +void setup() { + Serial.begin(57600); + scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); +} + +void loop() { + + if (scale.wait_ready_retry(10)) { + long reading = scale.read(); + Serial.print("HX711 reading: "); + Serial.println(reading); + } else { + Serial.println("HX711 not found."); + } + + delay(1500); + +} diff --git a/examples/HX711_timeout_example/HX711_timeout_example.ino b/examples/HX711_timeout_example/HX711_timeout_example.ino new file mode 100644 index 0000000..5e9a669 --- /dev/null +++ b/examples/HX711_timeout_example/HX711_timeout_example.ino @@ -0,0 +1,26 @@ +#include "HX711.h" + +// HX711 circuit wiring +const int LOADCELL_DOUT_PIN = 2; +const int LOADCELL_SCK_PIN = 3; + +HX711 scale; + +void setup() { + Serial.begin(57600); + scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); +} + +void loop() { + + if (scale.wait_ready_timeout(1000)) { + long reading = scale.read(); + Serial.print("HX711 reading: "); + Serial.println(reading); + } else { + Serial.println("HX711 not found."); + } + + delay(1500); + +} diff --git a/library.json b/library.json index d4c9452..7e2af84 100644 --- a/library.json +++ b/library.json @@ -6,12 +6,15 @@ "type": "git", "url": "https://github.com/bogde/HX711.git" }, - "version": "0.1", + "version": "0.7.1", "exclude": "tests", "examples": "examples/*/*.ino", "frameworks": "arduino", "platforms": [ "atmelavr", - "espressif" + "espressif8266", + "espressif32", + "atmelsam", + "ststm32" ] } diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..d632f5d --- /dev/null +++ b/platformio.ini @@ -0,0 +1,122 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +src_dir = examples/HX711_basic_example +include_dir = . + +[config] +build_flags = + -D VERSION=0.7.1 + -D DEBUG=1 + +src_filter = + +<*> + +<../../*.cpp> + + +[env:feather_328] +platform = atmelavr +framework = arduino +board = feather328p + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:atmega_2560] +platform = atmelavr +framework = arduino +board = megaatmega2560 + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:huzzah] +platform = espressif8266 +framework = arduino +board = huzzah + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:lopy4] +platform = espressif32 +framework = arduino +board = lopy4 + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:teensy31] +platform = teensy +framework = arduino +board = teensy31 + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:teensy36] +platform = teensy +framework = arduino +board = teensy36 + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:feather_m0] +platform = atmelsam +framework = arduino +board = adafruit_feather_m0 + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:arduino_due] +platform = atmelsam +framework = arduino +board = dueUSB + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:feather_m4] +platform = atmelsam +framework = arduino +board = adafruit_feather_m4 + +; Build options +build_flags = ${config.build_flags} +src_filter = ${config.src_filter} + + +[env:bluepill] +platform = ststm32 +framework = arduino +board = bluepill_f103c8 + +; Build options +;build_flags = ${config.build_flags} +src_filter = ${config.src_filter}