Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

I2C problem by MS5611 sensor


  • Please log in to reply
5 replies to this topic

#1 Sinan

Sinan

    Member

  • Members
  • PipPip
  • 10 posts

Posted 18 May 2012 - 12:15 AM

Hi everyone,

I am trying to build a variometer using the Mod-1009 board for MS5611-01BA barometric pressure sensor from Embedded Adventures.

Unfortunately, I cannot read values from the i2c port. SDA is connected to Analog 4, SCLK to 5 and the VCC to 3.3v. I am using the latest framework (4.2).

I am OK with C# and .net but I am clueless in this world. Bellow is my code where the device.Execute always returns zero in the ReadFromDevice method.

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace MS5611baro
{
  // Mod-1009 board for MS5611-01BA Barometric Pressure Sensor from
  // Embedded Adventures (http://www.embeddedadventures.com/barometric_pressure_sensor_module_mod-1009.html) 
  // MS5611 datasheet http://www.embeddedadventures.com/datasheets/ms5611.pdf
  // Mod-1009 description http://www.embeddedadventures.com/datasheets/MOD-1009_hw_v1.pdf
  // 
  // VCC  --> 3.3v
  // SDA  --> Analog 4
  // SCLK --> Analog 5
  // 
  // Pull up resistors: (from Mod-1009 description) The board comes with the pull-up resistors enabled. If you are
  //   connecting to an existing I2C buss that already has pull-up resistors, or you are using internal pull-ups in 
  //   your microcontroller, you can disable the pull-up resistors by cutting the PCB jumpers on the MOD-1009 board. 
  public class MS5611_MOD1009
  {
    private const byte _cmdReset = 0x1E;
    private const byte _cmdPromReadBase = 0xa0;
   
    private const ushort _i2cAddr = 0x76; //Embedded Adventures module CSB is VCC --> HIGH --> 0x76

    public UInt16[] CalibrationArray = new UInt16[6];
    public int LastTransactionCount = -1;

    private I2CDevice _device = new I2CDevice(new I2CDevice.Configuration(_i2cAddr, 10));

    /// <summary> Mod-1009 board for MS5611-01BA Barometric Pressure Sensor from Embedded Adventures</summary>
    public MS5611_MOD1009()
    {
      while (LastTransactionCount < 1)
      {
        WriteToDevice(_cmdReset, 100); // ResetSensor();       
      }
    }

    public bool WriteToDevice(byte command, int timeOut = 5)
    {
      I2CDevice.I2CWriteTransaction wt = I2CDevice.CreateWriteTransaction(new byte[] { command });
      LastTransactionCount = this._device.Execute(new I2CDevice.I2CTransaction[] { wt }, 3);
      return LastTransactionCount > 0;
    }

    public bool ReadFromDevice(byte[] readBuf, int timeOut = 100)
    {
      var rtArr = new I2CDevice.I2CReadTransaction[] { I2CDevice.CreateReadTransaction(readBuf) };
      LastTransactionCount = _device.Execute(rtArr, timeOut);  // --> returns allways zero
      return LastTransactionCount == readBuf.Length;
    }

    public void ReadCalibrationData()
    {
      for (byte i = 0; i < 6; i++)
      {
        CalibrationArray[i] = ReadSingleCalibrationValue((byte)(i + 1));
      }
    }

    private UInt16 ReadSingleCalibrationValue(byte valueToRead)
    {
      //  1 0 1 0 X X X 0  - The XXX part is used for the parameter index
      byte paramIndex = (byte)(_cmdPromReadBase + (valueToRead << 1));
      // This sets up the system into PROM read mode.
      if (WriteToDevice(paramIndex))       // --> returns true
      {
        byte[] readBuf = new byte[2];
        // This part gets the data from the system.
        if (ReadFromDevice(readBuf, 100)) // --> returns allways false, readBuf is empty {0, 0}
        {
          return (UInt16)(readBuf[0] << 8 | readBuf[1]);
        }
      }
      return 0;
    }
  }
}


using System;
using System.Threading;
using Microsoft.SPOT;

namespace MS5611baro
{
  public class Program
  {
    public static void Main()
    {
      var baro = new MS5611_MOD1009();
      baro.ReadCalibrationData();
    }
  }
}


Thanks for help,
Sinan

#2 Sinan

Sinan

    Member

  • Members
  • PipPip
  • 10 posts

Posted 18 May 2012 - 11:46 AM

