Introduction: Super Simple Raspberry Pi 433MHz Home Automation

Picture of Super Simple Raspberry Pi 433MHz Home Automation

This tutorial is one among many when it comes to using a Raspberry Pi to control wireless devices around the home. Like many others, it will show you how to use a cheap transmitter/receiver pair hooked up to your Pi to interact with devices operating on the commonly used 433MHz radio frequency band. It will specifically show you how to turn any electrical device on or off using your Pi by transmitting commands to a set of 433MHz remote-controlled power sockets.

Why did I create this tutorial if so many already exist? Mainly because pretty much all the other tutorials I came across seemed to overcomplicate things, especially on the software side. I noticed that they relied heavily on third-party libraries, scripts or code snippets to do all the work. Many wouldn't even explain what the underlying code was doing - they would just ask you to shove two or three pieces of software on your Pi and execute a bunch of commands, no questions asked. I really wanted to try and use my Pi to turn electrical devices on and off around my home using a set of 433MHz remote-controlled sockets, but I wanted to create my own version of the system that I could understand, hopefully eliminating the need to use someone else's libraries or scripts.

That is what this tutorial is about. The software side of this system consists of two very simple Python scripts - one for receiving and recording signals, and one for transmitting these signals back to the wireless power sockets. The actual reception/transmission of the signal relies only on the easy-to-use RPi.GPIO library which, at least for me, came pre-installed with Raspbian. This library can also be imported directly into Python.

For this project you will need:

  • A 433MHz transmitter/receiver pair. The ones most commonly used in this type of project seem to be these. Buying a pack of five like the one linked ensures that you have a few spares.
  • A set of 433MHz remote-controlled power sockets. I bought these which I'd highly recommend, but there are countless models available. Just make sure they operate on this frequency!
  • Some circuit-building accessories. I'd recommend using a breadboard and some jumper cables to make the circuit building process as easy as possible.

[If you decide to buy any of these products, I would greatly appreciate it if you access the listings using the above links - that way, I get a tiny share of the profits at no extra cost to you!]

Step 1: Setting Up the Receiver Unit

Picture of Setting Up the Receiver Unit

Before you can use your Pi to send commands to the remote-controlled sockets, you need to know what specific signals they respond to. Most remote-controlled sockets ship with a handset that can be used to turn specific units on or off. In the case of the ones I bought, the handset has four rows of paired ON/OFF buttons, each of which sends out an ON or OFF signal to a particular socket unit.

This brings up a question - how do we know which buttons correspond to which socket? This actually depends on the model you have. One of the main reasons I chose my particular model of socket (linked in the introduction) is that each unit has a small set of switches on the back which can be manually configured to make a particular socket respond to a particular set of ON/OFF buttons on the handset. This also means that you can unplug and move the sockets around the house knowing that a particular unit will always respond to the same ON/OFF signals.

Once you have figured out how your sockets interact with the handset, you will need to use your 433MHz receiver unit (pictured above) to 'sniff' the codes being sent out by the handset. Once you have recorded the waveforms of these codes, you can replicate them using Python and send them out using the transmitter unit.

The first thing to do here is wire the pins on your receiver to the correct GPIO pins on the Pi. The receiver unit has four pins, but only three of them are needed. I think both of the central pins give the same output, so you only need to connect to one of them (unless you want to stream the received signals to two separate GPIO pins).

The image above pretty much summarises the wiring. Each pin on the receiver can be wired directly to the corresponding pin on the Pi. I use a breadboard and jumper cables to make the process a bit more elegant. Note that you can choose any GPIO data pin to connect to either of the central receiver pins. I used the pin marked as '23' on my Pi header.

IMPORTANT: If you connect the pin marked '3v3' in the above image to a higher voltage pin on the Pi (e.g. 5v), you will probably damage the Pi as the GPIO pins cannot tolerate voltages above 3v3. Alternatively, you can power it with 5v and set up a voltage divider to send a safe voltage to the DATA pin.

The range of the receiver will not be very large at this voltage, especially if an antenna is not connected. However, you don't need a long range here - as long as the receiver can pick up the signals from the handset when they are held right next to each other, that is all we need.

Step 2: Sniffing the Handset Codes

Picture of Sniffing the Handset Codes

Now that your receiver is wired up to the Pi, you can start the first exciting stage of this project - the sniff. This involves using the attached Python script to record the signal transmitted by the handset when each button is pressed. The script is very simple, and I'd highly recommend you have a look at it before you run it - after all, the point of this project is that you won't just blindly run someone else's code!

Before you start this process, you will need to make sure you have the Python libraries needed to run the sniffer script. They are listed at the top of the script:

from datetime import datetime
import matplotlib.pyplot as pyplot
import RPi.GPIO as GPIO

The RPi.GPIO and datetime libraries were included with my Raspbian distribution, but I had to install the matplotlib library as follows:

sudo apt-get install python-matplotlib

This library is a commonly used graph plotting library that is very useful even outside of this project, so installing it definitely can't hurt! Once your libraries are up to date, you are ready to start recording data. Here's how the script works:

When it is run (using the command 'python ReceiveRF.py'), it will configure the defined GPIO pin as a data input (pin 23 by default). It will then continually sample the pin and log whether it is receiving a digital 1 or 0. This continues for a set duration (5 seconds by default). When this time limit is reached, the script will stop recording data and will close off the GPIO input. It then performs a little post-processing and plots the received input value against time. Again, if you have questions about what the script is doing, you can probably answer them yourself after looking at how it works. I have tried to make the code as readable and simple as possible.

What you need to do is look out for when the script indicates that it has **Started recording**. Once this message appears, you should press and hold one of the buttons on the handset for about a second. Be sure to hold it close to the receiver. Once the script has finished recording, it will use matplotlib to plot a graphical waveform of the signal it has received during the recording interval. Please note, if you are connected to your Pi using an SSH client such as PuTTY, you will also need to open an X11 application to allow the waveform to display. I use xMing for this (and for other things such as remote-desktopping into my Pi). To allow the plot to be displayed, simply start xMing before you run the script and wait for the results to appear.

Once your matplotlib window appears, the area of interest within the plot should be pretty obvious. You can use the controls at the bottom of the window to zoom in until you are able to pick out the highs and lows of the signal transmitted by the handset while the button was being held down. See the above image for an example of a complete code. The signal will probably consist of very short pulses separated by similar periods of time where no signal is received. This block of short pulses will probably be followed by a longer period where nothing is received, after which the pattern will repeat. Once you have identified the pattern belonging to a single instance of the code, take a screenshot like that at the top of this page, and continue to the next step to interpret it.

Step 3: Transcribing the Resulting Signal

Picture of Transcribing the Resulting Signal

Now that you have identified the block of periodic highs and lows corresponding to a particular button's signal, you will need a way of storing and interpreting it. In the above signal example, you will notice that there are only two unique patterns that make up the whole signal block. Sometimes you see a short high followed by a long low, and sometimes it's the opposite - a long high followed by a short low. When I was transcribing my signals, I decided to use the following naming convention:

1 = short_on + long_off
0 = long_on + short_off

Look again at the labelled waveform, and you will see what I mean. Once you have identified the equivalent patterns in your signal, all you have to do is count the 1's and 0's to build up the sequence. When transcribed, the above signal can be written as follows:

1111111111111010101011101

Now you just need to repeat this process to record and transcribe the signals corresponding to the other buttons on your handset, and you have completed the first part of the process!

Before you can re-send the signals using the transmitter, there is a little more work to do. The timing between the highs and lows corresponding to a 1 or a 0 is very important, and you need to make sure that you know how long a 'short_on' or a 'long_off' actually lasts. For my codes, there were three pieces of timing information I needed to extract in order to replicate the signals:

  • The duration of a 'short' interval, i.e. the beginning of a 1 or the end of a 0.
  • The duration of a 'long' interval, i.e. the end of a 1 or the beginning of a 0.
  • The duration of an 'extended' interval. I noticed that when I held a button down on the handset, there was an 'extended_off' period between each repeated instance of the signal block. This delay is used for synchronisation and has a fixed duration.

