初步完成龙台的读卡逻辑

This commit is contained in:
2024-12-09 18:28:36 +08:00
parent aa634c8860
commit 37fb40672a
15 changed files with 313 additions and 43 deletions

137
pkg/card_reader/reader.go Normal file
View File

@@ -0,0 +1,137 @@
package card_reader
import (
"context"
"fmt"
"github.com/munnik/modbus"
"go.uber.org/zap"
"io"
"math"
"strings"
"time"
)
type Reader interface {
io.Closer
SetUnitID(uint8)
Init() error
// OnCardInfo 会在卡号信息发生变化时调用回调函数,直到上下文被取消,或者 Reader 被关闭。需要在 goroutine 中调用。
OnCardInfo(context.Context, func(CardInfo))
}
type CardInfo struct {
Type uint16
ID string
}
type reader struct {
c *modbus.Client
}
func (r *reader) Init() error {
// 配置读卡间隔时间为 50 毫秒
err := r.c.WriteRegister(8, 0x0511)
if err != nil {
return err
}
// 由低到高输出 500 毫秒
err = r.c.WriteRegister(9, 0xF20A)
if err != nil {
return err
}
// 读取后自动清空高字节00 不清空 01 清空
err = r.c.WriteRegister(10, 0x0103)
if err != nil {
return err
}
// 自动读卡号高字节高4位0 读一次 1 连续读
err = r.c.WriteRegister(11, 0x0301)
if err != nil {
return err
}
return nil
}
func (r *reader) OnCardInfo(ctx context.Context, f func(info CardInfo)) {
for {
select {
case <-ctx.Done():
return
case <-time.After(100 * time.Millisecond):
{
// 读取状态寄存器确认是否信息已经准备好
status, err := r.c.ReadRegister(29, modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40030 error:", err)
break
} else if status == 0x0000 {
break
}
// 读取卡号长度
cardLength, err := r.c.ReadRegister(30, modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40031 error:", err)
break
}
dataLength := cardLength >> 8
// 读取卡类型
cardType, err := r.c.ReadRegister(31, modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40032 error:", err)
break
}
// 读取卡号数据
cardData, err := r.c.ReadRegisters(32, uint16(math.Round(float64(dataLength)/2)), modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40033~ error:", err)
break
}
s := make([]string, dataLength)
for i := 0; i < int(dataLength); i++ {
if i%2 == 0 {
s[i] = fmt.Sprintf("%02X", cardData[i/2]>>8)
} else {
s[i] = fmt.Sprintf("%02X", cardData[i/2]&0xFF)
}
}
f(CardInfo{
Type: cardType,
ID: strings.Join(s, ""),
})
}
}
}
}
func (r *reader) SetUnitID(unitID uint8) {
_ = r.c.SetUnitID(unitID)
}
func (r *reader) Close() error {
return r.c.Close()
}
// NewReader 创建一个新的读卡器
func NewReader(URL string) (Reader, error) {
// 配置串口客户端
c, _ := modbus.NewClient(&modbus.Configuration{
URL: URL,
Speed: 9600,
DataBits: 8,
Timeout: 2 * time.Second,
Logger: zap.NewStdLog(zap.L()),
})
// 打开串口连接
err := c.Open()
if err != nil {
return nil, err
}
return &reader{c}, nil
}