Just discovered the I2CAdapter class by Guido (gbreder). It looks promissing.

Regards,
Sinan

#3 Sinan

Sinan

    Member

  • Members
  • PipPip
  • 10 posts

Posted 18 May 2012 - 06:15 PM

Hi,

I have completely refactored my code around the I2CAdapter class. Although the code looks much better now, it still doesn't work. All read actions return 0 bytes.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Netduino.Extender.TransferAdapters;  

namespace MS5611baro
{
  public class Program
  {
    private const ushort _i2cAddr =0x76; //  Embedded Adventures module CSB is VCC --> HIGH --> 0x76
    static I2CDevice.Configuration _config;
    // From: Guido (gbreder)
    // http://forums.netduino.com/index.php?/topic/3471-netduino-firmware-v420-rc4-netduino-netduino-plus/page__hl__createreadtransaction__st__80
    static I2CAdapter _adapter;

    public static void Main()
    {
      _config = new I2CDevice.Configuration(_i2cAddr, 10);
      _adapter = I2CAdapter.Instance;
      ResetMS5611();
      UInt16[] calibrationArray = ReadCalibrationParameters();
      while (true)
      {
        int tempRaw = ReadIntFrom24bit(0x58);     // Command to convert temp D2 (OSR=4096)
        int pressureRaw = ReadIntFrom24bit(0x48); // Command to convert pressure D1 (OSR=4096)
      }
    }

    private static int ReadBytes(byte[] buf)
    {
      return _adapter.ReadBytes(_config, buf);
      // return _adapter.ReadInternalAddressBytes(_config, buf, _i2cAddr, 1);
    }

    static int WriteByte(byte B)
    {
      return _adapter.WriteBytes(_config, new byte[] { b });
      // return _adapter.WriteInternalAddressBytes(_config, new byte[] { b }, _i2cAddr, 1);
    }

    private static void ResetMS5611()
    {
      WriteByte(0x1E); // Reset command
      Thread.Sleep(100);
    }

    private static UInt16[] ReadCalibrationParameters()
    {
      UInt16[] calibrationArray = new UInt16[6];
      byte[] readBuf = new byte[2];
      for (int i = 0; i < 6; i++)
      {
        byte paramIndex = (byte)(0xA0 + ((i + 1) << 1)); // 1010XXX0 - The XXX part for the parameter index        
        WriteByte(paramIndex);                           // This sets up the system into PROM read mode.
        ReadBytes(readBuf);
        calibrationArray[i] = (UInt16)(readBuf[0] << 8 | readBuf[1]);
      }
      return calibrationArray;
    }

    private static int ReadIntFrom24bit(byte command)
    {
      WriteByte(command); 
      Thread.Sleep(10);
      WriteByte(0);  // Send read ADC command
      byte[] buf24 = new byte[3];
      ReadBytes(buf24);
      int result = (buf24[0] * 65536) + (buf24[1] * 256) + buf24[2];
      return result;
    }
  }
}

I have double checked all connections and read lots of documentation. I don’t know where to go from here.

Kind regards, Sinan

#4 Sinan

Sinan

    Member

  • Members
  • PipPip
  • 10 posts

Posted 24 May 2012 - 09:44 PM

Problem solved by applying 1.8K pull-up resistors. I first replaced the built in 10K resistors by 2.2K resistors but it didn’t worked. Also experimented with couple of other resistors without any luck. At the end, I have used the 10K and the 2.2K resistors in parallel (=1.8K) and finally tada… :) Cheers, Sinan

#5 Sinan

Sinan

    Member

  • Members
  • PipPip
  • 10 posts

Posted 28 May 2012 - 07:37 PM

I keep replying my own post, but one more update…

After reading this article and some more experiments, I have discovered that most trouble is caused by the type and/or the length of the cables on my breadboard. The SDA/CLK cables where 20cm long and I don’t know how thick they were. The connections where all OK. Anyway, everything started to work flawlessly after replacing these cables with very short (2 cm) ones. The pull-up resistor values are also less critical now, I can use the device with various resistors from 1k to 10k.
I suppose that this problem is caused due to wrong capacitance of the signal bus. Learning a lot these days.

Cheers, Sinan

#6 Coder Myers

Coder Myers

    New Member

  • Members
  • Pip
  • 3 posts

Posted 03 April 2013 - 04:05 PM

Thanks for this post, I believe I'm having the same issue with various other sensors.






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.