How to read data from serial and process it when a specific delimiter is found

huangapple go评论76阅读模式
英文:

How to read data from serial and process it when a specific delimiter is found

问题

我有一个设备,它持续通过串口发送数据。
现在我想读取并处理这些数据。
数据使用分隔符"!"发送,
一旦出现这个分隔符,我想要暂停读取以处理已经接收到的数据。
我该如何做到这一点?是否有任何文档或示例可以供我阅读或参考?

英文:

I have a device, which continues to send data over a serial port.
Now I want to read this and process it.
The data send this delimiter "!" and
as soon as this delimiter appears I want to pause reading to processing the data thats already been received.
How can I do that? Is there any documentation or examples that I can read or follow.

答案1

得分: 1

从串口读取数据,你可以在Github上找到一些包,例如tarm/serial

你可以使用这个包从串口读取数据。为了读取到特定的分隔符,你可以使用以下代码:

config := &serial.Config{Name: "/dev/ttyUSB", Baud: 9600}

s, err := serial.OpenPort(config)
if err != nil {
    // 停止执行
    log.Fatal(err)
}

// Golang的读取器接口
r := bufio.NewReader(s)

// 读取直到达到分隔符
data, err := r.ReadBytes('\x21')
if err != nil {
    // 停止执行
    log.Fatal(err)
}
// 或者使用 fmt.Printf() 和正确的占位符
// https://golang.org/pkg/fmt/#hdr-Printing
fmt.Println(data)

参考链接:https://stackoverflow.com/questions/17599232/reading-from-serial-port-with-while-loop

英文:

For reading data from a serial port you can find a few packages on Github, e.g. tarm/serial.

You can use this package to read data from your serial port. In order to read until a specific delimiter is reached, you can use something like:

config := &serial.Config{Name: "/dev/ttyUSB", Baud: 9600}

s, err := serial.OpenPort(config)
if err != nil {
    // stops execution
    log.Fatal(err)
}

// golang reader interface
r := bufio.NewReader(s)

// reads until delimiter is reached
data, err := r.ReadBytes('\x21')
if err != nil {
    // stops execution
    log.Fatal(err)
}
// or use fmt.Printf() with the right verb
// https://golang.org/pkg/fmt/#hdr-Printing
fmt.Println(data)

See also: https://stackoverflow.com/questions/17599232/reading-from-serial-port-with-while-loop

答案2

得分: 1

bufio的读取器对我来说不起作用 - 它在一段时间后就会崩溃。这是不可接受的,因为我需要一个稳定的解决方案来应对低性能系统。

我的解决方案是实现这个建议,并进行了一点修改。正如提到的,如果你不使用bufio,每次调用以下代码时缓冲区都会被覆盖:

n, err := s.Read(buf0)

为了解决这个问题,将buf0中的字节追加到第二个缓冲区buf1中:

if n > 0 {
    buf1 = append(buf1, buf0[:n]...)
}

然后解析存储在buf1中的字节。如果找到了你要查找的子集,可以进一步处理它。

  • 确保以适当的方式清除缓冲区
  • 确保限制循环运行的频率(例如使用time.Sleep
英文:

bufio's reader unfortunately did not work for me - it kept crashing after a while. This was a no-go since I needed a stable solution for a low-performance system.

My solution was to implement this suggestion with a small tweak. As noted, if you don't use bufio, the buffer gets overwritten every time you call

n, err := s.Read(buf0)

To fix this, append the bytes from buf0 to a second buffer, buf1:

if n > 0 {
    buf1 = append(buf1, buf0[:n]...)
}

Then parse the bytes stored in buf1. If you find a subset you're looking for, process it further.

  • make sure to clear the buffers in a suitable manner
  • make sure to limit the frequency the loop is running with (e.g. time.Sleep)

huangapple
  • 本文由 发表于 2017年7月16日 03:04:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/45121787.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定