Control The Lights with Any IR Remote

Have you ever wanted to turn off the lights without moving, especially when you started a film on TV or when you felt asleep after a busy day? If the switch is out of reach, it is most likely to leave the lights on. I inspired from that idea and built the perfect solution; an IR remote controlled light switch!?

The solution

With this easy-to-assembly IR controlled universal switch you can control not only your room illumination, but also turn on and off any device; i.e. your heater. The tiny software is designed to support most of the TV, DVD or Satellite remotes.

All you have to do is to build that circuit with easy to find components and connect it. TA-DA! Now you can press a key of your favorite IR remote to teach that key to it and then use the same key to switch it on/off.

Key features

  • Easy to build,
  • Needs only 9 components (plus 3 optional),
  • Under 1$ MCU,
  • Plugs directly to AC mains,
  • Works with almost every IR remote,
  • Can be used to switch any AC powered device,


Before giving the hardware and software, the usage should be described step-by-step.

  1. Power-on the circuit.
  2. Direct your remote controller at the circuit.
  3. Press a rarely used button 10 times until the relay switches.
  4. Now the key has been memorized, you can use that button to toggle.
  5. Use the reset button (if available) or power-off to clear the button setting.


The circuit is quite simple and it’s not necessary to make a PCB to build only one. I used a protoboard and the result is in the photo below. I use it as a normally-closed (NC) light switch.

IR remote controlled light switch circuit diagramBill of materials

  1. Microcontroller PIC12F508
  2. Infrared receiver TSOP2238 (or alternative for desired freq.)
  3. Resistor 100R/1W+
  4. 2x Diode 1N4007
  5. Zener diode 5v1/0.5W+ or 4v7/0.5W+
  6. Capacitor 2u2F/250VAC+
  7. Capacitor 1000uF/6V3+
  8. Relay, 5V/240VAC+ (current depends on the application)
  9. Reset button, momentary (optional)
  10. Connectors 250VAC (optional, 1×3 or 1×5)

Circuit diagram

The circuit diagram is given below.proteus circuit remote controlled switchNote that Proteus hides the power pins of the microcontroller in schematic but the required information is given below the microcontroller.

Power stage

This circuit is designed to be connected in series to an AC load, so it has to be powered from AC mains (220VAC-240VAC, 50Hz). Keeping simplicity in mind, a capacitive power supply suits well to this project.

The left-hand side connector J1 is the AC input. On the positive half-cycle, current flows over C1, D2 and charges the capacitor C2 up to zener voltage of D3 (4.7V or 5.1V). On the negative half-cycle, if flows through R1, D1 and C1 without going further into the circuit.

For further reading on capacitive supply Microchip AN954.

SPICE Simulation

The voltage ratings of the components are critical here. In addition, some components must meet specific power rating. The best practice to know the necessary ratings is simulation. Although the component library is not the richest, LTspice is a great tool for analog simulations and it comes for free.

ltspice spice circuit diagram 220vac 230vac 240vac capacitive supply simpleIt is wise to analyze the power circuit for two extreme operating regions; low current mode when the relay is off and high current mode when the relay is on. In the simulation green is output voltage, yellow is zener diode power and red is resistor power.

For the low current mode, a current smaller than the sum of supply currents of PIC (0.625mA) and TSOP (0.7mA) should be drawn. 4k7 equivalent load will draw about 1mA and it is reasonable for the simulation.

low current simulation of 220vac 230vac 240vac capacitive supply simpleThis is the case when the zener diode and the resistor are stressed the most. Observed peak powers are 1.0W for the zener and 4.7W for the resistor. Average powers are measured as 0.35W for the zener diode (should be chosen 0.5W) and 1.15W for the resistor (1.0W is also OK). The average output voltage is 4.73V because in the simulation 4.7V zener is used from LTspice library.

For the high current mode, a current as much as the relay current must be used. The relay has 70R coil and the small currents drawn by the other components can be neglected. So the equivalent load is 70R.

high current simulation of 220vac 230vac 240vac capacitive supply simpleHere the output voltage ripple is around 0.74V and the average output voltage is 4.41V. The values are suitable for both the microcontroller and IR receiver.

Control stage

The microcontroller reads the output of the IR receiver over GP5 pin and checks for known patterns. When a match is found, it drivers GP0, GP1 and GP2 to supply enough current to drive the coil of the relay (The maximum current sourced from a pin is 25mA and the relay draws 75mA) There is no need for a reverse diode between the coil pins when using 3 outputs because PIC has already reverse diodes (each capable of clamping 20mA). When a higher demanding relay is connected, GP4 can also be paralleled to those 3 pins but it is not smart to exceed the total current rating for a port which is documented as 75mA.

pic 12f508 gpio pin schematic

Electrical Connection

If you want to switch a lamp, then it is better to use the normally-closed (NC) output of the relay. Thus, the light can still be controlled by its own wall switch. If you want to switch a normally-off device, like a heater, prefer the normally-open (NO) output to keep it normally-off. The connection for a lamp is shown below.lamp electrical connection


The implementation of the software was the most tricky part because it needed lots of inspection on different remote controllers. And the second challenge was the non-debuggable MCU.

Remote controller signals

I connected TSOP2238 to USBee AX Pro logic analyzer and captured some button signals of different remote controllers with Salaee Logic software.

LG smart TV remote

LG remote controller signalSamsung smart TV remote

Samsung remote controller signal

Vestel radio Remote

Vestel remote controller signalNote that the output of TSOP (seen on the signals above) is inverted (active-low) but the software considers “0” as HIGH and “1” as LOW. So beware of that.

Reader algorithm

By inspecting the signals, an identification method is developed.

First, the start of a message must be detected. This will be done by detecting a long silence (LOW signal). We can consider any LOW signal that is longer than 5ms as an idle (inter-message) space.

TIME_IDLE_us IR signalSecond, to read the message bits we also need to determine (and ignore) the preamble (the leading HIGH-LOW sequence) signal. If the first HIGH signal after the idle period is longer than a threshold, it can be considered as a preamble. This threshold value is 3ms to cover all models.

TIME_PREAMBLE_MIN_us remote controller signalThird, in IR language a bit means a HIGH-LOW pair of signals. Each bit will be evaluated as a MARK if the length of LOW part is longer than a threshold, otherwise it will be evaluated as SPACE. This threshold is determined as 1ms.

TIME_MARK_MIN_usFinally, when a long silence is detected, the reception will be terminated and the received message is evaluated looking at its MARK and SPACE value. The last threshold that is used to determine that the bit is ended and also the message is ended at the same time. It is 3ms but could be the same as the idle time.

TIME_BITLEN_MAX_usCode implementation

The most useful feature of this project is that is can work with any remote controller. To cover that requirement, a memorizing function is needed. The tiny MCU used in this project has only 512B (512x12bits) program space and it’s not possible to implement a fully functional protocol reader algorithm. A universal reader that only records and matches the meaningful IR bits is implemented instead.

Setup and loop

The code is designed with setup and loop functions to make porting to Arduino easier. Setup function sets relay pins as output and TSOP pin as input then starts TMR0 by setting its prescaler.

The loop function runs the tasks and waits for the TMR0 to overflow the designed timeout. The settings in the header sets the looping frequency to 5kHz.

State machine

The state machine loops every 200us (1/5kHz) and is responsible for reading, storing , checking IR signals.

  1. Init state: creates a long delay if requested, clears the candidate message and resets the counters.
  2. Sync state: detects a long silence, thus aligns the algorithm to the beginning of a message.
  3. PreambleWait: detects the HIGH period of the preamble (goes to the next state on the FALLING edge).
  4. BitWait: waits until the HIGH edge of the first bit.
  5. BitHigh: waits until the LOW period of the bit, times out if the waiting takes longer than idle time.
  6. BitLow: measures the length of the LOW period of the bit. If it is longer than the threshold sets the corresponding bit in candidate message. If end-of-message is detected, goes to the Compare state.
  7. Compare: If the message is the first one after reset, copies the candidate to saved. Otherwise compares the candidate to the saved. If a pattern is not saved yet, it keeps comparing the candidate to the saved. If the same message has been repeating for REPEAT_TO_SAVE times, it stores the message permanently. Once a message is stored, it only checks the candidate and goes to Toggle state on match.
  8. Toggle: toggles the relay, starts the debounce counter and goes to the Init state.


Source code

main.c file:

main.h file:


The source code can be compiled using MPLAB X + XC8 (tried with v4.05 and v1.44) or stress-free online compiler MPLAB-Xpress. If you think you are too lazy to compile yourself, the hex file is here.

Final Words

The project is designed to be universal but there are always some exceptions. Everything is tested and works fine with the remote controller types listed above. When i have another remote controller i will also make the necessary tests with it immediately.

Due to the limitations of the MCU, a perfect software that covers every detail couldn’t be provided. It is also possible to switch to an Arduino UNO with the same logic and see what could be improved.

Have fun 😉