Main Site Documentation

Two I2C devices


#1

Initialization of the second device always causes an exception. When initialized with any one I2C device - everything is normal. In what may be the problem?

Error:


I2CDevice gyro = new I2CDevice(new I2CDevice.Configuration(0x69, 400)); // ITG3200
I2CDevice compass = new I2CDevice(new I2CDevice.Configuration(0x1E, 400)); // HMC5843

Ok:


//I2CDevice gyro = new I2CDevice(new I2CDevice.Configuration(0x69, 400)); // ITG3200
I2CDevice compass = new I2CDevice(new I2CDevice.Configuration(0x1E, 400)); // HMC5843

Ok:


I2CDevice gyro = new I2CDevice(new I2CDevice.Configuration(0x69, 400)); // ITG3200
//I2CDevice compass = new I2CDevice(new I2CDevice.Configuration(0x1E, 400)); // HMC5843


#2

Exception:

[quote]#### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (1) ####

Message:

Microsoft.SPOT.Hardware.Port::ReservePin [IP: 0000]

Microsoft.SPOT.Hardware.I2CDevice::.ctor [IP: 0021]

PandaCopter.Program::Main [IP: 002a]

A first chance exception of type ‘System.InvalidOperationException’ occurred in Microsoft.SPOT.Hardware.dll
An unhandled exception of type ‘System.InvalidOperationException’ occurred in Microsoft.SPOT.Hardware.dll
[/quote]


#3

I have no idea why this doesnt work, but have you tried with a small thread.sleep between initialize the second device?
Just a thought


#4

Error on the second initialization:

[quote]I2CDevice gyro = new I2CDevice(new I2CDevice.Configuration(0x69, 400));
Thread.Sleep(5000);
I2CDevice compass = new I2CDevice(new I2CDevice.Configuration(0x1E, 400));
Thread.Sleep(5000);[/quote]


#5

You can only have one I2CDevice object but then you can have multiple configuration , one per device

The name is misleading. It should have been I2CBus instead


#6

Ok, it means goodbye Thread.Gyro, Thread.Accel, Thread.Compass!
Hi Thread.Sensors!
:wink:


#7

You can still have separate threads!

You can use a mutex to control access to the i2c object.


#8

No it doesn’t! You can have multiple thread and each is reading I2C! The only thing you need to do is declare a global I2CDevice object that they all can share. But then each thread has I2CConfiguration

Lets see if I can explain this in code!

static I2CDevice MyI2CBus = new I2CDevice(null);
static I2CDevice.Configuration gyroconfig= new I2CDevice.Configuration(0x69, 400);
static I2CDevice.Configuration compasconfig = new I2CDevice(new I2CDevice.Configuration(0x1E, 400);

void threadgyro()
{
  while(true)
  {
    MyI2CBus.Config = gyroconfig;
    //...
  }
}

void threadcompas()
{
  while(true)
  {
    MyI2CBus.Config = compasconfig;
    //...
  }
}



#9

What is it locked MyI2CBus not need in this case?


#10

I only showed you a simple idea on how to use multiple I2C devices but that code is NOT complete NOR it will do anything. You will need to add some mechanism to make your code threads safe like Mike suggested


#11

Ok, thanks.
That is what I had in mind when talking about the meaninglessness of threads in this case. Too high costs of separate threads and the loss of the blocked sensor readings. In this case, preferably poll I2C sensors in a separate class.


#12

You can use my http://forums.netduino.com/index.php?/topic/563-i2cbus/ I2CBus class I created that implements the singleton pattern. This ensures that you will only have one instance of I2CDevice. All you have to do is pass in different I2CDevice configurations when using read or write transactions.

Here is an example of it in use with a Bosch BMP085 pressure sensor -> http://forums.netduino.com/index.php?/topic/578-bosch-bmp085-digital-pressure-and-temperature-sensor/


#13

You may also have a look here : http://www.fezzer.com/project/180/i2c-execute-extension/