IR interfacing with a LED messgage sign, part 3

Code finished, uploaded, time to take it out for a test. I wired up everything, confirmed that the IR LEDs were in fact lighting with my digital camera (FYI, IR LEDs will glow with a purple tint to them when viewed through most cameras). The first test was unsuccessful. The sign taunted me with it's “STOP MODE” message. The sign will beep on IR received but I heard nothing. So I spent some time adjusting the pulse times. Still nothing. I spent a few more hours adjusting the code without success.

Then, as a last ditch effort, I wondered what would happen if I flipped the pulses around. That is to say, instead of pulsing the IR LED at the top of the graph (1), pulse it only at the bottom of the graph (0). I made the change, uploaded the code and was rewarded with “BEEP BEEP BEEP” coming from the sign. I then tried to remember all of the other changes I made and reverted back to them.

Like any good programmer, the first thing to write is “HELLO WORLD.” It's not without it's problems, however. The key strokes aren't always received 100% which is frustrating. Double key presses (for instance, the two LL's in HELLO) need to have a long pause inserted into them or it believes the key was held down by accident. The sign is fairly old so it may not have the best equipment inside. Or I may have gotten something wrong. Anything's possible!

IR interfacing with a LED messgage sign, part 2

To make the Arduino transmit IR signals, you need an IR LED. I found a couple from an old Sun optical mouse and an old TV remote control. I used two emitters because that's what the original Pro-Lite remote has inside and it also gains distance (I hoped). I should probably be connecting these LEDs through a resistor and at various stages I did. But I figured the pulses were so short that it _may_ be ok. Besides, there's more where that came from.

I started the IR emitter sketch from this Arduino forum post. Actually, the part that was most interesting, was how to modulate the LED at a certain frequency.

// this will write an oscillation at 38KHz for a certain time in useconds
void oscillationWrite(int pin, int time) {
for(int i = 0; i <= time/26; i++) {
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);

This was to be the key to making it all work. I have no way of knowing if the actual modulation of the Pro-Lite IR remote is 38KHz but it seemed to work.

The next step was to pack the pulse widths into the five known types to put it into code. Perl to the rescue again.

A: S001011110110SRS001011110110SRS00100000
B: S001010001011SRS001010001011SRS00101000
C: S001010100011SRS001010100011SRS00100000
M: S001001000010SRS001001000010SRS00100100
X: S001011101011SRS001011101011SRS00101110
Y: S001010001110SRS001010001110SRS00101000
Z: S001011111010SRS001011111010SRS00101111

You'll notice I said five types yet there are only four represented above. That's because the five pulse (which I've called null) is between every pulse (the dip down to 0 on the graph). You'll also notice that the bitstreams always begin with “S0010” which I've hard coded since every pulse begins with it. You'll also notice the bitstream repeats a few times. So, when you reduce and remove repeats, you're left with this.

A: 11110110
B: 10001011
C: 10100011

Which reduces further into decimal, saving valuable memory space on the Arduino.

int A = 246;
int B = 139;
int C = 163;
int D = 170;
int E = 166;
int F = 202;
int G = 135;
int H = 10;
int I = 78;

Next up, finish up the code and give it a test drive.

IR interfacing with a LED messgage sign, part 1

We've had this ancient LED message signs made by Pro-Lite at work ever since I started. They were controlled by an equally ancient IBM PC that has since vanished along with the software and much hope of being able to use them again. There is a seemingly RS-232-ish port on the back with pins 2 and 7 wired which intuitively tells you, yes, serial! Pin 2 is TX which would be convenient because you wouldn't need a null modem cable to talk with it. But alas, I've tried many many ways and have come up empty.

The signs do also have remote controls. Clunky with a smooth surface membrane which proves to be frustrating at best. Besides, I'd like to the sign to display something useful, current and timely. Say, scrape some RSS feeds and display them.

So I figured that IR was going to be my best way in (at least at the moment). Plus, it's just fun.

Plus it gives me a project to use with the Arduino. The first step was to capture and decode the IR signals coming from the remote and translate that into code. I connected a Radio Shack 38Khz IR receiver to the Arduino and used the example sketch on the Arduino playground as a “scope” of sorts to record the pulses coming from the remote.

Analyze IR Remote
Bit stream detected!
0 0
284 0
284 1
6888 1
6888 0
7140 0
7140 1
8576 1
8576 0
8872 0
8872 1
10292 1
10292 0
10596 0
10596 1
15440 1
15440 0
15724 0
15724 1
17152 1
17152 0
17424 0
17424 1
22300 1
22300 0
22576 0
22576 1

It all comes down to timing. The left column is the time in microseconds and the right column is the state. If you use Excel and graph this, it looks like this.

This makes things a bit more clear as to what is going on but doesn't yet translate this into code at all. So, I next wrote a Perl script to parse through this output and produce something that was more useful. I compute the delta between each pulse to determine the pulse width in microseconds.

Pulse time: 6604 (1)
Pulse time: 296 (0)
Pulse time: 1440 (1)
Pulse time: 232 (0)
Pulse time: 1484 (1)
Pulse time: 244 (0)
Pulse time: 4880 (1)
Pulse time: 300 (0)
Pulse time: 1440 (1)
Pulse time: 280 (0)
Pulse time: 4840 (1)
Pulse time: 284 (0)
Pulse time: 3168 (1)
Pulse time: 280 (0)
Pulse time: 4844 (1)
Pulse time: 292 (0)
Pulse time: 3140 (1)
Pulse time: 272 (0)
Pulse time: 1468 (1)

Now you can see a pattern emerge. Most of the pulse widths cluster around five types. I've called them null, 0, 1, start, and repeat, based on their location in the bitstream and how the repeat in the bit stream. Also, since the Arduino IR receiver sketch has a resolution of 4 microseconds, there are going to be some discrepancies. So, I additionally calculate the average pulse widths within a certain amount of confidence.

Avg null pulse time: 282.732673267327 (101 samples)
Avg start pulse time: 6582.66666666667 (15 samples)
Avg zero pulse time: 1435.82978723404 (47 samples)
Avg one pulse time: 4171.59183673469 (49 samples)
Avg repeat pulse time: 54277.6 (5 samples)

So now I have most of the information needed to built an IR emitter. But first I needed to learn about IR modulation.

Converting standard joysticks to wireless infrared for Amiga CDTV and Chameleon 64

The Chameleon 64 is a great cartridge. With each release of the firmware, new features are being unlocked. Recently, the Minimig core was ported to the Chameleon 64 which means you can now have a fully emulated Amiga that fits in the palm of your hand.

To play games using a joystick, you need a CDTV infrared (IR) remote. They are still available for purchase here and here but it would take a few weeks for it to arrive.

I wanted to see if it’s possible to convert a standard joystick to wireless IR communications. I know it can be done– I’ve had some experience using Arduino’s to communicate over IR with a vintage LED sign I have. I reverse engineered the original protocol by using the original remote to the sign. That project taught me a lot.

In this case, I don’t have the remote. So I asked on the forum and got a response from the programmer of the Chameleon IR code with all the info I needed (Thanks Peter!).

This version uses an original Nintendo NES game pad for the joystick but this could be easily changed to support a standard 9-pin Commodore/Amiga/Atari style joystick. The gamepad is connected to the Arduino and decoded into button presses. It then transmits it via infrared signals to the Chameleon. The code uses the Arduino-IRremote library with additions (included) for the CDTV remote type added.

Download CDTV IR Remote