串口通信客户端封装:
package uart
import (
"encoding/hex"
"errors"
"github.com/jacobsa/go-serial/serial"
log "github.com/sirupsen/logrus"
"io"
"strings"
"time"
)
/*
定义串口客户端
*/
type SerialClient struct {
readWriter io.ReadWriteCloser
OutBuffer chan string
PortName string
baudRate uint
}
func NewSerialClient(portName string, baudRate uint) (*SerialClient, error) {
c := &SerialClient{
readWriter: nil,
OutBuffer: make(chan string, 1024),
PortName: portName,
baudRate: baudRate,
}
r, err := c.open(portName, baudRate)
if err != nil {
return nil, err
}
c.readWriter = r
return c, nil
}
func (c *SerialClient) Start() {
for {
buf := make([]byte, 1024)
n, err := c.readWriter.Read(buf)
if err != nil {
if err != io.EOF {
log.Error("Error reading from serial port: ", err)
//尝试重新打开
r, err := c.open(c.PortName, c.baudRate)
if err != nil {
time.Sleep(2 * time.Second)
continue
}
c.readWriter = r
}
continue
}
buf = buf[:n]
res := hex.EncodeToString(buf)
if strings.TrimSpace(res) == "" {
continue
}
log.Info("Rx: ", res)
c.OutBuffer <- res
}
}
func (c *SerialClient) open(portName string, baudRate uint) (io.ReadWriteCloser, error) {
options := serial.OpenOptions{
PortName: portName,
BaudRate: baudRate,
DataBits: 8,
StopBits: 1,
MinimumReadSize: 4,
}
r, err := serial.Open(options)
if err != nil {
return nil, err
}
c.readWriter = r
return r, err
}
func (c *SerialClient) SendMsg(data string) (int, error) {
var (
err error
)
if c.readWriter == nil {
log.Warn("")
return 0, errors.New("serial port is closed")
}
log.Info("send:" + data)
bytes, err := hex.DecodeString(data)
if err != nil {
return 0, err
}
return c.readWriter.Write(bytes)
}
单元测试:
package uart
import (
"iris/utils"
"testing"
"time"
)
func TestNewSerialClient(t *testing.T) {
c, err := NewSerialClient("COM4", 1500000)
if err != nil {
panic(err)
}
go c.Start()
c.SendMsg(utils.TrimHexStr("55 00 0A 00 00 00 00 00 42 00 00 E2 03"))
go func() {
tick := time.NewTicker(2 * time.Second)
for {
select {
case <-tick.C:
data := "55 00 0E 00 00 00 00 00 7A 00 04 00 00 00 00 DA 03"
c.SendMsg(utils.TrimHexStr(data))
}
}
}()
for {
select {
case res := <-c.OutBuffer:
println("received data " + res)
default:
}
}
}