Quantcast
Channel: Fedora People
Viewing all articles
Browse latest Browse all 29900

John McDonough: Hacking on an IR Remote

$
0
0

This post, rather long and geeky, is more of an attempt to record a little project for myself, but I am copying it to the Planet, even though it has little Fedora content, because my fellow Fedorans deserve an occasional peek at just how weird I am!

For Christmas, Santa brought me a PIC24FJ256DA210 Development Board.  This is quite a cool board, with an especially cool PIC.  The board includes the obligatory buttons and LEDs, along with a PICtail socket, Host, Device and OTG USB ports, a serial port, parallel and SPI Flash, SRAM, mTouch pads, and a display connector.  Plugged into the display connector is a 3.2" TFT display with a resistive touch panel.

The PIC24FJ256DA210 itself is quite interesting, including not only USB and PMP, and gobs and gobs of Flash and RAM (by PIC standards), but also a graphics controller.  I had done some graphics a while back on a 24F on the Explorer 16 Development Board.  I was interested in seeing how things changed with the controller on the PIC.

The demo app was pretty neat, one of the (many) things it did was to read JPGs off a thumb drive and display them.  On a PIC this is kind of a big deal since few PICs even have a USB stack, let alone the capability to interpret the FAT filesystem and decode JPGs in finite time.

In looking for a project to get my head around this thing, it turned out that a friend (N8ERO) was working on decoding the output from a TV remote. He was trying to draw the output graphically on a little black and white LCD.  It occurred to me that this was a sort of interesting project and would exercise the PIC.

I began by coming up with a scrolling graph on the Explorer 16 since I was already familiar with the older version of the Microchip Graphics Library, and I thought a speed comparison would be interesting.  Since I didn't need the touch screen for this application, but did need speed, I stuck to the graphics primitives portion of the library and avoided the Graphics Object Layer (GOL).  Although the scrolling wasn't terribly fast, handled by redrawing rather than memory copying, it was still pretty tolerable on the PIC24FJ128GA010, so now off to the the PIC24FJ256DA210 to see what the graphics controller could do with a pretty simple case.

(For the pathologically curious, the code for all these little exercises is on gitorious at https://gitorious.org/pic16/graphtest/trees - there's actually nothing in the master branch; each of these experiments is in its own branch.  The GA010 display is in graphAD branch.)

Microchip has some pretty slick hardware, but their software has never been anything to write home about.  The older Graphics Library had a mess of directories and files that made little sense.  I was hopeful that the new library would be an improvement.

Well, it was worse.  "Back in the day", you could download the Graphics Library.  Now, you need to download the "Microchip Application Library", which includes not just the Graphics Library, but all sorts of other things.  It isn't that the download is so burdensome, or the disk space is unmanageable, but the addition of all the other features, even if they are pretty neat, gives Microchip the opportunity to make it even more of a mess than it was before.

And it gets worse.  over the past few years Microchip has added a number of experimenter boards to their stable, including quite a collection of displays and a few graphics controllers.  When you dig down into the source, every line of code is preceded by about a half page of #ifdefs to select the appropriate PIC, board, controller, display panel and touch controller combination.  In some cases there are choices between serial and USB interfaces and SPI or parallel external flash. It is totally unreadable.

There are no actual "libraries" in the Graphics Library, something I thought a little odd.  Their sample projects include lots of source files into the project.  Well, of course, you need to set all those various #defines before compiling the code.  In many cases it isn't at all clear how you get some symbol or another defined without editing the Microchip code, but with a lot of digging you can get around it with our old friend -D.  (Would have been nice if the documentation provided a clue, tho.)

Speaking of documentation, there is quite a bit.  Most of it .chm files.  Now, .chm files in general tend to be trash.  The templates that Visual Studio provides lead the developer down the path of useless help files.  But to Microchip's credit, the MPLAB help files are among the best I've seen.

Unfortunately, the files provided with the application library are a newer version than can be handled by anything I could find in Fedora, newer even than could be read on the XP image I have on a VM.  Fortunately, the critical (to me) stuff was also available as .pdf.  There's a lot of stuff there I would like to explore that is only in .chm files, tho.

Sadly, the documentation is mostly disjointed.  They do have a pretty nice function reference for the Graphics Library, but it doesn't give you any help as to what the dependencies are, what symbols need to be defined for what purposes, etc.  There are other documents that help you figure out how to set the two dozen jumpers on the board, but those documents are scattered.  The best bet seems to be reading the schematics.  Those are annoying because they are spread out over umpteen pages.  I would rather deal with a humongous fold-out like Icom does.  A bit unweildy but at least you can trace lines with some degree of confidence.

After a bit of a struggle I managed to get my GA010 code working on the DA210, and the speed improvement was startling.  Even without using features of the controller the display was almost 20 times faster, although it felt faster than that. (graphAD-DA branch).

Earl provided me with an IR sensor he had ripped out of an old VCR or something.  I tacked it onto a PICtail prototyping board I had been using for various experiments, and when supplied with 5 volts, it seemed to be able to see my remote.  Unfortunately, it was totally blind when powered with 3.3 volts.  This is a problem.  The PIC24's are 3.3 volt parts.  Although the DA210 isn't a horribly expensive part, it is a TQFP100.  I've been able to deal with parts like that before, and although possible, it isn't any fun at all.  I really wanted to avoid damaging the PIC. But I'm also a big fan of simple, so rather than some elaborate voltage conversion scheme, I simply put a 10K between the sensor and the PIC on the theory that the sensor wouldn't be able to drive damaging current into the PIC through the 10K.

So, now we have the IR sensor connected to the PIC, but the PIC didn't seem to be able to detct anything.  Most of the PIC lines are used for the graphics controller.  Even tho the DA210 has 100 pins, the board has enough different functions that every pin has multiple uses.  The pins connected to the buttons, which are shared by mTouch pads and LEDs, seemed to be the best bet, and I could convince myself that I had the right pin by putting my meter on the PICtail and pushing the button, but still the PIC couldn't see anything.

After spending way too much time, I realized that the pull ups for the pushbuttons couldn't be overpowered through the 10K by the sensor.  But another blatantly obvious thing I should have seen; the pushbutton was enabled by a jumper!  Simply removing the jumper allowed the PIC to see the sensor.

Up to this point the slugging had been pretty slow.  Every step became a battle.  But from here on, once I had my head around the graphics so-called library and the board, things went surprisingly well.  From here on the vast majority of time was spent, well, tinkering.  I can really get wrapped up in making this or that look just right.  Foolish, really, since I have absolutely no eye for making things look right!

As I looked at the data from the sensor it became obvious that a scrolling display wasn't going to be much help.  Ultimately, the point is to be able to decode the pulses from the remote.  There were a LOT of pulses going by very fast.  If the data were scrolling by there would be no opportunity to examine it to look for patterns.

So, the scrolling display went out the window, in preference to a static graph. (readIR).  The approach I used, since I didn't know the speed, was to sample the data and put it in an array, then plot the data after the fact.  The PIC24FJ256DA210 has a lot of RAM, so a fairly large array wasn't out of the question.  I could then adjust the sampling time without messing with the graphing code until I could see the relative length of the pulses.

But, it turns out there are a LOT of pulses.  Given the 320x240 resolution of the little display I couldn't display even a significant fraction on them, and even if I could, the display wouldn't make much sense.

So, the next optimization was to make the array very large, and display the data a page at a time.  This was effective, and made for a nice display, but still it was difficult to make sense out of what I was seeing.

At this point I started digging around on the web to see if I could come up with the codes for my remote.  Unfortunately, not only did I not find my particular remote, but different sites seemed to have entirely different opinions of how to interpret the data stream.

It seemed to me that a less pretty approach might be more enlightening.  So the next approach was to display a string of characters, green for a low and white for high.  This evolved to displaying underbars for low and a digit, increasing as the pulse persisted, for high.  This made it quickly obvious that, other than the start pulse, there were only two pulse lengths.  Short pulses were either 1 or 2 samples, long 7 or 8 (after adjusting the sampling time to optimize the display).  (listIR commit 58bfdd2)

Once it became evident I only had two states, it seemed obvious to convert the pulse train into a number, using 0 for a short pulse and 1 for a long pulse.  Now I could easily see whether I had the timing right and understood the signal; if the same button resulted in the same number, and a different button gave a different number, I was close to having it decoded.

So initially I was pretty timid; get the number, look for one of a few hits in a case statement.  Of course, the case statement became immediately annoying as I added codes, so it went out the window in favor of a table lookup, which was not only shorter, but much easier for adding codes. I also quickly dispensed with the string display, and pretty soon my fancy graphics display was pretty boring.  All I really needed was the hex code (for adding new buttons) and the result.

So at this point, I'm kind of at the end of this experiment. I did notice that, although there are all sorts of claims of standards, the pulse lengths vary widely between different remotes.  But honestly, I don't have a burning application for this capability anyway, so I doubt I'll be motivated to expand to other remotes.



Viewing all articles
Browse latest Browse all 29900

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>