解码
http://www.arduino.cn/thread-4465-1-1.html
软件
在Arduino上写的代码一般都很简单,我们要做的就是发射一个信号(或者说编码)去控制遥控开关。
我们要用到一个叫RCSwitch的库(http://code.google.com/p/rc-switch/)。有兴趣的可以去这个网站看看它支持的芯片:SC5262 / SC5272, HX2262 / HX2272, PT2262 / PT2272, EV1527, RT1527, FP1527 or HS1527. 把这个库按照说明下载到本地并加入到库里面以后,我们就可以用了。
解码
我们第一步要做的是解码,电脑连上Arduino和接收模块,运行Examples>RCSwitch>ReceiveDemo_Advanced并打开串口监视器,然后按遥控器上的按钮,串口监视器里会显示读取到的原始数据和解码以后得到的编码。
示例:
Decimal: 1004883 (24Bit) Binary: 000011110101010101010011 Tri-State: 0011FFFFFF01u PulseLength: 163 microseconds Protocol: 1
Raw data: 5068,136,444,136,516,136,516,136,516,464,192,464,192,464,188,472,….
其中1004883是信号的编码,PulseLength是脉冲长度,Protocol是协议编号。记下来后面发射的时候有用。
发射
现在要试试用Arduino发射相同的编码去控制遥控开关。打开Examples>RCSwitch>SendDemo.修改脉冲长度,编码,删除没用的代码就可以运行一下了。运气好的话,这就成功了。
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
mySwitch.enableTransmit(10);
mySwitch.setPulseLength(163);
}
void loop() {
mySwitch.send(1004883, 24);
delay(2000);
}
2库解析
attachInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE);
开启0中断 2号引脚 每次电平改变触发handleInterrupt
void RECEIVE_ATTR RCSwitch::handleInterrupt() {
static unsigned int changeCount = 0; // 电平改变次数
static unsigned long lastTime = 0; // 上次记录时间
static unsigned int repeatCount = 0; // 重复次数
const long time = micros(); // 当前时间
const unsigned int duration = time - lastTime;// 当前减去上次时间 的时间差
if (duration > RCSwitch::nSeparationLimit) { // 如果两次电平改变间隔大于规定误差 //长时间没有发生信号电平变化这可以是两次传输之间的差距。
if (diff(duration, RCSwitch::timings[0]) < 200) {
// This long signal is close in length to the long signal which
// started the previously recorded timings; this suggests that
// it may indeed by a a gap between two transmissions (we assume
// here that a sender will send the signal multiple times,
// with roughly the same gap between them).
//这个长信号与开始先前记录的时序的长信号相接近。这表明它可能确实是由两个传输之间的差距(我们在这里假设发送者将多次发送信号,两者之间的差距大致相同)。
repeatCount++;
if (repeatCount == 2) {
for(unsigned int i = 1; i <= numProto; i++) {
if (receiveProtocol(i, changeCount)) {
// receive succeeded for protocol i
break;
}
}
repeatCount = 0;
}
}
changeCount = 0;
}
// detect overflow
if (changeCount >= RCSWITCH_MAX_CHANGES) {
changeCount = 0;
repeatCount = 0;
}
RCSwitch::timings[changeCount++] = duration;
lastTime = time;
}