Saturday 27 July 2013

Visual Studio's Make Object ID

Ever wished you could watch the value of an out-of-scope variable while debugging in Visual Studio? You can, if you use the Make Object ID option in the watch/local window. Here's an example, with a variable p that goes out of scope when control jumps to a new method, or back to the calling method:
class Person
{
    public Person(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        DoIt();
    }

    private static void DoIt()
    {
        var p = new Person("Baldrick");
        DoIt2();
    }

    private static void DoIt2()
    {
        return;
    }
}
If you step through this code in Visual Studio and add a watch to variable p in method DoIt, the watch window will look like this:


When you step into method DoIt2, or out to Main, and refresh the watch on p, you get this message in the watch window:


If you want to be able to reliably watch the variable, the solution is to Make Object ID. Let's take the code back to DoIt and right-click on the watch on variable p:

Click on Make Object ID, and you'll see variable p is allocated object ID "1#"

If you add a watch to 1#, this allows you to view the value of p even when p goes out of scope:

The 1# reference can be used to update the value of the underlying variable p:

which will be reflected when (if) the object comes back into scope:



What about Garbage Collection?

The Object ID doesn't create a managed reference to the underlying object, which means that it will not interfere with its garbage collection:




Sunday 21 July 2013

How to post an HTTP form with .Net Micro Framework

This snippet of code shows how to use the .Net Micro Framework to create a representation of an HTTP form, and post it to a URL:
        public void PostNameValues(string value1, string value2)
        {
            // Create the form values
            var formValues = "name1=" + value1 + "&name2=" + value2;

            // Create POST content
            var content = Gadgeteer.Networking.POSTContent.CreateTextBasedContent(formValues);

            // Create the request
            var request = Gadgeteer.Networking.HttpHelper.CreateHttpPostRequest(
                @"http://www.mjonesweb.co.uk/api/values" // the URL to post to
                , content // the form values
                , "application/x-www-form-urlencoded" // the mime type for an HTTP form
            );

            // Post the form
            request.SendRequest();
        }

Sunday 7 July 2013

Accessing the web with Gadgeteer ethernet module

I've discovered just how easy it is to use the Gadgeteer Ethernet J11D module from GHI Electronics to retrieve resources from the web. As ever, here's the project designer:

As for the code, it can be summed up in 3 steps:

  1. Get/supply an IP address
  2. Send a HTTP request to the URI
  3. Handle the HTTP response

using Gadgeteer.Networking;
using NetworkModule = Gadgeteer.Modules.Module.NetworkModule;
using Gadgeteer;

namespace Demo
{
    public partial class Program
    {
        void ProgramStarted()
        {
            //The other option is UseStaticIP
            ethernet.UseDHCP();

            //Set a handler for when the network is available
            ethernet.NetworkUp += ethernet_NetworkUp;
        }

        void ethernet_NetworkUp(NetworkModule sender, NetworkModule.NetworkState state)
        {
            //Set the URI for the resource
            var url = "http://i1072.photobucket.com/albums/w367/"
                + "M_J_O_N_E_S/MeGadgeteerSize_zps23202046.jpg?t=1373144748";

            //Create a web request
            var request = WebClient.GetFromWeb(url);

            //This is async, so set the 
            //handler for when the response received
            request.ResponseReceived += request_ResponseReceived;

            //Send the request
            request.SendRequest();
        }

        void request_ResponseReceived(HttpRequest sender, HttpResponse response)
        {
            if (response.StatusCode == "200")
            {
                //This only works if the bitmap is the 
                //same size as the screen it's flushing to
                response.Picture.MakeBitmap().Flush();
            }
            else
            {
                //Show a helpful error message
                lcd.SimpleGraphics.DisplayText("Request failed with status code " + response.StatusCode
                    , Resources.GetFont(Resources.FontResources.NinaB), Color.White, 0, 0);

                lcd.SimpleGraphics.DisplayText("Response text: " + response.Text
                       , Resources.GetFont(Resources.FontResources.NinaB), Color.White, 0, 50);

            }
        }
    }
}

Here's the result of the code:

And an example of when things don't go according to plan:

The web request can't only be used to download picture resources; if you request a run-of-the-mill HTML page, you are able to access the streamed response:


The code for this demo is available here on GitHub

Wednesday 3 July 2013

What I learned about bluetooth with Gadgeteer

The Project

My recent Gadgeteer project was to investigate the Bluetooth module with a view to having a hassle-free way to communicate either between 2 Gadgeteer devices or between Gadgeteer and a Windows client.

I decided the best way to learn how the bluetooth module worked was by using Gadgeteer -> Windows, as it would make debugging easier. I came across the Bluetooth library from 32feet - this is a lovely layer of abstraction over the complexities of the bluetooth protocol, and ultimately gives you access to any serial data via a NetworkStream.

The goal of this experiment was to take a picture with the camera, convert it to a windows-compatible bitmap, and stream that over bluetooth to the client, which would create a bitmap from the bytes and display it on the screen. What could be easier?

This is the gadgeteer project:
The Windows client was not fancy; it consisted of a form with a picture box and progress bar.

What I Learnt

  • You should chunk your data. After some experimenting, I found the most reliable way to transfer a 320x240 pixel bitmap (totalling 230,454 bytes) was to split it into 93 chunks of 2,478 bytes each. I hadn't been able to transfer more than around 8k successfully, and my cut-off for reliably transferring data was around 3k.
  • Base64 encodings change between implementations. Don't assume that the .Net Framework will be able to unencode a Base64 string that was encoded on the .Net MicroFramework; I haven't got to the bottom of this one yet; there'll be another post when [if] I do. ** UPDATE ** I think this was how I was using the Base64 data when I received it, I was trying to extract chars rather than bytes.
  • Bluetooth isn't quick. Transferring a 230k bitmap takes around 90 seconds.
  • The Gadgeteer Bluetooth module needs time to warm up. Standard operating procedure for the bluetooth module is to create a timer that fires after 3 seconds of the modules initialising, so it can then enter pairing mode.

The Code

The code is available on Github. The Gadgeteer code is here and the windows client is here

The Result

Here's a picture showing the Gadgeteer LCD screen and the windows client side-by-side; you'll have to take my word for it that the image was bluetoothed...