Closed maurorappa closed 6 years ago
Hi, think this seems to be quiet specific task to me and I think it does not make much sense, to be part of go-gpio, which is IMHO supposed to have only general functionality (similar to wiringPi and others), but I might be wrong.
Regarding the freezing issue, could you be more specific? Provide source code or something and I might be able to help.
I get your point, I'm trying to use this simple code to get frequency of a 440Hz square wave (50% duty cycle) I'm a generating with Arduino. This code freeze my RPi every time I run it (go version go1.11.1 linux/arm on Debian 9.4):
package main
import (
"fmt"
"github.com/stianeikeland/go-rpio"
"os"
"time"
)
var (
S0 = rpio.Pin(7)
)
func main() {
err := rpio.Open()
if err != nil {
fmt.Print(err)
os.Exit(1)
}
S0.Input()
S0.PullUp()
S0.Detect(rpio.FallEdge)
F :=0
c := 0
for c < 100000 {
if S0.EdgeDetected() {
F++
}
time.Sleep(time.Microsecond*10)
c++
}
fmt.Printf("F: %dHz",F)
}
The arduino code is:
void setup() {
}
void loop() {
tone(10, 440);
}
If I use a simple C utility it works perfectly:
/home/pi/freq_count_1 7
Monitoring gpios 7
Sample rate 5 micros, refresh rate 10 deciseconds
g=7 1 (403/411319032)
g=7 410 (410/999442)
g=7 406 (407/1001713)
...
I tested your code (without connecting to arduino, since I don't have any), and it does not freeze.
But there are several flaws in your code.
defer rpio.Close()
should be a present. But that is not the main issue.
Your code does not run for just 1 second as you might expect but much longer, for two reasons.
time.Sleep(0)
.Every loop iteration will take 10us + some noticable overhead.
Consequently, your program runs for 5-20 or even more seconds. This might give an impression that it is frozen.
Is this your case, or does your Pi really completely freeze?
Anyway, try to replace your loop with this code:
timeout := time.After(time.Second)
loop: for {
select {
case <-timeout:
break loop
default:
if S0.EdgeDetected() {
F++
}
}
}
This should give you much better results.
Ok, I'll try tonight. I am aware the code was a bit rudimental, I'm just trying to understand how to make it work!
The test program was still crashing, so I decided to use GDB:
(gdb) break 20 Breakpoint 1 at 0x9cf70: file /root/go/freq2.go, line 20. (gdb) break 21 Breakpoint 2 at 0x9cf80: file /root/go/freq2.go, line 21. (gdb) break 22 Breakpoint 3 at 0x9cf90: file /root/go/freq2.go, line 22. (gdb) break 23 Breakpoint 4 at 0x9cfa8: file /root/go/freq2.go, line 23. (gdb) run Starting program: /root/Go/freq [New LWP 544] [New LWP 545]
Thread 1 "freq" hit Breakpoint 1, main.main () at /root/go/freq2.go:20 20 /root/go/freq2.go: No such file or directory. (gdb) continue Continuing.
Thread 1 "freq" hit Breakpoint 2, main.main () at /root/go/freq2.go:21 21 in /root/go/freq2.go (gdb) continue Continuing.
Thread 1 "freq" hit Breakpoint 3, main.main () at /root/go/freq2.go:22 22 in /root/go/freq2.go (gdb) continue Continuing. CRASH!
Line 22 is:
22 S0.Detect(rpio.FallEdge)
if I run the program without this line, it executes but it doesn't detect any frequency:
Starting frequency detection F: 0
so the question is: Am I using a 'wrong' pin? I changed pin, used the C program and worked, tried the Go program and crashed again.
I'm running out of ideas....any hint?
Some ideas:
Are you using raspbian or some other distro? My raspbian works fine.
Raspbian GNU/Linux 8.0 (jessie)
Linux zero 4.14.74+ #1149 Mon Oct 8 17:26:51 BST 2018 armv6l GNU/Linux
Try to disable SPI interface in sudo raspi-config
.
Is there any reason your go source files are in /root/go
instead of eg. /home/pi/go
?
Are you running your program as root? (You should not have to, but who knows)
The solution mentioned here https://github.com/stianeikeland/go-rpio/issues/35#issuecomment-443115624 should work for you as well.
Hi,
I think it would be very useful if you can add a function which measure the frequency a GPIO pin change status. This will allow to interface with a multitude of sensors. Some examples of implementation in C are here: http://abyz.me.uk/rpi/pigpio/examples.html#C_code Arduino core library has a conceptually similar functio called pulseIn: https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/
I tried to use a loop with pin.EdgeDetected() and a microsecond sleep but my RPI freezes all the time.
Thanks