Archives for ESP8266 EspressIf SDK IR Remote

IR Remote Using ESP8266

Even though I live alone, there are 4 TVs spread around my house. And since only 1 set is needed at a time, only one DVR box is needed. So I used a 1-4 HDMI splitter/driver to distribute the signal from the one box to the 4 TVs. Using the attic pathway, direct connections were made to each of the sets. It was pleasing to see that the active HDMI splitter could drive the remote TVs without any pixelation or frame freezes. The furthest HDMI cable required 100 feet. But here was the problem…

The remote would only work when pointed directly at the DVR. Sure, my Att-Uverse service includes a free smartphone App to use as a remote control for the other TVs. But that experience is not the same as using the physical remote that you get with the DVR.

I did have one IR transmitter/receiver pair that I purchased off-the-shelf. Works great! But at nearly $50, it just seemed a bit cost prohibitive to add additional pairs for the other 2 sets. So that got me thinking…

Hmmm. A micro-controller would work. But the relatively high cost of an Arduino, Raspberry Pi or Particle WIFI enabled system was unappealing. So this looked like another opportunity to deploy the low cost ESP8266 as a solution. Here is what I came up with…

IR Remote Solution using ESP8266

Initially, I wanted a system that used an ESP8266 positioned locally at the TV set, one setup for each television. The system would use an IR sensor to read the remote code to determine which button was pressed. Then, the ESP8266 code would take advantage of the AT&T U-verse® Enabled SDK. This interface would, based on the button pressed, send commands to the DVR, over an internet connection.


But there was a problem…

You see, the SDK only supports mobile apps using iOS or Android platforms. While I believe there is a way to port the java-based SDK to the ESP8266 embedded platform, it is not an endeavor I wish to pursue at this time. That’s the problem-it will take too much time. I was hoping that ATT would provide the solution.

So I sent a request to ATT to provide an SDK suitable for micro-controller use. We shall see what they have to say about that. You never know unless you ask…

Plan B: Adding another ESP8266 at the DVR

In order to move forward with this project, an alternate approach was needed. One that could be totally controlled within the framework of a micro-controller system. Without the need for a 3rd-party API.

I really just came up with a tweak of the original concept. Instead of using the ATT SDK, the IR commands would be sent to the second ESP8266 setup, using an web-server client command. This added unit, functioning as a web server, would be responsible for receiving the remote control commands and then transmitting the corresponding IR code to the DVR, using an IR Diode similar to the type found in remote controllers.


ESP8266 IR Remote Hardware Configuration

Here is the schematic of the circuit I used to check out the ESP8266 IR Send/Receive software.


The left side of the ESP8266 is the standard design I use for all projects. It has proven to be very stable, with hundreds of flash cycles completed successfully and no unintended resets during operation.

Three LEDs are used in the circuit:

  1. Status LED – A standard LED used to provide visual feedback.
  2. IR Tx LED – Sends IR data to the DVR
  3. IR Rx LED – Receives IR data from the DVR remote control.

In addition, a simple push-button switch is used to send the last code saved to the DVR.

This circuit contains all the hardware needed for both ESP8266#1 and ESP8266#2. As you can see, there are only a few components needed. It is probably wise to stick with this single hardware configuration for both ESP8266 setups.

However, once tested and all the remote codes have been “learned” and saved, the two ESP8266 systems could be optimized as follows.


IR Transmit LED, Send switch and Status LED could be removed. The only thing needed is the receive IR. Remember, a separate ESP8266#1 circuit can be used for each TV you wish to control with a single DVR box.


IR Receive LED, Send switch and Status LED could be removed. The only thing needed is the Tx IR. Only one of these circuits will be needed, regardless of how many remote TVs are used.

IR Remote Control Signals

There are many great articles that provide details on how IR signals are generated, transmitted, received and decoded. Instead of repeating, here are a few references for further reading, if you want to know more. This post will concentrate on an ESP8266 IR remote solution.

ESP8266 IR Test Software

My initial idea was to port an existing IRremote library from the proven Arduino platform to the ESP8266. The obvious choice was the “RobotRemote” library provided as a standard Arduino IDE library. But the differences in the ESP8266 hardware from the Arduino ATmega chip made the porting difficult.

Even after resolving all the compile errors, I could not complete a successful link to all the libraries. Eventually I ended up abandoning the Arduino IDE platform for this project in favor of the EspressIF SDK.

But this decision came with additional challenges as the SDK does not easily support c++ class libraries. Like the “RobotRemote” library. This issue was overcome by decomposing the class structure into separate ANSI C functions.

But there was more to deal with…

Remote IR Signal Generation

The Arduino library relies on the PWM capability to generate the standard 38 kHz IR modulation frequency. Unfortunately, the ESP8266 PWM API only supports up to 100 Hz, a far cry from the needed bandwidth.

Fortunately, there is a way around this ESP8266 constraint. The trick is to create the 38 kHz modulation by simply toggling a digital output; logic 1 and logic 0. The duration of these pulses determine the command sent to the remote receiver. But how do we generate 38 kHz pulses?


Using the ESP8266 micro-second delay statement “os_delay_us(us)”, we can create a 38 kHz pulse train. Each pulse period is 1/38000 seconds (26.3 us) long. Rounding that off to 26 us, the modulation frequency is easily achieved with:

  loops = time/26;                    // "time" units are microseconds
  if(loops==0) loops=1;
  for (i=0;i<loops;i++) { 
          gpio_write(IR_SEND_PIN, 0); //Set GPIO12 LO -> IR On
	  os_delay_us(13);  //1M/38K/2
	  gpio_write(IR_SEND_PIN, 1); //Set GPIO12 HI -> IR Off
	  os_delay_us(13);  //1M/38K/2

Here, each iteration of the loops generates one 38kHz pulse (26 us). The number of pulses (loops) is determined by the desired number of microseconds.

Remote IR Signal Detection

In addition to generating IR codes, we must also be able to detect and decode IR signals received from a remote. That requires a sampling of the state of the IR detector diode (is it HI or LO). A 50 us timer callback function is implemented for this purpose, which is the same 20 kHz sampling frequency used by the original Arduino RobotRemote library. Since the 38 kHz modulation is removed by the IR detector, the remaining signal content (set of ones and zeroes) change at a lower rate. As result, the 50 us sample rate is adequate to accurately decode the incoming IR code.


Initial Implementation

My initial implementation provides a framework upon which to build an ESP8266 based IR remote application. It is not meant to be a complete application, merely a platform to prove the concept. From this structure, it will be possible to easily adapt the code for your specific needs. I plan to follow-up this post with my final design.

From the current structure, it will be a straightforward task to record and store all the IR remote codes for subsequent replay, on demand, by the ESP8266#2 web server.

Here is what this project currently does:

  1. With the push-button in the schematic open, the IR detector is monitored every 50 us for the presence of an IR code. Every time a logic state is detected  on this  sensor, the LED connected to GPIO16 is blinked. In addition, the received code is sent to the serial port. Once a valid code is detected, it is stored for playback, on-demand,  by the IR emitter diode.
  2. When the push-button in the schematic is pressed, the IR detection process is stopped and the last IR code store is transmitted. The code is repeated every 0.5 seconds as long as the button is pressed. IR detector sampling will resume once the button is no longer closed.

The code for this project is on Github here.

What to do next

Note that the IR codes sent to the serial output can be saved using any terminal program that saves the output to a file. By sequentially walking through each key on a remote, a map of button pressed to IR code can be created. This map will have 2 purposes in the final design:

  1. ESP8266#1:  The received code can be “looked up” in the map, to determine which remote key was pressed.
  2. ESP8266#2: Once the Web server receives a command to send a key code, the map will identify the code to send for that key.

The one shortcoming I have observed with this initial design is the limited range for both sending and receiving IR signals. Currently, the signal fades and starts to drop out beyond only 1 meter. This has one of two possible causes, which I intend to investigate.

Either the signal intensity is inadequate or the signal MARK/SPACE timing is off. We shall see.

I blew up a couple of IR Emitter Diodes using a transistor to increase the LED intensity. As results, a more thorough evaluation is needed before I proceed with additional modifications. I will provide additional information when a better solution is reached.


The project presented here provides a solid foundation for any ESP8266 application using IR communication. This design uses the EspressIf SDK but could most likely be adapted to work with the Arduino IDE. So that others may benefit, please post your work in the comments below if anyone has ported this to the ESP8266 Arduino IDE platform.

Hope you find this information useful…

Share This: