使用while循环从串口读取

时间:2013-07-11 16:56:53

标签: 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()
}

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

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

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

    if n > 0 {
        break
    }
}

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

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

2 个答案:

答案 0 :(得分:10)

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

您要做的是阅读,直到您达到某个分隔符。我不确切地知道您尝试使用哪种格式,但看起来\x0a可能是结束分隔符。

在这种情况下,您可以使用bufio.Reader这样的

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

在第一个\x0a之前读取数据。

答案 1 :(得分:1)

  

我猜每次循环传递后buf都会被覆盖。有什么建议吗?

是的,每次拨打buf都会覆盖Read()

文件句柄的超时将是我采取的方法。

s, _ := os.OpenFile("/dev/ttyS0", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0666)

t := syscall.Termios{
    Iflag:  syscall.IGNPAR,
    Cflag:  syscall.CS8 | syscall.CREAD | syscall.CLOCAL | syscall.B115200,
    Cc:     [32]uint8{syscall.VMIN: 0, syscall.VTIME: uint8(20)}, //2.0s timeout
    Ispeed: syscall.B115200,
    Ospeed: syscall.B115200,
}

// syscall
syscall.Syscall6(syscall.SYS_IOCTL, uintptr(s.Fd()),
    uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&t)),
    0, 0, 0)

// Send message
n, _ := s.Write([]byte("Test message"))

// Receive reply
for {
    buf := make([]byte, 128)
    n, err = s.Read(buf)
    if err != nil { // err will equal io.EOF
        break
    }
    fmt.Printf("%v\n", string(buf))
}

另请注意,如果没有更多数据读取且没有错误,os.File.Read()将返回错误io.EOFas you can see here.