Skip to content
This repository has been archived by the owner on Sep 20, 2023. It is now read-only.

HX711: unstable readings and reading before data is ready #439

Closed
chewr opened this issue Apr 15, 2020 · 2 comments
Closed

HX711: unstable readings and reading before data is ready #439

chewr opened this issue Apr 15, 2020 · 2 comments

Comments

@chewr
Copy link

chewr commented Apr 15, 2020

Describe the bug
The included HX711 driver does not respect the timing specifications described in the datasheet, and generates mostly false readings.

To Reproduce
Steps to reproduce the behavior:

  1. Run program
package main

import (
	"fmt"
	"os"
	"periph.io/x/periph/experimental/devices/hx711"
	"periph.io/x/periph/host"
	"periph.io/x/periph/host/rpi"
	"time"
)

func main() {
	host.Init()
	if err := mainE(); err != nil {
		fmt.Fprintln(os.Stderr, "error:", err)
		os.Exit(1)
	}
}

func mainE() error {
	// HX711 board configured with CLK @ P1_31 and DOUT @ P1_29
	hx, err := hx711.New(rpi.P1_31, rpi.P1_29)
	if err != nil {
		return err
	}

	time.AfterFunc(10*time.Second, func() { hx.Halt() })

	sampleCh := hx.ReadContinuous()
	for s := range sampleCh {
		// observe that many samples are garbage
		fmt.Printf("%8d\n", s.Raw)
	}
	return nil
}
  1. Run it.
  2. See that many samples are garbage. For me, half of all samples is -1; and many samples are suspiciously 2^n - 1.

Expected behavior
The driver should ideally read data when data is ready. In this case we see that samples are occasionally read out as garbage because data isn't ready or DOUT isn't stable.

Platform (please complete the following information):

Additional context
The AviaSC datasheet (https://components101.com/sites/default/files/component_datasheet/HX711%20Datasheet.pdf) provides a timing specification for the HX711. Note that it specifies a minimum of .1us after a falling edge on DOUT before data is ready to be read, and that it additionally specifies that DOUT is not stable until .1us after the rising edge on CLK. Additionally, it expects pulse width on CLK to be at least 1us.

I checked out the driver and first tried to fix this by adding sleeps, but interrupts are too coarse-grained to make .1-100us sleeps meaningful. I replaced sleeps with fine-grained busy waits, and eliminated the readings of -1.

I continued to get odd 2^n - 1 readings, so I replaced the WaitForEdge call in ReadTimeout with a busy wait (for !d.IsReady() {}), and this seems to have eliminated all or almost all of the garbage readings I was getting. I think that this could be evidence of false GPIO edge detection as described in this thread: https://www.raspberrypi.org/forums/viewtopic.php?t=134394.

I have only tested this with one board. I intend to see if I can get better readings the other HX711 boards I have, and potentially with one of those fancy $15 HX711s they sell at Sparkfun if issues persist.

@maruel
Copy link
Contributor

maruel commented Apr 17, 2020

At worst maybe use https://periph.io/x/periph/host/cpu#Nanospin ?

@maruel
Copy link
Contributor

maruel commented May 16, 2021

If you still face issues, Please file a bug at https://github.com/periph/devices. Will close for now as there's no AI.

@maruel maruel closed this as completed May 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants