package rfid import ( "context" "encoding/binary" "encoding/hex" "fmt" "io" "time" "github.com/tarm/serial" ) func NewReader(devName string, baud, readDuration int) *Reader { return &Reader{ DevName: devName, Baud: baud, ReadDuration: readDuration, } } type Reader struct { DevName string Baud int ReadDuration int EPCData string ReadTimestamp int64 DevPort *serial.Port } func (r *Reader) OpenSerial() (err error) { config := &serial.Config{ Name: r.DevName, Baud: r.Baud, ReadTimeout: 2 * time.Second, } r.DevPort, err = serial.OpenPort(config) return err } func (r *Reader) CloseSerial() error { return r.DevPort.Close() } // AutoReadStart 开启自动读取, 返回写入的指令长度和错误 func (r *Reader) StartAutoRead() error { cmd := "5A0001010B00100001000B0001021000050000000101005EE2" data, _ := hex.DecodeString(cmd) _, err := r.DevPort.Write(data) if err != nil { return nil } // todo parse response r.ReadResponse() return err } // StopAutoRead 停止读取 func (r *Reader) StopAutoRead() error { cmd := "5A000102FF0000885A" data, _ := hex.DecodeString(cmd) _, err := r.DevPort.Write(data) if err != nil { return nil } // todo parse response r.ReadResponse() return err } func (r *Reader) ReadResponse() (int, error) { buf := make([]byte, 1024) // 根据协议最大数据长度调整缓冲区 return r.DevPort.Read(buf) } func (r *Reader) ScanSpecificEPC(target string, minCount int) (bool, error) { err := r.StartAutoRead() if err != nil { return false, err } defer r.StopAutoRead() stop := time.After(time.Duration(r.ReadDuration) * time.Second) // 根据协议最大数据长度调整缓冲区 buf := make([]byte, 1024) scanCount := 0 for { select { case <-stop: return false, nil default: for i := 0; i < 1024; i++ { buf[i] = 0 // 清零或其他处理 } n, err := r.DevPort.Read(buf) if err != nil { return false, err } if n == 0 || n < 8 { continue // 如果没有读取到数据 } // 检查帧头 if buf[0] != 0x5A { continue // 忽略错误帧 } fmt.Printf("Recive message %x\n", buf[:n]) // 打印协议控制字进行调试 // 校验CRC //fmt.Printf("Crc %x\n",buf[n-2 : n]) receivedCrc := binary.BigEndian.Uint16(buf[n-2 : n]) computedCrc := CRC16XMODEM(buf[1 : n-2]) if receivedCrc != (computedCrc & 0xFFFF) { fmt.Println("CRC check failed") continue } // 解析协议控制字 (仅在需要时使用) //fmt.Printf("Control Word: %x\n", buf[1:5]) // 打印协议控制字进行调试 controlWord := binary.BigEndian.Uint32(buf[1:5]) if controlWord != ControlWordEPCReadResponse6C { fmt.Printf("Control Word: %d, rec word %d\n", ControlWordEPCReadResponse6C, controlWord) continue } // 解析EPC数据长度 epcLength := binary.BigEndian.Uint16(buf[7:9]) //fmt.Printf("EPC length %d, EPC %x \n", epcLength, buf[9:9+epcLength]) // 回调传送epc数据 //callBack(buf[9 : 9+epcLength]) epcData := fmt.Sprintf("%x", buf[9:9+epcLength]) if epcData == target { scanCount++ if scanCount > minCount { return true, nil } } fmt.Printf("read epc %s, target epc: %s\n", epcData, target) } } } func (r *Reader) ReadEPCData(ctx context.Context) error { err := r.StartAutoRead() if err != nil { return err } // 根据协议最大数据长度调整缓冲区 buf := make([]byte, 1024) for { select { case <-ctx.Done(): return nil default: for i := 0; i < 1024; i++ { buf[i] = 0 // 清零或其他处理 } n, err := r.DevPort.Read(buf) if err != nil && err != io.EOF { return err } if n == 0 || n < 8 { continue // 如果没有读取到数据 } // 检查帧头 if buf[0] != 0x5A { continue // 忽略错误帧 } fmt.Printf("Read message %x\n", buf[:n]) // 打印协议控制字进行调试 // 校验CRC //fmt.Printf("Crc %x\n",buf[n-2 : n]) receivedCrc := binary.BigEndian.Uint16(buf[n-2 : n]) computedCrc := CRC16XMODEM(buf[1 : n-2]) if receivedCrc != (computedCrc & 0xFFFF) { fmt.Println("CRC check failed") continue } // 解析协议控制字 (仅在需要时使用) //fmt.Printf("Control Word: %x\n", buf[1:5]) // 打印协议控制字进行调试 controlWord := binary.BigEndian.Uint32(buf[1:5]) if controlWord != ControlWordEPCReadResponse6C { fmt.Printf("Control Word: %d, rec word %d\n", ControlWordEPCReadResponse6C, controlWord) continue } // 解析EPC数据长度 epcLength := binary.BigEndian.Uint16(buf[7:9]) //fmt.Printf("EPC length %d, EPC %x \n", epcLength, buf[9:9+epcLength]) // 回调传送epc数据 //callBack(buf[9 : 9+epcLength]) r.EPCData = fmt.Sprintf("%X", buf[9:9+epcLength]) r.ReadTimestamp = time.Now().Unix() fmt.Printf("read epc %s\n", r.EPCData) } } }