英文:
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
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论