ESP8266 Remote Control

I needed a remote. Rather than buy one for $5, I opted to build one for $15.

Similar projects worth following
I recently moved, and my trusty TV died a tragic death - when we opened up the trailer, we found that it hadn't been secured well enough: the stand it was on was resting at a 45 degree angle, with the center of the screen resting on (and having obviously impacted) the corner of a dresser.

I found a cheap "broken" TV that for $30 that just needed a tiny bit of hot air work, and just like that, I was back up and running... except I wasn't: there was no remote. A cursory glance at ebay suggested I could get one for $5. A cursory glance at my office revealed an ESP-01 module waiting for a project - it's pretty obvious which one won out.

NOTE: The background image is adafruit's. It was a nice picture, and I don't have any right now.

I had a number of design goals making this project:

  1. I wanted it to be simple, mostly use parts I had on hand (to avoid the "why do you need to buy more parts?  You have so many parts!" discussion)
  2. I wanted it to be cheap: where I didn't have parts, I wanted to buy as few as possible
  3. I wanted it to be fast and easy to use: if it wasn't as convenient as a remote control (or not as functional), it wouldn't get used

I had an ESP-01 module already on hand, and I wanted to use it - I didn't want to have to buy another ESP module with more GPIO available or anything like that.  I knew I would need IR LEDs, and figured I'd have to buy a mosfet since they can consume up to 100mA.  I had 3.3v linear regulators and disposable USB cables on hand already, along with some 22 gauge solid-core hookup wire.

If I'm going to use my phone for 1 remote, I may as well use it for all of them - so I wanted to make it multi-protocol so I could handle different brands - even among my small collection of A/V equipment, I have different required modulation frequencies, bit timings, etc.

