Remote Power Control Switch

The background to this project is the desire to eliminate wall switches for lights, and to deal with a situation where a power switchboard would be difficult to access. The idea is to use a remote control unit to send commands to a master power switch unit. While the project may appear to be simple, it is presented here as a means of describing the use of the HopeRF modules RFM01 and RFM02 that provide a one way FSK RF datalink in the 434MHz band.

The specifications and overall design choices are:

  1. A 12 digit keypad allowing 10 power lines to be switched, with 2 commands for general use (such as "all power off").

  2. An RF link operating in the 434 MHz band (mainly because of ready access to low cost RF modules).

  3. The remote unit is built into a handheld case with 3V battery and keypad, and uses a 20 pin DIP ATTiny2313 microcontroller interfacing with a HopeRF RFM02 transmitter module. The smaller 14 pin AVRs have insufficient pins. The unit must be able to run at very low power while not in use.

  4. The master unit uses an ATMega48 microcontroller with a set of 8 electromechanical relays, and interfaces with a HopeRF RFM01 receiver module.

The unit has been in operation for nearly three years and has proven reliable except that the base station can hang after a short brownout that doesn't allow a proper reset to occur. A solution to this would be to use a better external reset circuit. The original alkaline batteries are still in use in the handsets. All documentation for code and gEDA PCB is available on GitHub. This can be downloaded in zip format.

The RF Modules

These modules are challenging to use, particularly as it is difficult to debug the system in a small lab if RF communication has not been established. Fortunately some developers who used these modules have generously made their work available (see references below), giving a base from which to begin.

The Hope RF module series consists of:

  • the RFM01, a receiver module possibly based on a chip from Silicon Labs Inc, namely the IA4320 Universal ISM Band FSK Receiver;

  • the RFM02 transmitter is possibly based on the IA4221 Universal ISM Band FSK Transmitter;

  • and the RFM12, a transceiver module, is possibly based on the IA4421 Universal ISM Band FSK Transceiver.

Datasheets for the underlying chipsets are readily available on the Internet and should be downloaded since they are significantly better than the HopeRF versions published as RF01, RF02 and RF12. Some code for the RF12 has been published by Tomasz bla Fortuna and Aleksander Mielczarek and possibly others. Code for the RF01 and RF02, which was critical in being able to complete this project in a reasonable time, has been published by Wilhelm Krüg. There is also a good deal of forum discussion, code and tutorials for the RFM12 transceiver. The RFM01 and RFM02 Rx/Tx pair is not commonly used and there is little supplementary information available.

The microcontroller interface is SPI which is supported in hardware on most of the AVR microcontrollers. However the RFM01 and particularly the RFM02 modules do not conform strictly to the SPI standard. For this reason it is necessary to ignore the hardware support in the AVRs and use "bit banging" to operate the SPI interface. This is offensive to one's aesthetic appreciation of these microcontrollers, but it simplifies the programming. It also frees up the hardware SPI port for firmware updating.

The overall approach to developing the system was as follows:

  1. Build the circuit to the point of connecting up the microcontroller for firmware programming, then to the SPI connection to the RF module.

  2. Establish the SPI interface using a CRO to verify operation. For the RFM02 transmitter there is very little that comes back from the module. A status read command may return some information but generally it's all zeros. The RFM01 receiver returns a more interesting set of status information. The best test is to set the clock output on the module (which on power-up is 1MHz) to 10MHz and verify that it has changed.

  3. Set up the RFM02 transmitter with parameters that have been successfully used. The one's I used were those published by Wilhelm Krüg. Verify that data transmitted over the SPI interface to the transmitter module looks correct (see below). Set it to transmit some data in rapid sequence.

  4. Set up the RFM01 receiver in the same way. The FFIT output and nIRQ will trigger when the FIFO has reached its preprogrammed limit, and this can be used to trigger a CRO. This will show if data is being received in sympathy with the data transmitted. Due to the asynchronous clocks at both ends it's more difficult to check the actual received data with a CRO, so some other way needs to be devised, such as RS232 transmission to a PC or toggling spare output ports.

Most commands sent to the modules are 8 or 16 bit words and use the standard SPI format. The RFM02 transmitter paces its own transmission of data bit by bit according to the data rate set in the module. There are two modes for this. I used the mode in which Tx data is sent over the SPI interface (which avoids using an extra port). This effectively breaks the SPI standard so that the SPI features of the microcontroller cannot be used. To start a data transmission a specific 8 bit command 0xC6 is sent, but the nSEL line is not lifted at the end of this command as is normally done to finish off a command. The module then takes over using nIRQ to signal when each data bit is to be provided. The datasheets are quite confusing about this process. When the command 0xC6 has been completed, nIRQ drops to indicate that the first databit is to be presented on the SDI line. When the bit period has ended, nIRQ rises for 1.6 microseconds to signal that the next bit is to be presented. The module transmits the first bit over the RF interface during this subsequent period. This continues as long as is desired, and is terminated when the nSEL line is raised by the microcontroller. The nIRQ is meant to be used as an interrupt to the microcontroller,

The Circuits

