zhangzengfei
2024-10-20 2fc94ba7b517125a7ed9771b48bb5d383021bc91
rfid/rw.go
@@ -13,18 +13,21 @@
func NewReader(devName string, baud, readDuration int) *Reader {
   return &Reader{
      DevName:      devName,
      Baud:         baud,
      ReadDuration: readDuration,
      DevName:       devName,
      Baud:          baud,
      ReadTimeout:   readDuration,
      Alive:         true,
      HeartbeatTime: time.Now().Unix(),
   }
}
type Reader struct {
   DevName       string
   Baud          int
   ReadDuration  int
   EPCData       string
   ReadTimestamp int64
   ReadTimeout   int
   Alive         bool
   HeartbeatTime int64
   DevPort       *serial.Port
}
@@ -81,7 +84,7 @@
func (r *Reader) ReadResponse() (int, error) {
   buf := make([]byte, 1024) // 根据协议最大数据长度调整缓冲区
   n, err := r.DevPort.Read(buf)
   fmt.Printf("Recive message %x\n", buf[:n])
   fmt.Printf("Recive message %X\n", buf[:n])
   return n, err
}
@@ -94,7 +97,7 @@
   defer r.StopAutoRead()
   stop := time.After(time.Duration(r.ReadDuration) * time.Second)
   stop := time.After(time.Duration(r.ReadTimeout) * time.Second)
   // 根据协议最大数据长度调整缓冲区
   buf := make([]byte, 1024)
@@ -121,7 +124,7 @@
         if buf[0] != 0x5A {
            continue // 忽略错误帧
         }
         fmt.Printf("Recive message %x\n", buf[:n]) // 打印协议控制字进行调试
         fmt.Printf("Recive message %X\n", buf[:n]) // 打印协议控制字进行调试
         // 校验CRC
         //fmt.Printf("Crc %x\n",buf[n-2 : n])
@@ -147,7 +150,7 @@
         // 回调传送epc数据
         //callBack(buf[9 : 9+epcLength])
         epcData := fmt.Sprintf("%x", buf[9:9+epcLength])
         epcData := fmt.Sprintf("%X", buf[9:9+epcLength])
         if epcData == target {
            scanCount++
            if scanCount > minCount {
@@ -165,6 +168,20 @@
   if err != nil {
      return err
   }
   go func() {
      for {
         err := r.SendAck()
         if err != nil {
            fmt.Println("send ack.", err.Error())
         }
         time.Sleep(30 * time.Second)
         if time.Now().Unix()-r.HeartbeatTime > 120 {
            r.Alive = false
         }
      }
   }()
   // 根据协议最大数据长度调整缓冲区
   buf := make([]byte, 1024)
@@ -190,10 +207,10 @@
         if buf[0] != 0x5A {
            continue // 忽略错误帧
         }
         fmt.Printf("Read message %x\n", buf[:n]) // 打印协议控制字进行调试
         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) {
@@ -201,25 +218,26 @@
            continue
         }
         // 解析协议控制字 (仅在需要时使用)
         //fmt.Printf("Control Word: %x\n", buf[1:5]) // 打印协议控制字进行调试
         r.HeartbeatTime = time.Now().Unix()
         r.Alive = true
         // 解析协议控制字
         controlWord := binary.BigEndian.Uint32(buf[1:5])
         if controlWord != ControlWordEPCReadResponse6C {
            fmt.Printf("Control Word: %d, rec word %d\n", ControlWordEPCReadResponse6C, controlWord)
            continue
         switch controlWord {
         case ControlWordDeviceInfo:
            parseDeviceInfo(buf)
         case ControlWordEPCReadResponse6C:
            // 解析EPC数据长度
            epcLength := binary.BigEndian.Uint16(buf[7:9])
            r.EPCData = fmt.Sprintf("%X", buf[9:9+epcLength])
            // 回调传送epc数据
            //callBack(buf[9 : 9+epcLength])
            fmt.Printf("Read epc %s\n", r.EPCData)
         }
         // 解析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)
      }
   }
}
@@ -230,6 +248,41 @@
   _, err := r.DevPort.Write(data)
   if err != nil {
      return err
   }
   // todo parse response
   r.ReadResponse()
   return nil
}
func (r *Reader) SendAck() error {
   cmd := "5A000101000000DCE5"
   //cmd := "5A000111120004000000015FFB"
   data, _ := hex.DecodeString(cmd)
   _, err := r.DevPort.Write(data)
   return err
}
func (r *Reader) SetPower(val int) error {
   if val < 10 || val > 33 {
      return fmt.Errorf("value out of range, must be between 0 and 255")
   }
   frame := []byte{0x5A, 0x00, 0x01, 0x02, 0x01, 0x00, 0x02, 0x01}
   frame = append(frame, byte(val))
   crc := CRC16XMODEM(frame[1:])
   crcBytes := make([]byte, 2)
   binary.BigEndian.PutUint16(crcBytes, crc)
   frame = append(frame, crcBytes...)
   fmt.Printf("set power %d, cmd %2X\n", val, frame)
   _, err := r.DevPort.Write(frame)
   if err != nil {
      return nil
   }
@@ -239,18 +292,71 @@
   return err
}
func (r *Reader) SetPower20() error {
   cmd := "5A0001020100020132D230"
func (r *Reader) SetBuzzer(enable bool) error {
   cmd := "5A0001011E000100653D"
   if !enable {
      cmd = "5A0001011E000101751C"
   }
   data, _ := hex.DecodeString(cmd)
   _, err := r.DevPort.Write(data)
   if err != nil {
      return nil
      return err
   }
   // todo parse response
   r.ReadResponse()
   return err
   return nil
}
func parseDeviceInfo(bytes []byte) {
   // 初始化解析的偏移量
   offset := 1
   // 解析协议控制字
   controlWord := bytes[offset : offset+4]
   offset += 4
   // 解析数据长度
   dataLength := int(bytes[offset])*256 + int(bytes[offset+1])
   offset += 2
   // 解析读写器序列号
   serialNumberLen := int(bytes[offset])*256 + int(bytes[offset+1])
   offset += 2
   serialNumber := bytes[offset : offset+serialNumberLen]
   offset += serialNumberLen
   // 解析上电时间(4字节)
   upTimeBytes := bytes[offset : offset+4]
   offset += 4
   // 解析基带编译时间长度(2字节)
   baseBandTimeLen := int(bytes[offset])*256 + int(bytes[offset+1])
   offset += 2
   // 解析基带编译时间(根据长度字段解析)
   baseBandTime := bytes[offset : offset+baseBandTimeLen]
   offset += baseBandTimeLen
   // 解析应用软件版本(4字节)
   appVer := bytes[offset : offset+4]
   offset += 4
   // 将字节数组转换为可读字符串
   serialNumberStr := string(serialNumber)
   baseBandTimeStr := string(baseBandTime)
   appVerStr := fmt.Sprintf("%d.%d.%d.%d", appVer[0], appVer[1], appVer[2], appVer[3])
   // 解析上电时间(将字节数组转为整数)
   upTime := int(upTimeBytes[0])<<24 + int(upTimeBytes[1])<<16 + int(upTimeBytes[2])<<8 + int(upTimeBytes[3])
   // 打印结果
   fmt.Printf("协议控制字: %X\n", controlWord)
   fmt.Printf("数据长度: %d\n", dataLength)
   fmt.Printf("读写器序列号: %s\n", serialNumberStr)
   fmt.Printf("读写器上电时间: %d秒\n", upTime)
   fmt.Printf("基带编译时间: %s\n", baseBandTimeStr)
   fmt.Printf("应用软件版本: %s\n", appVerStr)
}