使用while循环从串口读取

las*_*ain 7 go

我在Go写了一个简短的程序,通过串口与传感器通信:

package main

import (
    "fmt"
    "github.com/tarm/goserial"
    "time"
)

func main() {
    c := &serial.Config{Name: "/dev/ttyUSB0", Baud: 9600}
    s, err := serial.OpenPort(c)

    if err != nil {
            fmt.Println(err)
    }

    _, err = s.Write([]byte("\x16\x02N0C0 G A\x03\x0d\x0a"))

    if err != nil {
            fmt.Println(err)
    }

    time.Sleep(time.Second/2)

    buf := make([]byte, 40)
    n, err := s.Read(buf)

    if err != nil {
            fmt.Println(err)
    }

    fmt.Println(string(buf[:n]))

    s.Close()
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但在写入端口后,我必须等待大约半秒才能开始读取它.我想使用while循环而不是time.Sleep读取所有传入的数据.我的尝试不起作用:

buf := make([]byte, 40)
n := 0

for {
    n, _ := s.Read(buf)

    if n > 0 {
        break
    }
}

fmt.Println(string(buf[:n]))
Run Code Online (Sandbox Code Playgroud)

我想buf在每次循环传递后都会被覆盖.有什么建议?

Nic*_*ood 10

你的问题是,Read()只要它有一些数据就会返回 - 它不会等待所有的数据.有关详细信息,请参阅io.Reader规范

您想要做的是阅读,直到达到某个分隔符.我不知道你想要使用什么格式,但看起来可能\x0a是结束分隔符.

在这种情况下,你可以使用一个bufio.Reader这样

reader := bufio.NewReader(s)
reply, err := reader.ReadBytes('\x0a')
if err != nil {
    panic(err)
}
fmt.Println(reply)
Run Code Online (Sandbox Code Playgroud)

哪个会在第一个之前读取数据\x0a.

  • 谢谢你的建议。到目前为止,它工作正常,但我仍然必须使用`time.Sleep`,否则我会得到一个`panic: EOF`,因为在读取时缓冲区是空的。(顺便说一句:结束分隔符是`\x03`。在它之后,是两个十六进制字节的校验和。) (2认同)