Notes About Working with Various Arduino & Netduino Microcontroller Boards

Tuesday, December 18, 2012

MLX90614 Infrared Sensor & the Netduino Plus 2

The MLX90614 is a non-contact infrared temperature sensor. This example uses I2C for communication between the sensor and the Netduino (Plus 2). The following code reads the temperature every second and prints it out to the debugging console in degrees Fahrenheit. The code is derived from the Arduino example at Bildr and code posted in the Netduino community forum.  

Connections:
(With the small brass nib on the MLX90614 pointing to the right)
MLX90614  -->  Netduino Plus 2
Top Left       SDA  (4K7 pullup resistor)
Top Right      SCL  (4K7 pullup resistor)
Bot. Left      3V3  (0.1mf capacitor between
Bot. Right     GND    3V3 & GND)
Code:
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Reflection;
using System.Threading;

namespace MLX90614
{
    public class Program
    {
        public static void Main()
        {
            byte i2cAddr = 0x5A;
            I2CDevice mlx90614 = new I2CDevice(new I2CDevice.Configuration(i2cAddr, 100));
            while (true)
            {
                byte[] cmd = { 0x07 };
                byte[] tempData = { 0, 0 }; //LowByte, HighByte
                I2CDevice.I2CTransaction[] reading = new I2CDevice.I2CTransaction[] {
                    CreateWriteTransaction(cmd, 0x07, 1),
                    CreateReadTransaction(tempData, 0x07, 1)
                };
                int bytesRead = mlx90614.Execute(reading, 100);
                Double tempFactor = 0.02; // 0.02 deg./LSB (MLX90614 resolution)
                Double temp = ((tempData[1] & 0x007F) << 8) + tempData[0];
                temp = (temp * tempFactor) - 0.01;
                Double celcius = temp - 273.15;
                Double fahrenheit = (celcius * 1.8) + 32;
                Debug.Print(fahrenheit.ToString());
                Thread.Sleep(1000);
            }
        }

        static I2CDevice.I2CWriteTransaction CreateWriteTransaction(byte[] buffer, uint addr, byte addrSz)
        {
            I2CDevice.I2CWriteTransaction writeTransaction = I2CDevice.CreateWriteTransaction(buffer);
            Type writeTransactionType = typeof(I2CDevice.I2CWriteTransaction);

            FieldInfo fieldInfo = writeTransactionType.GetField("Custom_InternalAddress", 
                BindingFlags.NonPublic | BindingFlags.Instance);
            fieldInfo.SetValue(writeTransaction, addr);

            fieldInfo = writeTransactionType.GetField("Custom_InternalAddressSize", 
                BindingFlags.NonPublic | BindingFlags.Instance);
            fieldInfo.SetValue(writeTransaction, addrSz);

            return writeTransaction;
        }

        static I2CDevice.I2CReadTransaction CreateReadTransaction(byte[] buffer, uint addr, byte addrSz)
        {
            I2CDevice.I2CReadTransaction readTransaction = I2CDevice.CreateReadTransaction(buffer);
            Type readTransactionType = typeof(I2CDevice.I2CReadTransaction);

            FieldInfo fieldInfo = readTransactionType.GetField("Custom_InternalAddress", 
                BindingFlags.NonPublic | BindingFlags.Instance);
            fieldInfo.SetValue(readTransaction, addr);

            fieldInfo = readTransactionType.GetField("Custom_InternalAddressSize", 
                BindingFlags.NonPublic | BindingFlags.Instance);
            fieldInfo.SetValue(readTransaction, addrSz);

            return readTransaction;
        }
    }
}

3 comments:

  1. Hi,
    I tried the above code but I am getting an exception. Please advise what could be missed.
    here is the full log:
    http://db.tt/tVWM0N9V
    Thanks.

    ReplyDelete
    Replies
    1. Hi j -

      I'll run through the code and setup again tonight at home and see if I can reproduce the problem. You might want to try using some try-catch blocks to isolate which line is throwing the NullReferenceException.

      Delete
    2. Hi j -

      I've tested the hardware setup and the code again, and everything appears to be in order. I copied and pasted the code from the post above to make sure I didn't introduce any errors when I published the code, but I don't find any problems.

      It also looks like we've got the same versions of the .NET MF and so forth, so I don't think that can be the issue. Check that you've got the MLX90614 hooked up correctly (incl. the pull-up resistors).

      Otherwise, if you can narrow down which line is causing the exception, that might be helpful.

      Delete