sui77 / rc-switch

Arduino lib to operate 433/315Mhz devices like power outlet sockets.
1.94k stars 662 forks source link

Universal receiver and sniffer and protocol generator #103

Open Martin-Laclaustra opened 7 years ago

Martin-Laclaustra commented 7 years ago

Update 2017/04/30: Working on Raspberry Pi, ESP8266, and Arduino (tested). Use: git clone -b protocollessreceiver https://github.com/Martin-Laclaustra/rc-switch.git Among the examples, the sketch "ProtocolAnalyzeDemo" ease the creation of new protocols.

This works for single-sync-gap protocols with uniform width bits (all bits have the same length).

======================= Dear Suat and collaborators, thank you for your work developing the library. I have seen the request for receiving codes for unknown protocols and I have explored some ideas in a fork. It works (except for the inverted protocols) and receives the information regardless that the protocol is unkown. It is currently the "protocollessreceiver" branch at my fork. I added lots of comments, and the commits are also quite explicit. The changes can be reviewed in chronological order across the commits history to get the idea. Detection is based on repetition of the duration of a longer gap, and then regularity of the length of the bits read between those gaps. I created a verbose sniffer that performs a complete description of the signal received and proposes a protocol that can be copied directly into the protocol list if the aim is to generate new signals. I tested this on Raspberry pi because I do not have Arduino. However you should not have problems porting it to Arduino for testing.

To test this in Raspberry pi, once the wiringpi library is installed:

git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

write:

git clone -b verbosesnifferwithprotocollessreceiver --single-branch --recursive git://github.com/Martin-Laclaustra/433Utils.git
cd 433Utils/RPi_utils

edit RFSniffer.cpp to set your PIN in the line "int PIN = 2;"

make
sudo ./RFSniffer -v

I sent from another unit (as an example): sudo ./codesend 12345 4 and got the following:

Received 12345

=============================================
=============================================

GENERAL
=======
Received 12345
Bitlength 24
Protocol 4
Delay(short pulse length in us) 458
(delay from rc-switch is calculated from the sync gap and requires previous knowledge of the protocol)
(The following assumes protocols that detect the low period of sync)
(The next information is probably wrong for inverted protocols)
Sync bit high-low durations (in us) 442 2352

RAW SIGNAL (us)
===============
2352 
479 1174 468 1187 476 1184 470 1183 472 1182 475 1184 472 1188 463 1193 
467 1192 463 1189 1223 428 1224 437 457 1206 452 1207 450 1206 447 1206 
453 1201 455 1203 1208 459 1197 449 1206 451 441 1213 444 1209 1204 455 
442 

STATISTICS
==========
Data bit duration = 1656 and standard deviation (should be less than 10%) = 4.36
Do not use the rest of the information if big standard deviation
Long-to-short duration ratio for data bits (rounded) 3
Short duration (delay) recalculated from rounded ratio and average bit duration 414
Sync bit (in multiples of the previous short duration) 1 6

Proposed protocol for RCswitch
{ 414, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }
Note: inverted protocol is not implemented

STATISTICS OF VARIATION BY LEVELS
=================================
(These are probably artifacts from detection delays or signal creation)
(might be completely ignored, but pay attention to them if big differences are present and emission does not work)
number of bits set (in 12345): 6
longup, longdown, shortup, shortdown
1210, 1194, 461, 446
this might be useful for tweaking emmitting algorithms

=============================================
=============================================

I hope that this can be useful to figure out new protocols (or to be used directly for detection). The library should work almost exactly like the original (except for inverted protocols, and might be too permissive in identifying the protocol), and returns all data and protocol, and protocol is set to 0 when no protocol roughly matches.

Martin-Laclaustra commented 7 years ago

