我正试图从串行端口读取(树莓派上的GPS设备)。
按照http://www.modmypi.com/blog/raspberry-pi-gps-hat-and-python中的说明操作
我可以从shell读取
stty -F /dev/ttyAMA0 raw 9600 cs8 clocal -cstopb
cat /dev/ttyAMA0
我得到格式良好的输出
$GNGLL,5133.35213,N,00108.27278,W,160345.00,A,A*65
$GNRMC,160346.00,A,5153.35209,N,00108.27286,W,0.237,,290418,,,A*75
$GNVTG,,T,,M,0.237,N,0.439,K,A*35
$GNGGA,160346.00,5153.35209,N,00108.27286,W,1,12,0.67,81.5,M,46.9,M,,*6C
$GNGSA,A,3,29,25,31,20,26,23,21,16,05,27,,,1.11,0.67,0.89*10
$GNGSA,A,3,68,73,83,74,84,75,85,67,,,,,1.11,0.67,0.89*1D
$GPGSV,4,1,15,04,,,34,05,14,040,21,09,07,330,,16,45,298,34*40
$GPGSV,4,2,15,20,14,127,18,21,59,154,30,23,07,295,26,25,13,123,22*74
$GPGSV,4,3,15,26,76,281,40,27,15,255,20,29,40,068,19,31,34,199,33*7C
$GPGSV,4,4,15,33,29,198,,36,23,141,,49,30,172,*4C
$GLGSV,3,1,11,66,00,325,,67,13,011,20,68,09,062,16,73,12,156,21*60
$GLGSV,3,2,11,74,62,177,20,75,53,312,36,76,08,328,,83,17,046,25*69
$GLGSV,3,3,11,84,75,032,22,85,44,233,32,,,,35*62
$GNGLL,5153.35209,N,00108.27286,W,160346.00,A,A*6C
$GNRMC,160347.00,A,5153.35205,N,00108.27292,W,0.216,,290418,,,A*7E
$GNVTG,,T,,M,0.216,N,0.401,K,A*3D
$GNGGA,160347.00,5153.35205,N,00108.27292,W,1,12,0.67,81.7,M,46.9,M,,*66
$GNGSA,A,3,29,25,31,20,26,23,21,16,05,27,,,1.11,0.67,0.89*10
$GNGSA,A,3,68,73,83,74,84,75,85,67,,,,,1.11,0.67,0.89*1D
$GPGSV,4,1,15,04,,,34,05,14,040,21,09,07,330,,16,45,298,34*40
(我放了一些随机数据进去)
我正在围棋里读这个。目前,我有
package main
import "fmt"
import "log"
import "github.com/tarm/serial"
func main() {
config := &serial.Config{
Name: "/dev/ttyAMA0",
Baud: 9600,
ReadTimeout: 1,
Size: 8,
}
stream, err := serial.OpenPort(config)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1024)
for {
n, err := stream.Read(buf)
if err != nil {
log.Fatal(err)
}
s := string(buf[:n])
fmt.Println(s)
}
}
但这会打印格式错误的数据,我怀疑这是由于缓冲区大小或config
结构体中Size
的值错误,但我不确定如何从stty
设置中获取这些值。
回顾过去,我认为问题在于我得到了一个流,我希望能够迭代stty的行,而不是块。
$GLGSV,3
,1,09,69
,10,017,
,70,43,0
69,,71,3
2,135,27
,76,23,2
32,22*6F
$GLGSV
,3,2,09,
77,35,30
0,21,78,
11,347,,
85,31,08
1,30,86,
72,355,3
6*6C
$G
LGSV,3,3
,09,87,2
4,285,30
*59
$GN
GLL,5153
.34919,N
,00108.2
7603,W,1
92901.00
,A,A*6A
3条答案
按热度按时间6yoyoihd1#
从
serial.OpenPort()
返回的结构体包含一个指针,指向对应于打开的串行端口连接的打开的os.File
。当您从这个Read()
返回时,库将调用底层os.File
上的Read()
。此函数调用的文档为:
Read从文件中最多读取len(B)个字节。它返回读取的字节数和遇到的任何错误。在文件末尾,Read返回0,io.EOF。
这意味着你必须记录读取了多少数据。如果这对你很重要的话,你还必须记录是否有换行符。不幸的是,底层的
*os.File
没有导出,所以你会发现使用bufio.ReadLine()
这样的技巧很困难。修改库并发送一个拉取请求可能是值得的。正如Matthew兰金在评论中指出的,
Port
实现了io.ReadWriter
,因此您可以简单地使用bufio
来逐行读取。cnjp1d6j2#
变更
到
你可能会得到你想要的。或者我误解了这个问题?
vwkv1x7d3#
Michael Hamptom的answer的两个新增功能可能会很有用:
行尾
您可能会收到非换行符分隔文本的数据。
bufio.Scanner
默认使用ScanLines将接收到的数据拆分为行-但您也可以根据默认函数的签名编写自己的行拆分器,并为扫描仪设置它:读卡器关闭
你可能不会收到一个恒定的流,而只是偶尔收到一些字节数据包,如果没有字节到达端口,扫描器会阻塞,你不能直接杀死它,你必须关闭流,这实际上会引发一个错误,为了不阻塞任何外部循环并适当地处理错误,你可以把扫描器 Package 在一个接受上下文的goroutine中,如果上下文被取消,忽略错误,否则转发错误。原则上,这可能类似于
要停止扫描仪,您需要取消上下文并关闭连接: