【CPH系列】RFID标签读取模块,开发说明文档(包含重要内容和BUG)

总览

1.基本概念&&模块参数简介

2.基本命令格式说明

3.查询命令

4.设置命令

一、基本概念简介

1.读写器 属性简介

1.射频功率(RF-Power)

读写器在工作时射频功率的大小,在其他变量控制不变的前提下,RF-Power 越大,读取距离 越远。

2.盘点(Inventory)
盘点其实就是指读取操作,只不过是不间断的读取操作。

3.读(read)

读取标签中的数据内容。
实测最远读卡距离:810mm,0.81米(无遮挡,正向)
型号:CPH-305
最大功率设定:官方给出 15-30 dbm,但是实测使用上位机只能 0-20 dbm,>=20则向下取到20。

4.写(write)

向标签中写入数据。

2.RFID标签 属性简介

1.锁定

锁定指的是,如果标签被锁定之后,就没有办法再改变标签存储的数据,除非进行解锁操作。

2.灭活

标签被灭活之后,不会再对读写器的任何命令做出任何回应,数据无法被读取。

3.标签内存说明

4.读卡距离变近的原因

· 标签与人体皮肤接触

· 标签与金属接触

· 标签在高湿度环境中

· 标签与读卡器之间有高密度物体遮挡

3.通信 属性简介

1.RS232 / RS485

尽管 RS232 是全双工模式,但是它仍然比 485 要慢。

二、上位机参数设置

1.工作参数页面

工作模式:

分为主动模式、被动模式、触发模式。

标签过滤时间:

白话说,就是,如果设置为 60,那么:
如果现在扫描到了 A 标签,那么 60秒 内,不会再重复对 A标签 进行扫描。
但是并不影响扫描 B、C 标签等等...

读卡间隔时间:

给处理器处理数据留出时间。

一般设置为 3(30ms)即可。

触发延长时间:

如果设置读取的模式为 "触发模式",那么:
假如设置为 5,那么在发送读取命令后的 5秒 内,模块都会持续进行射频扫描。
直到读取到标签,或者 5秒 已经过去但没有读取到。才会停止。

读卡区域:

标签上一般有这几个区域:

EPC、TID、USER。

1.工作参数:

2.传输参数:

3.射频参数:




关于 RSSI 阈值的说明:

RSSI,代表了信号强度,在第一个页面中,我们看到的信息栏目中,就有 RSSI 参数,代表当前标签的信号强度。

关于 Session 的说明:


二、基本命令格式说明

1.帧 && 此RFID读写器模块的帧

帧,是上位机和 RFID读写器 传输数据的最小单元。

所有的交互都以帧为一个单位(最小单位)

在此 RFID读写器模块 中,帧的各项属性定义是这样的:

Header :数据帧的起始标志

由字符'R'和字符'F'组成。(R 和 F 的 ASCII 分别为:0x52、0x46)

