HX711 - which lib should I use?

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
walterheisenberg
Posts: 6
Joined: Sun Jan 27, 2019 11:50 am

HX711 - which lib should I use?

Post by walterheisenberg » Fri Feb 08, 2019 6:19 am

I connected a HX711 to my ESP32 and want to get it running. After searching the net, I found 2 libraries:

The official one here: https://github.com/SergeyPiskunov/micropython-hx711
Features:
read, on/off, is_ready

and another one:
https://github.com/HowManyOliversAreThe ... mpy-driver
Features:
read, on/off, is_ready, tare, raw_read
In this lib, I had to comment in @micropython.native to get it working on the ESP32

Which one should I use? What do you recommend? Which one is better, faster?
I am new to python programming and microcontrollers, so please give me a hint
The only source I could find in this forum was this thread, which lead me to the second lib
Thx

User avatar
Roberthh
Posts: 2462
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: HX711 - which lib should I use?

Post by Roberthh » Fri Feb 08, 2019 7:05 am

Take the one that works.
I can confuse you a little bit more by pointing at another (of dozens) implementation: https://github.com/robert-hh/hx711-lopy.
The interesting part is the variant which uses SPI. It avoids the basic problem with the HX711 drivers on ESP8266 or ESP32: a low pulse of about 60 µs resets the HX711, leading to a bad result. That is hard to achieve with pin toggling py python code. Using SPI avoids that. The drawback of the SPI implementation is, that you have to define a CLK Pin, which is actually not used. The clock for the HX711 is created with the MOSI pin. I have run that SPI version for few days with 80 samples/sec, and had no invalid reading. The toggle versions had between 2% and 0.1% bad readings.
The version pointed out was made for a Pycom LoPy. Therefore you must adapt the SPI init code at the start of __init__(). There is a lot of non-core methods around, which you might ignore. The most useful of them is the read_lowpass() one, which filters out the noise, better than the read_average() method.

walterheisenberg
Posts: 6
Joined: Sun Jan 27, 2019 11:50 am

Re: HX711 - which lib should I use?

Post by walterheisenberg » Sun Feb 10, 2019 4:45 pm

Thank you for the tips. Everything is up and running without SPI for now.
What is your opinion about this:
Would it be better to replace read() with read_lowpass() in read_average()?
I want to get the average value of 3 lowpass filtered readings.
Thx

Here is another lib with different calculation:
https://github.com/Honey-Pi/rpi-scripts ... 11.py#L331
Do you think this one gives better results and it is worth looking into it?

User avatar
Roberthh
Posts: 2462
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: HX711 - which lib should I use?

Post by Roberthh » Sun Feb 10, 2019 7:29 pm

It adds no value if you replace read() in read_average() with read_lowpass(). If the output of read_lowpass() is still fluctuation too much, change the time constant to a lower value.
The other lib you pointed at looks like bloatware. Practically, it returns what read_average() does, just with much more fuzz around it. And, to make it even worse, it uses the numpy lib - for calculating something trivial as the average and standard deviation.

jstrebel
Posts: 3
Joined: Wed Sep 13, 2017 4:09 pm

Re: HX711 - which lib should I use?

Post by jstrebel » Fri Feb 12, 2021 9:55 am

Hello, I hope somebody could help a beginner.
After my first success to run the I2C version hx711-lopy I tried to use the SPI version of this library (class)
I get the following Error:
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "hx711_spi.py", line 9, in __init__
AttributeError: type object 'SPI' has no attribute 'MASTER'

Your help would be appreciated to helping me to solve the problem. I have difficulty to understand why this code produces this error.
For all what I have googled so far I do not see a difference why this code runs on the ESP8266 but not on ESP32.
My guess is that the ESP32 micropython does not support SPI.Master. How do I get around this?
I am running micropython 1.14 on the ESP32
Thank you Jakob

# https://github.com/robert-hh/hx711-lopy ... /hxtest.py
#
from hx711_spi import *
from utime import ticks_ms, ticks_diff, sleep, sleep_ms
from machine import Pin, SPI, idle

hx = HX711(19,23,5) # spi ports: 19=MISO data, 23= MOSI, clock, 5 chip select (line7)

(this is the code part of hx711_spi.py)

from machine import Pin, SPI, idle


class HX711:
def __init__(self, dout, pd_sck, spi_clk, gain=128):

self.pSCK = Pin(pd_sck, mode=Pin.OUT)
self.pOUT = Pin(dout, mode=Pin.IN, pull=Pin.PULL_DOWN)
self.spi = SPI(0, mode=SPI.MASTER, baudrate=1000000, polarity=0, # (line9)
phase=0, pins=(spi_clk, pd_sck, dout))
Last edited by jstrebel on Fri Feb 12, 2021 11:01 am, edited 1 time in total.

User avatar
Roberthh
Posts: 2462
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: HX711 - which lib should I use?

Post by Roberthh » Fri Feb 12, 2021 10:59 am

drop "mode=SPI.MASTER, ". That is used by the Pycom variant of Micropython, and even there redundant.

The instantiation of SPI should be:

