Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WaitForEdge generated unexpected results #37

Open
zombie-k opened this issue Nov 15, 2023 · 4 comments
Open

WaitForEdge generated unexpected results #37

zombie-k opened this issue Nov 15, 2023 · 4 comments

Comments

@zombie-k
Copy link

Describe the bug
WaitForEdge generated unexpected results,Problems arise when using edge detection for ultrasonic ranging,When the sensor is stationary, the calculated values ​​deviate significantly

To Reproduce
Steps to reproduce the behavior:

  1. Run program
package main

import (
	"fmt"
	"log"
	"periph.io/x/conn/v3/gpio"
	"periph.io/x/conn/v3/gpio/gpioreg"
	"periph.io/x/host/v3"
	"time"
)

var (
	trig gpio.PinIO
	echo gpio.PinIO
)

func Test() {
	if _, err := host.Init(); err != nil {
		log.Fatal(err)
	}

	trig = gpioreg.ByName("23")
	echo = gpioreg.ByName("24")
	trig.Out(gpio.Low)
	echo.In(gpio.PullDown, gpio.BothEdges)

	for {
		test(trig, echo)
		time.Sleep(time.Millisecond* 10)
	}
}

func test(trig gpio.PinIO, echo gpio.PinIO) {
	trig.Out(gpio.Low)
	time.Sleep(time.Microsecond * 2)
	trig.Out(gpio.High)
	time.Sleep(time.Microsecond * 10)
	trig.Out(gpio.Low)

	// Low -> High
	echo.WaitForEdge(time.Second)

	ts := time.Now()
	// High -> Low
	echo.WaitForEdge(time.Second)
	cost := time.Since(ts)
	dis := float32(cost.Nanoseconds()) * 0.000000343 / 2.0 * 100
	fmt.Printf("distance: %vcm\n", dis)
}
  1. Run it.
  2. See error

Expected behavior
The expected result is 180+-cm, but the actual value will be 180+-cm at one time and 8+-cm at another time, and the two will alternate repeatedly. (180+- is the current true value)

Platform (please complete the following information):

  • OS: Raspbian bookworm
  • Board Raspberry Pi 4

Additional context
I have used polling to verify and can get the expected results

@maruel
Copy link
Member

maruel commented Nov 15, 2023

The problem with WaitForEdge() is that the implementation in https://github.com/periph/host/blob/main/sysfs/gpio.go is dependent on sysfs which is sensitive to timing issues from linux.

@zombie-k
Copy link
Author

The problem with WaitForEdge() is that the implementation in https://github.com/periph/host/blob/main/sysfs/gpio.go is dependent on sysfs which is sensitive to timing issues from linux.

The problem with WaitForEdge() is that the implementation in https://github.com/periph/host/blob/main/sysfs/gpio.go is dependent on sysfs which is sensitive to timing issues from linux.

So for my problem, I can only use polling instead of WaitForEdge, right? Or is there any way to avoid this timing-sensitive problem?

@gsexton
Copy link

gsexton commented Sep 28, 2024

@zombie-k A new implementation of GPIO has been created that uses ioctl() interface, and not sysfs. You might try re-testing your code with the HEAD of periph.io/x/host.

You can clone the repo, and in your go.mod file put:

replace periph.io/x/host/v3 v3.8.2 => path to cloned repo

and rebuild it. Note that you'll need to remove any references to sysfs from your code.

@maruel
Copy link
Member

maruel commented Sep 30, 2024

Simpler, you can do the following:

go get periph.io/x/host/v3@7540d26b4dc114207d0e5f7603b0f176bf5805dd

No need for a replace statement or checking out locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants