智能开关的无线协议详解
本帖最后由 Alexie 于 2013-5-17 14:42 编辑ITEAD智能开关使用的是433MHz无线频段进行数据通讯,采用的是OOK的调制,通过占空比做简单的编码表示0和1。我们知道这样做确实不太稳定和可靠,不过因为单火线的供电方式只能提供不到100uA的持续电流,我们是在无法使用蓝牙,wifi等稳定可靠的通讯方式,433MHz的简单调制通讯是综合了供电问题和距离问题后的一个妥协选择,使用这个方法我们可以让开关直接的通讯距离达到30米,普通的房间之间穿墙传输都可以轻松完成。
下面我们详细介绍下智能开关的数据传输格式。开关间的每一次数据传输都是由4段数据流+结束码组成,而每段数据流又由引导码+32位数据组成,如下图所示。
从图上的时序可以看出,引导码是由一段400us的高电平加上一段10ms的低电平信号而构成。紧接着的32位数据是由一个8位的命令加上24位的IDKEY而构成的,对于智能开关的按键来说,每一个IDKEY都是独一无二的。其中,数据0是由一段400us的高电平加上一段400us的低电平而构成;而数据1是由一段400us的高电平加上一段1.2ms的低电平而构成。引导码和32位数据会被重复发送四次,以免数据接收终端由于恶劣的环境而不能有效地接收到首次数据。最后,结束码是由一段400us的高电平,一段10ms的低电平再加上一段400us的高电平而构成。这样就完整地发送了一次命令。
我们知道你们肯定要吐槽为什么使用的不是定长的编码,而是非等长的。其实,我们原先的设计是400us高电平加上1.2ms低电平表示数据1,1.2ms的高电平加上400us的低电平表示数据0,这样每个数据都是等长的1.6ms。 不过最后因为一言难尽的原因,最后协议被修改为以上的格式,这也是综合了各种情况后的妥协结果。
智能开关的固件里现在支持下面的几种命令:
控制开:0x02+ 24位IDKEY
控制关:0x03+ 24位IDKEY
控制反转状态: 0x01+ 24位IDKEY
请求配对指令: 0x40000000
开状态: 0x06+ 24位IDKEY
关状态: 0x07+ 24位IDKEY
配对成功指令: 0x50+ 24位IDKEY
若智能开关上的某一个按键被你的设备,遥控器,手动触摸中任意一种方式控制改变了状态,它将在改变状态后的0.4s左右发送自身当前状态信息。捕捉此信息即可得到相应按键的当前状态。
上面的内容是智能开关使用的通讯方式,我们知道,通过433MHz的方式我们是无法直接通过手机来直接控制它的,因为手机不支持433MHz频段的无线通讯。所以,我们就做了一个智能中转盒来完成这个从手机到433MHz的无线中转。那么,为了支持这些控制指令,我们必须为手机也建立一个简单的命令协议,以便手机或者其他终端通过蓝牙发送指令来控制开关。
下面就是我们为手机蓝牙通讯部分建立的一个简单控制协议:
注* 奇偶校验位为字节2到字节5的奇偶校验和。
手机通过蓝牙发送对应的指令,中转盒即可给转换成对应的智能开关指令,并通过433MHz的无线通讯协议方式发送给智能开关。
当然除了使用智能中转盒外,你也可以使用其他任何设备加上433MHz的无线通讯模块来控制智能开关,为了方便大家DIY,我们提供了一个专门的智能开关通讯库(Arduino版本),让你可以通过Arduino控制板加上433MHz的无线模块,简单调用433MHz发送和接收函数来控制智能开关了。
接下来我们简单介绍一下“ITEAD Intelligent Switch Protocol”库中的一些函数:
Switch.Init(baud)
函数功能:初始化智能中转盒,包括串口的波特率、设置发射引脚为输出、初始化接收中断等。
函数参数:
baud:串口的波特率
Switch.PAIR()
函数功能:发送请求配对命令0x40000000
Switch.ON(IDKEY)
函数功能:开启ID地址为IDKEY的智能开关。
函数参数:
IDKEY:此参数为32位,因为智能开关对应的IDKEY只有24位,高8位为无效位,后24位才是真正的有效IDKEY。
Switch.OFF(IDKEY)
函数功能:关闭ID地址为IDKEY的智能开关。
函数参数:
IDKEY:此参数为32位,因为智能开关对应的IDKEY只有24位,高8位为无效位,后24位才是真正的有效IDKEY。
Switch.INVERT(IDKEY)
函数功能:反转ID地址为IDKEY的智能开关的当前状态。
函数参数:
IDKEY:此参数为32位,因为智能开关对应的IDKEY只有24位,高8位为无效位,后24位才是真正的有效IDKEY。
Switch.QUERY(IDKEY)
函数功能:查询ID地址为IDKEY的智能开关当前的状态。
函数参数:
IDKEY:此参数为32位,因为智能开关对应的IDKEY只有24位,高8位为无效位,后24位才是真正的有效IDKEY。
Switch.Available()
函数功能:433接收到开关返回给串口的数据的字节总数。
Switch.Read()
函数功能:读取433接收到开关返回给串口的数据。
库里面带有一个demo的例程,如下:
#include <CloudSwitch.h>
void setup(){
Switch.Init(115200);
Switch.ON(0x000002C2); //Turn on the switch with 0x0002C2 IDKEY.
}
void loop(){
while(1)
{
if(Switch.Available())
{
unsigned char value = Switch.Read();
Serial.write(value);
}
}
}
把上面的demo程序下载到智能中转盒或者Arduio开发板中,就可以实现开启IDKEY为0x0002C2的智能开关,并且通过串口可看到智能开关以HEX形式返回的32位数据(8位状态位+24位IDKEY)。如果开关通过遥控或触摸改变开关状态,在串口上也会打印出相应的状态。
mark{:soso_e179:} 好像可以直接用来控制我们的BOXZ机器人了吧 手里还没有433模块,这个用的是软串口?
看到“这样每个数据都是等长的1.6ms”让我想起了红外的NEC协议:lol 幻生幻灭 发表于 2013-5-18 15:05 static/image/common/back.gif
手里还没有433模块,这个用的是软串口?
看到“这样每个数据都是等长的1.6ms”让我想起了红外的NEC协议:lo ...
不是串口哦 就是用一个普通IO口而已~ 加了个定时器做计时
433MHz的穿透性强点 如果2.4G这种功耗下根本无法工作..就算有低功耗的距离也成问题 :lol非常棒的开源开关 好贴要果断mark!:lol Alexie 发表于 2013-5-18 20:31 static/image/common/back.gif
不是串口哦 就是用一个普通IO口而已~ 加了个定时器做计时
433MHz的穿透性强点 如果2.4G这种功耗下根本 ...
在吗。。。为啥我用的上边的方法怎么不能调试呢 不错,谢谢啦! 好帖子,赞一个! 深受启发!好! 好帖子,赞一个!:D:D:D:D :):):):):):)好帖子,赞一个 太厉害了,可以留个联系方式吗?:)
页:
[1]