To determine these timing values, you can use the zoom function on the matplotlib window to zoom all the way in and place the cursor over the relevant parts of the signal. The cursor location readout at the bottom of the window should allow you to determine how wide each part of the signal is that corresponds to a long, short or extended interval. Note that the x-axis of the plot represents time, and the x component of the cursor readout is in units of seconds. For me, the widths were as follows (in seconds):

  • short_delay = 0.00045
  • long_delay = 0.00090 (twice as long as a 'short')
  • extended_delay = 0.0096

Step 4: Setting Up the Transmitter Unit

Picture of Setting Up the Transmitter Unit

Once you have collected your codes and timing data, you can disconnect your receiver unit as you will no longer need it. You can then wire up the transmitter directly to the relevant Pi GPIO pins as shown in the above image. I've found that the pins on the transmitter units are labelled, which makes the process easier.

In this case, it is OK to power the unit using the 5v supply from the Pi as the DATA pin will not be sending signals to the Pi, only receiving them. Also, a 5v power supply will provide more transmission range than using the 3v3 supply. Again, you can connect the DATA pin to any appropriate pin on the Pi. I used pin 23 (the same as for the receiver).

Another thing I'd recommend doing is adding an antenna to the small hole on the top right of the transmitter. I used a 17cm long piece of straight wire. Some sources recommend a coiled wire of similar length. I'm not sure which is better, but the straight wire provides enough range for me to turn the sockets on/off from any location in my small flat. It is best to solder the antenna, but I just removed some of the plastic from the wire and wrapped the copper through the hole.

Once the transmitter is wired up, that's all the hardware setup done! The only thing left to do now is set your sockets up around the house and have a look at the transmitter program.

Step 5: Transmitting Signals Using the Pi

This is where the second Python script comes in. It is designed to be just as simple as the first, if not more so. Again, please download it and look over the code. You will need to edit the script to transmit the correct signals according to the data you recorded in step 3, so now's a good time to have a quick glance at it.

The libraries needed to run this script were all pre-installed on my Pi, so no further installation was needed. They are listed at the top of the script:

import time
import sys
import RPi.GPIO as GPIO

Underneath the library imports is the information you will have to edit. Here is how it looks by default (this is the information corresponding to my sockets as determined using step 3):

a_on = '1111111111111010101011101'
a_off = '1111111111111010101010111'
b_on = '1111111111101110101011101'
b_off = '1111111111101110101010111'
c_on = '1111111111101011101011101'
c_off = '1111111111101011101010111'
d_on = '1111111111101010111011101'
d_off = '1111111111101010111010111'
short_delay = 0.00045
long_delay = 0.00090
extended_delay = 0.0096

Here we have eight code strings (two for each pair of on/off buttons on my handset - you may have more or fewer codes) followed by the three pieces of timing information also determined in step 3. Take the time to make sure you have entered this information correctly.

Once you're happy with the codes/delays you've entered into the script (you can rename the code string variables if you like), you are pretty much ready to try out the system! Before you do, take a look at the transmit_code() function in the script. This is where the actual interaction with the transmitter occurs. This function expects one of the code strings to be sent in as an argument. It then opens up the defined pin as a GPIO output and loops through every character in the code string. It then turns the transmitter on or off according to the timing information you entered to build up a waveform matching the code string. It sends each code multiple times (10 by default) to reduce the chance of it being missed, and leaves an extended_delay between each code block, just like the handset.

To run the script, you can use the following command syntax:

python TransmitRF.py code_1 code_2 ...

You can transmit multiple code strings with a single run of the script. For example, to turn sockets (a) and (b) on and socket (c) off, run the script with the following command:

python TransmitRF.py a_on b_on c_off

Step 6: A Note on Timing Accuracy

As mentioned, the timing between the transmitted on/off pulses is quite important. The TransmitRF.py script uses python's time.sleep() function to build up the waveforms with the correct pulse intervals, but it should be noted that this function is not entirely accurate. The length for which it causes the script to wait before executing the next operation can depend on the processor load at that given instant. That is another reason why TransmitRF.py sends each code multiple times - just in case the time.sleep() function is not able to properly construct a given instance of the code.

