USB Funk

Managing 433MHz radio-controlled sockets with the PC

Picture: Radio-controlled socket

After I bought a whole shopping cart full of radio-controlled socket sets at a reasonable price in the hardware store, I quickly realized how convenient it is to switch the laser printer or the Christmas lights by radio.

But it would be even better to automate the switching processes via PC, and to script them or to control them remotely via internet. So a USB interface was needed!

The idea of wireless sockets is not completely new; the code is partly taken from the talking alarm clock 2 and was used there to switch on the bedside lamp at alarm time.

During the implementation of the radio protocol I also came across the EtherSex project, where a similar idea in combination with a network module makes switching from the LAN possible. But if you run a home server anyway, this solution is rather overkill. The goals of my USB interface were therefore a simple design, small dimensions and low component costs.

Picture: USB Funk interface
Picture: Bottom side of the board

To keep the component costs for the USB interface as low as possible, an ATMega48 with AVR V-USB (a software USB stack) is used. The controller gets via USB control message the house code, code (adjustable via DIP at the socket) as well as switch status (on/off) and converts this information into the radio code of the original remote control. It transmits by using a cheap amplitude modulated transmitter module on 433,92MHz. These are available ready to install incl. postal approval at RS Components and various other dealers. I use the QAM-TX1. As 433MHz antenna a wire in Lambda/4 is used. So it has to be rather exactly 17,3cm long.

The circuit is as already said very simple. Three resistors and two Z-diodes for the USB interface, a crystal for the controller and the 433MHz transmitter module. The blue light emitting diode indicates the operating status. Glowing = standby, short blinking = packet sent.

Picture: Circuit diagram

Picture: Dip switch

The sockets are addressed with a 10 bit dip switch. The digits 0...5 correspond to the house code and the letters A...E to the code of the respective wireless socket. I convert the house code binary, so I assign the switches to the valence 1, 2, 4, 8 and 16. In the picture, switches 1 and 5 are active, resulting in the house code 1 + 16 = 17. With this code, only one switch may be active at a time. It is used to assign the sockets to the individual buttons on the remote control. If "A" is active, the socket reacts to the keys "A" (on/off) on the original remote control with the corresponding identical house code. "E" is not available there as a button, but can also be addressed with the USB interface if you can do without using the remote control.

I would like to go into more detail about the firmware. The PowerSwitch example project of the V-USB driver served as a template for the development, because it offers a similar functionality. Host computer and controller communicate by means of the so-called Control Endpoint 0. According to the specifications a Control Message is intended to identify or configure USB devices. The Endpoint 0 must be present on every USB device. Apart from the information just mentioned, it can of course also transmit other short manufacturer-specific data - such as here three bytes that are to be sent to the wireless socket.

The data structure of the Control Endpoint 0 has a length of 8 bytes. Important for us are bRequest, wValue and wIndex. bRequest is an unsigned char. It contains which action the usbfunk interface should execute. (See requests.h) The other two values are 16 bit variables (word) and so I use the lower byte of wValue for the house code and the upper byte for the code. wIndex is 1 or 2 depending on whether it should be switched on or off. The corresponding structures and libusb commands are described on the Driver API page in the Wiki of the V-USB driver.

A request of type FUNK_RQ_TX calls the function void wireless_switch( uint8_t housecode, uint8_t code, uint8_t state ); which converts the decimal numbers into the appropriate wireless code and activates the transmitter.

Picture: States of the pins

All dip switches switch to logical 0 (GND). An open switch means floating (f), the third state logical 1 (VCC) remains unused. The wireless_switch() function now converts the passed decimal numbers into binary 2 bit follow; since only 0 and f occur, 5 bit house code, 5 bit code as well as 2 bit status are each converted directly into their corresponding pulses.

In the transmit buffer, a 0 means a short pulse with a long pause and a 1 means a long pulse with a short pause. Bytes 00 (GND = switch closed, input value 1) and 01 (floating, switch open, input value 0) are stored. This inverts the actual logic, but it is easier to consider closed switches as a logical 1. This has to be considered when passing or converting the variables housecode, code and state.

Here is the capture of my logic analyzer on the TTL output of a receiver. This code switches the socket with housecode 17 and code A from the previous example:

Picture: Data packet

The output of the data to the port is done in a timer interrupt. This is preloaded with appropriate values to run exactly to the next edge. There it triggers and switches the transmitter on or off. The sync pulse is generated after 48 edges (12 bit x 2 pulses, one rising and one falling). Preload values are defined in the wireless.h and keep the timings of the original remote control sufficiently. The pulse sequence must be repeated at least twice for the receiver to switch. For this reason it is sent 5 times for safety.

The firmware is included in the archive in form of the sourcecode and a hexfile. If you want to compile the code yourself you can do this as usual with avr-gcc by typing "make" and "make program" (for flashing). Avrdude also sets the correct fusebits.

The PC console tool is located in the folder "cli". It can be compiled under Linux as usual with "make". If this fails, the libusb-devel package may be missing.

An overview of the possible commands is displayed when calling "usbfunk" without or with wrong parameters.

Picture: Screenshot

To switch the radio-controlled socket shown as an example on the previous page, the tool is called as follows:

sudo ./usbfunk pt2 17 A on

Important: It is necessary to run the program as root under Linux, otherwise no access to the USB port is possible. If you want to avoid root rights you can also create a udev rule.

USBFunk 2

Due to the demand, a slightly larger board was designed, which does not need SMD components. This is much easier to build. Instead of the ATMega48 now an ATMega88 is used. Firmware updates are easily possible via bootloader.

Picture: USBFunk II

Manufacturer Type Model Chipset From Firmware
Kangtai wireless socket - PT2272A-L2 v1.0
Elro wireless socket/dimmer AB-4xx (Home Control) HX2272 v1.0
Elro wireless socket AB-600S SC5272S-L4 v1.1
HIG wireless socket - SC5272S-L4 v1.1
Düwi / Intertechno wireless socket PAR-1500 or the like SC5272S-L4 v1.1
Düwi / Intertechno wireless dimmer ITR-300 or the like SC5272S-L4 v1.1
Intertechno radio chime ITR-7000 SC5272S-L4 v1.1
Heidemann radio chime HX series unknown v1.1
Elro wireless socket HE-874 (Home Easy UK) unknown v1.2

In version 1.2 a bug in the USB communication is fixed! It is recommended to flash the latest firmware to the interface!

Software with graphical user interface

To simplify the usage, a software for Windows was developed, too.

Picture: USBFunk GUI screenshot

Note for driver installation

The included driver works up to and including Windows 7. For Windows 8/8.1/10 it has to be installed with the tool Zadig. The procedure is identical to the one I described for my LED ticker on page 2 in the PDF.

Graphical user interface
Data sheets
Previous versions
Further links and information