NeoAtlantis应用科学和神秘学实验室 最近迁移到了一个新地址。因为建筑过于陈旧,很多设备开关十分不便,于是负责人安装了一些433MHz上的遥控插座,稍微改善了这一局面。
负责人虽然知道现在早已有借助WIFI的智能插座,也可以通过 Google 助理等控制,甚至通过IFTTT实现复杂的自动化,但是,这些方案对网络的依赖在他看来是个问题。
比较起来,两种方案各有优劣:
433MHz 无线遥控 | WiFi 插座 | |
---|---|---|
即插即用 | 较好(对码简单) | 需要配置网络,不太容易 |
安全可靠性 | 较差,无加密,无反馈 | 较好 |
依赖网络的可靠性 | 无 | 需要网络 |
扩展性 | 差,遥控器按钮有限 | 好 |
自动化 | 不自动 | 容易自动化 |
可以看出,使用无线遥控的方案,比起WiFi插座还差的地方在于:无法自动化,且无法获得被控制的设备状态。
自动化的好处是显而易见的:
- 比如可以节省电力消耗(实验室负责人发现电热水器就是一个很大的耗电来源,尤其在冬季)
- 比如可以自动规划一些事情(比如使用的高压电饭锅还没有预约功能,但是可以通过智能插座实现)
- 比如到家自动开灯,白天自动关灯,节约电力
为了达到上述目的,本实验室准备DIY一个方案,实现互联网或者短信到433MHz信号的网关。市场上虽然已经有类似的产品,但是自己动手,仍然是一种不错的训练。
1. 初步分析信号
要了解如何控制433MHz的无线开关,第一步就是捕捉和分析开关的信号。最简单的办法,是使用rtl_433这个程序,配合RTLSDR完成。
编译安装的过程可以在上面这个程序的Github中看到,这里不再详述。运行程序,然后按下遥控器按钮,可以看到如下信息:
可以看到,这个433MHz的遥控器基本上是使用了Nexa或者Proove Security的协议(即使遥控器本身并不是这个牌子)。这个信息比较有用,可以先记住。
图片上打码删去的部分是这个设备的特征编码(House Code),一共有8位。注意到,这个设备的遥控器上有6个按键,对应3个设备的各自开关; 又有2个额外的总开关按键,可以同时控制3个设备。这是怎么做到的呢? 多按几次,就可以看到:所有的3个设备都共享同样的House Code,但是Unit和Group不同:
- 当Group不为零的时候,为群组控制,所有共享同样House Code的设备的状态都会变为State的状态(开或关)。
- 当Group为零的时候,Unit是被控制的具体设备编号,目前因为遥控器上只有3个设备,这个编号可以发射的值是0,1或2。这个编号具体能到多少的范围,还有待研究。
2. 捕捉信号波形
为了模拟遥控器的输出,我们需要捕捉出这个信号的具体波形。(另一种办法是分析rtl_433
这个程序的代码,但是这样似乎难度更高)。办法很简单,使用gqrx
这个程序,调到433.92MHz,具体看下波形:
使用菜单中的Tools
->I/Q Recorder
这个工具,可以记录一段时间内的SDR原始数据。
这一数据量较大,因此一定要快速操作。IQ数据是将SDR采样得到的结果按照复数形式 \(I+Q\mathbf{i}\) 记录的文件。因为是复数,所以信号中同时具有幅度和相位的信息,可供程序解码使用。
我们感兴趣的是这个信号的波幅与时间的关系。使用如下show.py
代码,打开文件,然后用matplotlib
绘图:
运行代码:
$ python3 show.py <gqrx捕捉的raw文件>
就可以看到如下一幅图像:
3. 具体分析波形细节
上述matplotlib
显示波形的窗口可以查看细节。具体方式是在工具栏中选择放大镜形状的图标,然后在需要查看的部分上绘制一个方框。这样显示窗口就会缩放到对应的波形上去了。
这是第6号波形,即第3个按钮“关闭”按键的信号。从图中我们可以得出第二个重要信息:每个按键的传送分为6段。(实际上如果仔细分析,可以看到这6段是重复发送6次)
而具体每段发送的波形,就是我们需要了解的信号了:
4. 脉冲位置编码
下面展示波形的前几个脉冲。在matplotlib
的绘图窗口中移动鼠标,可以找到鼠标光标所指的信号序号。下图中已经标注了各个脉冲的上升(->
)和下降(<-
)沿对应的序号。
根据信号序号换算到时间,需要知道采样率。此次录制的信号,采样率为1.8MHz,因此每个采样样本对应的时间为:
\[ \frac{1s}{1.8 \times 10^{6}} = 5.55 \times 10^{-7} s = 0.555 \mu s \]
据此可以计算上述脉冲的时长和间隔,列表如下:
脉冲编号 | 前一个脉冲下降沿序号 | 上升沿序号 | 下降沿序号 | 距离前一个脉冲的序号差 | 距离前一个脉冲的时长(us) | 脉冲长度 | 脉冲时长(us) |
---|---|---|---|---|---|---|---|
1 | - | 26506929 | 26507427 | - | - | 498 | 277 |
2 | 26507427 | 26512218 | 26512716 | 4791 | 2661 | 498 | 277 |
3 | 26512716 | 26513179 | 26513677 | 463 | 257 | 498 | 277 |
4 | 26513677 | 26516115 | 26516630 | 2438 | 1354 | 515 | 286 |
5 | 26516630 | 26519051 | 26519549 | 2421 | 1345 | 498 | 277 |
6 | 26519549 | 26520013 | 26520511 | 464 | 258 | 498 | 277 |
7 | 26520511 | 26522966 | 26523447 | 2455 | 1364 | 481 | 267 |
8 | 26523447 | 26523928 | 26524391 | 481 | 267 | 463 | 257 |
9 | 26524391 | 26524855 | 26525336 | 464 | 258 | 481 | 267 |
10 | 26525336 | 26527791 | 26528272 | 2455 | 1364 | 481 | 267 |
11 | 26528272 | 26528753 | 26529216 | 481 | 267 | 463 | 257 |
我们能据此得出什么结论呢?
为了获取一点提示,我们可以参考https://github.com/merbanan/rtl_433/blob/master/src/devices/nexa.c
,即rtl_433
这个程序源码中对应nexa
系列信号的解码参数。
可以看出:
- 我们得到的结果,脉冲长度大约在257到286微秒之间,与程序中的
short_width
给的数值270相符。 - 而除了第1个脉冲外,其余脉冲距离前一个脉冲的时间也只有两种情况:
- 一个脉冲长度,约270微秒;
- 一个长脉冲长度,约1360微秒。这就是程序中备注的 1:5 或 1300微秒的来源。
- 第一个脉冲与后续脉冲间隔较长,为2661微秒。对应程序中备注的 1:10 或 2700 微秒。根据
sync_width
这项的名字,可以认为这是某种前导信号,用于激活或者同步接收设备。
此外,另一个重要的分析线索是程序中modulation
这项的值PPM
。经过Google查询,得知PPM全称为Pulse Position Modulation,脉冲位置调制。具体在德语维基中有一个说明示意图:
可以看出,这个与我们的分析是一致的。可以想象,如果要模仿遥控器控制我们的433MHz设备,需要:
- 根据遥控器的编码规则构建编码(本文尚未分析到这一步,但是可以根据RTLSDR的捕获结果直接得到)
- 以基础的270us为时间单位,控制433Mhz发射模块的开关,产生信号。具体步骤如下:
- 发射1个时间单位的同步信号
- 等待10个时间单位
- 根据要发射1还是0, 要么发射1个单位的信号后等待1个单位的时间,或者等待5个单位的时间
- 将上一步的信号重复6次发射。(重复间隔经过类似的分析,应该在10毫秒以上)
5. 接下去的步骤
接下来,为了实现控制,还要做的事情有:
- 研究遥控器发射信号的编码规则。包括House Code、单元或群组的控制信息。
- 研究如何使用单片机发射信号。
- 尝试使用我们的程序,给遥控插座重新设定House Code(即重新对码)。