I have personally never had issues with time.sleep() when it comes to sending the codes. I do however know that my time.sleep() tends to have an error of about 0.1ms. I determined this using the attached SleepTest.py script which can be used to give an estimate of how accurate your Pi's time.sleep() function is. For my particular remote-controlled sockets, the shortest delay I needed to implement was 0.45ms. As I said, I haven't had issues with non-responsive sockets, so it seems like 0.45 ± 0.1ms is good enough.

There are other methods for ensuring that the delay is more accurate; for example, you could use a dedicated PIC chip to generate the codes, but stuff like that is beyond the scope of this tutorial.

Step 7: Conclusion

Picture of Conclusion

This project has presented a method for controlling any electrical appliance using a Raspberry Pi and a set of 433MHz remote-controlled sockets, with a focus on simplicity and transparency. This is the most exciting and flexible project that I have used my Pi for, and there are limitless applications for it. Here are some things I can now do thanks to my Pi:

  • Turn on an electric heater next to my bed half an hour before my alarm goes off.
  • Turn the heater off an hour after I've gone to sleep.
  • Turn my bedside light on when my alarm goes off so that I don't fall back to sleep.
  • and many more...

For most of these tasks, I use the crontab function within Linux. This allows you to set up automatic scheduled tasks to run the TransmitRF.py script at specific times. You can also use the Linux at command to run one-off tasks (which, for me, needed to be installed separately using 'sudo apt-get install at'). For example, to turn my heater on half an hour before my alarm goes off the next morning, all I need to do is type:

at 05:30
python TransmitRF.py c_on

You could also use this project in conjunction with my Dropbox home monitoring system to control appliances over the internet! Thanks for reading, and if you would like to clarify something or share your opinion, please post a comment!

Comments

robtperk (author)2017-11-04

You might want to check the wattage of your RF controlled switch. Mine (Elekcity) are rated at 1200 watts, and I guarantee that your heater is probably 1500 watts, 25% over the rating. Be careful.

TomV135 (author)2017-11-02

Thanks for this great tutorial, I get it to work when I change the transmit script from a_on ='10101010' to code = '101010'

What is missing since I get this error?

for i in code:

NameError: name 'code' is not defined

maurizionnn (author)2017-10-28

Hi All,

this post was very helpful and i would like to thank you.

My version of the receiver and the transmitter is very simple but very powerful :

the receiver will record all GPIO inputs on a list ( 4 sec lenght ) and write the result on a binary file named with the corresponding functionality ( 1_on , 1_off , etc etc )

The corresponding transmitter will read the file ( as input ) transmitting GPIO Outputs .

This work for every protocol and no decoding is necessary !

BR,

Maurizio

apetit (author)2017-10-23

Thank you very much for replying and help offer. I am going to check this as soon as possible.

armyofme (author)2017-10-14

Thank you so much for this guide. It has been really helpful and I know have control of all my cheap wall switches. The only thing I haven't managed to do is the Homeeasy light switches. The code block is very different to the wall switches....all 1s with different gaps between :s Any ideas how I can record this signal?

nathanjj (author)armyofme2017-10-20

actually looking at your code again it can be done with just the 1s and 0s. Your code starts as 101010101 1001 1001 1001...etc. short-on/short-off=0, short on/long off=1

armyofme (author)nathanjj2017-10-21

YAY! Thank you so much nathanjj. I got there with your help.

Basically my timings were slightly out and by comparing the graphs I could find the problems and adjust the times. For anyone else reading with a Homeeasy dimmer this is my amendment of the original script...it may work for you.

#!/usr/bin/python
import time
import sys
import RPi.GPIO as GPIO
import cgi
import cgitb
cgitb.enable()

x_on = '0222213131312232221232212232132221'
short_delay = 0.00018
medium_delay = 0.00036
long_delay = 0.001359
longer_delay = 0.002715
extended_delay = 0.01019

NUM_ATTEMPTS = 10
TRANSMIT_PIN = 24

def transmit_code(code):
'''Transmit a chosen code string using the GPIO transmitter'''
GPIO.setmode(GPIO.BCM)
GPIO.setup(TRANSMIT_PIN, GPIO.OUT)
for t in range(NUM_ATTEMPTS):
for i in code:
if i == '0':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(longer_delay)
elif i == '1':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(long_delay)
elif i == '2':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(medium_delay)
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(long_delay)
elif i == '3':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(medium_delay)
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(medium_delay)
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(long_delay)
else:
continue
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(extended_delay)
GPIO.cleanup()

if __name__ == '__main__':
for argument in sys.argv[1:]:
exec('transmit_code(' + str(argument) + ')')

nathanjj (author)armyofme2017-10-21

Glad to help. I think it can still be done with zeros and ones only but in the end it doesnt matter how you do it as long as the signal is replicated.

armyofme (author)nathanjj2017-10-21

Do you think 1 and 0s would be a more precise way of replicating the signal?

nathanjj (author)armyofme2017-10-22

If it works then it doesn't really matter, does it. Doing it this way is probably not true Manchester encoding/decoding but the beauty of DIY is there's more than one way to achieve the result. 1s&0s would take longer to manually convert to the code string but would simplify the python script. Currently if you had another device with more pulses in a group you have to add an elif to cover that scenario whereas going back to 1s&0s with on/off delays could handle whatever combination of 1s&0s came along. food for thought :) You would still have to have specific code for that first rouge pulse.

armyofme (author)nathanjj2017-10-21

Great idea! So yes I had a go at your suggestion sending my signal with
the transmitter at the same time as using the receiver in order to
compare. And my signal is very similar to the signal I'm wanting to send
but there are a few bizzare anamolies :s At the end it's meant to do
'32221' instead it does '321121'. There are also some other issues: the
size of the gap between the first and second '2' and the bizzare second
'3' with the longer middle pulse. What do you think? Any suggestions on
how I can alter the script further in order to get a closer match?

nathanjj (author)armyofme2017-10-20

I had a signal that appeared to be made up of combinations of short and long pulses. I used short/short = 0, short/long = 1, long/short =2, long/long =3.

It looks like your signal pattern is made up of short pulses rather than on/off lengths. Can you make a code counting the groups of pulses close together which are then separated by the longer space. I would read your signal as 1222213131312232221232212232132221. Change the python code to send the required number of short pulses separated by the short delay and then send the long delay between codes. eg if code = 1 then transmit_pin 1, sleep short_delay, transmit_pin 0, long delay. elif code = 2 then transmit_pin 1, sleep short, transmit_pin 0, sleep short_delay, transmit_pin 1, sleep short_delay, transmit_pin 0, sleep long_delay etc.

armyofme (author)nathanjj2017-10-20

So...I now tried your first suggestion and altered the script but I made one change. I treated that rogue first signal as separate transmision calling that code 0 (basically a transmit1, short delay, transmit0, LONGER delay). Also I noticed that the gap between signals in a block was double the length than between 1s and 0s so I called this a MEDIUM delay in the script. I'm not sure if this was the right thing to do but it seemed logical although it is still not working :( Here's my script...can you spot any glaring errors?

#!/usr/bin/python
import time
import sys
import RPi.GPIO as GPIO
import cgi
import cgitb
cgitb.enable()

x_on = '0222213131312232221232212232132221'
short_delay = 0.00018
medium_delay = 0.00036
long_delay = 0.001359
longer_delay = 0.002715
extended_delay = 0.01019

NUM_ATTEMPTS = 10
TRANSMIT_PIN = 23

def transmit_code(code):
'''Transmit a chosen code string using the GPIO transmitter'''
GPIO.setmode(GPIO.BCM)
GPIO.setup(TRANSMIT_PIN, GPIO.OUT)
for t in range(NUM_ATTEMPTS):
for i in code:
if i == '1':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(long_delay)
elif i == '0':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(longer_delay)
elif i == '2':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(medium_delay)
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(long_delay)
elif i == '3':
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(medium_delay)
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(medium_delay)
GPIO.output(TRANSMIT_PIN, 1)
time.sleep(short_delay)
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(long_delay)
else:
continue
GPIO.output(TRANSMIT_PIN, 0)
time.sleep(extended_delay)
GPIO.cleanup()

