Sep. 17, 2017

DIY TV remote controller, part 2: electronics and software test

After some research, I decided to use the Arduino Nano for this project, and got a half dozen units along with some miscellaneous components. They were bizarrely cheap - something like $3 / per on average. So far things are working fine. The clone Nanos I bought came with the CH340 USB to Serial chip so it required a driver installation from the vendor, but otherwise worked fine once I set the IDE to the right COM port.

Think I'm sold on Arduinos in general - the in-circuit code update makes it so easy to prototype and debug. And now I'm thinking of buying a cheap laptop for future projects, so that I'm not tethered to my desktop.

My setup here uses a transistor to power the infrared LED. An Arduino can source up to 40 mA per pin, but the Infrared LED I'm using takes 70 - 100 mA in pulsed mode. It can probably work well enough with that, but I was planning to use several LEDs in the final device, so that meant using a different power source. The circuit was supposed to use an NPN transistor, but I used an N-channel MOSFET I had laying around, the IRFD120.

The dominant infrared library for Arduino is IRremote and there are tons of tutorials and examples about it. It seems to have used parts of the LIRC project as a way to shape its code. That's where I ran into a snag.

IRremote's sendSharp() function doesn't work for all devices.

The Sharp-manufacturer codes from the LIRC listing didn't seem to work at all: volume up / mute / down codes were supposed to be 0x40a2, 0x43a2 and 0x42a2. I verified that the infrared LED was sending something by looking at it through a smartphone camera, but I didn't have an oscilloscope to compare original and constructed signals, and nothing was happening.

Troubleshooting with LIRC

Last year I bought the Vero 2, a Linux-based streaming device running OSMC and Kodi, and though it came with a radio remote controller it also had an infrared receiver and ran LIRC. After ssh'ing into the device, I killed the lircd daemon and ran irrecord -d /dev/lirc0 myconf.conf to inspect what my TV's remote controller was sending.

Using irrecord, I recorded the actual Sharp remote and my breadboard prototype's signals. The two conf files irrecord generated should have been identical, but they weren't. Something was wrong.

begin remote

  name  sharp.conf
  bits           15
  eps            30
  aeps          100

  one           250  1828
  zero          250   790
  ptrail        249
  gap          66772
  toggle_bit_mask 0x0

      begin codes
          volup                    0x40A2 0x435D
          voldown                  0x42A2 0x415D
          mute                     0x43A2 0x405D
          pwr                      0x41A2 0x425D
      end codes

end remote
begin remote

  name  dinotest5-arduino.conf
  bits           15
  flags SPACE_ENC
  eps            30
  aeps          100

  one           211  1844
  zero          211   837
  ptrail        206
  gap          40808
  toggle_bit_mask 0x0

      begin codes
          a                        0x7442 0x77BD
          b                        0x7442 0x77BD
          c                        0x3842 0x3BBD
      end codes

end remote

Irrecord verified that I was looking at the correct sharp codes as per LIRC documentation of a similar device. However, my prototype was off in a bunch of places. The gap value difference made me think that my nano's timing might be off (wrong oscillator, configuration error?), but a separate blinking LED test confirmed my stopwatch matched count of 1 second blinks after ten minutes. So that wasn't it.

I started suspecting the IRremote library's version of sendSharp(). First thing I noticed from looking at the generated LIRC configuration file of my actual remote is that the toggle bit mask was different than expected in the documentation.

IRrecord and raw signals to the rescue

Not having an oscilloscope, I ordered a 38 KHz infrared receiver that I originally thought I wouldn't need. Once I connected it and ran the IRrecord example to spy on the raw IR signals, everything started working. Well, almost. The serial monitor in the Arduino IDE showed activity and that was encouraging. Arduino's serial monitor and overall interface is so incredibly useful for development.

With my setup, I had to make a couple of alterations to the sample program - replace pin numbers, change input mode to INPUT_PULLUP, and tweak the buttonState logic to flip LOW and HIGH. But it worked, and worked great. The program could record some of my other devices and emit their signals, and those worked. All except for the Sharp TV, because I believe the signal has to be inverted as per their protocol, so that'll take an additional step or two.

Next steps: power management and button matrix

Specifically, I want to put the Nano to sleep and connect a pushbutton matrix circuit that can wake it up via interrupt pin. Most examples of the button matrix circuit I've seen weren't designed with an interrupt in mind. There are dedicated integrated circuits that can send an interrupt signal, but I figured the Nano has plenty of I/O pins available in my circuit to allow for 25 - 30 buttons, and I'm thinking I'll need 20 (4 + 5 I/O pins.)

Cheap Thrill

Before I wrote any code to send meaningful signals, I tested the infrared LED with my smartphone camera and recorded this. It's startling how bright infrared LEDs are, since we can't see at that wavelength.

Being a nerd, I found this oddly satisfying to watch, and it gave me some hints as to how to position the IR LEDs in the remote.

Find this interesting, or useful? Consider sharing the post.

Leave a Reply

Your email address will not be published. Required fields are marked *

Posts on this blog solely represent my personal opinions and technical experience.

© 2009-2019 Edin (Dino) Beslagic