Tuesday, July 15, 2014

C# (Mono) Code to Read an TMP102 I2C Temperature Sensor on a Raspberry Pi

Mono is an open source implementation of the Microsoft .NET framework that allows you to compile and run .NET programs on non-Windows platforms.  That includes the Raspberry Pi.  It actually proved to be quite easy to install Mono (v. 3.2.8) on the RPi and get some C# code running.  This example shows how to call the i2cget utility from a C# program to read the temperature from a TMP102 and print the results in degrees Celsius and Fahrenheit in the terminal window.

To install Mono, run the following apt-get command as root:

apt-get install mono-complete

The will get you the complete Mono package.

For this example, I am using the TMP102 on a breakout board from Sparkfun.

Connect the SDA and SCL pins between the TMP102 and the RPi.  Connect VCC to 3.3V and connect the ground.  With the solder jumper on the TMP102 in place (by default) the I2C device address is 0x48.

The i2cget utility is included with the i2c-tools package. If you don't already have it installed, you can run the following command as root to install it -

apt-get install i2c-tools 

C# Code


Use your favorite text editor to save this code to a file called Tmp102.cs.

using System;
using System.Diagnostics;
using System.Threading;

public class Tmp102
{
    private string i2cgetExe = "/usr/sbin/i2cget";
    private string i2cgetCmdArgs = "-y 1 0x48 0 w";
    private string hexString = "";
    private Process p;

    public Tmp102()
    {
        p = new Process();
    }

    public double tempC
    {
        get { return readRawTempData() * 0.0625; }
    }
    public double tempF
    {
        get { return this.tempC * 1.8 + 32; }
    }

    private int readRawTempData()
    {
        // Don't raise event when process exits
        p.EnableRaisingEvents = false;
        // We're using an executable not document, so UseShellExecute false
        p.StartInfo.UseShellExecute = false;
        // Redirect StandardError
        p.StartInfo.RedirectStandardError = true;
        // Redirect StandardOutput so we can capture it
        p.StartInfo.RedirectStandardOutput = true;
        // i2cgetExe has full path to executable
        // Need full path because UseShellExecute is false

        p.StartInfo.FileName = i2cgetExe;
        // Pass arguments as a single string
        p.StartInfo.Arguments = i2cgetCmdArgs;
        // Now run i2cget & wait for it to finish
        p.Start();
        p.WaitForExit();
        // Data returned in format 0xa017
        // Last 2 digits are actually most significant byte (MSB)
        // 2 digits right after 0x are really least significant byte (LSB)
        string data = p.StandardOutput.ReadToEnd();
        // Get LSB & parse as integer
        hexString = data.Substring(2, 2);
        int lsb = Int32.Parse(hexString,
            System.Globalization.NumberStyles.AllowHexSpecifier);
        // Get MSB & parse as integer
        hexString = data.Substring(4, 2);
        int msb = Int32.Parse(hexString,
            System.Globalization.NumberStyles.AllowHexSpecifier);
        // Shift bits as indicated in TMP102 docs & return
        return (((msb << 8) | lsb) >> 4);
    }

    public static void Main()
    {
        Tmp102 t = new Tmp102();
        while(true)
        {
            // Print temp in degrees C and F to console
            Console.WriteLine("{0}°C  {1}°F", t.tempC , t.tempF);
            Thread.Sleep(1000);
        }
    }
}

Compiling & Running the Code


To compile a Mono executable, run the following command:

gmcs Tmp102.cs

Then execute the program by running 

mono Tmp102.exe

Press Ctrl-C to terminate the program.

1 comment: