Golang 从串行读取

标签 go serial-port

我正在尝试从串行端口(Raspberry Pi 上的 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

(我放了一些随机数据)

我正尝试在 Go 中阅读此内容。目前,我有

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 的行,而不是 block 。流是这样输出的:

$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

最佳答案

serial.OpenPort() 返回的结构包含指向打开的 os.File 的指针对应打开的串口连接。当你Read()由此,图书馆调用Read()关于标的os.File .

documentation for this function call是:

Read reads up to len(b) bytes from the File. It returns the number of bytes read and any error encountered. At end of file, Read returns 0, io.EOF.

这意味着您必须跟踪读取了多少数据。如果这对您很重要,您还必须跟踪是否有换行符。不幸的是,潜在的 *os.File不导出,所以你会发现很难使用像 bufio.ReadLine() 这样的技巧.可能值得修改库并发送拉取请求。


正如 Matthew Rankin 在评论中指出的那样,Port工具 io.ReadWriter所以你可以简单地使用 bufio逐行阅读。

    stream, err := serial.OpenPort(config)
    if err != nil {
            log.Fatal(err)
    }

    scanner := bufio.NewScanner(stream)
    for scanner.Scan() {
        fmt.Println(scanner.Text()) // Println will add back the final '\n'
    }
    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }

关于Golang 从串行读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50088669/

相关文章:

go - Fileserver() 总是返回 index.html

c - 如何在 DE2 上通过串口发送数据

PHP - 从 Windows 读取 COM 端口

amazon-web-services - 如何检查 AWS X-Ray 是否已配置

go - 获取子域名

c++ - 如果您可以在 C++ 中将串行数据视为文件,那么 termios 的用途是什么?

usb - 有人在ChibiOS上成功使用过USB转串口库吗?

linux - 我试图通过串口发送一个命令列表,但只有第一行被设备占用,其他的被忽略

go - Go中的可选参数?

go - 将参数传递给 Negroni 中间件