Remote Control of Mains Sockets using an I2C Bus

Radio Control Hanset Signal Format:-
I’ve been looking at different ways of controlling the Radio Control mains sockets from the Raspberry PI, and built an RF sniffer circuit based on 433MHz modules available on ebay. The receiver just connects into the microphone socket on a PC, and I’ve used Audacity ( an audio editing application ) to view the signals. Here’s the signal output by the transmitter…


A quick look inside the transmitter module reveals that it uses the HS2260-R4 chip, and its datasheet can be found here… HS2260-R4 Encoder from Princeton Technolgy Corp. The data sheet explains that I have sniffed a sequence of 6 code words with a sync bit being the pause between the words. So zooming in on a single code word starts to show the data being transmitted…

So the encoder chip is a bit non-standard as it uses tri-state inputs. This means each pin can have 3 states, zero, one or floating. This makes decoding the code word possible. We need to read the digits as blocks of two pulses…

  • Zero is represented by two short pulses.
  • One is represented by a short pulse followed by a long pulse.
  • Two ( float ) is represented by two long pules.
  • ( the forth combination of a long pulse followed by a short pulse is not implemented. )

So reading the code word from left to right gives 00111 11102 02. The last pulse is the start of the sync bit, so can be ignored.

So sniffing all the combinations for this radio control handset gives…

  • 00111 11102 02 = channel 1 on
  • 00111 11102 20 = channel 1 off
  • 00111 11120 02 = channel 2 on
  • 00111 11120 20 = channel 2 off
  • 00111 11200 02 = channel 3 on
  • 00111 11200 20 = channel 3 off
  • 00111 12100 02 = channel 4 on
  • 00111 12100 20 = channel 4 off
  • 00111 21100 02 = channel 5 on
  • 00111 21100 20 = channel 5 off

Then I’ve had to do a bit of trial and error, and found that this sequence breaks down into 3 data segments.

The first 5 digits are the handset address. This is standard binary as the mains sockets don’t recognise a two ( float ) in this section of data. This address is hardcoded by solder links on the transmitter handset PCB, and can be in the range 0 to 31. The example shows transmitter address 7.

The next 5 digits are the channel number. There doesn’t seem to be much real logic behind this, and is probably a result of the way the circuit is implemented at the receiver end in the mains sockets. The channel number is defined by one of the five bits being active and set to ‘2’. This limits the range of channel numbers to 5. The first 3 bits when inactive are set to ‘1’, the last two bits when inactive are set to a ‘0’. I’ve tried putting Binary Coded Decimal in this section, but the receivers just won’t respond. However, the recievers do seem to respond to a zero, giving an extra channel over the transmitter handsets. The example shows transmitter address 7, channel 1.

The next two digits provide the ‘on/off’ information and use a mechanism similar to the channel data. ’02’ represents ‘on’. ’20’ represents ‘off’. The example shows transmitter address 7, channel 1, on.

I had initialy hoped to just connect a HS2260-R4 chip to the Raspberry Pi GPIO pins, but the use of the tri-state inputs made this a non starter. So instead I decided to use the I2C bus and a Microchip PIC 12LF1552. This chip operates from a 3.3volt supply, so won’t need any level shifting circuitry on the I2C bus, draws less than 2mA at 20MHz, so can be powered from the Raspberry PI and provides a single chip solution to the encoder circuit.

I2C interface to the Rasperry pi:-
Getting the I2C bus running was not as easy as I had hoped. The applcation note from Microchip stops short of providing a fully working example ( but it really isn’t far off ), and there are a number of discussions around the chipset on the Raspbery Pi performing ‘I2C clock stretching’. Eventualy I invested in a Bus Pirate to debug the system, and managed to implement a solution that avoids these limitations. It isn’t glamorous, and performs no error checking. So passing invalid data to the PIC chip is one way of causing the chip to crash. However, as long as valid data is used, the chip provides a reliable and versatile solution, as it allows the selection of channel number AND handset address, providing a theoretical limit of 160 (32×5) radio control channels – or possibly 192 (32×6) channels if you use channel ‘0’. So more than enough for around the house.

I’ve loaded i2c-tools on the Raspberry Pi, so a typical Linux command line to the PIC chip would be…
sudo i2cset -y 1 0x08 0x07 0x10
which translates to… I2C bus 1, I2C device 8, Radio Control handset address 7, Radio Control channel 1, switch off. This results in the following data transfer over the I2C bus…
The first byte is the address of the PIC chip on the I2C bus. This is hardcoded in the PIC chip, so will always be 0x08. Also note that the value transmited over the bus is twice the value entered at the command line. This is due to the least significant bit being used to differentiate between a read or a write transfer, and the remaining data bits being shifted up one to accomaodate. The next two bytes are the data we are sending. The first byte is the remote control handset address we are going to use, in this case 0x07. Then the first 4 bits of the final byte represents the channel number ( 1 ), and the last four bits represent the function. Zero indicates ‘off’, any over value indicates ‘on’.

So another couple of examples…
sudo i2cset -y 1 0x08 0x07 0x11

sudo i2cset -y 1 0x08 0x1F 0x50
which translates to… I2C bus 1, I2C device 8, Radio Control handset address 31, Radio Control channel 5, switch off

Signal comparison:-
The first signal is from the Radio control handset address 7, pressing the channel 1 on button…

The second signal has been created by the PIC chip being passed the equivalent Linux command ( sudo i2cset -y 1 0x08 0x07 0x11 )…

Here’s a video of what it looks like in action…

Leave a Reply


− four = 3