iPhone 2.0 Location Services

So it looks like a company called SKYHOOK Wireless is powering the Wi-Fi location services in the the new iPhone 2.0 update. This is good news for first generation iPhone users as it adds really very good positioning to the cell tower service from the 1.0 release.

What was interesting to me was how they gather this data. They pay folks to drive around with one of their boxes (which I assume is a laptop of some sort with a GPS and a Wi-Fi antenna to record all positions of all Wi-Fi APs that are found along with strengths.

You can even earn some extra money by being a driver for them (if they need your area scanned or rescanned I suppose) by filling out their online form.

Let me know in the comments if you sign up and if you get accepted!

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);
delayMicroseconds(13);
digitalWrite(pin, LOW);
delayMicroseconds(13);
}
}

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
Waiting...
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.

A recent visitor to a DSWA electronics recycling station

Jeff recently visited a DSWA electronics recycling drop off station to depart with an old CRT television and shot these pictures. Walking into the drop off box is kinda like taking your life into your own hands, walking around haphazardly placed televisions and other equipment that could easily fall and crush your legs. Fun! A sign warns that the area is under video surveillance so don't take the trash, promise? What really happens to this stuff after the working bits are removed and resold at the mercantile store?

Thanks, Jeff!

Reminder: Charge your NiMH batteries!

A reminder: charge you NiMH batteries if you haven't used them in a while. NiMH batteries will loose their charge in storage rapidly so you need to pull them out periodically and top them off. I have 6 sets of four NiMH batteries around, mainly for use in my speedlite flashes. I have to remember to charge them once a month and before I need to use them.

Pictured is my La Crosse BC-900 NiMH charger (Amazon, $80) which has turned out to be the best battery charger evar. Selectable charge rates, discharge and refresh cycle (bring previously dead NiMH batteries back to life, really!).