Introduction: Using 433MHz Remote Controlled Switches on Arduino

About: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I like. Other than my hobbies that involves grassroots medicine in S.E.&P Asia. I have buil…

I guess everybody knows those remote controlled switches that in their simplest form come in a couple (mostly 3) of switcheable devices to plug into the mains outlet and that will receive a plug of a lamp or something and that can be switched on and off by a small hand held device. Using an Arduino or other micro controller instead of the handheld transmitter to switch those devices on and off is the basis of many DIY 'home automatisation' projects.
Still, for the novice it can be a bit daunting to get one of those sets and use them in combination with a microcontroller.

My goal in this instructable is to help those people on their way. However, I owe a big word of thanks to Jeroen Meijer for developing a great library, adding classes for some of the remotes I had and for helping me understand the concept of 'trits'

Most of those remote control sets work o a frequency of 433.92 MHz (usually referred to just as '433 MHz'), some however work on 315 MHz, 868 MHz or 2.4GHz. Working with 433 MHz is the simplest and cheapest as the transceivers are ubiquitous and cheap. The 868 MHz protocols often send data back and forth and the transceivers are more expensive and harder to find. The 315 MHz transceiver sets are also cheap and easy to find but not too many commercially available switches work with 315 MHz Therefore I will focus on the 433Mhz systems.

433 MHz Transmitters and receivers usually come in a pair and are available for around 1 euro per pair in the various chinese webshops. The transmitters are actually quite decent, but the receivers are crap. They do work and can be used but dont expect miracles. As most of the people are interested in controlling devices from thei mirocontroller they will mostly only use the transmitter, so the quality of the receiver module isnt that important, but if you want to receive data from say a weatherstation, you may want to invest 1 or 2 euro more and buy a crystal driven receiver.

Hooking up your transmitter and Receiver

The transmitters come usually with 3 pins: Vcc, Ground and data. The data pin needs to be connected to one of the digital pins of the Arduino, say pin 7 if you ned to use the receiver, that usually has 4 pins: Vcc Ground and two data pins. One of the datapins needs to beonnected to a digital pin. Most libraries expect this to be Digital pin 2. However, some (not all) so called 'sniffer' programs that are used to discover the code for a device, expect the datapin on analoge pin A0

Antenna

Without antenna, the range of the cheap transmitters is really limited. In combination with the receiver of the pair perhaps only centimeters. If used in combination with a commercially available switch maybe 2 meters. You will need an antenna to increase the range to acceptable standards. The easiest antenna is the so called 1/4 lambda or 1/4 wavelength antenna. For the 433 MHz transceivers this comes down to a straight wire antenna with a length of 17.2 cm. in its simplest form this is therefore just a stiff piece of wire with a length of 17.2 cm. That will give you a decent range. nevertheless, the 1/4 wavelength straight antenna is not ideal as it expects a groundplane. With a bit more effort however it is possible to make a so called 'coil loaded antenna' that will increase the range significantly. I have written a seperate instructable about that one.

The libraries

One of the advantages of the Arduino system are the available libraries. For control of Remote Switches there are basically 6 libraries:

  • RCSwitch from Suat Özgür
  • RemoteSwitch from Fuzzilogic aka Randy Simons
  • NewRemoteSwitch from Fuzzilogic. This one is specifically aimed at the new ClickOn/ClickOff system
  • a fork of the RemoteSwitch by Jeroen Meijer. This is a complete overhaul of the Fuzzilogic with various protocols added. Now on github
  • RemoteSensor from Fuzzilogic. This one is more aimed at receiving data from a weather stations
  • InterruptChain from Fuzzilogic, I doubt if you will need this one

