Skip to content

Instantly share code, notes, and snippets.

@amotl
Last active June 19, 2019 23:23
Show Gist options
  • Select an option

  • Save amotl/94c83f3ecc3dbf181da708fdd8ef9f45 to your computer and use it in GitHub Desktop.

Select an option

Save amotl/94c83f3ecc3dbf181da708fdd8ef9f45 to your computer and use it in GitHub Desktop.
Reading the HX711 using SPI

Author: robert-hh, @robert-hh

Source: https://forum.micropython.org/viewtopic.php?f=16&t=2678&start=10#p29735

For interest, I also made a driver using SPI. In that case, MOSI is used as the clock signal. The SPI clock signal is not used. It was made for a LoPy, so it will not immediately run on other MicroPython hardware, YMMV. The interesting parts are the data structures for clock and the lookup table for fast transformation.

The reason for using SPI was, that the ESP32 - just like the ESP8266 - is not good at fast toggling and reading, eventually not matching the timing requirements of the HX711. Using SPI ensures fast timing.

class HX711:
"""
Use SPI for ensuring appropriate timing when reading the HX711.
The ESP32 - just like the ESP8266 - is not good at fast toggling and reading
of general i/o ports, eventually not matching the timing requirements of
the HX711. Using SPI ensures fast timing.
Source: https://forum.micropython.org/viewtopic.php?f=16&t=2678&start=10#p29735
"""
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, phase=0, pins=(spi_clk, pd_sck, dout))
self.pSCK(0)
self.clock_25 = b'\xaa\xaa\xaa\xaa\xaa\xaa\x80'
self.clock_26 = b'\xaa\xaa\xaa\xaa\xaa\xaa\xa0'
self.clock_27 = b'\xaa\xaa\xaa\xaa\xaa\xaa\xa8'
self.clock = self.clock_25
self.lookup = (b'\x00\x01\x00\x00\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x04\x05\x00\x00\x06\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x08\x09\x00\x00\x0a\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x0c\x0d\x00\x00\x0e\x0f')
self.in_data = bytearray(7)
self.set_gain(gain);
def set_gain(self, gain):
if gain is 128:
self.clock = self.clock_25
elif gain is 64:
self.clock = self.clock_27
elif gain is 32:
self.clock = self.clock_26
self.read()
def read(self):
# wait for the device to get ready
while self.pOUT() != 0:
idle()
# get the data and set channel and gain
self.spi.write_readinto(self.clock, self.in_data)
# pack the data into a single value
result = 0
for _ in range (6):
result = (result << 4) + self.lookup[self.in_data[_] & 0x55]
# return sign corrected result
return result - ((result & 0x800000) << 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment