Sensing the environment – OneWire Temperature Sensor (DS18B20)

Using the following setup, I have been able to read the temperature using the DS18B20 Sensor.

2013-11-25 21.47.54

I have created a controller based on the OneWire class and sample code found here

public class OneWireTemperatureSensorController : TemperatureController
    {
        private readonly OneWire _oneWire;
        public OneWireTemperatureSensorController(Cpu.Pin pin)
        {
            _oneWire = new OneWire(new OutputPort(pin, false));

        }
        public double ReadTemperatureToConsole(TemperatureEnum setting)
        {
            double returnTemperatureCelcius = -999;
            try
            {
                if (_oneWire.TouchReset() > 0)
                {
                    _oneWire.WriteByte(0xCC);     // Skip ROM, only one device
                    _oneWire.WriteByte(0x44);     // Temp conversion

                    while (_oneWire.ReadByte() == 0) ;   //Loading

                    _oneWire.TouchReset();
                    _oneWire.WriteByte(0xCC);     // Skip ROM
                    _oneWire.WriteByte(0xBE);     // Read

                    ushort temperature = (byte)_oneWire.ReadByte();
                    temperature |= (ushort)(_oneWire.ReadByte() << 8); // MSB

                    returnTemperatureCelcius = temperature / 16.0;

                    Debug.Print("Temperature: " + returnTemperatureCelcius + "° C" ;
                }
                else
                {
                    Debug.Print("ReadTemperatureToConsole " + "No device detected");
                    //Could be that you read to fast after previous read. Include Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                Debug.Print("ReadTemperatureToConsole " + ex.Message);
            }
            return returnTemperatureCelcius;

        }
    }

In case of multiple sensors read here

Now as you might have noticed, I have also added a base controller for temperature readings which can convert to temperature values.

    public class TemperatureController
    {
        public static string GetTemperatureFormat(TemperatureEnum setting)
        {
            switch (setting)
            {
                case TemperatureEnum.Celcius:
                    return "° C";
                case TemperatureEnum.Fahrenheit:
                    return "° F";
                case TemperatureEnum.Kelvin:
                    return "° K";
                default:
                    return " ?";
            }
        }

        internal static double Convert(TemperatureEnum from, TemperatureEnum to, double temperature)
        {
            if (from == TemperatureEnum.Celcius && to == TemperatureEnum.Fahrenheit)
                return ((1.80 * (temperature / 16.0)) + 32);

            if (from == TemperatureEnum.Celcius && to == TemperatureEnum.Kelvin)
                return temperature + 273.15;
            return -999;
        }
    }

Which uses an Enum:

    public enum TemperatureEnum
    {
        Celcius = 1,
        Fahrenheit = 2,
        Kelvin = 3
    }

Implementing the base Controller in the ReadTemperatureToConsole Method

        public double ReadTemperatureToConsole(TemperatureEnum setting)
        {
            double returnTemperatureCelcius = -999;
            double returnTemperatureFahrenheit = -999;
            double returnTemperatureKelvin = -999;

            try
            {

                // DS18B20, NETMF 4.2
                // center pin is connected to digital pin 0, right pin is connected to 5V,
                // left pin GND, 4k7 pull-up  resistor between 5V and the center pin

                if (_oneWire.TouchReset() > 0)
                {
                    _oneWire.WriteByte(0xCC);     // Skip ROM, we only have one device
                    _oneWire.WriteByte(0x44);     // Start temperature conversion

                    while (_oneWire.ReadByte() == 0) ;   // wait while busy

                    _oneWire.TouchReset();
                    _oneWire.WriteByte(0xCC);     // Skip ROM
                    _oneWire.WriteByte(0xBE);     // Read Scratchpad

                    ushort temperature = (byte)_oneWire.ReadByte();
                    temperature |= (ushort)(_oneWire.ReadByte() << 8); // MSB

                    returnTemperatureCelcius = temperature / 16.0;
                    returnTemperatureFahrenheit = Convert(TemperatureEnum.Celcius, TemperatureEnum.Fahrenheit, returnTemperatureCelcius);
                    returnTemperatureKelvin = Convert(TemperatureEnum.Celcius, TemperatureEnum.Kelvin, returnTemperatureCelcius);

                    Debug.Print("Temperature: " + returnTemperatureCelcius + GetTemperatureFormat(TemperatureEnum.Celcius));
                    Debug.Print("Temperature: " + returnTemperatureFahrenheit + GetTemperatureFormat(TemperatureEnum.Fahrenheit));
                    Debug.Print("Temperature: " + returnTemperatureKelvin + GetTemperatureFormat(TemperatureEnum.Kelvin));
                    //return temperature/16.0;
                }
                else
                {
                    Debug.Print("ReadTemperatureToConsole " + "No device detected");
                    return 0;
                }

            }
            catch (Exception ex)
            {
                Debug.Print("ReadTemperatureToConsole " + ex.Message);
            }
            switch (setting)
            {
                case TemperatureEnum.Celcius:
                    return returnTemperatureCelcius;
                case TemperatureEnum.Fahrenheit:
                    return returnTemperatureFahrenheit;
                case TemperatureEnum.Kelvin:
                    return returnTemperatureKelvin;
                default:
                    return -999;
            }

Simplified form of usage would be

private static OneWireTemperatureSensorController _tempertureController;
public static void Main()
{
 _tempertureController = new OneWireTemperatureSensorController(Pins.GPIO_PIN_D0);
 while (true)
 {
 Tick(null);
 //Thread.Sleep(10 * 1000 ); //sleep 10 seconds
 Thread.Sleep(1000 * 60 * 30); //sleep 30 minutes
 }
}

private static void Tick(object state)
{
 var temp = _tempertureController.ReadTemperatureToConsole(TemperatureEnum.Celcius, false);
}
About these ads

Care to comment?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s