For completeness sake I also mention the Manchester library and the VirtualWire library, but these are aimed more at interArduino communication. In this tutorial I will focus on the RCSwitch library and Jeroen Meijers fork of the RemoteSwitch library. The main difference between thosw two is that the RCSwitch library sends numbers and the RemoteSwitch sends protocols. The advantage of the former is that you can send basically any code without knowing what kind of protool your Remote uses. The disadvantage is that you need to know all he codes for on and off of each device. The advantage of the latter is that for a number of generally used remote switches the library will know what thecode is or will be. The disadvantage is that if you have an undefined brand, it is going to be difficult to send the comands for that one.

Remote Controlled Switches

The RemoteSwitches As said, these usually come with 3 pluggable outlets and a handheld transmitter. Many of those use the same chip. the PT2262 oe equivalent. Therfore, many brands od Switches share protocols and in fact it is not uncommon that many brands are exactly the same, just a different name.

So, you have bought a set of Remote Controlled Switches, you have connected your transmitter on a digital pin (e.g. D7), you have added an antenna and installed both the RCSwitch as well as the RemoteSwitch library (forked one or old one). Now what? Well the easiest would be if you bought a set of switches that you know will be supported by a protocol in the remoteSwitch library and that you checked it uses the 433Mhz frequency, because if not you have to figure out the codes. if you are not sure, check if a description is found in the library that could apply to your remote controled There is one significant thing you need to check: How do you select the channel your remote controlled switch reacts to. or in other words: hiw does your remote controlled switch knows what button on the transmitter is 'his'? Well there are several possibilities: There is only one dial switch with 3-5 positions. or maybe 3-5 DipSwitches. This is probably an older (but still manufactured) remote controlled Switch that is covered by a protocol in the RemoteSwitch library. It only allows for selecting of the device, but not of the base channel the remote is working on, so if your neighnour has the same set, chances are you can control his lmpas (and vice versa)

Your remote switch has two dials, more than 5 dipswitches, or a dial combining letters and numbers. This usually means you can set the base address of your system plus the channel for each device.Usually, the transmitter itself also has some dip switches that need to be set in the same combination. This means that if your neigbour has the same set, chances are you cannot control eachothers lights.

There are no DIP-switches or rotary dials to set on your remote switch at all. This usually means you have a 'learning' system in which you have to sync your remote switch with the transmitter. It also means that somehow you have to figure out the base code your system is working on.

Step 1: Using 433MHz Remote Controlled Switches on Arduino: the SelectRemote

The SelectRemote No. 1728029 is a bulky receiver that has a rotary dial on the back with 5 positions. It comes with a handset that has only 4 choices.

If you use the RemoteSwitch library, the Blokker3 protocol is the one to be used. Program will be as follows:

#include <RemoteSwitch.h>
BlokkerSwitch3 blokkerTransmitter(7);

void setup(){}
void loop()
{
blokkerTransmitter.sendSignal(1,true);
blokkerTransmitter.sendSignal(2,true);
blokkerTransmitter.sendSignal(3,true);
delay(2000);
blokkerTransmitter.sendSignal(1,false);
blokkerTransmitter.sendSignal(2,false);
blokkerTransmitter.sendSignal(3,false);
delay(2000);
}

In order to use the RCSwitch library, you need to know the codes for ON and OFF for each individual device.

These are:

ON 1 : 0011 1111 0000 0011 0000 0000 //4129536
ON 2 : 0000 1111 0000 0011 0000 0000 //983808
ON 3 : 0011 0011 0000 0011 0000 0000 //3343104
ON 4 : 0000 0011 0000 0011 0000 0000 //197376
OFF 1 : 0011 1111 0000 0000 0000 0000 //4128768
OFF 2 : 0000 1111 0000 0000 0000 0000 //983040
OFF 3 : 0011 0011 0000 0000 0000 0000 //3342336
OFF 4 : 0000 0011 0000 0000 0000 0000 //196608
with "0" is 240us on, 740us off and "1" is 740us on, 240us off

