Introduction: ESP-12 Infra Red Blaster

Infra Red remote control blaster using esp8266

Transmits remote control codes received from Web supporting multiple output devices.

Built in simple web page mainly for testing.

Normal use is via POST messages which can come from web pages or from IFTTT / Alexa voice control.

Supports an Amazon Echo/Dot activate detector to mute / quieten as soon as activate word is spoken.

Commands are either single commands or sequences. Sequences can be stored as named macros which can then be used as commands or in other sequences.

Recent history and list of macros may be obtained via the web interface

Supports OTA uploading of new firmware and uses WifiManager library for initial wifi set up

Step 1: Hardware

Uses following components

  • ESP-12F module
  • 3.3V regulator (MP2307 mini buck regulator)
  • MOSFET switches (AO3400)
  • Infra Red emitter (3mm)
  • Light Dependent Resistor GL2258 (Optional Alexa activity detector)
  • Resistors
  • Decoupling capacitor (20uF)
  • USB female socket (preferably solder friendly with sleeve
  • 3 pin IC socket strip for Alexa detector
  • Mechanical parts (can be 3D printed)

Can be assembled into ESP-12F project box

  • Attach regulator to USB connector and insert into box
  • Make up IR driver onto small piece of vero board (3 wires, +5V, 0V gate input)
  • Connect IR driver to USB +5V, 0V
  • Insert 3 pin IC socket into project box if using Alexa detector. Connect to +3.3V, 0V and wire for input
  • Make up ESP-12F with 2.2K from GPIO15 to GND, EN to Vdd, 4K7 GPIO13 to Vdd, Alexa input to GPIO13, IR driver to GPIO14 , 0V and Vdd to 3.3V
  • Make up Alexa detector and support buffer if required.

Note it can be easier to program ESP-12F first if you have some sort of serial programming facility or temporary breadboarding facility like this to connect to the serial ports.

Subsequent programming can be done using the built in OTA update.

Step 2: Software

The ir Blaster uses an Arduino sketch available on github

This needs to adjusted to suit local conditions and then compiled in a esp8266 Arduino environment.

The following libraries needed, most are standard or can be added. The last two are included in the git.

  • ESP8266WiFi
  • ESP8266WebServer

  • FS.h

  • DNSServer

  • ESP8266mDNS

  • ESP8266HTTPUpdateServer

  • ArduinoJson

  • BitTx (included in Git)

  • BitMessages (included in Git)

Items in the sketch to be changed include

  • Authorisation code for web access AP_AUTHID
  • Wfi manager password WM_PASSWORD
  • firmware OTA password update_password
  • New IR devices / button codes (see later)

Once this is done then it should first be uploaded using conventional serial upload.

As SPIFFS is used then the memory should be prepared by installing and using the arduino ESP8266 Sketch Data upload tool. This will upload the data folder as initial SPIFFS content

When the device can't connect to the local network (as will happen first time) then Wifi manager will create an access point (192.168.4.1). Connect to this network from a phone or tablet then browse to 192.168.4.1 You will get a web interface to connect to the local wifi. Subsequent accesses will use this. If local network changes then it will switch back to this config mode.

Subsequent update may be done by compiling an export binary in Arduino environment and then accessing the OTA interface at ip/firmware.

Step 3: Add Device / Button Codes

Note: This section has changed from previous method where configuration which was previously compiled into the code. It now uses files which are loaded from SPIFFs filing system. This makes it much easier to upload new definitions.

The button definitions are included in the buttonnames.txt file. It is a global list of names across all remotes in use as many names tend to be common. As supplied this contains details for the remotes I use. New entries can be added. There is space for a total of 160 names but this can be increased by adjusting constants in bitMessages.h and recompiling. The names defined here are the names to be used when sending commands.

Each remote device is defined in a file called dev_remotename. It consists of a config section at the top and then a mapping table from buttonnames to codes which are hex strings containing the bits to be sent. Only the buttonnames required need to be defined.

The config section at the beginning of a device file contains parameters to be used when sending a code. The first entry is the devicename which is used when sending a command. Other parameters are described in the readme on the code site.

Most remotes belong to one of 3 protocol categories (nec, rc5 and rc6). nec is probably the most common and has a simple header structure and bit timing. There is a slight variant of this which differs only in the header pulse timing. rc5 and rc6 are protocols defined by Philips but also used by some other manufacturers. They are a little more complicated and rc6 in particular has a special timing requirement for one of the bits.

To capture the codes for a new remote I use a IR receiver (TSOP) commonly used with plug in remote receivers. This does the basic decoding and gives a logic level output. They normally come with a 3.5mm jack with +5V, GND, DATA connections. I sacrificed one, shortened the lead and put it through an inverting 3.3V buffer to feed a GPIO pin on a Raspberry Pi.

I then use a python tool rxir.py (in git tools folder) to capture codes. To make it easier to use to capture a large number of buttons then the tool uses a text definition file to define the buttons on the remote and is just the names of the buttons in a group on the remote. For example, one might have a new Sony remote and one sets up 3 text files called sonytv-cursor, sonytv-numbers, sonytv-playcontrols each with the relevant button names in. The tool will prompt for the device (sonytv), the section (cursor) and which protocol to use (nec, nec1, rc5, rc6). It will then prompt sequentially for each button press and write results to a sonytv-ircodes file. Sections can be repeated if required to check captures are good. Bits from the .ircodes file can be edited into the BitDevices tables.

Step 4: Web Control and Macros

The basic web control is either a single get or a json post which may contain a sequence.

The get to /ir has 6 parameters

  • auth - containing the authorisation code
  • device - the name of the remote device
  • parameter - the name of the button
  • bits - an optional bit count
  • repeat - an optional repeat count
  • wait - a delay in mseconds before the next command can be executed.

The device can also be 'null' to get just a delay, 'macro' to use the macro referred to by the parameter, or 'detect' to use the Alexa detect feature (see later).

The post to /irjson consists of a json structure like

<p>{</p><p>   "auth":"1234",</p><p>   "commands": [</p><p>        { "device":"yamahaAV","parameter":"hdmi4","wait":"5000","bits":"0","repeat":"1"},</p><p>        { "device":"yamahaAV","parameter":"mute", "wait":"100", "bits":"0","repeat":"1"}</p><p>    ]</p><p>}</p>

The sequence can be any length and devices may be macro references.

The same structure may be used to define macros. Just include macro:"macroname", at the top level e.g. after auth. THe actual contents are stored in a file called macroname.txt

Macros can be deleted by defining them with no "commands".

Other web commands

  • /recent (lists recent activity)
  • /check (shows basic status)

  • / (loads a web form to send commands manually)

  • /edit (loads a web form to view file list and delete/ upload files)

  • /edit?file=filename (view contents of a specific file)

  • /reload (reloads buttonnames and device files. Use after changing any of these)

Step 5: Alexa Voice Control

Previously IFTTT was used to route Alexa through to the irBlaster. Amazon stopped the IFTTT integration on October 31st 2023. A direct custom skill using python is now used instead..

First port forward the port used to your blaster in your router so it is accessible from the internet. It can be good to use a dns service like freedns to give your routers external ip a name and make it easier to handle if this ip changes.

Create a login for developer.amazon.com if you don't have one. Use same amazon login as your main Amazon login / alexa devices.

Create a new custom skill in the Alexa skills IDE and upload the skill definition from the Alexa folder included with the irBlaster repository.

Build the skill model in the IDE. You can change the main Alexa trigger words and also the transmitIntent action words if required. The default needs a command like "Alexa ask remote control to push power" where power is the action required.

On the code tab edit the lambda_function.py file.

Edit the commands dictionary to add or remove button names and the associated json command to send to the ir blaster.

Edit the url to have your server address, port number and auth code number. Leave the %c; this gets replaced by the specific command used.

Save and Deploy.

Step 6: Alexa Activate Detector

Although the Echo / Dot voice recognition is good it can sometimes get confused if the sound is playing from say a TV unless you get close and speak loudly.

To improve this I added an activate detector to my Dot. As soon as the keyword (Alexa is said) the ring of LEDs light up. The detector feeds this into the blaster where it will use the alexaon macro to mute the TV, similarly at the end of processing a command the lights go off and the alexaoff macro restores the sound.

The 'detect' command can also be used to turn this on and off. So for example I use the initial turnon macro to enable the detection and the turnoff macro to disable it. This can also be used within the action macros to support a real mute and unmute coomand which would otherwise be problematic.

The physical detector is an light dependent resistor which the circuit supports. I mount mine on the Dot with a 3D printed bracket