Saturday, February 12, 2011

The skewed accelerometer

What can you do if your WP7 accelerometer is not correctly calibrated? As I found out, there seems to be no OS mechanism to calibrate the accelerometer. So if you have a production device you will have to return it for repair or replacement. But what do you do if you have a loaner preproduction device like I do? Well, you have to fix the accelerometer the only way you can: through software.

A correctly calibrated accelerometer should return the vector (0, 0, -1) when you place your device with the screen up on a flat surface (like your office floor). If you have a skewed accelerometer like I do, then you should be able to compensate the difference to the reference vector, once you know what your device is reporting when placed on the floor with the screen up.

To do just that, I wrote a very simple Silverlight application for WP7 that polls the accelerometer every second and displays the vector components, both the sampled value and an average value in order to smooth out the natural variations in the sampling.

You can get the sample application with source code here. After running this app on the floor, I noticed that the Y component of the accelerometer vector was slightly skewed to -0.15, while all other components reported the expected values. After adding 0.15 to the Y component, I got back a calibrated accelerometer.

Now I can get back to my XNA gravity ball code and make it work like it should.

Friday, February 11, 2011

MediaElement and downloaded sound

In a nutshell: when you download a sound file to play on a MediaElement, make sure you set the AutoPlay property to True if you call SetSource with the download stream. This stream does not support seeks, so it must play immediately. If you want to store the sound to play it later, store it in a MemoryStream (it supports seeks). I found this out the hard way...

Tuesday, February 8, 2011

The Tabukiniberu bug

This was first presented to me as the "Marshall islands bug": our Silverlight application was opening the Google map in the middle of the Pacific, where it should be showing the mid-Atlantic. Looking closely to the map, I found this extraordinary name: Tabukiniberu, an island in the Pacific near the Equator (the Marshall islands are farther to the north). So what on Earth (literally) was my code doing to spin half the globe and show this (hopefully) beautiful island?

The SL4 app I've been working for in the last 6 months uses both Bing and Google maps AJAX controls due to the different quality of the map content. Google maps are way better on some regions where our business is growing, like Africa and Eastern Europe. On the code side, Bing seems to be better.

When there is nothing to display on the map, the application usually centers on point (0, 0) with a zoom level of 2, providing the "classic" (for my European patterns) wold view with Europe on the top right and the Americas to the left. When there is something to display, the code pans and zooms in to the area of interest so that all pushpins are shown. This particular bug occurs in Google maps code when you call fitBounds on an empty LatLngBounds variable (I mean, initialized but without any added bounds). Instead of showing the mid-Atlantic, you are thrown on a 180 degree spin around the globe to a place very close to Tabukiniberu. Well, at least on the map...