Closed ifree92 closed 4 years ago
Hm, pretty strange. When I do the same but manually using pin.Read() in cycle inside go routine - then no stuck. But stuck only by using EdgeDetected in go routine.
And when I try to put everything inside go routine, then the device is getting stuck immediately after application runs.
go func() {
pin := rpio.Pin(10)
pin.Input()
pin.PullUp()
pin.Detect(rpio.FallEdge)
lastTime := time.Now().UnixNano() / 1000000
for {
if pin.EdgeDetected() {
now := time.Now().UnixNano() / 1000000
diff := now - lastTime
lastTime = now
fmt.Println("Heyhey!", diff)
}
time.Sleep(time.Millisecond * 35)
}
}()
UPD: strange. After reboot the stuck is happening not always after run. The kind of random...
UPD2: for now I'm using this "rakes" to keep it working.
package main
import (
"fmt"
"github.com/stianeikeland/go-rpio"
"log"
"time"
)
// This function getting my device stuck!
func pinWatcher(pinNum uint, ch *chan int64) {
pin := rpio.Pin(pinNum)
pin.Input()
pin.PullUp()
pin.Detect(rpio.FallEdge)
lastTime := time.Now().UnixNano() / 1000000
for {
if pin.EdgeDetected() {
now := time.Now().UnixNano() / 1000000
diff := now - lastTime
lastTime = now
*ch <- diff
}
time.Sleep(time.Millisecond * 35)
}
}
// Plan B for a while...
func pinWatcher2(pinNum uint, ch *chan int64) {
pin := rpio.Pin(pinNum)
pin.Input()
pin.PullUp()
lastTime := time.Now().UnixNano() / 1000000
lastState := rpio.High
for {
state := pin.Read()
if state == rpio.High {
} else if state == rpio.Low {
if lastState == rpio.High {
now := time.Now().UnixNano() / 1000000
diff := now - lastTime
lastTime = now
*ch <- diff
}
}
lastState = state
time.Sleep(time.Millisecond)
}
}
func main() {
err := rpio.Open()
if err != nil {
log.Fatal(err)
}
ch := make(chan struct{})
gpio10pulses := make(chan int64)
go pinWatcher2(uint(27), &gpio10pulses)
go func() {
log.Println("Init reader")
for {
select {
case pin10Diff := <-gpio10pulses:
fmt.Println("Pulse", pin10Diff)
}
}
}()
fmt.Println("init")
<-ch
}
I'm wondering if this could be related how gpio memory is accessed. https://github.com/stianeikeland/go-rpio/blob/a36b96d0b1a40b37017d64875275e7e6312408c7/rpio.go#L634-L637
Are you running as root or regular user? Could you try to run as root if not?
@stianeikeland I have made some experiments. Yes, the stuck possible only if I run application as regular user. With root everything is stable.
But I found one interesting behaviour. If I run firstly with root, but then re-run with regular user - then everything good. Pretty strange
Hi,
I think this is the same issue as #35,
There is already a warning comment in the documentation of EdgeDetect
:
// WARNING: this might make your Pi unresponsive, if this happens, you should either run the code as root,
// or add `dtoverlay=gpio-no-irq` to `/boot/config.txt` and restart your pi,
Problem is that normally the edge events produces interruptions, which are not handles by the system, and after some number of unhandled interruptions the pi freezes.
We are trying to disable the interruptions, but it only works with root:
https://github.com/stianeikeland/go-rpio/blob/a36b96d0b1a40b37017d64875275e7e6312408c7/rpio.go#L383-L387
If you don't call ~EdgeDetect(noEdge)
~ Close()
before your program ends, the interruptions will stay disabled until next restart of your pi, this explains the "interesting" behavior you observed.
@stianeikeland We should probably find some better way to solve this issue.
Yes, that's it. Now everything clear. Thank you for support and help. Basically I don't think this issue is related somehow to the library, more to raspberry workflow. I think the issue might be closed.
And I have faced with one mandatory bug. We are using on our terminals this displays: https://www.waveshare.com/wiki/10.1inch_HDMI_LCD#Driver
The resistive touchscreen is connecting through the GPIO pins. So, when I'm running with sudo my application with edge detection - the touchscreen is not working.
In this case I have to use manual reading inputs, no other solution for me right now. Just FYI, or maybe for someone who will face with the same issue.
Yes, unfortunately, disabling the IRQ may cause some other GPIO libs/drivers to not working. I forgot to mention that.
I'm running this code (just experimenting for now) and after some time (about 1 minute) device is going to be stuck. (I did the same actions with another languages: python, nodejs, but nothing, everything works stable and great, but when running this go application - I have a stuck and need just manually disconnect device from power supply and enable again).
I have Raspberry Pi 3 Model B. Hardware : BCM2835 Revision : a22082
Kernel: 4.19.58-v7+
Distributor ID: Raspbian Description: Raspbian GNU/Linux 10 (buster) Release: 10 Codename: buster