Improving the canonical Arduino HX711 library for ESP8266, ESP32 and beyond

The HX711 is a bit too slow for the ESP32 (or the ESP too fast), here is an advice to
slow down the ESP32 itself to 80 MHz:

2 Likes

Most interesting question: Did you also switch to GitHub - queuetue/Q2-HX711-Arduino-Library: Simple Arduino driver for the HX711 ADC or was it simply the one used in this video?

But besides this… slowing down a CPU in favour of getting reasonable results of a particular sensor because your library seems to behave wrong, can be considered the wrong way - if it is not a small front end processor dedicated to that sensor, but here it isn’t.

A much better approach is to have the used function (here: shiftIn()) be aware of clockspeed, or even better, together with frequency, fine-tune it’s duty cycle. Others have this problem too, and so his fix led into a fork of the Bogde/HX711 lib (currently only two commits ahead of bogde):


This is also an upstream issue, and so @lemio escalated it there:


"Software efficiency halves every 18 months, compensating for Moore’s Law.” - David May’s law

1 Like

…and the ringing of that signal in the video needs taming (though it is not reason of the problem discussed here):

We have used the Arduino HX711 library from “bogde” for a long time and with different boards.

We did some adjustments while switching to the ESP8266 a longer time ago and now the same is needed for the ESP32.

We found some (suboptimal) solutions for this, see inital posting, and also a fork of Bodge’s lib optimized for the ESP32:

I think Lemio’s lib is not compatible with the ESP8266 so it would be nice if we can merge the best of all in the well known bodge lib.

1 Like

Hi Clemens,

good idea, lot’s of people are still struggling with the same issues over and over again, even with ESP8266 and the legacy constructor stuff, which is still available. See also the following issue where we added some notes the other day about an early spring cleanup which is dearly needed.

https://github.com/bogde/HX711/pull/113#issuecomment-456171954

Cheers,
Andreas.

Thanks a bunch! While this is a good start, I always felt this still missed out on the interrupt handling side. Lucky enough, this already got addressed by protecting the sensor reading with a critical section, see disable interrupts when CLOCKing in the same thread.

Good to finally see how you would do this from ESP-IDF userspace:

// Enter critical section. Turn off interrupts.
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mux);

// Do some critical stuff here.
// Please note the ESP32 has two cores, so really every code accessing the
// hardware should be protected by appropriate synchronization mechanisms.

// Leave critical section. Turn on interrupts again.
portEXIT_CRITICAL(&mux);

Please also read this important piece on how to program for the ESP32.

As indicated in the IDF documentation, those calls are not only for disabling interrupts on the ESP32, but also protect from the multi-core concurrent access of the same variable, see ESP-IDF FreeRTOS SMP Changes: Critical Sections & Disabling Interrupts.

See also Protect code when accessing shared resources.

1 Like

In the Facebook group to Side Project: HaniMandl, halbautomatischer Honig-Abfüllbehälter Marc is using the adaption of the HX711.cpp form lemio to get the lib running with the ESP32: HX711/HX711.cpp at master · lemio/HX711 · GitHub

Other people recommaned to use the normal bogde lib https://github.com/bogde/HX711/blob/master/HX711.cpp and remove this section in HX711.cpp

#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
#endif
1 Like

erm… yes. And what should that change, given that this legacy case doesn’t really affect anybody nowadays?
If this conditional matches, the ARDUINO_VERSION has to be revised! ;)

Both conditions will probably evaluate to truthy values when running on ESP32, so this will activate the guard on modern platforms, which is clearly wrong.

As this was introduced (by me, actually) to support ancient ArduinoCore/AVR HALs, we should really get rid of this before even thinking about getting the guard right by applying ARDUINO_VERSION archeology.

Apparently, this pragma already evaluates to true when running on ESP8266, see Solution to ESP8266 wdt issue and "yield()" problem · Issue #73 · bogde/HX711 · GitHub.

Solution

(while completely maintaining backward compatibility)

https://github.com/bogde/HX711/issues/73#issuecomment-374422765

Background

The constant evaluated through the #pragma is actually called ARDUINO and probably was only called ARDUINO_VERSION in the early days, see Solution to ESP8266 wdt issue and "yield()" problem · Issue #73 · bogde/HX711 · GitHub.

Actually, the guard was improved by adding #ifndef ESP8266 only recently, see more stability for ESP8266 by el3ctrician · Pull Request #113 · bogde/HX711 · GitHub. Obviously, this will still not work on ESP32.

@thias had this some day (don’t know what SDK, don’t like to search that… ;)

See also above and…

They already did just that:

I’m curious… is ARDUINO_VERSION actually defined for Arduino boards? I’ve done a text search over every Arduino IDE directory, and then the whole PC, and the only reference to ARDUINO_VERSION that was found was in HX711.cpp. Just to double-check, I plugged in my old Arduino Uno and tried to use ARDUINO_VERSION in some code, but the result was error: 'ARDUINO_VERSION' was not declared in this scope. (This was with a clean install of the Arduino IDE, along with the ESP8266 boards.)

See also:

cargo-culting for too looong… Bp

Hi there,

Just wanted to let you know that we managed to make a start in the dry dock [1] (branch “spring-cleaning”) by pulling in various pieces from the issue tracker of the Arduino HX711 library as well as a fork supporting ESP32 already (@lemio/HX711) as suggested here (thanks, @weef!).

Now, we are looking forward to receive test reports from people owning real hardware. While being at it, we will also be happy to hear about further suggestions. Note: We didn’t even try to compile this yet, so there might be dragons.

With kind regards,
Andreas.

[1] GitHub - hiveeyes/HX711 at spring-cleaning

A short detour…

HX711 library archaeology

While working on Improving the canonical Arduino HX711 library for ESP8266, ESP32 and beyond, we stumbled upon the origins of this well known library used throughout the Arduino community.

Weihong Guan published the first open source implementation of a HX711 driver within his aGuegu’s arduino libraries collection in 2013 already.

image

image


@clemens and @mois probably might know about the roots of this library already, others might enjoy the time travel.

It compiles now for the ESP32 what it not does with this lines!

Just wanted to give you an update about this. We have been able to compile successfully for all of the atmelavr , espressif8266 , espressif32 , atmelsam and ststm32 platforms, but we don’t have any hardware around to conduct further tests.

So, we would like this to get more eyeballs and we will be happy to hear about successful reports from the community running this on real iron, actually on as much as possible things supported by the Arduino framework. Maybe someone of you can afford some minutes if you still have a MCU and a HX711 breakout around on your workbench?

Even if you have moved on to a next generation chip this library could make it work already. We will appreciate your feedback, thanks in advance.

Pull request:

Branch “spring-cleaning”, with changes:

1 Like

I’ve tested the updated library successfully on these guys:

  • Adafruit HUZZAH ESP8266
  • Heltec WiFi Kit 32 (ESP32)
  • Adafruit Feather HUZZAH32 (ESP32)

See also Spring cleaning with multiarch support by amotl · Pull Request #123 · bogde/HX711 · GitHub.

2 Likes

Code is running fine on an Adafruit Feather M0 RFM95 Lora (ATSAMD21G18 Cortex M0) board.

3 Likes

Hi there,

we just wanted to share the news that the revamped revision of the HX711 library by Bogdan Necula has been accepted to be added to the Arduino Library Manager:

As Nathan Seidle states it, this

will help many many people.

Cool thing, thanks to Bogdan and all others who have supported us in this endeavor. Keep up the spirit and have a good weekend.

With kind regards,
Andreas.

References

3 Likes

Aaaannd:


[ I have installed it manually ages ago, so it’s not showing up as installed on this screenshot ]

Very nice and many thanks!!

Btw. it’s a good idea to un-install your probably existing and hand-installed HX711 version and re-install it via the Arduino library manager to get notified about library updates.

  1. Under Windows go to C:\Users\[your-user-name]\Documents\Arduino\libraries and delete the directory HX711-master to uninstall the lib. Afaik there is no way to do this via the Arduino IDE for former *.zip-file installed libs.

  2. Re-install the lib now via the library manager. Open it ia Tools > manage libraries then you will see the library manager window, type HX711 in the searach form and you will get the list as above. Finally klick “install”! Done!

2 Likes