Frame type :帧的类型(1 byte

区分、指明这个数据帧是命令,响应或者是通知类型的数据帧。

· 命令帧:value == 0

上位机 发送给 RFID读写器模块的命令。

· 响应帧:value == 1

RFID读写器模块 执行完 上位机 的命令后,告知上位机执行结果而返回的报文。

· 通知帧:value == 2

RFID读写器模块 在没有接收到 上位机 命令的情况下,主动发送给主机的数据。例如RFID读写器主动读卡模式下读到数据后自动上传给主机。

Address :RFID的设备地址(2 byte

由2个字节组成,MSB在帧的前面,LSB在帧的后面。

作为设备的一种标识,命令帧中只有地址和RFID读写器设备内的地址一致时设备才会响应。

否则地址不一致的情况下RFID读写器不会执行主机的命令 。

Frame Code :帧的识别码(1 byte

指明发送的是什么命令;

或指明此条帧是对什么命令的回复。

Param Length :帧的参数长度(2 byte )(N bytes的中的 N)

由 2 个字节组成,

MSB(1 byte)在帧的前面,

LSB(1 byte)在帧的后面。

Parameters :数据帧的参数(N byte

参数的数据类型均以 TLV 的格式来表示。

TLV:标签(Tag),长度(Length),值(Value)

除了基础的 TLV,其余的 TLV 均可嵌套。

TLV 的嵌套非常灵活,请看下面例子:

Checksum :帧的校验码

保证数据帧的完整性。

数据在传输过程中可能会因为干扰、信号衰减等原因导致部分字节被修改,

Checksum 可以用来检测这种错误。

checksum 的计算方式如下:

c 复制代码
RFID_UINT8 caculate_checksum(RFID_UINT8 *buff_ptr,RFID_UINT8 len)
{
    RFID_UINT8 index = 0;
    RFID_UINT8 check_sum = 0;
    for (index = 0; index < len ; index++)
    {
        check_sum += buff_ptr[index];
    }
    check_sum = ~check_sum + 1;
    return check_sum;
}

为了方便大家,写了一个 python 脚本,用于方便计算 checksum,只需要输入内容,自动计算出 checksum

通过网盘分享的文件:checksum_calcu.python

链接: https://pan.baidu.com/s/1Wcg19Y9fqG7o-zCkZZn2mg?pwd=7uvu

提取码: 7uvu

使用方法:放在你想要放在的目录下,然后使用 python 运行它。

比如,cd 进入目录后,运行命令:

kotlin 复制代码
python checksum_calcu.python

当然,前提是,你已经在电脑中安装了 python 程序。

运行效果图:

2.关于16进制

为什么写成 0x52、0x46 而不是 52、46 呢?

因为需要区别," 0x "只是一个前缀,

它代表了"这个数是一个 16进制 而非其他(比如说 10进制)

三、查询命令 && 设置命令

1.查询命令 - 设备软件版本等信息(0x40)

查询命令:

c 复制代码
52 46 00 00 00 40 00 00 28

1.1 写 帧 的 Header:'R'、'F' == 52 46

1.2 因为,这个 帧 是 上位机 发送给 RFID读写器模块 的内容,所以:Frame Type == 00(0x00)

1.3 然后是 Address,默认的 MSB 和 LSB 都是 1 byte 的 0x00,所以 Address == 00 00

1.4 Frame Code,帧的识别码。0x40 代表了:"我们要查询设备的版本号" 这个命令

1.5 Param Lenght(MSB LSB):MSB 是数据的高字节(靠左),LSB 是数据的低字节(靠右)。

Param Lenght 一共包含 2 byte,举例:0x000B(转换成10进制,则 == 11)

MSB == 00、LSB == 0B
所以说,Param Lenght = 00 0B 的意思是,后面的 TLV Param 的总长度(包含嵌套)= 11

当我们实际去看的时候,也确实发现 TLV Param 的 Length == 11:

07 01 00 20 03

02 02 08 21 01

06

在上面的图中,返回的数据帧,我们解析:

发送帧:52 46 00 00 00 40 00 00 28

返回帧:52 46 01 00 00 40 00 0B 07 01 00 20 03 02 02 08 21 01 06 BD

首先拆解 返回帧:

Header:52 46

Frame type:01(代表返回帧特性)

Address(MSB LSB):00 00(默认地址)

Frame Code:40(代表这个帧要 → 查询版本号)

Param Length:00 0B

2.设置命令 - 开始盘存标签(0x21)

开始盘存标签的串口命令:

c 复制代码
52 46 00 00 00 21 00 00 47

开始盘存,其中有效信息 TLV == 07 01 00

3.设置命令 - 主动盘存标签模式(0x22)

命令:

c 复制代码
52 46 00 00 00 22 00 00 46

发送命令后,设置 RFID读取器模块 的 读取逻辑 为 "主动读取",
且立即进行 1次 主动读取 操作。(仅读取 1 次)

(若命令发出瞬间,没有读取到信息,那么则读取失败不返回任何值)


3.1 发送给 RFID读取器模块,若 没有读取到任何 RFID 标签 返回值如图:

我们查看一下返回值,和返回值 的 相应格式进行一下对比:
52 46 01 00 00 22 00 03 07 01 50 EA

Header:52 46

Frame type:01(0x01)

Address:00 00(default)

Frame Code:22(0x22,因为响应的操作 "主动盘存标签" 的代码是0x22)

Param Length:00 03(长度 = 3,包含 07 01 50

TLV:07 01 50(Tag:07,Length:01,StateCode:50。这个 TLV 的 StateCode 是 0x50 ,代表 "读取失败")

3.2 发送给 RFID读取器模块,若 读取到了 RFID 标签 返回值如图:

TLV(部分TLV,此TLV貌似嵌套了):07 01 00(Tag:07,Length:01,StateCode:00。这个 TLV 的 StateCode 是 0x00 ,代表 "读取成功")

每次盘点,倒数第二位都会变(除了 checksum 的倒数第一位),这就导致了,checksum 和这个数一起改变,这导致最后 2位 一直在改变。原因...

4.设置命令 - 停止盘存标签 模式(0x23)

命令:

c 复制代码
52 46 00 00 00 23 00 00 45

可以看到,HOST ← Reader 的值中,后面的 TLV 部分的值:

c 复制代码
07 01 00

其中,07 大概是 "盘存类型的命令(或操作)" 的意思,01 是 TLV value 的长度,00 是 TLV 的 value。

关于 value 的值:
0x00 → SUCCESS
0x50 → FALSE

所以 07 01 00 的意思就是:"盘存类型的命令" → 命令已经成功执行

操作将会中断正在进行盘点的操作,让设备处于 STOP 停止模式:

5.设置命令 - 设置单个参数值(0x48)

请注意,这个命令比较特殊。

设置单个参数的值,实际上 "单个参数" 只有 4 个可选参数。

这四个可选参数,可以任意选择任何一个,以 改变它们的具体值。

它们分别为:

☆ 0x01:1 byte,设置功率

最大值为 10进制 的 30(16进制 == 0x1E)

比如说,我们可以设置功率为25,25的16进制是:0x19,:

☆ 0x02:1 byte,设置蜂鸣器

boolean值:0x00 为 OFF,0x01 为 ON

☆ 0x03:1 byte,设置标签过滤时间

也就是,我们扫描一次标签之后的冷却时间,在多少秒之后才能再次扫描。取值范围 0-255(10 进制),16进制为 0x00 ~ 0xFF。参考示意图如下:

0x04:4 byte,参数结构如下:

6.(!!重要!!)设置命令 - 设置功率官方文档让人误解的点

6.(!!重要!!)设置命令 - 设置功率官方文档让人误解的点

6.(!!重要!!)设置命令 - 设置功率官方文档让人误解的点

官方文档中写了这样一段设置功率的命令,令人费解:


你可以看到,明明在 26 后面跟着的是 03 01 09 C4,作为修改功率的 TLV 存在,
但是,下面的解说却解释了 02 01 1E 作为修改功率的 TLV?!
这完全是两个格式的 TLV,它们的参数数量都不同。
然而,诡异的是,这两个 TLV 所构成的帧,都能够正常修改功率(???)

完全超出了我的预料,经过近 2小时的实验,我得出了原因,真正的修改功率的帧的内容应该是这样的:

c 复制代码
52 46 00 00 00 48 00 05 26 02[也可以是03,无所谓] 01 08[功率值的16进制,允许0x00~0x1E] C3[可以是任意值,C3只是一个占位字节,但不能省略] 27[前置字节串的checksum]

比如:52 46 00 00 00 48 00 05 26 03 01 1E D3 00
是设置功率为30dbm,D3仅是一个占位符,你如果将它改为D4,也能设置功率。
这两段命令是完全相等效的。只是你在改成D4后,需要重置CHECKSUM:
52 46 00 00 00 48 00 05 26 03 01 1E D4 FF

在官方文档 4.4 中:

我们能够看到这样一段话:
"例如设置功率: 52 46 00 00 00 48 00 05 26 02 01 1E checksum 1E转换十进制的值为30,则该命令就是将功率设置为30dbm"

计算出checksum(==0xD4),得出的命令帧为:

c 复制代码
52 46 00 00 00 48 00 05 26 02 01 1E D4

这个命令帧照理说应该是生效的,因为这是文档中给出的示例。
然而实际的结果是,它无法修改功率。这是文档中的一个错误。(我不知道大家看到的时候文档是否已经被修正)

所以,只需要按照我上面说的那个命令才能够修改功率:

c 复制代码
52 46 00 00 00 48 00 05 26 02[也可以是03,无所谓] 01 08[功率值的16进制,允许0x00~0x1E] C3[可以是任意值,C3只是一个占位字节,但不能省略] 27[前置字节串的checksum]

比如:52 46 00 00 00 48 00 05 26 03 01 1E D3 00
是设置功率为30dbm,D3仅是一个占位符,你如果将它改为D4,也能设置功率。
这两段命令是完全相等效的。只是你在改成D4后,需要重置CHECKSUM:
52 46 00 00 00 48 00 05 26 03 01 1E D4 FF

查看被修改的功率的命令:

c 复制代码
52 46 00 00 00 49 00 03 26 01 01 F4

7.查询命令 - 查询当前设定的功率值(单参数查询)(0x49)

命令:

c 复制代码
52 46 00 00 00 49 00 03 26 01 01 F4

内容解析:

49:查询单个参数值的 Frame Code。

00 03:后续 TLV 的长度。

26:查询单个参数的 TLV 中的第一个参数"命令类型",只要是单参数查询都是 26。

01:此 TLV 中的 value 的长度。

01:value 的值,0x01,代表查询功率。

F4:checksum。

8.查询命令 - 查询当前蜂鸣器状态(单参数查询)(0x49)

命令:

c 复制代码
52 46 00 00 00 49 00 03 26 01 02 F3

内容解析:

49:查询单个参数值的 Frame Code。

00 03:后续 TLV 的长度。

26:查询单个参数的 TLV 中的第一个参数"命令类型",只要是单参数查询都是 26。

01:此 TLV 中的 value 的长度。

02:value 的值,0x02,代表查询 蜂鸣器状态(0x00关闭,0x01开启)。

F3:checksum。

9.查询命令 - 查询当前标签过滤时间(单参数查询)(0x49)

命令:

c 复制代码
52 46 00 00 00 49 00 03 26 01 03 F2

内容解析:

49:查询单个参数值的 Frame Code。

00 03:后续 TLV 的长度。

26:查询单个参数的 TLV 中的第一个参数"命令类型",只要是单参数查询都是 26。

01:此 TLV 中的 value 的长度。

03:value 的值,0x03,代表查询 代表查询 标签过滤时间(同一标签的扫描冷却时间,16进制 0x00-0xFF,也就是10进制的1-255)

F2:checksum。

10.查询命令 - 查询当前Mixer Gain、IF AMP Gain、Threshold(单参数查询)(0x49)(改命令存疑,暂时无效)

命令:

c 复制代码
52 46 00 00 00 49 00 03 26 01 04 F1(不成功,需要继续咨询客服)

内容解析:

49:查询单个参数值的 Frame Code。

00 03:后续 TLV 的长度。

26:查询单个参数的 TLV 中的第一个参数"命令类型",只要是单参数查询都是 26。

01:此 TLV 中的 value 的长度。

04:value 的值,0x04,代表查询 代表查询 :

Mixer Gain(混频增益):默认为9

IF AMP Gain(中频放大增益):默认为36

Threshold(信号门槛):值越高读卡距离越近,因为阈值升高了,读取自然费力 ------ 需要更大的信号才能触发读取。默认值为0x00A0。

F1:checksum。

关于 Mixer Gain、IF AMP Gain、Threshold:
我们可以想象,Mixer Gain、IF AMP Gain 分别是 2个 大喇叭,它们用来将高频微弱的射频信号放大,然后再发射出去,传递到 RFID 标签那里。

更多内容在我的博客中,搜索 "CPH" 获取。

相关推荐
驱动探索者2 天前
Zephyr 获取 cpu 占用率异常bug分析
bug·rtos·zephyr
薛定e的猫咪3 天前
【调试技巧】vscode 四种断点调试,快速定位 bug
ide·vscode·python·bug
藏,捉3 天前
使用自己绘制的板子通过485与西门子PLC1214C通讯,控制舵机摇摆运动
单片机·工控·485通讯
万粉变现经纪人3 天前
如何解决 pip install 编译报错 ‘cl.exe’ not found(缺少 VS C++ 工具集)问题
开发语言·c++·人工智能·python·pycharm·bug·pip
月小满4 天前
DataV轮播时其他组件的内容也一起滚动 修复bug的方法
前端·vue.js·bug·大屏端
桃子丫4 天前
AD转 Cadence学习指南-BUG篇
bug
testtraveler4 天前
[Fix] ImportError: libtorch_cpu.so: undefined symbol: iJIT_NotifyEvent
pytorch·python·bug
测试者家园4 天前
从“找 bug”到“降风险”:测试思维模式的底层迁移
软件测试·bug·风险管理·持续测试·测试基础·智能化测试·测试思维模式
chde2Wang5 天前
运行scala文件报错xsbt.CompilerInterface
bug·scala
离离茶6 天前
【笔记1-8】Qt bug记录:QListWidget窗口的浏览模式切换为ListMode后,滚轮滚动速度变慢
笔记·qt·bug