用手机实现射频开关

栏目: 软件资讯 · 发布时间: 6年前

内容简介:前段时间发现有个电动门,可以用遥控器来进行控制,但是这个门一般都是室内的人进行控制,用来给室外的人开门,感觉比较麻烦,于是就琢磨着能不能做一个装置,这样能够通过手机在门外操控,就可以方便开门

用手机实现射频开关

阅读: 126

前段时间发现有个电动门,可以用遥控器来进行控制,但是这个门一般都是室内的人进行控制,用来给室外的人开门,感觉比较麻烦,于是就琢磨着能不能做一个装置,这样能够通过手机在门外操控,就可以方便开门

遥控器的外观如下

文章目录

射频应用的工作原理

首先,在淘宝上看到了类似的遥控器模块,发现了基本都是差不多的原理,网上的一些原理图如下,基本上都是利用的433M的射频芯片,如EV1527,PT2262等芯片,专门用在一些低成本的遥控开关上 用手机实现射频开关

接着继续搜索了一下一般射频应用的数据信号调制方式,下面是一个文献里面的说明 用手机实现射频开关

结合笔者以前的开发经验,这种射频芯片的编码也就是简单的串行编码(主要是调制方式比较低级,也只能进行这种编码方式),然后具体的编码内容也就是一个同步头,然后跟着N个数据,每个byte的8个bit从低位开始传输,顶多最后再附加一个校验码(一般为CRC或者简单地进行异或处理)

既然知道了工作原理,就开始进行大概的系统设计了。由于手头上有一个树莓派,那么一部分工作就可以基于树莓派来完成。整体方案由4个部分组成

利用树莓派通信

树莓派:自带蓝牙模块(支持BLE,Bluetooth Low Energy),用来作为BLE Peripheral(GATT Server),通过手机连接BLE,手机APP给树莓派发送命令,然后树莓派再控制其他设备发射射频信号 用手机实现射频开关