if __name__ == '__main__':
for argument in sys.argv[1:]:
exec('transmit_code(' + str(argument) + ')')

armyofme (author)nathanjj2017-10-20

Firstly thank you so much for taking the time to respond...I really appreciate the help as I would like to be able to do this.

I just tried your last suggestion using just the ones and zeros to no avail :(

The pattern seems very regular except for the gap between the first and second pulse where this is much longer than the other gaps. Does this need to be recorded in a different way?

apetit (author)armyofme2017-10-18

I am getting a similar pattern as you with my HomeEasy remote and haven't figured out how to read it/make it work.

If anyone has a tip for this...

nathanjj (author)apetit2017-10-20

I'm new at this as well but I got mine to work using this tutorial but had to make minor modifications. Just look for the pattern in your signal, it may not be based on on/off length exactly as in the tutorial. figure out a way to represent the pattern with 0s 1s 2s 3s etc and then adjust the python transmit code to be able to replicate it. If you want further info I can send pictures of my signal/code and how I adapted it to work. My switch device is a Kambrook remote switch. The remote has a slider switch for A,B,C,D and then 5 on/off switches for each channel. My remote can control up to 20 devices.

armyofme (author)apetit2017-10-19

I've had no luck decoding the signal despite reading many related pages. Unfortunately a lot of the stuff I read went over my head as I'm no expert in this field! I think it's something to do with Manchester coding (http://labalec.fr/erwan/?p=1457).

However I have found a solution to controlling my Homeeasy wall dimmer. But from a different angle... https://github.com/nbogojevic/piHomeEasy

With this script you can send out a signal with the transmitter attached to your pi and pair it with the wall receiver in learn mode. If you want to use it with wall dimmer switch like me you have to change the piHomeEasy.cpp script as advised here: https://www.raspberrypi.org/forums/viewtopic.php?...

If you need any help give me a shout.

Andrew

PeterO102 made it! (author)2017-02-07

Hi There,

Finally found a way to get codes of my AWST-8800 Kaku switches.

can someone support me with the code translate. Its more then in tutorial and i don't see the 0 strings.. only 1 ...

nathanjj (author)PeterO1022017-10-20

short-on/short-off=0, short-on/long-off=1

ФаигБ (author)2017-09-30

You could use this library if you have Arduino:

https://github.com/faig3105/RFTransmitter

Meheecan (author)2017-09-26

You mention the range is not very large. What effective range do you experience at 3v3? I would like to build a similar setup but require a range of about 30-40m. The transmitters/receivers you link to boast a 500m range, but I'm assuming this is at 12v. Should I look at setting up a 5v circuit with a voltage divider like you suggested?

You also mention any pi model will do. Have you by any chance tried this with a pi zero?

ewv1 (author)2017-09-25

Hello. Please help to understand the definition of the values short_delay, long_delay, extended_delay. Can't figure out between what points on the graph to measure the interval? I made a chart:

TimB355 made it! (author)2017-09-21

Thank you so much for these instructions..

I think I've successfully captured my ceiling fan codes, but I'm having a problem transmitting them. I'm using the transmit.py script, but it doesn't seem to be respecting the timing. I end up with what looks like really long transmissions of the 0's and 1's (See attached)

Any ideas?

Thomas Groell (author)2017-09-04

Great Instructables, thanks a lot! This is by far the most accessible method for beginners, very helpful stuff!

I managed easily with my RF sockets but I'm struggling with RF bulb holders that I ordered here https://www.aliexpress.com/item/4pcs-E27-Wireless-... The principle should be the same, and even though the code has 2 more characters than on sockets (i think 25 instead of 23 combinations of 1s & 0s), it's strange that I can't manage to make it work.

Has anyone else tried already to replicate this for bulb holders to remotely turn on/off lights?

decioaccietto (author)2017-07-07

Hi!.. thanks for the tutorial.. I could make the sniff well.. but I realice something, the code has differents times. I try with differents 433Mhz controls.. can you give me a hand? thanks!

danieltmb (author)decioaccietto2017-08-09

You have to use 4 different peaks. 1 for short_on followed by long_off. 0 for short_on followed by short_off. 2 for long_on followed by short_off. And 3 for long_on followed by long_off.

If I done it right for you it is than: 10231103111022311030230303031.

Hope it helps

LeoB69 (author)2017-07-21

Thanks George and JoeR

I live in an apartment building and had too much RF interference to do the pattern decoding in 1 shot. I changed the detection to a loop and was able to see the real patterns. My version of JoeR's code follows:

pattern = []

for i in range(len(RECEIVED_SIGNAL[0])):

if timedeltas[i]<0.0003:

pattern.append(1)

elif 0.0003<timedeltas[i]<0.0008:

pattern.append(0)

elif 0.0008<timedeltas[i]<0.1:

pattern.append('space')

# break # at the first space break

# print pattern # this includes high and low

pattern = pattern[::2] # you only want the odd values ie the high

pattern = [str(i) for i in pattern]

patternstr = ''.join(pattern)

print patternstr

pattern = []

Also because of the interference the times were not accurate. It took a number of runs to get valid tImes.

I'm using ElekCity outlet modules and the lights are working great.

QuentinB28 made it! (author)2017-06-06

Worked right away, awesome.

eslondon (author)2017-05-30

Hi George/people. Great tutorial. I have been following it, but I am stucked in sniffing the signals, since, working from a Mac, haven´t been able to display the graph (as you did with Xming). I wonder if you have any reference on which app my do the job in Mac, similar to Xming. I ran the code and it goes until **Plotting results**, then the program quits and no graph appears.

I tried with XQuartz and different X11 apps, but no luck yet.

Thanks you.

E

Mr.C23 (author)2017-05-14

Thanks for your wonderful tutorial !

Bruno_G (author)2017-05-13

HI, I'd like to use the PI with a 433mhz PIR, but I do not know how to check the code of the sensor, i.e. I decoded it with RFSniffer, but I am not able to create the script for checking when it is activated. Do you have any suggestion?

A strange thing: the receiver receives a lot of signals also when the Sensor is switched off, perhaps there is noise in the environment.

Thanks

Bruno_G (author)2017-05-04

Hi, I bought the xcsource receiver suggested in the tutorial, but the technical specification reports a 5V working voltage, so I'd like to know if I must use the 3v3 or the 5V PIN. Can you help me? thanks

RudyV7 (author)Bruno_G2017-05-07

The maximum input voltage op the GPIO pins is 3V3 so, do,'t use 5V. The receiver will work on 3V3 also. Beware, 5V on one or more GPIO pins is gonna damage the RPI.

JoeR158 (author)2016-11-12

Really nice instructions!!

I added the following code to the end of the receive code to calculate the spaces without zooming on matplotlib as it was giving some hit and miss results on the control of my system. The code is fairly rough as its a Saturday after some beers..

currentvalue= 0

changepoints = []

timedeltas = []

for i in range(len(RECEIVED_SIGNAL[0])):

if RECEIVED_SIGNAL[1][i] != currentvalue:

try:

dt = RECEIVED_SIGNAL[0][i]-changepoints[-1]

timedeltas.append(dt)

except:

pass # for the first one there wont be anything in changepoints

changepoints.append(RECEIVED_SIGNAL[0][i])

currentvalue = RECEIVED_SIGNAL[1][i]

#print timedeltas[0:100]

shortlist = []

longlist = []

spacelist =[]

for i in range(100): #i looked at the first 100 changes you could do more

if timedeltas[i]<0.0003: # note the values here were from experimentation... bit of lazy coding

shortlist.append(timedeltas[i])

elif 0.0003<timedeltas[i]<0.0008:

longlist.append(timedeltas[i])

elif 0.0008<timedeltas[i]<0.1:

spacelist.append(timedeltas[i])

print shortlist

print longlist

print spacelist

print sum(shortlist)/len(shortlist),sum(longlist)/len(longlist),sum(spacelist)/len(spacelist)

RudyV7 (author)JoeR1582017-05-05

Hey JoeR158, I'm trying to put your script after the receive code. After running it I always get an error in this line:'if timedeltas[i]<0.0003: # note the values here were from experimentation... bit of lazy coding'. The error I'm getting is 'IndexError: list index out of range'. Any thoughts wat goes wrong and how to fix it?

JoeR158 (author)JoeR1582016-11-12

you can also use this to calculate the 1 0 pattern, this goes after the code above

pattern = []

for i in range(100):

if timedeltas[i]<0.0003:

pattern.append(1)

elif 0.0003<timedeltas[i]<0.0008:

pattern.append(0)

elif 0.0008<timedeltas[i]<0.1:

pattern.append('space')

break # at the first space break

print pattern # this includes high and low

pattern = pattern[::2] # you only want the odd values ie the high

pattern = [str(i) for i in pattern]

patternstr = ''.join(pattern)

print patternstr

Steve_Bl (author)2017-02-25

Update:- changed from Pi zero to Pi3 and have successfully got codes for the Status plugs using pigpio 433 code. The DMiotech light switches continue to be elusive.

Steve_Bl (author)2017-02-25

I have been following this and had no success, just noise. Has anyone been successful getting the code structure for DMiotech light switches? I got mine from Amazon sold by sourcingmap.

leopard_14 (author)2017-02-14

How can I adapt the TransmitRF.py scripts that if I run it, the sockets spring on and if I quit the program the sockets turn off

HarryM33 (author)2017-02-08

Hey there,

I have a bit of a problem with it, I have this big rectangle every time and I don't know how to put for it...

I have found for the code

0000011011011111110001001111110011011101111111 but I think I made a mistake doing the translation.

Any idea ?

Thank you

george7378 (author)HarryM332017-02-09

Hey - looks like you just have some extra syncing transmissions or something which come before your actual code. I'd just take the timings and on/off values and put them in their own 'send_sync_code()' method or something, then you can just call that before you send your actual code.

pipberry (author)2017-02-03

Hey There!

Thanks so much for your tutorial! It was a lot of fun so far wiring things up, playing with code etc. But I do have one question. I have the following plot attached and I cannot figure out what binary sequence it translates to.

Do you have any idea????

Thank you again!

danicymru (author)2017-01-13

hi george7378. Thanks for this - it was a lot of help in understanding 433rf codes and the receive and transmit modules. You might be interested in the stuff I've done which really builds on what you have posted here. see https://danicymru.wordpress.com/2016/12/15/433mhz-rf-nexa-sockets-and-the-blyss-wireless-doorbell/

george7378 (author)danicymru2017-01-14

Hi! That's a great post, thanks for sharing. Yeah, there's a lot of room for extension, I always thought it would be nice to make a good user interface for it and maybe run it from a Pi using a touch screen, but I haven't started looking at that yet.

AlinD7 (author)2016-12-16

This is very cool. I would like to use your system to track a bunch of temp/humidity sensors (specifically this one: AcuRite-06002M-Wireless-Temperature-Humidity - it is only $12 on Amazon). Do you think it would work? The sniffing would be a bit tricky as the received data needs to be reverse engineered to find the format.

george7378 (author)AlinD72017-01-04

Hey, thank you! Yes, you should be able to receive data from it, just make sure it's close enough to the receiver module during sniffing. I'd be interested to see what you pick up, post a screenshot if you can :)

AlinD7 (author)george73782017-01-04

Yes, i had to re-write the sniffer, but i got some cool data. If you send me your email, i can send you shots, etc.

RaresD (author)2016-10-30

Great tutorial! It worked on the first try.

Thanks a lot! :)

mauern (author)2016-10-26

I think the labels of 5v and DATA are mixed up in the picture of the transmitter?

george7378 (author)mauern2016-10-27

Hey - what makes you think that? I think the picture's right.

About This Instructable

147,394views

134favorites

License:

More by george7378:Super simple Raspberry Pi 433MHz home automationRaspberry Pi home monitoring with Dropbox
Add instructable to: