自发电遥控开关接收的研究
前面提到了315Mhz和433Mhz 发送接收模块,淘宝上这种发送+接收模块一套只要3.8。这次文章研究的目标是:如何让接收模块能够收到自发电无线开关(TEL0146)发送的信号。
首先需要对这种模块的基本原理有了解,根据【参考1】资料,它使用调幅AM,OOK方式。我的理解是这种方式下:用无信号表示当前输出为0;发射433.29Mhz的无线信号表示当前输出为1。
此外与这种方式类似还有一种ASK(“振幅键控”)的调制方式:当需要输出0时,发射幅度较低的433.29Mhz的无线信号(下图A1);当输出1时,发射幅度较高的433.29Mhz的无线信号(下图A2)。
在【参考4】给出的频谱分析的结果中可以更清晰的看到二者区别,左侧是 ASK,右侧是 OOK 方式。
当然,我手上没有频谱仪无法“看”到实际发射的信号,但是我可以使用示波器查看接收模块的输出引脚。接收模块有4个引脚,分别是:GND,DATA,DATA,VCC(中间2个引脚都是用于输出的DATA)。经过实验该接收模块刚好能够接收到手中这个发射器的数据,因此就先用它进行实验。
接下来使用示波器直接观察 DATA引脚,了解一下模块输出的形式。使用的代码是RCSwitch中的例子:
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
mySwitch.enableReceive(2);// Receiver on interrupt 0 => that is pin #2
}
void loop() {
if (mySwitch.available()) {
Serial.print("Received ");
Serial.print( mySwitch.getReceivedValue() );
Serial.print(" / ");
Serial.print( mySwitch.getReceivedBitlength() );
Serial.print("bit ");
Serial.print("Protocol: ");
Serial.println( mySwitch.getReceivedProtocol() );
mySwitch.resetAvailable();
}
}
当按下“开”按钮,模块收到 16529064(0x00FF 36A8);当按下“关”按钮,模块收到 16529060(0x00FF 36A4).
使用示波器查看接收模块的输出引脚,可以看到如下波形。就是说当没有数据的时候,引脚为高,之后会拉低一段时间,然后发送数据,发送完毕再次拉高。
类似的,当我使用自发电无线开关时,接收模块也会输出类似波形。因此,它无法工作的问题是软件解码的问题,而不是硬件的问题。
在 RCSwitch.cpp 有下面一段代码:/* Format for protocol definitions:
* {pulselength, Sync bit, "0" bit, "1" bit, invertedSignal}
*
* pulselength: pulse length in microseconds, e.g. 350
* Sync bit: {1, 31} means 1 high pulse and 31 low pulses
* (perceived as a 31*pulselength long pulse, total length of sync bit is
* 32*pulselength microseconds), i.e:
* _
* | |_______________________________ (don't count the vertical bars)
* "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse
* and 3 low pulses, total length (1+3)*pulselength, i.e:
* _
* | |___
* "1" bit: waveform for a data bit of value "1", e.g. {3,1}:
* ___
* | |_
*
* These are combined to form Tri-State bits when sending or receiving codes.
*/
#if defined(ESP8266) || defined(ESP32)
static const VAR_ISR_ATTR RCSwitch::Protocol proto[] = {
#else
static const RCSwitch::Protocol PROGMEM proto[] = {
#endif
{ 350, {1, 31 }, {1,3 }, {3,1 }, false }, // protocol 1
};
意思是使用高电平和低电平不同的比例来确定当前数值为0还是1.比如:高电平持续350us,然后出现一个1050us的低电平,那就是1:3,在 Protocol 1 中,这个值为0;反之高电平持续1050us,然后出现一个350u的低电平,那就是3:1,表示值为1。接下来我们要首先查看一下正确的抓取值,然后再反推编码方式。我们使用 rf433snif-main 这个代码,这个是专用用来统计时间的分析工具。抓取如下,左侧是原始数据,右侧是我们标记的结果(标注了前面49个数据,因为第50个数据有跟着一个很长的延时,猜测是在数据传输过程中一笔数据会重复三次):
Signal duration: 1445023 us
N LOW,HIGH
-----BEGIN RF433 LOW HIGH SEQUENCE-----
, 11166
000 1076, 384 1
001 1072, 384 1
002 1072, 392 1
003 1064, 392 1
004 1064, 392 1
005 1064, 396 1
006 328,1116 0
007 328,1120 0
008 324,1120 0
009 320,1116 0
010 1060, 396 1
011 1064, 400 0
012 324,1120 0
013 1056, 408 1
014 1052, 408 1
015 316,1128 0
016 1048, 412 1
017 312,1128 0
018 1048, 412 1
019 312,1136 0
020 1044, 416 1
021 308,1132 0
022 308,1136 0
023 308,1136 0
024 308, 11204 0
025 1048, 412 1
026 1048, 416 1
027 1044, 416 1
028 1044, 416 1
029 1044, 420 1
030 1040, 416 1
031 304,1140 0
032 304,1140 0
033 304,1136 0
034 308,1136 0
035 1044, 420 1
036 1044, 420 1
037 304,1136 0
038 1044, 416 1
039 1044, 420 1
040 304,1140 0
041 1040, 424 1
042 300,1140 0
043 1040, 420 1
044 300,1140 0
045 1040, 420 1
046 304,1140 0
047 304,1140 0
048 304,1144 0
049 300, 11224
….中间省略…..
-----END RF433 LOW HIGH SEQUENCE-----
Waiting for signal...
看起来这里的猜测需要一些运气,重新写出来是下面这样:
1111110000100110101010000111111000011011010101000
1F84D50FC36A8
有了上述的知识之后,目标非常明确,设定用于接收的GPIO引脚上会出现一个高低电平的的序列,我们需要根据序列的时间间隔来判断无线开关是否有按下。同样的代码抓取(特别注意,下面的序列是通过给自发电开关上电的方法来让其发射,这样更稳定的。具体抓到的原始数据在后面),整理之后可以看到下面的有规律的排列:
3098,104,296,104,296,104,297,104,296,104,296,104,296,104,296,105,296,104,296,104,296,104,296,305,96,304,96,104,296,104,296,305,96,304,96,304,96,304,96,304,97,303,97,103,297,104,296,104,296,104,
就说说,拉低3100us,然后是 100us 高,300us低….因此,理论上修改前面的Protocol结构体加入这个特征应该是可以实现的,但是不知道什么原因,无法收到。最终,我编写一个简化版的识别代码:
const unsigned long int SelfSwitch[] =
{
100, 300, 100, 300, 100, 300, 100, 300, 100, 300,
100, 300, 100, 300, 100, 300, 100, 300, 100, 300,
100, 300, 300, 100, 300, 100, 100, 300, 100, 300,
300, 100, 300, 100, 300, 100, 300, 100, 300, 100,
300, 100, 100, 300, 100, 300, 100, 300
};
static int receiverPin = 2;
static int interruptPin = 0;
unsigned long lastTime = 0;
unsigned long int timings;
unsigned int pos;
boolean shoot;
void setup() {
Serial.begin(1000000);
pinMode(receiverPin, INPUT_PULLUP);
interruptPin = digitalPinToInterrupt(receiverPin);
lastTime = micros();
attachInterrupt(interruptPin, handleInterrupt, CHANGE);
Serial.println("Waiting INPUT pin HIGH");
Serial.println(sizeof(SelfSwitch) / sizeof(unsigned long int));
while (digitalRead(receiverPin) != HIGH) {}
pos = 0;
shoot=false;
}
int MaxP=0;
void loop() {
if (shoot) {
Serial.println("Fired!");
shoot=false;
}
if (pos>MaxP) {
Serial.println(pos);
MaxP=pos;
}
}
void handleInterrupt() {
if (pos < sizeof(SelfSwitch) / sizeof(unsigned long int)) {
timings = micros() - lastTime;
lastTime = micros();
}
// 对于第一个需要特别处理
if (pos == 0) {
// 如果第一个在之间,那么开始记录
if ((timings > 2900) && (timings < 3100)) {
pos++;
return ;
}
}
// 如果超出范围
if ((timings>SelfSwitch+80)||(timings<SelfSwitch-80)) {
// 超出范围的情况下有可能是新的开始
if ((timings > 2900) && (timings < 3100)) {
pos=1;
return ;
}
pos=0;
} else {
//没有超过范围,满足要求
// 如果到达最后一个,表明发生
if (pos==sizeof(SelfSwitch) / sizeof(unsigned long int)-1) {shoot=true; pos=0;}
else pos++;
}
}
当接收模块收到信号时,GPIO会拉低,首先判断这个是否为 3000us的起始标志(特别注意,从2900到3100us都会被认定为启示标志。同样的,后面判定的信号也有一个容错范围)。起始之后,逐一对照SelfSwitch中定义的序列,如果相同,那么继续下一个,否则重新开始。这样,如果都能匹配上就认为确实收到了无线开关的发送信号。经过测试,代码勉强能够工作,需要离得非常近(5CM),并且需要多按下几次。我猜测是因为发射端功率比较小,并且接收模块灵敏度不是很高的缘故。当然,如果真正想用,需要接收模块更好的天线,更加灵敏的芯片,不妨尝试数字无线开关接收端(TEL0142)。
参考:1. https://baike.baidu.com/item/433m%E6%97%A0%E7%BA%BF%E6%A8%A1%E5%9D%97?fromModule=lemma_search-box2. http://www.energiazero.org/arduino_sensori/Complete%20Guide%20for%20RF%20433MHz%20Transmitter.pdf3. https://www.rfwireless-world.com/Terminology/OOK-vs-FSK-vs-ASK.html4. https://www.solidremote.com/blog/what-is-ask-and-ook-modulation/
附录:1. 抓取的能够正常通讯的遥控器数值:Signal duration: 1445023 usN LOW, HIGH-----BEGIN RF433 LOW HIGH SEQUENCE----- , 11166000 1076, 384 001 1072, 384002 1072, 392003 1064, 392004 1064, 392005 1064, 396006 328,1116007 328,1120008 324,1120009 320,1116010 1060, 396011 1064, 400012 324,1120013 1056, 408014 1052, 408015 316,1128016 1048, 412017 312,1128018 1048, 412019 312,1136020 1044, 416021 308,1132022 308,1136023 308,1136024 308, 11204025 1048, 412026 1048, 416027 1044, 416028 1044, 416029 1044, 420030 1040, 416031 304,1140032 304,1140033 304,1136034 308,1136035 1044, 420036 1044, 420037 304,1136038 1044, 416039 1044, 420040 304,1140041 1040, 424042 300,1140043 1040, 420044 300,1140045 1040, 420046 304,1140047 304,1140048 304,1144049 300, 11224050 1036, 420051 1040, 420052 1040, 420053 1044, 416054 1044, 424055 1036, 424056 300,1144057 304,1140058 304,1140059 304,1140060 1040, 424061 1036, 424062 300,1144063 1036, 424064 1040, 424065 300,1144066 1036, 424067 304,1140068 1040, 428069 296,1148070 1036, 424071 300,1144072 304,1148073 300,1144074 300, 11232075 1036, 420076 1040, 424077 1036, 424078 1040, 424079 1036, 424080 1036, 424081 300,1144082 300,1144083 300,1144084 300,1144085 1036, 424086 1036, 424087 300,1148088 1032, 428089 1040, 420090 300,1148091 1036, 424092 300,1144093 1040, 424094 300,1148095 1032, 428096 296,1148097 300,1148098 300,1148099 300, 11232100 1036, 424101 1040, 420102 1040, 424103 1036, 424104 1036, 424105 1036, 428106 296,1148107 300,1144108 300,1144109 300,1148110 1036, 424111 1036, 424112 300,1144113 1036, 424114 1036, 432115 296,1152116 1032, 424117 300,1148118 1036, 428119 300,1144120 1040, 428121 296,1148122 296,1144123 300,1148124 296, 11232125 508,175872126 200, 880127 676, 160128 848, 124129200000, 0130200000, 0131200000, 0132200000, 0133 12296, 11176134 1072, 392135 1064, 396136 1064, 396137 1064, 400138 1060, 404139 1056, 404140 316,1132141 312,1128142 312,1128143 316,1128144 1052, 412145 1048, 412146 312,1128147 1052, 408148 1048, 412149 312,1132150 1048, 412151 312,1132152 1048, 412153 312,1132154 1048, 412155 312,1132156 312,1136157 308,1136158 308, 11212159 1048, 412160 1048, 412161 1048, 416162 1044, 416163 1044, 412164 1048, 416165 308,1136166 308,1136167 308,1136168 308,1136169 1048, 416170 1044, 416171 308,1132172 1048, 416173 1044, 416174 308,1136175 1044, 416176 308,1140177 1040, 416178 308,1140179 1044, 416180 308,1140181 308,1140182 304,1140183 304, 11224184 1044, 416185 1044, 416186 1044, 416187 1044, 416188 1044, 416189 1048, 420190 304,1144191 304,1136192 308,1140193 304,1140194 1044, 416195 1044, 420196 308,1140197 1044, 420198 1044, 420199 304,1140200 1044, 420201 304,1140202 1044, 420203 304,1140204 1044, 420205 304,1140206 308,1140207 304,1140208 308, 11228209 1044, 420210 1040, 420211 1040, 420212 1040, 420213 1044, 416214 1044, 416215 308,1144216 304,1140217 308,1144218 300,1140219 1044, 416220 1044, 420221 308,1136222 1040, 420223 1040, 424224 300,1144225 1040, 424226 300,1144227 1040, 420228 304,1144229 1040, 420230 304,1140231 304,1140232 304,1140233 304, 11236234 1040, 416235 1044, 420236 1044, 420237 1044, 420238 1044, 420239 1044, 420240 304,1140241 304,1148242 300,1140243 308,1136244 1044, 420245 1040, 420246 304,1140247 1040, 420248 1040, 424249 304,1140-----END RF433 LOW HIGH SEQUENCE-----Waiting for signal... 2.抓取的自发电开关数据。⸮⸮)⸮Signal duration: 210193 usN LOW, HIGH-----BEGIN RF433 LOW HIGH SEQUENCE----- , 38599000 116,3084001 112, 284002 108, 288003 108, 284004 112, 284005 108, 284006 112, 284007 112, 284008 112, 284009 112, 284010 108, 284011 108, 288012 308, 88013 308, 88014 108, 288015 108, 288016 308, 92017 304, 92018 304, 92019 304, 92020 304, 92021 304, 92022 104, 292023 104, 292024 104, 292025 104,3092026 104, 288027 104, 292028 104, 292029 104, 292030 104, 292031 104, 292032 104, 292033 104, 292034 104, 292035 104, 292036 104, 292037 304, 92038 304, 92039 104, 292040 104, 292041 304, 92042 304, 92043 304, 92044 108, 98916045 36,1072046 40,2668047 68, 740048 64,3240049 148, 28050 36,2304051 40, 392052 32, 600053 60, 48054 216, 856055 20, 588056 128, 284057 20, 876058 48, 392059 36,1696060 72, 988061 60, 360062 84, 104063 24,1220064 128, 140065 64, 216066 52,1108067 52, 96068 32, 100069 16, 176070 44, 760071 88, 192072 60, 648073 100, 720074 196, 752075 100,1136076 96, 68077 32, 288078 52, 284079 20, 176080 136, 372081 24, 60082 60, 140083 56, 76084 352, 492085 36, 320086 76, 244087 100, 144088 364, 720089 68, 132090 204, 336091 236, 32092 100, 100093 232, 380094 192, 28095 264, 132096 28, 28097 136, 752098 60, 312099 88, 360100 236, 588101 104, 432102 92, 156103 56, 40104 176, 252105 72, 456106 36, 92107 160, 88108 112, 336109 232, 56110 264, 80111 56, 160112 136, 44113 272, 88114 136, 40115 108, 112116 372, 84117 56, 532118 284, 48119 360, 88120 36, 164121 80, 88122 88, 212123 64, 12124 32, 116125 124, 192126 376, 260127 112, 296128 56, 84129 128, 328130 128, 592131 200, 608132 380, 172133 40, 140134 100, 148135 56, 480136 64, 356137 640, 356138 120, 12139 16, 220140 124, 536141 320, 84142 60, 80143 44, 128144 120, 52145 72, 44146 108, 36147 204, 76148 88, 224149 308, 108150 8, 52151 64, 8152 128, 36153 80, 428154 204, 96155 108, 68156 88, 180157 116, 28158 172, 136159 76, 40160 92, 84161 52, 516162 472, 472163 156, 84164 292, 368165 180, 120166 268, 196167 248, 0168 188, 236169 172, 104170 24, 36171 140, 180172 180, 192173 108, 136174 112, 140175 72, 16176 292, 48177 164, 136178 8, 240179 76, 92180 156, 32181 264, 292182 600, 260183 88, 76184 412, 88185 108, 184186 60, 52187 236, 0188 168, 68189 76, 80190 100, 568191 436, 156192 108, 72193 68, 304194 120, 544195 4, 20196 180, 68197 48, 48198 188, 244199 160, 104200 496, 184201 148, 276202 8, 116203 64, 24204 168, 520205 20, 172206 104, 340207 108, 72208 384, 48209 164, 164210 176, 76211 228, 40212 200, 248213 188, 132214 328, 92215 152, 112216 176, 64217 132, 80218 76, 144219 196, 228220 140, 40221 16, 280222 272, 100223 900, 152224 48, 92225 572, 52226 68, 196227 120, 256228 156, 128229 48, 48230 36, 128231 772, 232232 516, 60233 272, 172234 164, 92235 568, 144236 80, 120237 16, 8238 164, 28239 16, 88240 304, 180241 652, 340242 48, 108243 116, 32244 264, 36245 200, 192246 448, 68247 180, 552248 80, 80249 80, 76-----END RF433 LOW HIGH SEQUENCE-----
Waiting for signal...
本位接收的完整代码:
用于监听信号的代码:
厉害厉害!! 赞赞赞赞赞 厉害厉害 不错不错
页:
[1]