I updated the code to provide reasonable recognition and decoding capacity for INVERTED signals. Now it is a complete possible drop-in replacement for the original receiving code of rc-switch, with the advantage that it can also recognize UNKNOWN PROTOCOLS (that is, with different timings to those in current protocols' table, given that a minimum similar structure is present).

TEST: sudo ./codesend 987654 6 from one device produced

Received 987654

=============================================
=============================================

GENERAL
=======
Received 987654
Bitlength 24
Protocol 6
...

in the one with the receiver.

I would appreciate if someone tested whether this works equally well with arduino and ESP8266. This is a step forward towards a possible recording - playing back signals from unknown protocols, but without requiring to record the whole signal, but only the essence (short pulse length, sync timings, short-long ratio, and inversion + code in binary).

kyet commented 7 years ago

Hi. In my test, DC250, AC114 are not working. I tried both real remote controller and code (protocol 7 and 8).

Here is experimental results,

Sender

541 [~/rc-switch] $ sudo ./codesend 12345 4      
sending code[12345]                              

Receiver

Received 12345

=============================================
=============================================

GENERAL
=======
Received 12345
Bitlength 24
Protocol 1
..skip..

confirm that receiver is working. But there is no log on DC250 and AC114.

Martin-Laclaustra commented 7 years ago

Strange... did you use the protocollessreceiver branch of rc-switch?

In the first place, @kyet, thank you for testing!

My results were positive, the protocollessreceiver branch of the library was able to detect these new protocols out-of-the-box. May I ask you to revise your test procedure? I am particularly interested in the results of the test for the original remote controls, but please, check first that you are able to reproduce this following test (detection of signals generated by rc-switch library).

I cloned fresh versions of ninjablocks/433Utils and sui77/rc-switch (I could have used my branches but I did not want to enter any additional factor to signal generation) in one device with an emitter connected. I added the following protocols to rc-switch.cpp

{ 150, { 34,  3 }, {  1,  3 }, {  3,  1 }, false },    // protocol 7 (AC114)
{ 360, { 13,  4 }, {  1,  2 }, {  2,  1 }, false },    // protocol 8 (DC250)
{ 650, {  1, 10 }, {  1,  2 }, {  2,  1 }, true }      // protocol 9 (Mandolyn/Lidl TR-502MSV/RC-402/RC-402DX)

(The last one is from a recent commit)

I cloned fresh versions of ninjablocks/433Utils and Martin-Laclaustra/rc-switch (-b protocollessreceiver) in one device with a receiver connected. Note that this version of rc-switch does NOT include the new protocols. git clone -b protocollessreceiver git://github.com/Martin-Laclaustra/rc-switch.git

And used these three commands in the device with the emitter connected:

$ sudo ./codesend 712347 7
$ sudo ./codesend 812348 8
$ sudo ./codesend 912349 9

And this was achieved in the receiver device:

$ sudo ./RFSniffer
Received 712347
Received 712347
Received 712347
Received 712347
Received 812348
Received 812348
Received 812348
Received 812348
Received 912349
Received 912349
Received 912349
Received 912349

I would be grateful if some other programmers would test and try to reproduce these successful results (also reproduce it with Arduino), and also test original remotes of different brands.

GMXX commented 7 years ago

Just tried the AC114 protocol code and it doesn't work either, both with my own remote and code. Anyone figured this out?

kiralikbeyin commented 7 years ago

@Martin-Laclaustra thanks alot for the example in #135

image Raw data : 356,464,356,196,612,216,596,220,592,500,324,224,588,504,312,240,584,508,312,232,584,508,312,240,572,516,304,248,568,520,300,252,568,248,568,260,560,536,284,256,556,532,288,256,568,260,556,264,552,9568,364,460,352,196,612,216,596,224,584,508,320,232,588,504,308,240,580,512,308,240,576,512,308,240,576,524,296,244,572,520,304,244,572,252,564,260,552,532,296,256,556,532,292,256,564,260,552,268,552,9572

@Martin-Laclaustra 1-I counted but i don't know how to use 11101010101010111010111 (is this count true?) 2-{1,36} Where did "1" came from? I looked other protocols ; { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3 { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5 30 or 6 any example? 3-I installed your fork lib to esp but didnt get any =====STATISTICS===== data, is it working only on Rpi?

Maybe this helps to someone: Now i can decode remocon with; { 270, { 1, 36 }, { 1, 2 }, { 2, 1 }, true } // protocol 10 REMOCON-555 Serial output : 9087528 24 267 11

Suggestion; another source for transmitting / understanding (decoding is like raw data , but transmitting works very good, if you dont need exact decoded dec numbers ) For easy try;

https://github.com/pimatic/RFControl

#include <RFControl.h>
//get your own raw data from lib example 
unsigned long buckets[] = {308, 936, 9632, 0, 0, 0, 0, 0};
char compressTimings[] = {"01101010011001100110101001100101010101010101101002"};

unsigned int qw[] = {368, 876, 996, 264, 976, 284, 964, 288, 332, 920, 956, 292, 332, 920, 956, 300, 324, 924, 948, 312, 936, 316, 936, 324, 300, 948, 928, 328, 296, 948, 304, 948, 308, 936, 312, 940, 312, 932, 324, 928, 320, 932, 320, 932, 940, 320, 928, 332, 296, 9668};
void setup() {
  Serial.begin(9600);
  // RFControl::startReceiving(0); 
  //  RFControl::sendByCompressedTimings (4, buckets , compressTimings, 8);
  //  delay(5000);
  //  RFControl::sendByTimings (4, qw, 50 , 11);
}

and thanks a lot @sui77 !

Martin-Laclaustra commented 7 years ago

I updated the branch:

I have tested this to be working on Raspberry Pi, ESP8266, and Arduino, for the 6 "official" protocols in RCSwitch.cpp, and for a protocol 1 remote control.

Flavien06 commented 7 years ago

Hello, I use remote Mandolyn/Lidl TR-502MSV with RC-710 @Martin-Laclaustra I have install with your git and I add protocol 7,8 and 9.

With "sudo ./RFSniffer -v" i have

https://paste2.org/efekjaBV Proposed protocol for RCswitch { 641, { 115, 1 }, { 1, 2 }, { 2, 1 }, true }

I added the suggested protocol. With protocol 10 "sudo ./RFSniffer -v" https://paste2.org/ksWFcUWG

But they not works ! With : ./codesend 210 10 ./codesend 195 10 I have https://paste2.org/VeXnZIDP

Ideas?

Note: LEM/Ariane YCT-100N with YCR-3500N perfectly work with ./codesend 5242901 1

Martin-Laclaustra commented 7 years ago

I think it is the bit-length. Please note that your protocol is 20 bits and the default sending length is 24 bits. You should dig a little bit in the code to see how to set the bit-length. Please report back with advances. Note: this issue is about the universal receiver. I believe that it is better to open new issues for support of new switches by rcswitch.

mpember commented 7 years ago

Has anyone successfully used this method with an rf3399-based device?

I've been able to get the C-based code found here to work, but would love to be able to use a python version to remove the need to recompile the code each time I want to change something.

As far as I can tell, it uses a 48-bit protocol.

Thanks

Martin-Laclaustra commented 7 years ago

That will not be automatically decoded with my branch. "This works for single-sync-gap protocols with uniform width bits (all bits have the same length)." In the link you provide the signal length for 1s and 0s differs. It looks single-sync-gap though, so you could implement a protocol with rcswitch. Manually record and interpret your signals with SimpleRcScanner and create a protocol. I suggest to open a new issue to describe your progress.

It would look something like: { 290, { 1, 34 }, { 1, 1 }, { 2, 1 }, false }

mpember commented 7 years ago

Thanks for the advice. Unfortunately I don't have any Arduino hardware, only RPi devices. I've ordered a couple of WeMos units, but it will take 4-6 weeks for them to arrive.

Martin-Laclaustra commented 7 years ago

You don't need an Arduino. There are other tools to record the raw signal in RPi. If you do not feel confident to modify the arduino code to work in RPi (should not be very complex), try to record the signal of the transmitter with ReceiveRF.py.

mpember commented 7 years ago

I had a brief attempt as using the python script. I got lost when it complained about needing a license key for the code that generates the graph. I may give it another look after I finish some other parts of the project.

Thanks

Martin-Laclaustra commented 7 years ago

@mpember I ported SimpleRCScanner to Raspberry pi.

You can download it at the rpi_capture branch at my fork of SimpleRCScanner: here.

mpember commented 7 years ago

@Martin-Laclaustra

I had an attempt. The scanner never displayed any output.other than a screen full of 0s.

Since the reason I started down this path was to try and replace an executable with a python equivalent, I have decided to simply replace the few Kambrook sockets that use the unsupported protocol.

I appreciate all the assistance. In the end, it will be easier to give the Kambrook sockets to a mate who already has a number of them. Since he is not using a python-based setup, the advantage of an all-Python codebase isn't applicable.

Martin-Laclaustra commented 7 years ago

@mpember

The scanner never displayed any output.other than a screen full of 0s.

Most probably you are attaching the receiver to the wrong pin. The pin in the code refers to wiringpi numbering. Either change the code or attach the receiver to the correct pin.

Anyway I am sorry that you could not solve your challenge.

mpember commented 7 years ago

Most probably you are attaching the receiver to the wrong pin.

It is possible. After starting from scratch, I took a different approach. I connected both the sending and receiving programs to an unused GPIO pin.

This also removed any chance of noise.

I sent the command 3 times

Here's what I got: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,892752,706,346,375,362,720,381,352,357,740,356,351,370,719,372,360,360,354,370,347,380,349,366,364,359,344,378,348,370,367,353,351,374,348,371,719,370,706,388,332,400,709,370,703,382,355,372,350,371,722,369,720,371,351,368,763,371,350,369,349,370,351,370,349,369,351,370,725,366,363,358,346,375,350,363,728,373,349,369,722,369,713,380,721,364,719,377,721,370,718,382,721,369,721,1244806,607,389,344,371,715,376,353,358,723,368,350,372,722,360,356,359,366,355,339,366,347,360,344,363,342,364,343,362,345,362,367,361,341,365,714,363,713,365,344,374,705,362,713,363,344,362,343,364,716,361,713,365,351,360,715,363,344,363,342,367,340,364,343,362,345,363,714,363,344,362,343,362,345,363,755,392,349,371,731,340,737,371,721,373,719,356,734,370,721,370,723,369,746,1062210,291,372,713,518,217,369,724,376,355,371,725,371,354,372,719,370,366,378,340,349,346,397,345,363,347,364,345,366,346,365,345,366,347,366,347,365,717,367,716,366,344,367,717,365,717,368,339,364,346,366,716,365,717,366,345,366,717,365,347,366,345,367,347,365,346,366,346,366,717,375,343,366,345,365,346,397,719,359,373,369,732,364,726,372,725,374,725,372,726,373,736,361,726,371,746

Is that a clearer representation of the code?

lrv209 commented 6 years ago

Has anyone found that the RC-Switch ReceiveDemo-Advanced sketch wont capture the codes for some RC Transmitters? I have successfully used the sketch to capture the codes for a Watts Clever RC operating on 433.92mHz but I also have an Arlec unit (RC213) supposedly operating on the same frequency but am unable to capture the sent codes. I have tested the sender unit and it works fine and sends a signal that appears binary in shape when viewed on an oscilloscope although I am pretty new to all this so hoping I am seeing and saying things correctly. (I believe the binary signal may be 32bit?/). The Oscilloscope signal is hard to capture as there is also a lot of background noise being captured by the Rx so very hard to get a steady signal and doubt my ability to convert that image to a binary number anyway although I believe it can be done. I have opened the Arlec RC213 Tx and it has RC-10-V1-2 and the number 4801 printed on the board. The transmitter puck has HD R433M printed on it and the 14 pin chip has no ID at all. I have seen the comment above from Martin Laclaustra and do, I think, have the latest version of RC-Switch (2.6.2) downloaded today but cant see the ProtoAnalyzeDemo referenced and while I have found the ProtoAnalyzeDemo sketch it wont compile as it fails at Line 85 "Serial.println((mySwitch.getReceivedLevelInFirstTiming() == 0) ? "down" : "up" );". If anyone has any suggestions for a rank beginner on all the things I am probably doing wrong please help with whatever you can suggest. It would be great to get these codes as my whole house is kitted out in Arlec RC units.

mpor commented 6 years ago

Hi all, thanks to you guys i have been able to finally acquire what my remote is sending.

The point now is that, as far as i understand, there is no straightforward way to emulate it with my own circuit.

I attached a couple of shots of what i grabbed while the remote was sending the 'Turn On' and the 'Turn Off' commands. As you can see, what consistent across a single command, and different across different commands, is the 'Received' field: 2017753 looks to be the code for 'Turn On', and 2017755 for 'Turn Off'; all the rest is not helping me a lot.

Any hint about how i could proceed?

Thanks a lot in advance Mirco

turnoff turnon

Martin-Laclaustra commented 6 years ago

At https://github.com/sui77/rc-switch/blob/a9da9c36820b02fc5613dfe2437e1187bcf5b402/RCSwitch.cpp#L82 replace or add your protocol. Then use the send function with your codes and length (22bits).

mpor commented 6 years ago

Wow! Thanks a lot, i made it working!!! Very good stuff guys, congratulations! And super clear explanations!

kefabean commented 5 years ago

Thanks for this - this has saved my bacon and enabled me to get an Energenie 433Mhz smart socket working again that was intermittently playing ball. Turns out the 'pulselength' was out by just enough to make it work most of the time but fail intermittently. This enabled me to sniff the exact pulselength (from the original remote control) and now I have a working RPi transmitter again! Thanks @Martin-Laclaustra for this awesome bit of code!

bdfreeman1421 commented 5 years ago

Awesome patch - the Universal Sniffer worked great with the recommended decoding on a PAGTR-011 315 MHz transmitter.

aldoaldoaldo commented 5 years ago

I am using rc-switch and a couple 433Mhz tx-rx to transmit small amount of data between 2 points, in other words I don't control a switch. There are other rf tx libs but I have seen this one works also with the ESP WiFi turned on (I guess it is more efficient in the use of the hardware) so I am using it. Protocol 1 for the first tests. However I am thinking that it would be better for me to "create" a new protocol so this device won't interfere (or receive interference) with/from existing switches. While doing this BTW it would be also nice to be able to transmit/rx more than 24 bit. Do you have suggestions about this? Of course this new protocol should:

ChrisCross-33 commented 4 years ago

Hello, I am unable to produce any output with the https://github.com/Martin-Laclaustra/rc-switch/blob/protocollessreceiver/examples/ProtocolAnalyzeDemo/ProtocolAnalyzeDemo.ino on my Arduino. It works with one remote but I cannot seem to find a protocol for the other one. Simply nothing happens and when I ignore the .available() it fills the screen with Unknown encoding

With the help of https://github.com/sui77/SimpleRcScanner/blob/master/htdocs/Sketchbook/SimpleRcScanner.ino I got the raw data: https://gist.github.com/ChrisCross-33/592d43036e3ec541abd594b153f00d71

https://test.sui.li/oszi/ gives me: signal

I think this is:

1000010110100101000010110110100000
xx<-----------32----------------->

but my knowledge of math is limited so I am having trouble figuring out how to turn that into the definition that I can add to the RCSwitch.cpp to put it next to { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1 and the likes

Any help is appreciated.

Bungeefan commented 1 year ago

Hi, sadly I don't really know much about you guys talking here but big thanks to @Martin-Laclaustra!

I bought the "Brennenstuhl Comfort-Line" off Amazon and wasn't able to sniff the codes with either rpi-rf (the python port of rc-switch) nor with the RPi_Utils, but thanks to the branch provided by Martin, I was finally able to easily get the right codes from my remote.

Funnily enough, sending works both with codesend and rpi-rf_send.

Amazon Link (not sponsored): https://www.amazon.de/Brennenstuhl-Funkschalt-Set-Funksteckdosen-Innenbereich-Kindersicherung/dp/B099653MQ4