WaitForEdge generated unexpected results
Opened this issue · 4 comments
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:
- 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)
}
- Run it.
- 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
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.
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?
@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.
Simpler, you can do the following:
go get periph.io/x/host/v3@7540d26b4dc114207d0e5f7603b0f176bf5805dd
No need for a replace statement or checking out locally.