spi = SPI(0, baudrate=1_000_000, polarity=0, phase=0, sck=Pin(5), mosi=Pin(23), miso=Pin(19))

jstrebel
Posts: 3
Joined: Wed Sep 13, 2017 4:09 pm

Re: HX711 - which lib should I use?

Post by jstrebel » Fri Feb 12, 2021 11:35 am

Thank you for your very fast Response. I got a stepp further.

self.spi = SPI(0,baudrate=1000000, polarity=0,
phase=0, sck=Pin(5),mosi=Pin(23),miso=Pin(19))

Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "hx711_spi.py", line 9, in __init__
ValueError: SPI ID must be either HSPI(1) or VSPI(2)

**************************

self.spi = SPI(1,baudrate=1000000, polarity=0,
phase=0, sck=Pin(5),mosi=Pin(23),miso=Pin(19))
Gain & initial value set
Traceback (most recent call last):
File "<stdin>", line 72, in <module>
File "<stdin>", line 21, in run
NameError: name 'temp' isn't defined

*************************************
self.spi = SPI(2,baudrate=1000000, polarity=0,
phase=0, sck=Pin(5),mosi=Pin(23),miso=Pin(19))
Gain & initial value set
Traceback (most recent call last):
File "<stdin>", line 72, in <module>
File "<stdin>", line 21, in run
NameError: name 'temp' isn't defined

User avatar
Roberthh
Posts: 2462
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: HX711 - which lib should I use?

Post by Roberthh » Fri Feb 12, 2021 12:01 pm

The temp is related to the test setup, where I also had connected a DS18B20. Remove everything related to that. I have conected it to my ESP32 now. The code for hxtest is:

Code: Select all

from hx711_spi import *
hx = HX711(19, 23, 5)

from utime import ticks_ms, ticks_diff, sleep, sleep_ms
from machine import Pin

hx.OFFSET = 0 # -150000
hx.set_gain(128)
sleep_ms(50)

data = [0 for _ in range(100)]

def get_median(hx, num=100):
    for _ in range(num):
        data[_] = hx.read()
    data.sort()
    return data[num // 2]

def run(loops = 100):
    start = ticks_ms()
    hx.set_gain(128)
    sleep_ms(50)
    resulta = get_median(hx, loops)
    hx.set_gain(32)
    sleep_ms(50)
    resultb = get_median(hx, loops)
    print(resulta, resultb)

def run100(loops=100, delay = 1):
    for _ in range (loops):
        run(100)
        if delay:
            sleep(delay)

def minmax(loops=10000, raw=True):
    hx.set_gain(128)
    middle = hx.read_average(min(loops, 1000))
    hx.filtered = middle
    middle = abs(middle) - hx.OFFSET
    cnt0003 = 0
    cnt001 = 0
    cnt003 = 0
    cnt010 = 0
    cnt030 = 0
    cnt100 = 0
    cntx = 0
    print ("Mittelwert", middle)
    for _ in range(loops):
        if raw is True:
            val = abs(hx.read()) - hx.OFFSET
        else:
            val = abs(hx.read_lowpass()) - hx.OFFSET
        if middle * (1 - 0.00003) < val < middle * (1 + 0.00003):
            cnt0003 += 1
        elif middle * (1 - 0.0001) < val < middle * (1 + 0.0001):
            cnt001 += 1
        elif middle * (1 - 0.0003) < val < middle * (1 + 0.0003):
            cnt003 += 1
        elif middle * (1 - 0.001) < val < middle * (1 + 0.001):
            cnt010 += 1
        elif middle * (1 - 0.003) < val < middle * (1 + 0.003):
            cnt030 += 1
        elif middle * (1 - 0.01) < val < middle * (1 + 0.01):
            cnt100 += 1
        else:
            cntx += 1
            print("Really out of band at %d: %d %x"  % (_, int(val), int(val)))

    print("+/- 0.003%% %f\n+/- 0.01%% %f\n+/- 0.03%% %f\n+/- .1%%   %f\n+/- .3%%   %f\n+/- 1%%  %f\nBeyond:  %f" %
          (cnt0003/loops, cnt001/loops, cnt003/loops, cnt010/loops, cnt030/loops, cnt100/loops, cntx/loops))


run()
# minmax(10000)

jstrebel
Posts: 3
Joined: Wed Sep 13, 2017 4:09 pm

Re: HX711 - which lib should I use?

Post by jstrebel » Fri Feb 12, 2021 12:19 pm

Thank you Robert it worked.
It was my stupidity not looking a the consequences when I removed the temperature part in the hxtest Shame on me.
Great help /J

hgrbirchall
Posts: 3
Joined: Sun Feb 14, 2021 6:45 pm
Location: London, UK

Re: HX711 - which lib should I use?

Post by hgrbirchall » Sun Feb 14, 2021 7:02 pm

Robert

I have just been following through your example programme on the LoPy4, which I got running without too much issue.

I was wanting to run the same programme on the Raspberry Pi Pico, but it threw an exception that the maching.idle module does not exist within the micropython port for the Pico. I was wondering if you had a work around for it?

Thanks in advance

Hugh

Post Reply