My build log details more of my thought process, but these were some of my considerations in designing - I could have rolled my own circuit board and gone way more in depth on this project (and considered it), but simple design and fast iteration won out.

  • Debugging and Polishing

    Joshua Broekhuijsen09/14/2019 at 01:06 0 comments

    I've got it almost 100% of the way, now - though it wasn't an easy road to get there.  Let's see if I can list the things that went wrong...

    1. My UART was transmitting LSB-first, which... is probably universally true but I didn't anticipate it.  Simple enough: change my char from 0x24 to 0x12 and transmit that instead.  Woo!
    2. I was calculating parity wrong for the apple TV - my original code (which I will not post because it was absolutely awful) was XORing all the bits to the left, but then checking parity on the rightmost bit - again a simple fix; just had to change the bit-shift direction on each operation for the parity function.
    3. The apple remote spec is... interesting.  It includes a provision for "Remote ID", which is 8 bits - so there are 255 possible remote IDs, and any given apple TV is listening for only one of them, I think.  When making my code I chose an arbitrary "0x37", but turns out that 1/255 chance shot-in-the-dark was wrong.  I ended up taking my apple remote and an IR demodulator to an oscilloscope (that I dearly wish I owned, but, alas, do not) and manually decoded the remote ID - turned out to be 0xAE.
    4. Had to sanity check every single remote code "fixer" function - I pass it just the command and brand, say "l08" for "LG, command 0x08" which represents power toggle on my TV.  The function is supposed to "correct" it - take that minimal data and generate a uint32_t full of the right bits to transmit.  Long story short: each of those was wrong because I screwed up my bitwise operations.  All fixed now, thanks to some debugging time with Mr. Oscilloscope.

    Once I actually got my very first bit of success - toggling the TV power - it felt like the end was in sight.  I've spent some time polishing, and came to a few realizations:

    1. I didn't much like the way some of the UI elements were working - for instance, a single button to turn on the TV, change the input, turn on a device (apple TV or blu-ray player) just... wasn't working out; particularly since it was the only way to get to the remote for that device.  I opted to make the buttons up top just bring me to the remote for the given device (unless there isn't one), and then include a button to "switch source here" on that specific device remote.
    2. The load times when making a new request to the ESP for another html page - say "tv.html" followed by "apple.html" - were frustratingly long.  I changed the architecture to hold all the button data for each remote in a JSON object, then dynamically "build" the elements on the remote when requested - this way the remote load time is dependent on my device's javascript speed, rather than my ESP8266's wifi speed.
    3. I was having some intermittent issues with the websocket when I left the page alone - I changed it to verify the websocket connection (and re-establish it if necessary) each time I press or release a button.

    Once I felt confident enough, I soldered it all onto some protoboard.  Please note that I generally like to design circuit boards in KiCAD, tinker with them for 134 years, then get them manufactured so they're nice and orderly - my protoboard soldering is... not pretty.  Fortunately, it IS functional.  The trailing wire you see in the pictures below is my cut-up power cable from an old USB charger.

    Oh, yeah - I only had a surface-mount 3.3V regulator so I improvised and made it a through-hold component by bodging on some 22-gauge solid core wire, then hot glueing and electrical taping the whole thing together.  It's art, I tell you: art.  Hard to tell in the pictures, but all the necessary resistors are under the ESP8266, which is, itself, in an 8-pin female header - so it can be removed for reprogramming/replacement.

    I'll be trying it out and probably 3d-print a new case for it in the next few days!

  • (Almost) The Whole Thing in One Log

    Joshua Broekhuijsen09/06/2019 at 16:49 0 comments

    After acquiring and repairing a "new" TV - sans remote control - I decided to improve my A/V setup with some custom automation, a-la-ESP8266 hosting a webserver to provide a phone-based remote control.

    I spent some time researching IR protocols - how they work, differences between brands, etc - and decided that this should be quite possible.  For those curious, IR for remote controls is usually modulated in the 30-50khz range with a 30% or so duty cycle.  Unfortunately, the software PWM implementation available to me on the ESP-01 module can only reach 1Khz, which is not even close to sufficient.  With rather limited GPIO options - and a desire to avoid external hardware as much as possible - I started exploring.

    My devices - an odd hodgepodge of whatever was cheap - include Sony, LG, and Apple components (OK, maybe not so much 'cheap' on the last one, but you get the point).  These have IR modulations of 38Khz, 38.2Khz, and 40Khz respectively.  Though lacking a sufficiently-powerful PWM, the ESP-01 module DOES have a UART that can operate pretty quickly....

    After running some numbers, I determined that I could configure the UART in 7N1 mode - that is 7 data bits, no parity, and 1 stop bit.  There's also a start bit, so each data frame looks something like this: 0xxxxxxx1 - I fill in the seven "x"s with whatever I want - for my purposes, I chose 0x24, so my full frame looks like: 001001001 - if I transmit this at a baud rate of 114667, I get a pin modulating in a pretty-darn-passable impersonation of a 38.2Khz 30% PWM signal.  If I change the baud to 120K, I've got a pretty good 40Khz signal, too.

    The hardware is pretty straightforward:  The ESP-01 module itself, a cannibalized USB power-only cable from who-knows-what, a 3.3V linear regulator so as to not fry my ESP module, 3 IR LEDs (one for each device I want to control) with a current-limiting resistor, and a MOSFET for switching them on and off (along with a gate resistor, just for safety - though depending on the hardware behind the UART, which I haven't bothered looking up, that may or may not be necessary).

    The software is less straightforward: once embedded, I really don't want to have to take it out in order to change something if I get a different blu-ray player, or want it to control another device.  I've never actually developed on an ESP8266 before, despite owning several and reading a number of projects.  I'll just check to se--- yep, there's a library for OTA updates.  Great.  OK, well, I want the buttons to work just like a remote: press it to start sending the signal, hold it down and the signal should repeat.  That kind of prohibits a simplistic approach of just using links with GET parameters embedded, may some sort of AJAX or websocke-- yep, there's a websockets library.  OK.  What's this about inlining all the HTML to output?  That's kind of a nightmare, isn't it?  What if I could use some sort of filesy- oh, SPIFFS.  Neat.  I don't want to deal with assigning a static IP to the ESP, can I -- Oh, mDNS.  Wait, is there a library for friggin' everything?  Apparently.

    The actual software development was a little bit annoying - I had to research the codes my remote(s) would send so I could simulate them all, and understand the protocols: my appleTV, though using the same modulation scheme as NEC encoding, doesn't follow the whole spec - it does whatever it wants, pretty arbitrarily, with the bits.  The LG tv is pretty good: follows spec AND publishes its remote codes in the manual!  Very nice.  Sony, of course, had to roll their own scheme entirely - but it's not too bad to implement.  There are libraries for remote controls, but given how I want mine to function I think it'll just be easier to write my own.  The general operation looks something like this:

    The initial HTTP request on the ESP redirects...

    Read more »

View all 2 project logs

Enjoy this project?



don.vukovic wrote 09/07/2019 at 00:04 point

This project too great !!

I do hope you will share your code.

  Are you sure? yes | no

Joshua Broekhuijsen wrote 09/07/2019 at 04:43 point

I plan on it, once I've got it working!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates