Adding an Accelerometer to the Windows 8 Simulator

I have been busy developing for Windows 8 for a while now. Until Microsoft releases a WinRT “Surface” device (October?) I thought it would be nice to be able to test my apps transitions between ApplicationViewState.

I have an accelerometer in my .Net Gadgeteer kit…and a wifi module…hmm.

What I built is a gadget that exposes JSON formatted accelerometer data via a web service. Any Windows 8 (WinRT) applications can consume this service. There are a few details to getting this to work. I will briefly go over the main things to be aware of here. I will post the entire project later.

Here is what it looks like tacked on my laptop:

Accel

Across the top (from left to right): OLED Display, SEEED Studio Accelerometer, GHI Spider board, Wifi module
Across the Bottom: power module, battery pack.
On the table is a ClearWire wifi router.

Here are some of the main things to be aware of:

Time Series Graph
I added a OLED Display because it was very handy to have a time series graph to display the x,y,z axis’ for troubleshooting.

Time Series Graph

Here is the code for the graph:

 public class GraphHelper
    {
        uint currentX;
        uint MaxX;
        uint _y;
        uint _GraphHeight = 10;
        Gadgeteer.Modules.Seeed.OledDisplay _display;

        public GraphHelper(uint y, Gadgeteer.Modules.Seeed.OledDisplay display )
        {
            _y = y;
            _display = display;
            currentX = 0;
            MaxX = _display.Width;
            Clear();
        }
        private void Clear()
        {
            _display.SimpleGraphics.DisplayRectangle(Gadgeteer.Color.Gray, 1, Gadgeteer.Color.White, 0, _y, _display.Width, _GraphHeight);
        }
        float _maxG=1;
        public void AddDataPoint(float range)
        {
            //check if new values are larger than we expected.
            //I assume the range is between 1 and -1.
            //If the range is larger then we need to adjust.
            if (System.Math.Abs((int)System.Math.Ceiling(range)) > _maxG)
                _maxG = range;
            //shift all values to positive range.
            //TODO: fix variable names...
            float rangeNorm = range + _maxG;
            float integral = _GraphHeight / _maxG;
            rangeNorm = rangeNorm * integral;
            rangeNorm -= _GraphHeight;
            rangeNorm += _y +  (float)(_GraphHeight * 0.5);
            if(currentX==0)
                Clear();
            if ( rangeNorm < _y)
                rangeNorm = _y;
            if(rangeNorm > (_y + _GraphHeight))
                rangeNorm = _y + _GraphHeight;
            if (currentX <= MaxX)
            {
                _display.SimpleGraphics.SetPixel(Gadgeteer.Color.Green, currentX++, (uint)System.Math.Ceiling((uint)System.Math.Ceiling(rangeNorm)));
            }
            else
            {
                currentX = 0;
            }
        }

Here is how you would call its c’tor to put a graph halfway down the screen (display_height/2=64)and plot a point :

this.graphX = new GraphHelper(64, _display );
graphX.AddDataPoint( (float) averagedAcceleration.X );

Windows 8 Capabilities Panel in Visual Studio 12
Pay attention to the Capabilites tab in the Package.appxmanifest. I had enabled “Internet(Client)” and thought I was good to go. No so. There is also a “Home or Work Networking” capability. For connections to resources on a LAN you need to enable this.

Reactive Extensions for .Net are Very Cool
In my Win8 application I needed to call the sensor service on a timer. There are many ways I could have done this. I wanted a quick and easy solution that would work with the async nature of WinRT development and I knew for certain that this code would be not in a production system…ever. This isn’t to say RX .Net isn’t production worthy, just that this usage of a timer is probably not optimal for production but is great for demo code.

             var fivePerSecond = Observable.Interval(TimeSpan.FromMilliseconds(200))
                .ObserveOnDispatcher()
                .Subscribe(num =>
            {
                Get_Sensor_Data();
            });

Every 200 ms this will call Get_Sensor_Data()…which then calls MoveCube() here:

    HttpResponseMessage response = await rootPage.httpClient.GetAsync("http://192.168.1.10");
    await Helpers.MoveCube(response, renderer);
    Page.NotifyUser.Text = "Completed";

And finally, we get to the MoveCube()…

internal static class Helpers
    {
        internal static async Task MoveCube(HttpResponseMessage response, DxRenderer.Cube cube)
        {
            string responseBodyAsText;
            responseBodyAsText = await response.Content.ReadAsStringAsync();

            JsonValue value = JsonValue.Parse(responseBodyAsText);
            var c = value.GetObject();
            string sx = (c["Accel"] as JsonValue).GetObject()["x"].GetString();
            string sy = (c["Accel"] as JsonValue).GetObject()["y"].GetString();

            float.TryParse(sx, out cube.X);
            float.TryParse(sy, out cube.Y);
        }
    }

SharpDX is DirectX for C#
Finally, Jose Fajardo, who has published some very useful demos of SharpDX, provided the starting point for the Win8 cube rotation via accelerometer. I wasn’t able to get the SharpDX demos that come with SharpDX to run. But I was able to get Jose’s samples working. So thanks Jose! SharpDX is the only way I know of to do DirectX in WinRT apps using C#.

GHI Electronics: New GHI NETMF v4.1 and .NET Gadgeteer Package

There are some significant updates including drivers for WiFi and other modules, and bug fixes for Ethernet and Button.

This release requires reflashing the mainboard. The tool at Start->GHI Electronics->GHI NETMF v4.1 SDK->Firmware Update->Fez Spider Updater makes this easier than otherwise.
It requires going into serial mode to reflash the bootloader, which means flipping little switches on the mainboard. Be aware that the updater does not update the MAC address so you have to update that manually if you want to use Ethernet, using the MFDeploy tool (Start->Microsoft .NET Micro Framework v4.1->Tools->MFDeploy.exe) then choose USB then choose Target->Configuration->Network then change the field MAC Address to the text written on the mainboard sticker but with dashes between each pair of characters (e.g. if your mac is 123456789012 then you should use 12-34-56-78-90-12 in the MAC Address box).

You can download the updater here: http://www.tinyclr.com/support or directly here.

I will try to post more on this later.

.Net Gadeteer: Display speed test

There are currently two display options available for .Net Gadgeteer…that I know of. You can always create your own too. But of the two for sale currently which is faster at displaying graphics?

The contenders are:

To find out I created a simple test. The code below starts a stopwatch timer, then draws a bunch of elipses, and then stops the stopwatch and checks the time difference. I am assuming that rendering elipses is the same as rendering other objects but I should test other things like text just to see. We will have to come back to this later.

Here is code for testing the speed of the Seeed Studio OLED display. To test the GHI 3.5″ touch display just swap out the OLED display with the GHI display. I just used the visual designer to do this and the only code change was to rename oledDisplay with “display” (the default name for the GHI display in the designer).


        void ProgramStarted()
        {
            Debug.Print("Program Started");
            DateTime start;
            TimeSpan end;
            oledDisplay.DebugPrintEnabled = false;
            start = DateTime.Now;
            for (uint i = 0; i < 128; ++i)
            {
                oledDisplay.SimpleGraphics.ClearNoRedraw();
                oledDisplay.SimpleGraphics.DisplayEllipse(GT.Color.FromRGB((byte)(i << 0), (byte)(i << 1), (byte)(i << 2)), i + 50, i + 20, (uint)System.Math.Floor(i * .1), (uint)System.Math.Floor(i * .6));
            }
            for (uint i = 128; i > 0; --i)
            {
                oledDisplay.SimpleGraphics.ClearNoRedraw();
                oledDisplay.SimpleGraphics.DisplayEllipse(GT.Color.FromRGB((byte)(i << 0), (byte)(i << 1), (byte)(i << 2)), i + 50, i + 20, (uint)System.Math.Floor(i * .1), (uint)System.Math.Floor(i * .6));
            }
            end = DateTime.Now - start;
            Debug.Print("Test1: " + end);
            oledDisplay.SimpleGraphics.DisplayText("Test1: " + end, Resources.GetFont(Resources.FontResources.NinaB), GT.Color.White, 50, 50); 
}

Here are the results and I was surprised by the results.
The GHI display was twice as fast as the smaller Seeed Studio display.
I’ll post exact numbers if someone requests it. But twice as fast is convincing. For anything requiring fast display updates, like testing new modules, I would recommend the 3.5″. Once you have things figured out move to the OLED if the form factor requires it. For instance, I was playing with the gyro module and the accelerometer module and the 3.5″ display was very handy in getting a sense of the modules behavior.

That said, I really like the Seeed Studio display. It is perfect for small form factors (its tiny at 26.8mmx26.8mm) and the colors are very bright. Both displays have their purposes. Just be aware of the speed advantage the 3.5″ display offers.