How many remote controllers do you have in the house? One for the TV, one for the DVR, one for the Blu Ray player…
There are five remotes sitting on the coffee table in our living room. Plus another couple scattered around the house, controlling table lamps and other TVs. And do you know what? This post isn’t even about those.
I got to thinking that it would be nice to be able to control lights and maybe other devices in the home with a remote. And it’s not that hard. An Arduino Nano, an IR receiver sensor – the ubiquitous and cheap 1838T will do nicely – a few passives and a relay.
Following the YouTube video below, I had an Arduino Nano reading IR remote signals within minutes. Adding a relay would have taken just a few minutes more (the video demonstrates controlling some LEDs).
But that’s thinking too small. It would control only one device at a time. So here’s what I’m thinking: replace the Nano with an ESP32 board. You then have just one IR receiver that can communicate to multiple devices. It detects signals from a remote control and sends out appropriate MQTT messages over the home network and/or interacts with an API on the home intranet server.
Each device that you want to control would have an ESP8266 board and whatever else it needs (eg, relay). Or maybe it’s connected to the network via Ethernet. There are lots of possibilities.
Why is this better? Well, let’s say you have three buttons on your remote that you’ve labelled ‘ALL LIGHTS’, ‘DAY LIGHTS’ and ‘EVENING LIGHTS’. The codes these send out would be interpreted by the IR receiving device, the ESP32 one, which then sends out MQTT messages such as ‘home/all_lights’, ‘home/day_lights’ and ‘home/evening_lights’. You could then program the ESP8266 boards that control individual lights to respond accordingly. Some lights will come on in response to ‘home/day_lights’ while others will switch off. With a single remote button, you can select patterns of lighting. And that’s just the start.
Getting the message
This is going to be a multi-part series that will probably unfold slowly, but let’s at least get the basics sorted.
Swapping in an ESP32 board for the Arduino Nano isn’t as simple as it seems. The IRremote library by the excellent Ken Shirriff is available via the Arduino boards manager or on GitHub here. It claims to support the ESP32, but in fact the support is patchy. When I tried to compile a sketch, it failed, telling me that:
'SEND_PIN' was not declared in this scope
This was especially annoying given that I don’t need the ESP32 to send any signals, it only has to receive.
I believe there may be more recent forks of this library that perhaps offer better support for the ESP32, but I chose instead to follow the advice in this forum thread and hack the library code.
The solution was to edit the boarddefs.h file. If you go to wherever your Arduino folder is located, go into ‘libraries’ and then ‘IRremote’, you’ll find the boarddefs.h file there.
Scrolling down you’ll find a section that looks like this:
#elif defined(ESP32) #define IR_TIMER_USE_ESP32
That’s the whole entry for the ESP32. I added some stuff so that it now reads:
#elif defined(ESP32) #define IR_TIMER_USE_ESP32 // --- ADDED STUFF BELOW --- // see: https://github.com/z3t0/Arduino-IRremote/issues/582 // ESP32 has no onboard LED so we don't define BLINKLED // avr/interrupt.h is not present #undef HAS_AVR_INTERRUPT_H // Disable sending #undef SENDING_SUPPORTED #define SEND_PIN -1 // Supply own enbleIRIn #undef USE_DEFAULT_ENABLE_IR_IN
Eh voila! It now compiles. It means you can’t use the ESP32 for sending signals, but apparently there are issues with that anyway and it’s not necessary for this project.
In the video above, the presenter uses IR receiver modules, which are very cheap on eBay. But it’s just as easy to use the 1838T itself, along with a few passive components.
The diagram for a typical circuit that you’ll find on the 1838T datasheet and elsewhere on the interwebs (above) shows four passive components. I’ve seen examples of this detector being used with no passives, but I figured I’d play along with the datasheet, more or less. Also, those modules are pretty much just the sensor plus the passives indicated in the datasheet.
There are two capacitors between VCC and GND – a 100µF and a ‘104’, which is the code printed on 0.1µF ceramic capacitors. Presumably these are being used as bypass caps to filter noise. For my first experiments, I used only the 0.1µF. For any final design I’ll probably add the other cap too.
There’s also a 100Ω resistor in series between the VCC supply (can be 3.3V or 5V) and the 1838T’s VCC pin. Finally, there’s a weak pullup resistor between VCC and the signal (OUT) line. The diagram suggests a value of more than 20kΩ – I used 47kΩ.
For playing around, I decided to add a regular LED just as a way of signalling that stuff is happening.
In the picture of the test setup below, you’ll also see a capacitor on the power rail. I’m in the habit of throwing these things in just to help keep the supply stable. The ESP32 module itself is one I bought for cheap on eBay – listed as the DOIT Development Board.
The code for this project is in a GitHub repository: ESP32_IR_IoT_hub.
There’s also a simple sketch just for decoding the signals from a remote control. This should work with most microcontroller boards – Arduinos, Teensy, ESP etc. The repo is: IR_remote_decode.