发卡关卡的读卡流程完成

This commit is contained in:
2024-12-10 17:40:59 +08:00
parent 193fa806c2
commit 25cb34f6f5
6 changed files with 157 additions and 60 deletions

View File

@@ -14,9 +14,13 @@ import (
type Reader interface {
io.Closer
SetUnitID(uint8)
// WriteUnitId 写入读卡器的 UnitID
WriteUnitId(uint16) error
// Init 初始化读卡器配置
Init() error
// OnCardInfo 会在卡号信息发生变化时调用回调函数,直到上下文被取消,或者 Reader 被关闭。需要在 goroutine 中调用。
OnCardInfo(context.Context, func(CardInfo))
OnCardInfo(context.Context, func(*CardInfo))
GetCardInfo() *CardInfo
}
type CardInfo struct {
@@ -28,6 +32,14 @@ type reader struct {
c *modbus.Client
}
// WriteUnitId 写入读卡器的 UnitID
func (r *reader) WriteUnitId(id uint16) error {
v := id<<8 + 1
zap.S().Infof("WriteRegister 40007 %#x", v)
return r.c.WriteRegister(6, v)
}
// Init 初始化读卡器配置
func (r *reader) Init() error {
// 配置读卡间隔时间为 50 毫秒
err := r.c.WriteRegister(8, 0x0511)
@@ -52,57 +64,64 @@ func (r *reader) Init() error {
return nil
}
func (r *reader) OnCardInfo(ctx context.Context, f func(info CardInfo)) {
// GetCardInfo 获取卡号信息
func (r *reader) GetCardInfo() *CardInfo {
// 读取状态寄存器确认是否信息已经准备好
status, err := r.c.ReadRegister(29, modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40030 error:", err)
return nil
} else if status == 0x0000 {
return nil
}
// 读取卡号长度
cardLength, err := r.c.ReadRegister(30, modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40031 error:", err)
return nil
}
dataLength := cardLength >> 8
// 读取卡类型
cardType, err := r.c.ReadRegister(31, modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40032 error:", err)
return nil
}
// 读取卡号数据
cardData, err := r.c.ReadRegisters(32, uint16(math.Round(float64(dataLength)/2)), modbus.HoldingRegister)
if err != nil {
zap.S().Errorln("ReadRegister 40033~ error:", err)
return nil
}
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)
}
}
return &CardInfo{
Type: cardType,
ID: strings.Join(s, ""),
}
}
// OnCardInfo 会在卡号信息发生变化时调用回调函数,直到上下文被取消,或者 Reader 被关闭。需要在 goroutine 中调用。
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, ""),
})
info := r.GetCardInfo()
if info != nil {
f(info)
}
}
}