| | |
| | | |
| | | 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 |
| | | } |
| | | |
| | |
| | | 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 |
| | | } |
| | |
| | | |
| | | 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) |
| | |
| | | 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]) |
| | |
| | | |
| | | // 回调传送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 { |
| | |
| | | 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) |
| | |
| | | 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) { |
| | |
| | | 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) |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | _, 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 |
| | | } |
| | | |
| | |
| | | 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) |
| | | } |