30 July 2014

433 MHz RF module with Arduino Tutorial 4:

WARNING: Please check whether you can legally use RF transmitters and receivers at your location before attempting this project (or buying the components). This project is aimed at those who are looking to automate their home.

There are 4 parts to this tutorial:

To get the most out of this tutorial - it is best to start at tutorial Part 1, and then progress to Part 2 then Part 3 and then do Part 4 last. Doing the RF tutorials in this order will help you to understand the process better.



Project 4 : 433 Mhz RF remote replacement tutorial

Carrying on from my previous "433MHz transmitter and receiver" tutorials (1,2 & 3): I have thrown away the need to process the signal with a computer. This means that we can now get the Arduino to record the signal from an RF remote (in close proximity), and play it back in no time at all.

The Arduino will forget the signal when powered down or when the board is reset. The Arduino does not have an extensive memory - there is a limit to how many signals can be stored on the board at any one time. Some people have opted to create a "code" in their projects to help maximise the number of signals stored on the board. In the name of simplicity, I will not encode the signal like I did in my previous tutorials.

I will get the Arduino to record the signal and play it back - with the help of a button. The button will help manage the overall process, and control the flow of code.

Apart from uploading the sketch to the Arduino, this project will not require the use of a computer. Nor will it need a sound card, or any special libraries. Here are the parts required:


 

Parts Required:

Fritzing Sketch


 


 
 

Arduino Sketch


 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  
  
  
/* 
  433 MHz RF REMOTE REPLAY sketch 
     Written by ScottC 24 Jul 2014
     Arduino IDE version 1.0.5
     Website: http://arduinobasics.blogspot.com
     Receiver: XY-MK-5V      Transmitter: FS1000A/XY-FST
     Description: Use Arduino to receive and transmit RF Remote signal          
 ------------------------------------------------------------- */
 
 #define rfReceivePin A0     //RF Receiver data pin = Analog pin 0
 #define rfTransmitPin 4  //RF Transmitter pin = digital pin 4
 #define button 6           //The button attached to digital pin 6
 #define ledPin 13        //Onboard LED = digital pin 13
 
 const int dataSize = 500;  //Arduino memory is limited (max=1700)
 byte storedData[dataSize];  //Create an array to store the data
 const unsigned int threshold = 100;  //signal threshold value
 int maxSignalLength = 255;   //Set the maximum length of the signal
 int dataCounter = 0;    //Variable to measure the length of the signal
 int buttonState = 1;    //Variable to control the flow of code using button presses
 int buttonVal = 0;      //Variable to hold the state of the button
 int timeDelay = 105;    //Used to slow down the signal transmission (can be from 75 - 135)

 void setup(){
   Serial.begin(9600);    //Initialise Serial communication - only required if you plan to print to the Serial monitor
   pinMode(rfTransmitPin, OUTPUT);    
   pinMode(ledPin, OUTPUT); 
   pinMode(button, INPUT);
 }
 
 void loop(){
   buttonVal = digitalRead(button);
  
   if(buttonState>0 && buttonVal==HIGH){
     //Serial.println("Listening for Signal");
     initVariables();
     listenForSignal();
   }
   
   buttonVal = digitalRead(button);
   
   if(buttonState<1 && buttonVal==HIGH){
     //Serial.println("Send Signal");
     sendSignal();
   }
   
   delay(20);
 }
 
 
 /* ------------------------------------------------------------------------------
     Initialise the array used to store the signal 
    ------------------------------------------------------------------------------*/
 void initVariables(){
   for(int i=0; i<dataSize; i++){
     storedData[i]=0;
   }
   buttonState=0;
 }
 
 
 /* ------------------------------------------------------------------------------
     Listen for the signal from the RF remote. Blink the RED LED at the beginning to help visualise the process
     And also turn RED LED on when receiving the RF signal 
    ------------------------------------------------------------------------------ */
 void listenForSignal(){
   digitalWrite(ledPin, HIGH);
   delay(1000);
   digitalWrite(ledPin,LOW);
   while(analogRead(rfReceivePin)<threshold){
     //Wait here until an RF signal is received
   }
   digitalWrite(ledPin, HIGH);
   
   //Read and store the rest of the signal into the storedData array
   for(int i=0; i<dataSize; i=i+2){
     
      //Identify the length of the HIGH signal---------------HIGH
      dataCounter=0; //reset the counter
      while(analogRead(rfReceivePin)>threshold && dataCounter<maxSignalLength){
        dataCounter++;
      }  
      storedData[i]=dataCounter;    //Store the length of the HIGH signal
    
      
      //Identify the length of the LOW signal---------------LOW
      dataCounter=0;//reset the counter
      while(analogRead(rfReceivePin)<threshold && dataCounter<maxSignalLength){
        dataCounter++;
      }
      storedData[i+1]=dataCounter;  //Store the length of the LOW signal
   }
   
     storedData[0]++;  //Account for the first AnalogRead>threshold = lost while listening for signal
     digitalWrite(ledPin, LOW);
 }
 
 
 /*------------------------------------------------------------------------------
    Send the stored signal to the FAN/LIGHT's RF receiver. A time delay is required to synchronise
    the digitalWrite timeframe with the 433MHz signal requirements. This has not been tested with different
    frequencies.
    ------------------------------------------------------------------------------ */
 void sendSignal(){
   digitalWrite(ledPin, HIGH);
   for(int i=0; i<dataSize; i=i+2){
       //Send HIGH signal
       digitalWrite(rfTransmitPin, HIGH);     
       delayMicroseconds(storedData[i]*timeDelay);
       //Send LOW signal
       digitalWrite(rfTransmitPin, LOW);     
       delayMicroseconds(storedData[i+1]*timeDelay);
   }
   digitalWrite(ledPin, LOW);
   delay(1000);
   
   
   /*-----View Signal in Serial Monitor 
   for(int i=0; i<dataSize; i=i+2){
       Serial.println("HIGH,LOW");
       Serial.print(storedData[i]);
       Serial.print(",");
       Serial.println(storedData[i+1]);
   }
   ---------------------------------- */
 }
 
 


 

Now let's see this project in action !

Have a look at the video below to see the Arduino turning a light and fan on/off shortly after receiving the RF signal from the RF remote. The video will also show you how to put this whole project together - step by step.

The Video


 


This concludes my 433MHz transmitter and receiver tutorials (for now). I hope you enjoyed them.
Please let me know whether this worked for you or not.
I have not tested this project with other remotes or other frequencies - so would be interested to find out whether this technique can be used for ALL RF projects ??

 
 



If you like this page, please do me a favour and show your appreciation :

  Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
Have a look at my videos on my YouTube channel.


 
 

 
 
 



However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.

40 comments:

  1. Hello, Nice explanation. This helps to understand the basic principle for receiver and transmitter using arduino. Just another query it is possible to take a note of the sniffed data from existing remote and play the same data via another transmitter using arduino. Basically I want o first read the data from each button of the existing RF remote and use the data in my transmitter to play it.

    ReplyDelete
    Replies
    1. At the end of the Arduino code - you will see a section which allows you to transmit the signal to the serial monitor. You could send the signal to an SD card, or just store them on your computer using the Processing IDE . I assume you have already looked at tutorials 1 - 3.
      Once you have the stored signal, you can just send it back to another Arduino, and transmit the signal as required.

      Delete
  2. Hei, thanks for your interesting tutorial. I'm a newbie to Arduino and I wonder how come the LED on pin 13 and ground wouldn't burn without any resistor. Thank you :)

    ReplyDelete
    Replies
    1. That is a good question. Some people say that there is an onboard resistor attached to pin13, while others say that newer boards don't have this resistor.
      While I have used this technique numerous times without any problems, I would recommend that you either stick with the onboard LED, or attach a resistor in series (just in case).
      Excellent question !!

      Delete
    2. Here is an article that supports the use of a resistor in series.
      But in the comments of that article, there are people that say that some Arduino boards have an onboard resistor in series with pin13.

      Use this technique at your own risk. But thank you for this question. Because I think I will recommend a resistor in future tutorials.

      Delete
  3. Hello,

    Thanks for your tutorials, however on tutorial #4 your push button is floating so it will turn on at random, it's much better to make use of the internal pull-up resistor by adding the following to void setup() :-

    digitalWrite(button, HIGH);

    Then change the coding so buttonVal==HIGH becomes buttonVal==LOW and wire the button so when pressed it goes to GND.

    In this state the button is always pulled up HIGH and GND pulls it LOW when the button is pressed, otherwise the button will float and trigger randomly.

    Thanks.

    ReplyDelete
    Replies
    1. Ha Ha, I always forget about this floating problem... Well picked up. Thank you.

      Delete
    2. 'Anonymous' or Scott can please you provide a few more details on the code and circuit changes to remove the floating button issue. Also for the serial print to be effective as it is hit and miss at the moment with the floating button.

      As an interim I worked out that the best way to get a reliable recording is to have the button switched on when the Arduino is reset. This is giving excellent results and I'm truly amazed at how effective this is.

      It is managing to record and playback all ID's for 'type 2' devices that were failing as highlighted in my post on the tutorial 2 page. It is also working for some RF activated relays that I will call type 3 devices. Strangely it is still not working for type 1 devices. Type 1 are Status remote sockets as shown at http://www.amazon.co.uk/Status-SREMSOC3PK3-Remote-Control-Socket/dp/B003XOXAVG

      The protocol for the Status remote sockets is covered in Geoff Johnson's article at http://www.hoagieshouse.com/RaspberryPi/RCSockets/RCPlug.html

      Scott is there any reason why your sketch isn't able to record and playback this protocol?

      For reference I have included below an on and an off signal for the Status remote sockets as recorder by rtl_433.exe (rtl recording software for windows).



      Delete
    3. This comment has been removed by the author.

      Delete
    4. Sorry Scott, forget to paste in the on off signals. See below.

      signal_len = 85221, pulses = 174
      Iteration 1. t: 156 min: 79 (76) max: 234 (98) delta 125
      Iteration 2. t: 156 min: 79 (76) max: 234 (98) delta 0
      Pulse coding: Short pulse length 79 - Long pulse length 234

      Short distance: 65, long distance: 221, packet distance: 2378

      p_limit: 156

      [00] {25} 04 db fb 00 : 00000100 11011011 11111011 00000000
      [01] {25} 04 db fb 00 : 00000100 11011011 11111011 00000000
      [02] {25} 04 db fb 00 : 00000100 11011011 11111011 00000000
      [03] {25} 04 db fb 00 : 00000100 11011011 11111011 00000000
      [04] {25} 04 db fb 00 : 00000100 11011011 11111011 00000000
      [05] {25} 04 db fb 00 : 00000100 11011011 11111011 00000000
      [06] {24} 04 db fb 00 : 00000100 11011011 11111011 00000000

      *** signal_start = 312812343, signal_end = 312878215
      signal_len = 65872, pulses = 124
      Iteration 1. t: 156 min: 79 (59) max: 234 (65) delta 212
      Iteration 2. t: 156 min: 79 (59) max: 234 (65) delta 0
      Pulse coding: Short pulse length 79 - Long pulse length 234

      Short distance: 66, long distance: 222, packet distance: 2379

      p_limit: 156

      [00] {25} 04 db f3 00 : 00000100 11011011 11110011 00000000
      [01] {25} 04 db f3 00 : 00000100 11011011 11110011 00000000
      [02] {25} 04 db f3 00 : 00000100 11011011 11110011 00000000
      [03] {25} 04 db f3 00 : 00000100 11011011 11110011 00000000
      [04] {24} 04 db f3 00 : 00000100 11011011 11110011 00000000

      Delete
    5. Hi Paul,
      Wow - you seem to be knee deep in RF signals :)
      I was just about to respond to you, to ask if you had a chance of looking at Tutorial 4, when I came across this message... so looks like you have managed to work your way through most of your problems....
      I would like to say that I did have to go through a bit of trial and error, and sometimes got a bit confused by the RF results that I was getting. There are few sites that explain that there is a delay when you write to the pin, and then go on explain the frequency calculations.

      To solve the Floating push button - read this tutorial.

      I am not seeing your on/off signals recorded by rtl_433.exe
      You may want to expand the dataSize variable to a higher value, and once you know the length of the signal, bring it down to what-ever number you discover. I think the maximum number you can use for this variable is 1700 (on an Arduino UNO) - due to memory restrictions. But see how you go.
      And you may need to play around with the timeDelay variable as I did in Tutorial 3. You might want to incorporate the calibration process into this tutorial??

      And finally, I think Geoff Johnson noted that HIGHs and LOWs were reversed in his sketch. I think I had a similar issue, so you may want to try reversing them to see if that helps.

      Delete
    6. Sorry Paul,

      I re-posted my message because I needed to change something and add something. And now I see you have posted your signals... but I don't know if it actually helps me to figure out what is happening on your side...

      Delete
    7. Hi Paul,

      Geoff Johnson uses a timeDelay of around 222 Microseconds ??

      Delete
    8. Hi Scott,

      Spent a few hours yesterday trying to 'crack' the Status sockets but no joy. Strange thing is the relays I use have a RF signal 'learn' facility and when I use the Status remote to 'teach' them the RF they are controlled by your sketch. The same applies when I use another well done RF library.

      Cloned another RF device earlier today. It is a 'security' device which I will call type 4. So types 2, 3 and 4 working well but not type 1, yet.

      Delete
    9. Paul - Glad to hear that this is working for so many of your devices - but there is obviously something different about your "type 1" device. Check to make sure that it is not using a rolling code (after some time)??
      I will also advise you to post your question to the Arduino Forums... tell them what you are trying to do, what you have done, and see if the "experts" can get you on the right track.
      Show the code you are using - as this may help narrow down the issue.

      I would be interested in the outcome - so please post a link to your forum post.

      Regards
      Scott

      Delete
    10. Hi Scott,
      The Status sockets (type 1 device) do not use rolling codes of any type. Looking at the devices that your sketch controls compared with the one type that is doesn't (excluding rolling codes of course) the common factor appears to be signal length. Your sketch works where the long pulse is double the short pulse but Status sockets have long pulses three times the length of the short pulses. This is the only factor I can see different, plus maybe the reversing of the signal (low becomes high and high becomes low).

      For reference Pilight has no trouble controlling the Status sockets.

      Can you please contact me via Facebook.

      Delete
  4. Hi there,
    best wishes from Germany. I started the other way round. Found these cheap modules on Ebay where they are available for less than 1 Euro, if you take five of them. That's only about half the amount you have to pay for a beer in a pub here. Looking for information after the purchase I found your tutorials. It was a really good idea to keep them simple. I am still a beginner with the Arduino and those explanations on the internet where the authors try to impress the reader with their knowledge are not helpful. So yours on the contrary is very helpful.
    Thanks says Georg

    ReplyDelete
    Replies
    1. Possibly because I don't have much knowledge :)

      Thanks for the feedback Georg

      Delete
    2. You have plenty of knowledge Scott. Thanks for a great set of tutorials on RF.

      Delete
    3. Great stuff. Works like a charm. Since I am a beginner at Arduino stuff too, this post was really helpful to start getting up to speed and have fun at the same time :)

      Delete
    4. +Arjan - am glad it worked for you. Thanks for the feedback.

      Delete
  5. Hi Scott,

    Thank you for creating this tutorial! I am new to electronic/Arduino and have decided to use your tutorial to build my first real project for the home.

    The ceiling fans in my home seem to operate on 303.9MHz according to the FCC docs (https://apps.fcc.gov/oetcf/eas/reports/ViewExhibitReport.cfm?mode=Exhibits&RequestTimeout=500&calledFromFrame=N&application_id=u9yrEznUvQJtU3fTqdh%2BxA%3D%3D&fcc_id=L3HFAN-9T). Do you think the 315MHz receiver/transmitter would work for me?

    ReplyDelete
    Replies
    1. Hi Matt,
      I don't think the 315MHz transmitter will work with your fan - but I'm not 100% sure. However, the modules are so cheap, that it might be worth trying. If you want to make your own transmitter, then this article may be useful: http://www.talkingelectronics.com/projects/27MHz%20Transmitters/27MHzLinks-3.html

      Delete
    2. This discussion may also enlighten you.
      https://community.particle.io/t/303-9-mhz-rf-transmitter/9062/9

      I did not read all of it - so don't know if they figured it all out in the end.
      But looks like they were trying to do the same thing as you.

      Delete
    3. Thanks for your reply, Scott. I think I will go ahead and buy the transmitters on the off chance that they do work (like you said, incredibly cheap). I'll be sure to report back with my findings just in case anyone else is looking for this information in the future. Thanks again!

      Delete
  6. Forgive me for being a slow follower and thank you so much for this tutorial. I have been studying your tutorial for a few days now and still confused. I enabled the "view signal serial monitor". and got the log (listed below) when pressed the channel 1 o the ZAP Outet switch transmitter.

    http://www.amazon.com/Etekcity-Programmable-Electrical-Converter-Appliances/dp/B00DQELHBS/ref=sr_1_sc_1?ie=UTF8&qid=1435444721&sr=8-1-spell&keywords=ZAP+Outet+switch

    @Scott, Can you please guide me what is the next steps to do to get the RF Calibration Table for on/off switch?

    ReplyDelete
    Replies
    1. Hi Unknown,

      I have moved your query to the ArduinoBasics forum - which is a much better place to discuss this type of thing: http://arduinobasics-forum.1116184.n5.nabble.com/Quick-questions-about-ArduinoBasics-projects-f3.html

      Thank you very much Paul Alcock for your response to Unknown's question. Just letting you know that I moved your response to the forum also.

      Regards,
      Scott

      Delete
  7. First of all thanks for sharing Scott. I tried this project and it works very well. I want to ask that; if we want to add 6 button have the same features, how arrange circuit and program code sketch? Help me please

    ReplyDelete
    Replies
    1. You may find that you have to re-use some variables - otherwise you may run out of memory. My advise is to try to add just one extra button... and then the rest will become clear. Give it a go - and if you still cannot get that to work - let me know.

      Delete
    2. Thanks for your reply Scott. I've tried add a button and connected to arduino like other button. Also tried to change code configuration but it doesn't compile. There was too much error. I think I'm not good at programming

      Delete
    3. Hi Omer,

      Perhaps paste your code and take a picture or show a diagram of you setup by posting these to the ArduinoBasics forum. I will have a look, and make the necessary recommendations from there.

      Delete
    4. Thanks Scott. I posted to forum

      Delete
  8. I'd like do to the same with a raspberry to not have the memory limitation and being able to listen for a longer period of time. Do you know of any project/code that would do that ?

    ReplyDelete
    Replies
    1. I know nothing about the Raspberry Pi. Actually that is not true. I know what they are, but have never used one.
      If you want more memory, perhaps consider the Arduino MEGA.

      Delete
  9. thank you its a great tutorial
    i have a question lets say i want to control an rf relay module with remote .
    the rf relay have only receiver , can arduino know if the relay is on HIGH or LOW without the transmitter module on the rf relay ?
    thank you

    ReplyDelete
    Replies
    1. Hi Elidor,
      "If a tree falls in a forest and no one is around to hear it, does it make a sound?"

      You can transmit to the relay module, but will not know if it is actually on or not, unless you send some message back to the transmitting Arduino. If you test it and find that it works 100% of the time, then you could "assume" that it has worked, but will never know for sure.

      There has to be some signal back, (eg. RF response, or change in Light, or sound or something that you can receive from the relay event - providing the transmitting Arduino is in a place to be able to receive that signal.)

      Or you just trust that it happened.

      Delete

Feel free to leave a comment about this tutorial below.
Any questions about your particular project should be asked in the ArduinoBasics forum.

Comments are moderated due to large amount of spam.