Using Azure Mobile Services on the Raspberry Pi with Mono

In my previous posts I explained how you can get the Mono framework running on your Raspberry Pi (model 1 or 2). This Mono framework allows you to execute your beloved .NET code on top of Linux. In this post I’ll quickly show you how to connect to Azure Mobile Services from .NET code running on the Raspberry Pi. As an example I’ll use the built-in temperature sensor of the Pi, which values will be sent to a Mobile Service.

First you’ll need to make sure you are running the latest version of Mono, so go through my Getting started with the Raspberry Pi 2, for .NET developers. To verify if everything is ok so far, go to a command prompt (local or via SSH) and type:

mono --version

The output should report you are running version 3.12.0 (at the time of writing).

rpi-mobileservices1

If you are running an earlier version of Mono, you can upgrade to the latest one by executing the following commands in a prompt.

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install mono-complete

Now let’s go to Azure and create a Mobile Service if you don’t already have one. Any Mobile Service with at least 1 table will do for now, if you’ve never created one you can check out steps to get started in this article. I created a table called SensorValue and I didn’t bother yet creating columns since they will be automatically created later one, with the help of Azure’s Dynamic Schema creation.

Now let’s start Visual Studio and create a new C# Console Application, this will be the code that will run on the Raspberry Pi. Add the Azure Mobile Services NuGet Package.

Next add a class with a name that corresponds with the one you used to name your table in the Mobile Service (I uses SensorValue). In that class add these 3 properties:

public class SensorValue
{
    public string Id { get; set; }
    public string Sensor { get; set; }
    public double Value { get; set; }
}

Next, in the Program class, add the MobileService property with the Application URL and Application Key which you can copy from the Azure Portal. (you can even copy the entire code snippet from the Quick Start section of your Mobile Service)

public static MobileServiceClient MobileService = new MobileServiceClient(
    "https://<<your url>>.azure-mobile.net/",
    "<<your key>>"
);

Also in the program class add the following method which will read the current temperature from the built-in Pi’s sensor.

private static double GetThermalZone0Temp()
{
    string tv;
    using (System.IO.TextReader tr =
        new System.IO.StreamReader("/sys/class/thermal/thermal_zone0/temp"))
    {
        tv = tr.ReadLine();
    }
    return double.Parse(tv) / 1000;
}

Finally, write the following code in the Main method which will post the temperature to the Mobile Service.

static void Main(string[] args)
{
    Console.Write("Posting ");
    
    double temp = GetThermalZone0Temp();
    Console.Write(temp);
    
    MobileService.GetTable<SensorValue>().InsertAsync(
        new SensorValue()
        {
            Sensor = "Thermal Zone0 Temperature",
            Value = temp
        }).Wait();
    Console.WriteLine(", done!");
}

When you’d build the code now, copy it to the Raspberry Pi and try to run it, you’d get a pretty nasty unhandled exception:

System.TypeInitializationException: An exception was thrown by the type initializer for RpiInternalTemp.Program ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Net.Http, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.

As the exception points out, the requested System.Net.Http version can’t be loaded on the Pi. To get around this, modify the App.config file in Visual Studio and add the following assembly binding (in the configuration > runtime > assemblyBinding element):

<dependentAssembly>
  <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
</dependentAssembly>

Finally we are ready to build the project, copy the result to the Pi and run it. Once again, check my previous post on how to do this this easily with the Bitvise SSH client. The files you need to copy are: the .EXE, the .DLL’s, and the .EXE.CONFIG you can find in the output folder of your project. If everything went ok, you can execute the Console app using the mono command.

When you check your Mobile Service you’ll find the posted value.

You can find the complete source code of the Console Application on my GitHub.

  4 comments for “Using Azure Mobile Services on the Raspberry Pi with Mono

  1. Thomas Schmidt
    February 24, 2015 at 2:36 pm

    Hi Jan,
    do you have setup instructions for Mono 3.12 for the PI 1? I’d like to do ASP.NET on the Pi 1. My current Mono is a bit old, 3.2.8.
    Thomas

    • jan
      February 24, 2015 at 4:25 pm

      Hey Thomas, check the section “If you are running an earlier version of Mono, you can upgrade to the latest one” in this post. It should upgrade your Mono to the latest version.

      • Thomas Schmidt
        February 26, 2015 at 6:25 pm

        Hi Jan,
        I did that and the install failed with lots of errors. It began with a segmentation fault in one of the install commands.
        I tried everything to uninstall the fragments but failed.
        Finally I had to restore from a backup I luckily did a fortnight ago….
        So, I’m bound to mono 3.2.8. My attepts to compile the newest sources failed with compilation errors. n The actual version is not RasPi compatible.
        Thomas

  2. François
    June 9, 2015 at 3:51 pm

    Hi Jan, We needs to connect a Raspberry Pi to Azure Service Bus using mono, we faced the following issues :
    Unhandled Exception:
    System.TypeInitializationException: An exception was thrown by the type initializer for TimerManager
    CreateWaitableTimer.

    Do you have any ideas ?
    Best Regards.

Leave a Reply

Your email address will not be published. Required fields are marked *