The circuits (receiver, switch, and transmitter) are reasonably straightforward. The receiver PCB includes a serial to RS232 converter and options to use the Hope RFM12 transceiver module but this is not used in this application. Apart from power connections, only the SPI lines and nIRQ on the RF modules are needed. The SDO line doesn't exist on the RFM02 transmitter and status is read through the nIRQ line. The AVRs have their own internal clock so the clock output on the modules isn't needed (this turns off when the module sleeps, which we don't want to happen in this application). The nIRQ interrupt was also not used as the application is very simple. Only the keypad interrupt was used to wake the remote unit microcontroller from a power-down sleep state.

A quarter wave whip aerial for the 434MHz band is only about 170mm long which is simple enough for the receiver. It was still too long for the handheld remote unit, so a bottom loaded whip was used and stretched along the length of the case (a loop aerial wasn't chosen due to its sensitivity to detuning in a hand-held unit). The aerial design for 434MHz, using wire gauge 0.025" (US wire gauge 22), and with a length of 0.125m (0.403ft) requires a 0.04uH inductor for a bottom loaded aerial. A coil 6 turns (0.2" long for 22 gauge wire) and 0.1" diameter should be adequate. This was wound over a small resistor acting as a former. This was all very approximate, but the modules have a built in automatic tuning mechanism which attempts to overcome inaccuracies and other detuning effects (up to a point). Ironically a longer wire wrapped around inside the case and without the inductor gave better performance.

The RFM modules all have a DIL header with 2mm spacing rather than the more commonly available 0.1 inch spacing. Rather than attempt to solder wires to the pins, it is possible (just) to bend the pins to fit onto a prototyping circuit board with 0.1 inch spaced holes. This gave a solid anchor for the module on the board. The PCB of course doesn't have this problem and sockets are available.

The keypad circuit for the remote unit uses the design described in Atmel's application note AVR240: "4 x 4 Keypad - Wake-up on Keypress". This needs only three 1N914 diodes to provide an interrupt line to wake the microprocessor from power-down sleep. The program given here uses INT1 but INT0 could also have been used.

The Remote Unit Firmware

See the Doxygen documentation. The main program focuses around a sleep command which is executed when no key is detected as being pressed on the keypad. Both the module and the microcontroller are put into power-down sleep which theoretically pulls about 3 microamps of current, mostly drawn by the RFM02 module. The measured value was 50 microamps, but this was at the lower limit of accuracy of the meter. When a keypad interrupt wakes up the microcontroller, a debounce process waits for the keypress to stabilize, and a single byte of data is transmitted representing the numerical keypress value. The program loops waiting for the key to be released. The data is transmitted continually while the key is held down.

For the data transmission, the writeDataCMD() function starts off the process by sending the 0xC6 command to the module, and returns with nSEL still held low. The writeByteTx(n) function paces the transmission of a byte of data by monitoring the nIRQ line. The program sends a series of 0xAA bytes for receiver synchronization, followed by a 2DD4 synchron word needed by the receiver to indicate the start of the message. Any number of data bytes can then be sent. The stopDataTx() function lifts the nSEL line to terminate the transmission, and powers down the module transmitter. Small timing errors can cause the power-down command to be interpreted as part of the data so there must be a small delay inserted between the last data bit and the power-down command.

The Master Unit Firmware

See documentation. The program continually checks for received data, which is indicated by the FFIT (FIFO trigger) bit in the status word. The FIFO is set to trigger at 8 bits to allow a single byte to be received. As each byte is received it is checked for validity and one of 12 counting bins is incremented. When the number of valid words received reaches 10, the bins are examined to find the one with the most number of  counts. This provides a simple estimation in the presence of possible corrupted data.

Once a valid command has been established the corresponding port is toggled to allow power switching on or off. A lock is set to prevent further received data causing the switch to toggle spuriously. A delay of about 2 seconds, during which no valid data must be received, is required before the lock is lifted and further commands may be received.

The RF02 receives data by extending the status command beyond the 16 status bits. When the 16 status bits have been read, the first bit in the FIFO is presented. Further SCK pulses will present subsequent data bits until the 8 FIFO bits have been read out. The readDataByte() function reads the status bits and checks the first bit to determine if FFIT is set. If so, it reads out the 8 data bits and returns these with the first 8 status bits. Otherwise the full status word is returned.

Because the master unit will remain idle for very long time periods, it is preferable to use the nIRQ pulse to wake up the microcontroller from a power down sleep when the FIFO is triggered. Once the 2 second delay has been completed, the microcontroller can be returned to sleep mode. The RFM01 module draws about 10mA. It doesn't have a sleep command, but all internal circuit blocks could be turned off, reducing the current drain to about 0.3 microamp. This could be done for short periods of time as the transmitter continues to transmit the same data as long as the key is pressed, giving the Rx time to wakeup and receive the signal.


  1. Telemetry system using the RFM01 and RFM02 modules and ATMega8 by Wilhelm Krüg.

  2. RFM01 and RFM02 libraries for Arduino.

  3. Tutorial on the RFM12 transceiver.

  4. Example Code and tips for using the RFM12 and RFM12B transceiver modules by Aleksander Mielczarek.

  5. Code and advice for the RF12 transceiver Tomasz bla Fortuna.

  6. Library for RFM12B on Arduino.

Original prototype of the receiver board using PMOS switches.

Second version of the receiver board including the PMOS MOSFET switch and an RS232 converter. The RF module on the left can be either a receiver or transceiver module with jumpers set appropriately. This board is intended to double as a bidirectional wireless communications link.

The transmitter board and case.

First created 22 June 2011

Last Modified 8 September 2014
© Ken Sarkies 2011