As i said, im using code from:
ITG3200+ADXL345+HMC5883L MULTIPLE I2C ON SAME BUS:
http://code.tinyclr.com/project/441/itg3200adxl345hmc5883l-multiple-i2c-on-same-bus/
Modified the BMP085 code from Nicolas3 (also from tinyclr.com) like this
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using NETMF.IO.I2C;
using TDK.NETMF.AUV_PII.Sensors;
namespace SensorsLibrary.IMU.Sensors
{
public enum Oversampling : byte
{
None = 0,
Level1,
Level2,
Level3,
}
public class BMP085 : AbstractI2CDevice
{
#region Fields
private Int16 AC1, AC2, AC3, B1, B2, MB, MC, MD;
private UInt16 AC4, AC5, AC6;
private LowPassFilter filterTemperature = new LowPassFilter(0.1);
private LowPassFilter filterPressure = new LowPassFilter(0.1);
private LowPassFilter filterAltitude = new LowPassFilter(0.1);
#endregion
#region Properties
/// <summary>
/// 0 = low precision and power to 3 = higher both
/// </summary>
public byte OS { get; set; }
/// <summary>
/// Milliseconds between mesures
/// </summary>
public int Refresh { get; set; }
/// <summary>
/// True if sensor responding
/// </summary>
public bool Ok { get; private set; }
/// <summary>
/// In Celcius
/// </summary>
public double Temperature { get {return filterTemperature.Value;} }
/// <summary>
/// In Pa
/// </summary>
public int Pressure { get{return (int)filterPressure.Value;}}
/// <summary>
/// In mm
/// </summary>
public double Altitude { get{return filterAltitude.Value;}}
#endregion
//0 to 3 : 0 = low precision and low power and 20ms, to 3 = higher both and 40ms, refresh=seconds between capture, if 0 : only manual calls to ReadSensor()
// Oversampling: Datasheet says:
/// <summary>
/// BMP085 breakout board. I2C address: 0x77
/// </summary>
/// <param name="clockRate">Clockrate on the I2C Bus</param>
/// <param name="timeout">in ms</param>
/// <param name="OSS">
/// None: Conversion time max: 4.5 ms / RMS hPa: 0.06 / RMS m: 0.5
/// Level1: Conversion time max: 7.5 ms / RMS hPa: 0.05 / RMS m: 0.4
/// Level2: Conversion time max: 13.5 ms / RMS hPa: 0.04 / RMS m: 0.3
/// Level3: Conversion time max: 25.5 ms / RMS hPa: 0.03 / RMS m: 0.25
/// </param>
/// <param name="refresh">if 0 : only manual calls to ReadSensor()</param>
public BMP085(int clockRate, int timeout, Oversampling OSS = Oversampling.None, int refresh = 60)
: base(0x77, clockRate, timeout)
{
int actualRefresh = refresh;
if (refresh > 0)
{
switch (OSS)
{
case Oversampling.None:
if (actualRefresh < 5)
actualRefresh = 5;
break;
case Oversampling.Level1:
if (actualRefresh < 8)
actualRefresh = 8;
break;
case Oversampling.Level2:
if (actualRefresh < 14)
actualRefresh = 14;
break;
case Oversampling.Level3:
if (actualRefresh < 26)
actualRefresh = 26;
break;
}
}
Refresh = actualRefresh;
Ok = false;
// Calibration
I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0xAA });
byte[] RawData = new byte[22];
xActions[1] = I2CDevice.CreateReadTransaction(RawData);
if (Write(xActions, 100) != 23)
return;
AC1 = (short)((short)(RawData[0] << 8) + (short)(RawData[1]));
AC2 = (short)((short)(RawData[2] << 8) + (short)(RawData[3]));
AC3 = (short)((short)(RawData[4] << 8) + (short)(RawData[5]));
AC4 = (ushort)((ushort)(RawData[6] << 8) + (ushort)(RawData[7]));
AC5 = (ushort)((ushort)(RawData[8] << 8) + (ushort)(RawData[9]));
AC6 = (ushort)((ushort)(RawData[10] << 8) + (ushort)(RawData[11]));
B1 = (short)((short)(RawData[12] << 8) + (short)(RawData[13]));
B2 = (short)((short)(RawData[14] << 8) + (short)(RawData[15]));
MB = (short)((short)(RawData[16] << 8) + (short)(RawData[17]));
MC = (short)((short)(RawData[18] << 8) + (short)(RawData[19]));
MD = (short)((short)(RawData[20] << 8) + (short)(RawData[21]));
if (AC1 * AC2 * AC3 * AC4 * AC5 * AC6 * B1 * B2 * MB * MC * MD == 0)
return;
Ok = true;
OS = (byte)OSS;
Refresh = refresh;
if (refresh > 0)
new Thread(Capture).Start();
}
private void Capture()
{
while (true)
{
ReadSensor();
Thread.Sleep(Refresh);
}
}
public bool ReadSensor()
{
Int32 X1, X2, B5, B6, X3, B3, P, UT, UP;
UInt32 B4, B7;
I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0xF4, 0x2E });
if (Write(xActions, 100) != 2)
{
Ok = false;
return false;
}
Thread.Sleep(5);
I2CDevice.I2CTransaction[] xActions2 = new I2CDevice.I2CTransaction[2];
xActions2[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0xF6 });
byte[] RawData = new byte[2];
xActions2[1] = I2CDevice.CreateReadTransaction(RawData);
if (Write(xActions2, 100) != 3)
{
Ok = false;
return false;
}
UT = (Int32)((Int32)(RawData[0] << 8) + (Int32)(RawData[1]));
// Pressure
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0xF4, (byte)((OS << 6) + 0x34) });
if (Write(xActions, 100) != 2)
{
Ok = false;
return false;
}
Thread.Sleep(OS > 0 ? OS * 10 : 5);
xActions2[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0xF6 });
byte[] RawData2 = new byte[3];
xActions2[1] = I2CDevice.CreateReadTransaction(RawData2);
if (Write(xActions2, 100) != 4)
{
Ok = false;
return false;
}
UP = (((Int32)(RawData2[0]) << 16) + ((Int32)(RawData2[1]) << 8) + (Int32)RawData2[2]) >> (8 - OS);
// Calculus
X1 = (UT - AC6) * AC5 >> 15;
X2 = ((Int32)MC << 11) / (X1 + MD);
B5 = X1 + X2;
filterTemperature.Update(((double)((B5 + 8) >> 4)) / 10);
B6 = B5 - 4000;
X1 = (B2 * (B6 * B6 >> 12)) >> 11;
X2 = AC2 * B6 >> 11;
X3 = X1 + X2;
B3 = ((((Int32)AC1 * 4 + X3) << OS) + 2) >> 2;
X1 = AC3 * B6 >> 13;
X2 = (B1 * (B6 * B6 >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = AC4 * (UInt32)(X3 + 32768) >> 15;
B7 = ((UInt32)(UP - B3)) * (UInt32)(50000 >> OS);
P = (B7 < 0x80000000) ? (Int32)((B7 * 2) / B4) : (Int32)((B7 / B4) * 2);
X1 = (P >> 8) * (P >> 8);
X1 = (X1 * 3038) >> 16;
X2 = (-7357 * P) >> 16;
filterPressure.Update(P + ((X1 + X2 + 3791) >> 4));
filterAltitude.Update((44330.75 * (1 - System.Math.Pow((double)Pressure / 101325, 0.19029))) * 1000);
Ok = true;
return true;
}
public override bool Connected()
{
//TODO: Needs to be fixed..
return DeviceIdentifier()[0] == 0;
}
public override byte[] DeviceIdentifier()
{
//TODO: Needs to be fixed..
return new byte[1] { 0 };
//throw new NotImplementedException();
}
}
}
And i’m constructing the objects like this:
private const int I2C_CLOCK_RATE = (int)I2CBus.I2CBusSpeed.ClockRate400;
private const int I2C_TIMEOUT = 500;
gyro = new ITG3200(I2C_CLOCK_RATE, 0, false);
//at 1kHz/(20+1) = 47.6 Hz sampling rate
gyro.setSampleRateDivider(40);
gyro.setFilter(ITG3200.Filter.LP20Hz_Int1kHz);
// We have no power concerns, turn all axes on
gyro.Sleep(false, false, false, false);
//Set the clock source to PLL attached to the Z gyro
//it's much more accurate than the default internal oscillator
gyro.setClockSource(ITG3200.ClockSource.INT_OSC);// .PLL_ZGRYO_REF);
//calibrate after changing settings
Thread.Sleep(100);
gyro.calibrate();
compass = new Compass(I2C_CLOCK_RATE, I2C_TIMEOUT);
compass.SetScale(1.3);
compass.SetContinuous();
accel = new ADXL345(0x53, I2C_CLOCK_RATE, I2C_TIMEOUT);
accel.Range = 2;
accel.FullResolution = true;
accel.EnableMeasurements();
accel.SetDataRate(ADXL345.DataRates.DataRate50Hz);
pressure = new BMP085(I2C_CLOCK_RATE, I2C_TIMEOUT, Oversampling.Level2, 50);
and then i a loop in main, i read the different values off the sensors, and then wait for 50ms
(lots of code anyway…