树莓派板子上有4个USB口,可以作为USB Host使用,挂载各种USB设备,还有一个有线的网口和一个WIFI、蓝牙二合一的芯片。(树莓派是一个国外的开源硬件,经历了很多代的发展,具体可以参考 https://www.raspberrypi.org

  • MCU:由于树莓派运行的是 Linux 系统,虽然有IO口,但是实时性很差,需要用到一个MCU来调制射频信号,MCU接收树莓派的命令进行工作
  • 射频发射模块:通过MCU控制射频发射模块,来发射无线信号
  • 射频接收模块:捕获遥控器的射频信号,分析遥控数据,便于模拟发射

框图如下

用手机实现射频开关

自掏腰包,在淘宝了买了两个小模块,一个是用于发射另外一个是接收的

用手机实现射频开关

前面两个字节都是一样的,为了保密,没有显示出来。这几个按键的编码数据,区别主要在于第三个字节的高4位,每个bit代表一个按键。

其中,接收模块是5V供电,而发射模块的供电范围是3~12V,根据发射功率的要求,可以选择合适的供电电压。

STM32

MCU选择了比较简单的STM32,也是自掏腰包购买的,一个简单的开发板,带USB功能,可以直接接入树莓派的USB上,不仅仅可以取电,还可以进行USB通信,真的是一举两得 用手机实现射频开关

硬件买到手,把各个模块接好,通过杜邦线来连接STM32板子与射频发射和接收模块,整体的框架如下 用手机实现射频开关

开始着手软件的开发了,首要目标是破解门禁的遥控器的编码

利用STM32的两个IO口,一个用来接收数据,一个用来发送数据,分别连接到接收模块和发射模块对应的PIN脚,接收数据的IO口配置为外部电平跳变中断(EDGE FALLING下降沿和EDGE RISING上升沿),这样的目的是为了保存各个电平信号的时间,用一个内置的定时器来计时(计时周期为10us)。

由于空中的各种电磁波的影响,就算在没有发射器在433M频段中发送数据,接收器也会有各种杂波,而IO接收模块的输出IO口电平也会一直杂乱地跳变,生成很多垃圾数据,所以只能在内存中用一个循环的Buffer去不断地存储两次电平跳变之间的时间,分析的时候需要剔除垃圾数据,找到有效的数据。

代码编写完后,通过JLINK调试器进行在线调试,为了抓到需要的数据,需要在手动按下遥控器的按钮后,保证数据发射完成(一般1S内都可以发射完毕),马上通过调试器停住MCU,然后去分析BUFFER里面的时间数据 用手机实现射频开关

通过watch窗口查看buffer里面的数据,很容易就找到了同步头,然后后面的数据也很容易分析出来。找到一个同步头以及下一个同步头,就可以得出一帧的数据,结果发现,两个同步头之间一共有24个bit的数据,也正好就是3个字节的数据。

就按照这种方式,抓到了4个按键的编码数据,分别为

名称 编码数据
自动 0xXX, 0xXX, 0x17
全锁 0xXX, 0xXX, 0x87
常开 0xXX, 0xXX, 0x27
半开 0xXX, 0xXX, 0x47

捕获到按键的编码数据,那么就开始写发送代码了,由于接收器的灵敏度的原因,接收器不一定会在第一次接收到有效数据就识别出来,所以开始的一些数据可能会被丢失。于是,每次发射信号时,需要把完整的编码发送5次,然后最后加上一个同步头,这样保证门禁的接收器每次都可以稳定接收成功。

同步头 数据1 数据2 数据3 …… 同步头 数据1 数据2 数据3 同步头
1 …… N=3,4,5

经过漫长的coding,终于完成了发送代码的编写,然后测试了一下,效果还不错,如果发射天线的位置摆放好,20米内的传输不成问题。

但是由于遥控器上没有一次性开门并关门的按键,所以每次需要发送“常开”的命令,再发送“自动”的命令,这样才能保证开门后,还能自动关门(用遥控器也得这样操作)。所以接收到开门指令,那么MCU会先发射一个“常开”的命令,然后等待5秒钟后,自动再发送一个“自动”的命令。

(虽然这种操作很蠢,但是门禁只支持这种操作,我也没有办法)

接下来就是完成USB的通信了,由于需要与树莓派进行通信,最简单的方式就是用STM32实现一个USB串口的功能,这样树莓派上面就可以直接操作TTY串口进行数据收发。

STM32工程里面直接加入ST官方的Virtual Com Port(VCP)的USB Middleware和对应的Driver,编译顺利通过,然后修改一下USB数据传输的接口代码(VCP除了USB都有的一个控制断点EP0,还有一个EP1,可以双向传输,配置的是Buck传输模式,stm32的USB支持Full Speed,也就是USB2.0,每次Buck传输最多可以传输64个字节)。

设计了一个简单的通信协议:

起始码 0xAA
命令 CMD
数据长度 N
数据内容 DATA(N bytes)
校验和 SUM(0xAA+CMD+N+DATA+SUM=0)

正确应答,回复相同数据,错误应答,CMD置0。

为了简单编码,限制了每次传输的数据长度,一个USB Buck传输的64个字节,可以传输一整个packet,这样树莓派那边不用做状态机保存临时数据。

把写好的程序烧写到STM32里面,然后通过USB插入到树莓派上,查看树莓派的dmesg

用手机实现射频开关

树莓派能够识别STM32的模拟串口,并挂载了串口设备/dev/ttyACM0,但是编码的时候还是不能把串口名字写死,需要通过枚举每个串口然后比较对应USB设备的PID和VID才能正确匹配(STM32的VCP里面的默认PID为22336,VID为1155)。

测试脚本

在树莓派上面,利用 Python 写了一个测试脚本, 用手机实现射频开关

其中SpController是自己写的一个class,主要是来进行串口的读写操作的。执行脚本,STM32在收到正确的数据后,能够正确地解析,接着发射“常开”按键,门禁那边滴一声响,门缓缓打开,然后5秒后,STM32发送“自动”按键,又是滴的一声,门自动关上。

到这里为止,工作基本上完成一半了。剩下的就是在树莓派上开发蓝牙的BLE Peripheral,然后再开发一个APP来与之对接了。

利用蓝牙连接APP

Linux系统上面主要用的是Bluez( http://www.bluez.org/ )来作为蓝牙的协议栈,一般都是通过串口来与蓝牙芯片进行通信,有的蓝牙模块是USB接口,但是也是一个USB转串口的模块,所以对于蓝牙协议栈来说是一样的。而Bluez分为两部分,一部分是用户层的库,单独发布的,另一部分是Kernel的驱动,是随着Linux内核一起发布的。我们需要关心的是用户端的Library。

首先查看树莓派自带bluez的版本,通过bluetoothd –version得到当前的版本是43,而官网上最新的是5.50,所以在树莓派上面wget把source code下载下来,解压,然后./configure –enable-experimental –enable-debug –enable-deprecated –enable-testing,其中–enable-experimental至关重要,因为默认bluez不启动experimental选项,只有经典蓝牙的功能,而BLE的功能都在experimental里面。所以要使用BLE必须带上experimental选项。configure完就是简单的make和make install了,安装成功后,查看版本,为5.50,说明安装成功 用手机实现射频开关

Bluez有一个核心服务就是Bluetoothd,它能够管理设备接入和验证、蓝牙广播、服务注册和管理等功能,而与客户端是通过DBUS进行通信,通过一些对象的代理,去调用对应的方法。Bluetootd作为一个service启动,默认是不启用experimental功能的,所以需要在service文件里面加入-E选项,这样,Bluetoothd启动的时候才会加载BLE相关的功能。 用手机实现射频开关

由于以前从来没使用过Bluez,又是漫长的学习和研究。Bluez源代码里面提供了一些example,大部分都是基于python的示例,然后通过DBUS与bluetoothd来通信,实现一些服务的注册和使用。

不过最后还是利用 C语言 完成了程序的编写,虽然python基于DBUS也可以完成类似的功能,但是DBUS的接口无法操作广播的interval,默认广播的interval是1280ms,这个广播周期太长,无法快速让手机搜索到,只能调用C语言的接口,手动发送HCI命令来把interval设置到30ms,所以参考了bluetoothctl这个 工具 的代码,完成了所有代码的编写。程序运行起来后,会生成一个名字叫nsfocus_door的蓝牙设备,利用手机上的一个BLE工具(nRF Connect)可以进行BLE扫描和设备连接等操作,可以搜索到对应的设备

用手机实现射频开关

在BLE的GATT里面自定义了一个service和一个characteristics,如下图(由于UUID是随便给的,没有遵循SIG的规范,所以显示的是Unknown,但是不影响使用) 用手机实现射频开关

只要往这个characteristics写入一个任意的数据,那么就会触发开门的操作。

最后就剩下写一个安卓app了,这个也是一个重任,虽然看起来原理比较简单,就是搜索一个BLE设备,然后connect,读取所有service,并向目标characteristics写入一个数据。难点在于不同安卓版本对蓝牙的支持不太一样,新系统已经放弃了一些老版本接口的使用,所以在app代码里面,需要判断当前安卓系统的版本来调用不同的方法,否则,很容易出现问题。

这里推荐大家用两个BLE的SDK,是由Nordic公司制作的,源代码在github上面可以下载,在Android Studio也可以直接引用jcenter里面的库。

  • Android-BLE-Library
  • Android-Scanner-Compat-Library

这两个SDK能够隐藏了一些复杂的BLE操作,而且能够兼容从4.4到8.0的安卓系统,用起来比较方便,开发者可以把主要的精力花在业务代码上。不过这两个库用的语法需要JDK 1.8版本才支持(主要是用了一些Lambda表达式),而Android Studio默认用的是1.7的版本,需要在build.grade里面加入一个compileOptions

用手机实现射频开关

APP开发的效果展示

以下是APP的图标

用手机实现射频开关

以下是APP的界面,比较简单,但是功能足够用

用手机实现射频开关

App进入后,无需用户任何操作,会自动去搜索蓝牙并进行相应的操作,开门完成后,默认会自动退出,整个过程不超过5秒,最短2秒就可以完成,开门是相当的方便。如果第一次操作不成功,用户可以点击中间的开门按钮,会重新来过。

存在的问题

  • 射频的安全性:由于电动门遥控的数据没有加密也没有滚码防止重放攻击,所以一旦被外部盗取,就很危险
  • 命令的丢失,由于先要发送“常开”命令,再发送“自动”命令,万一“自动”命令没有收到,那么门就不会自己关上了。必须再开一次门,听到两个滴声,才能离开。射频是单向通信,无法做到闭环控制,无法保证每次发命令都能接收到,特别是在干扰比较大的情况下。
  • BLE的数据写入未加密,没有防止重放攻击。APP没有做加固,代码没有混淆,安全机制不够,如果能够与云端结合管理加密秘钥就最好了。

经验的总结

  • 整个项目做下来,还是花了相当多的精力,主要是bluez的开发那一块,的确非常多的坑,而且也没有什么文档可以参考,主要就是研究bluez的source code,中途由于碰到了很多问题,一度想过放弃,但最终还是坚持下来了,说多了都是泪。
  • 由于要做到应用开机启动,还要在bluetoothd启动后再启动,而bluetoothd依赖于hciattach,但是hciattach初始化很慢,所以在应用启动的时候需要不断去查询hciattach是否初始化完毕,然后不断轮询,否则后面的操作都会失败。这种问题在正常开发的时候从来不会遇到,真正部署才能发现问题。
  • 平时加班做做,也不影响正常上班的时间,对提升自己的能力还是挺有帮助的。至少学了很多方面的知识。
  • 淘宝采购的一些物料和模块,也不贵,加起来不到20块钱,所以学习成本还是很低的,至少没有大出血。
  • 如果有人能帮我开发一个IOS版本就更好了

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ruby on Rails Tutorial

Ruby on Rails Tutorial

Michael Hartl / Addison-Wesley Professional / 2012-8-6 / USD 44.99

"Ruby on Rails(TM) Tutorial by Michael Hartl has become a must-read for developers learning how to build Rails apps." -Peter Cooper, Editor of Ruby Inside Using Rails, developers can build web applica......一起来看看 《Ruby on Rails Tutorial》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具