Program with RCSwitch will be:

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup()
{
// Transmitter is connected to Arduino Pin #7  
mySwitch.enableTransmit(7);
// Optional set pulse length.
// mySwitch.setPulseLength(320);
// Optional set protocol (default is 1, will work for most outlets)
// mySwitch.setProtocol(2);
// Optional set number of transmission repetitions.
// mySwitch.setRepeatTransmit(15);
}
void loop() 
{ 
mySwitch.send("001111110000001100000000");// Device 1 ON
delay(1000);
mySwitch.send("001111110000000000000000");// Device 1 OFF
delay(1000);
}

Step 2: Using 433MHz Remote Controlled Switches on Arduino: the Powertran A0342

The Powertran A0342 is very similar to the Selectremote, but it has a selector on the transmitter to select between channels 1-4 or 5-8.
When using the RemoteSwitch library, the Blokker protocol can be used.

For the RCSwitch library you need the ON and OFF codes for ach device.. Those are as follows:

ON 1 : 0011 1111 0000 0011 0000 0000 //4129536
ON 2 : 0000 1111 0000 0011 0000 0000 //983808
ON 3 : 0011 0011 0000 0011 0000 0000 //3343104
ON 4 : 0000 0011 0000 0011 0000 0000 //197376
ON 5 : 0011 1100 0000 0011 0000 0000 //
ON 6 : 0000 1100 0000 0011 0000 0000 //
ON 7 : 0011 0000 0000 0011 0000 0000 //
ON 8 : 0000 0000 0000 0011 0000 0000 //

OFF 1 : 0011 1111 0000 0000 0000 0000 //4128768
OFF 2 : 0000 1111 0000 0000 0000 0000 //983040
OFF 3 : 0011 0011 0000 0000 0000 0000 //3342336
OFF 4 : 0000 0011 0000 0000 0000 0000 //196608
OFF 5 : 0011 1100 0000 0000 0000 0000 //
OFF 6 : 0000 1100 0000 0000 0000 0000 //
OFF 7 : 0011 0000 0000 0000 0000 0000 //
OFF 8 : 0000 0000 0000 0000 0000 0000 //

with "0" is 240us on, 740us off and "1" is 740us on, 240us off

Step 3: Using 433MHz Remote Controlled Switches on Arduino: the ELRO AB440

The ELRO AB440 is a remote controlled set of Swithes that have 12 DIP switches to be set to select the receive address (on which they connect with the transmitter) and to select teh device address (that tells them wether they are device A, B, C, or D).
The hand-held transmitter has 5 dip switches that need to corrspond with the first 5 dip positions on the receiving remote controlled Switch.

If you use the forked RemoteSelect library, you do not need to know the transmitted codes at all, as it has a protocol especially for this device, you only need to know the dip positions.
If I would set the dip position on the transmitter to ON-OFF-ON-ON-ON or expressed as 10111, then in decimal that is '23' However, the RemoteSwitch library sees thie left Dip as the LSB so it becomes 11101 which is '29'.
With a similar DIPposition (ON-OFF-ON-ON-ON) on the Switches

When using the forked RemoteSwitch library, theprogram would be as follows

#include <RemoteSwitch.h>
ElroAb440Switch ab440Switch(7);

void setup(){}

void loop()
{
ab440Switch.sendSignal(29, 'A', true);
ab440Switch.sendSignal(29, 'B', true);
ab440Switch.sendSignal(29, 'C', true);
delay(2000);
ab440Switch.sendSignal(29, 'A', false);
ab440Switch.sendSignal(29, 'B', false);
ab440Switch.sendSignal(29, 'C', false);
delay(2000);
}

If you want to use the classic RemoteSwitch library, use the

'TypeA_WithDIPSwitches.pde' example
If you would have set the DIP Switches e.g. like "1011100100", (for device 'C') you can use the statements: mySwitch.switchOn("10111","00100");and mySwitch.switchOff("10111","00100");

If you want to use the RCSwitch library you need to know the precise codes that are sent for each device's ON and OFF. These can easily be measured with a sniffer, but they can also be calculated.
To set the ELRO AB440 Switch to channel 29 device A, the dip switches are as follows:

ON-OFF-ON-ON for the channel

ON-OFF-OFF-OFF for device A

the protocol of the AB440 sends an ON as '00' and an OFF as '01' so that are 16 bits that are being sent.those 16 bits are then followed by a meaningless '01' and then by an ON code 00 01 or an OFF code 01 00

The table below shows this

onoffonononABCDnaON/OFF
00010000000001010101000129Aaan
00010000000001010101010029Auit
00010000000100010101000129Baan
00010000000100010101010029Buit
00010000000101000101000129Caan
00010000000101000101010029Cuit

the codes to use for the RC Switch library are thus as follows:

A 1049937 000100000000010101010001
A 1049940 000100000000010101010100
B 1053009 000100000001000101010001
B 1053012 000100000001000101010100

C 1053777 000100000001010001010001
C 1053780 000100000001010001010100

Step 4: Using 433MHz Remote Controlled Switches on Arduino: the EuroDomest 972080 or ENER002

The Eurodomest/ENER is a learning system that will not lose the settings if taken out off the wall-socket (at least not for a while). It is the same as the Efergy Eas Off

They are programmed very easily by putting them in a wall socket, pressing the buttun on the Switch long enough for the LED to start flashing, and then press the 'ON' code for the desired channel on the handheld transmitter.

These receivers supposedly can learn the old kaku_switch protocol. They are receptive to remotes of other systems when programmed as such, but I found that they do not always recognize the codes sent by other remotes during programming so you may only be able to only switch on or off a lamp when programmed with another remote.

The RemoteSwitch library has a protocol for these devices but there is a small problem: you need to establish the base address of the set that you have. That in fact is not so hard if you hook up the receiver of the transceiver pair you bought to pin2 and use one of the sniffer programs. in fact it is easier than working with the RCSwitch library as that libary requires you sniff the codes of every button. For the RemoteSwitch library sniffing only 1 button is enough
Suppose you press the button 'A on' and the output of your sniffer program is as follows:

Received 9588047 / 24bit Protocol: 1

the number 9588047 is equal to 100100100100110101001111

As the first 20 bytes of the Eurodomest form its base address that will be

10010010010011010100 which equals 599252

so that is the baseaddress.

In a program it will look like this:

#include <RemoteSwitch.h>
Ener002Switch enerswitch(7);
const unsigned long euro=599252;

void setup(){}

void loop()
{
enerswitch.sendSignal(euro, 1, true);
enerswitch.sendSignal(euro, 2, true);
enerswitch.sendSignal(euro, 3, true);
delay(2000);
enerswitch.sendSignal(euro, 7,false);//switch all off
delay(2000);
enerswitch.sendSignal(euro, 1, true);
enerswitch.sendSignal(euro, 2, true); 
enerswitch.sendSignal(euro, 3, true); 
delay(2000); 
enerswitch.sendSignal(euro, 7,true);//switch all ON
delay(2000);
enerswitch.sendSignal(euro,7,false)
}

For the Netherlands: As per Januari 2016 the Eurodomest is phased out at the Action stores and is being replaced by the ProMAX

Step 5: Using 433MHz Remote Controlled Switches on Arduino: the EverFlourish EMW203RW

The EverFlourish EMW203RW from the German DIYMaxeda group (Praxis, Formido, Brico, Plan-It). It is a sturdy outdoor (green) or indoor (white) switch with a transmitter for 3 switches. They can be set to 4 channels, with 3 positions each. It is identical to the Fjärrströmbrytarset 3-pack that was sold at one time by Clas Ohlson in Sweden


#include <RemoteSwitch.h>
EverFlourishSwitch everswitch(7);
void setup() {
}
void loop() {  
  everswitch.sendSignal('A', 1, true);
  delay(2000);
  everswitch.sendSignal('A', 1, false);
  delay(2000);
}

Should you want to use the RC switch librariy, you need the codes for each device's ON/OFF for each channel A-D
The first 2 Channels have the following codes:

A1 1381719 1381716 / 000101010001010101010111 000101010001010101010100
A2 1394007 1394004 / 000101010100010101010111 000101010100010101010100

A3 1397079 1397076 / 000101010101000101010111 000101010101000101010100

B1 4527447 4527444 / 010001010001010101010111 010001010001010101010100

B2 4539735 4539732 / 010001010100010101010111 010001010100010101010100

B3 4542807 4542804 / 010001010101000101010111 01000101010100010101010

The codes for the channels C -D can easily be measured with a sniffer (I didnt bother as I only needed to establish the protocol), or be calculated:

To make sense of this code, it is easiest to separate them in 'trits'. Let's look at the 'on' code for 'A1' :
000101010001010101010111
ABCD123nanananaON

The first four trits set the device_address (A-D) with a selected letter grounded (00) and the nonselected floating (01)., the next 3 the Switch id (1-3) then there are 4 non relevant trits and then one trit for on (11=High) or off (00=grounded).

'B1-ON', according to that logic, should then be:
010001010001010101010111
ABCD123nanananaON

which -as we can see in the sniffed code- is correct.

So the code for 'ON' on device 1 on channel C would be:
01 01 00 01 00 01 01 01 01 01 01 11

Step 6: Ringing the The Quhwa QH-832AC Doorbell

I found the Quhwa QH-832AC aka QH-C-CE-3V, aka SelectPlus, aka 1-by-One in a local thrift shop ("Action"). It exists in Black and in White.It seems that all the white sets have the same code and all the black sets have a seperate 'same' code. The code is determined by the bell knob. A white bell can be programmed by a black knob and vice versa.

I wanted my Arduino be able to ring the doorbell. Sadly my regular approach by trying to sniff the code with my arduino didnt work,so eventually I reverted to a logic analyzer and found the following codes (How I got to this look here.):
The white button sends the code

010101100101011001011001101010101010

the '1' represents a short puls (250-275u sec) and the '0' a long pulse (950-1000 u sec).
If we then see 'long-short' or '01' as a '1' and 'short-long' as a '0' than this becomes

111011101101000000 or 3BB40

To make it more visual:

           ___
'0':     _|   |   (T,3T)
            _     
'1':    ___| |     (3T,T)

When I did the same exercise for the black button that gave 111100001100110000=3C330 It seems that the first 14 bits are a unique bell identifier and the last 4 bytes have no specific meaning.

In order to have the Arduin ring the bell we need to write a routine that takes the number.'111011101101000000' and for each '1' sends a LOW followed by a HIGH with the LOW 3 times longer than the HIGH

For each '0' it sends a LOW followed by a long HIGH

(there is some variance in the measured LOWS and HIGHS, but a factor 4 seems too high).

Fortunately I found a piece of code that does exactly that (glad to give honors if i remembered how i got it)

const byte rfPin=7;

void setup()
{
SelectPlus(0x3BB40);// White
//SelectPlus(0x3C330);// Black
}

void loop()
{
//SelectPlus_Send(0x3BB40);// 11 1011 1011 0100 0000
}
    
void SelectPlus(uint32_t address) {
    int pulseWidth= 325;// Pulse breedte in uS
    byte repeat = 16;   //  repeat send   
    uint32_t databit;
    uint32_t mask = 0x10000;
    uint32_t sendbuff;

    for (byte j = 0; j <= repeat; j++) {
        sendbuff=address;  
        // send 3 HIGH pulses for syncing
        digitalWrite(rfPin, HIGH);
        delayMicroseconds(pulseWidth * 3);
        
        // Send command
        for (int i = 0; i < 18;i++) {  // 18bits
            databit = sendbuff & mask; // Get most left bit
            sendbuff = (sendbuff << 1);// Shift left

            if (databit != mask) {                 // Write 0
                digitalWrite(rfPin, LOW);  
                delayMicroseconds(pulseWidth);
                digitalWrite(rfPin, HIGH); 
                delayMicroseconds(pulseWidth * 3);
            } else {                               // Write 1
                digitalWrite(rfPin, LOW);
                delayMicroseconds(pulseWidth * 3);   
                digitalWrite(rfPin, HIGH);
                delayMicroseconds(pulseWidth);     
            }
        }
        digitalWrite(rfPin, LOW);          
        delayMicroseconds(pulseWidth * 16); 
    }
}

The chime itself is quite tolerant in the code I sent. If I would have programmed it with the code 1BB40, it would still ring when triggered from my arduino but not when the bell knob is pressed. This has its advantages if you want the Arduino to detect your doorbell pressed and decide if it will ring the bell or not.

The code in the Button usually is the same for an entire batch. The code I gave is for date code 914. Other production dates may have different codes. For other dates you might be helped by this library.

Also, if you want to try this with your Raspberry Pi, look here.

Step 7: Using 433MHz Remote Controlled Switches on Arduino: a LED Dimmer

Jeroen Meijer, the author of the fork of the RemoteSwitch library, pointed out to me that he has added a class to be used with cheap RF LED Dimmer that is available in chinese webshops.

Jeroen analysed the code is very akin to that of the Eurodomest, albeit that it has a 19 bit address and a 5 bit command structure.
His fork of the RemoteSwitch library contains a class -CnLedDim1Switch- to control this dimmer.

Still, you need to find out what the base address of the dimmer is

The codes are also easy to snif. The left 19 bits forming the base address of the device.

So if pressing the button ‘ON’ generates the code:

on 6670849 / 0110010111001010000 00001,

then ‘0110010111001010000’ or ‘208464’ is the baseaddress and ‘00001’ the command code for ON

In a program that looks as follows:

#include <RemoteSwitch.h>
CnLedDim1Switch ledDimSwitch(7);
const unsigned long dimaddress = 208464;
const byte pwr = 1;
const byte licht = 4;
const byte BrightUp = 5;
const byte BrightDown = 6;
const byte Full = 7;
const byte Half = 8;
const byte Quart = 9;
const byte Mode = 11;
const byte SpeedUp = 13;
const byte SpeedDown = 15;

void setup(){}

void loop()
{
ledDimSwitch.sendSignal(dimaddress,Quart);
delay(1000);
ledDimSwitch.sendSignal(dimaddress,Half);
delay(1000);
ledDimSwitch.sendSignal(dimaddress,Full);
delay(1000);
}

..

Step 8: Using 433MHz Remote Controlled Switches on Arduino: HomeEasy

I myself have no experience with the HomeEasy devices but they are frequently used. The RemoteSwitch library has a class for them but there is also a ton of information available, e.g.
In the Arduino Playground.

In this blog

In the HomeEasy hacking Wiki.

The in Scandinavia popular Nexa-PE3 is also said to work according to the HomeEasy protocol ad even has its own library.

The Promax, a learning switch that is replacing the Eurodomest at Action stores (Netherlands), supposedly also has a HomeEasy protocol. The sender though is said to send two protocols an AC protocol and an Home Easy EU protocol. It is most likely akin to the HomeEasy HE874. It is said to have a different, dedicated protocol though

Step 9: Using 433MHz Remote Controlled Switches on Arduino: Unknown Brand

A friend in the UK picked up this set at Lowe's Hardware I believe.
Don't needed to be a rocket scientist to find out this set was compatible with the ENER/Eurodomest Class in the forked RemoteSwitch library

Step 10: Using WiFi

Gradually Rf433 controlled switches are phased out by WiFi /network controlled switches.
However there are options to include RF controlled switches in a WiFi or Ethernet controlled environment

SonOff brings the Rf bridge that translates MQTT signals into Rf signals.
With its standard firmware it can control four 4-button remotes. reflashed with Tasmota software one can send RAW rf codes, virtually making every remote controllable.

A DIY bridge can be made following 1technophile's instructions on github.