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.
Dang, I looked at your code and totally missed your commenting system, my bad.
In that case you are missing some needed, I call it coffee code;
// required i2c kick
OutputPort p = new OutputPort(Pins.GPIO_PIN_SDA, true); p.Write(false); p.Dispose();
throw that near the beginning of main.
I am also using the ADXL345, on a 9DoF board. I seemed to remember not getting anything out of it without sending some config to the device - and you do not appear to have any (not totally sure, it was one of the devices, but memory on which one isnt quite 100%)
I'm not sure why your one device works without 'coffee', at least its worth a try.
With 4.3 the .Execute returns always returns 0 bytes.
I figured my wiring was wrong or the ADXL345 was fragged, but when I tried the same software and device on my NP1 it worked fine.
I had a look at my code and built a cut back test application which checked the deviceID for the ADXL345 and read the time from the DS1307. This showed the same symptoms - the DS1307 worked on both Netduino devices, and the ADXL345 only worked on the NP1.
I have had a look at the forums, tried the repeated Execute patch, the sleep on start up, custom.dfu, checked the pull-up resistors, tried slower I2C bus speeds etc. but still the same symptoms.
I have run out of ideas, any suggestions...
My cut back test application code and a picture of my NP1+NP2 config are attached.
EDIT: - In my simple demo application the failure occurs with only one device on the I2C bus. For the demo application to work you will need to comment in/out one of the two main() methods. One main is for the DS1307, the other is for the ADXL345
Bryn
DeviceInfo:
HAL build info: 4.3.1.0, Netduino Plus 2 (v4.3.1.0) by Secret Labs LLC
OEM Product codes (vendor, model, SKU): 34, 177, 4102
Serial Numbers (module, system):
00000000000000000000000000000000
0000000000000000
Solution Build Info: 4.3.1.0, Netduino Plus 2 (v4.3.1.0) by Secret Labs LLC
AppDomains:
default, id=1
Assemblies:
mscorlib,4.3.1.0
Microsoft.SPOT.Native,4.3.1.0
Microsoft.SPOT.Hardware,4.3.1.0
Microsoft.SPOT.Net,4.3.1.0
System,4.3.1.0
Microsoft.SPOT.Hardware.SerialPort,4.3.1.0
Microsoft.SPOT.IO,4.3.1.0
System.IO,4.3.1.0
Microsoft.SPOT.Hardware.PWM,4.3.1.0
Microsoft.SPOT.Hardware.Usb,4.3.1.0
SecretLabs.NETMF.Diagnostics,4.3.1.0
SecretLabs.NETMF.Hardware.Netduino,4.3.1.0
Microsoft.SPOT.Hardware.OneWire,4.3.1.0
Microsoft.SPOT.Time,4.3.1.0
SecretLabs.NETMF.Hardware,4.3.1.0
I2C-NP2-Minimal-4.3,1.0.0.0
My experience was you could not access different devices on the bus like that. Granted I'm a newb, but after digging I finaly came up with just setting a different device config, and not creating separate instances. Some of the 'generic' code I've seen published tried to abstract this, although I prefer to do it myself.
Here is a code extract illustrating what I am saying; I may be totally wrong, if I am, some please tell me.
I2CDevice.Configuration accellConfig = new I2CDevice.Configuration(0x53, 400),
gyroConfig = new I2CDevice.Configuration(0x68, 400),
MagnConfig = new I2CDevice.Configuration(0x1e, 400);
I2CDevice i2cBus = new I2CDevice(null);
System.Threading.Thread.Sleep(20);
// devices initialize
i2cBus.Config = gyroConfig;
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x16, 0x03 << 4 | 0x04 }) }, 100);
System.Threading.Thread.Sleep(5);
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x15, 0x07 }) }, 100);
System.Threading.Thread.Sleep(5);
I2CDevice.I2CTransaction[] gyroTrans = new I2CDevice.I2CTransaction[] {
I2CDevice.CreateWriteTransaction(new byte[] { 0x1D }),
I2CDevice.CreateReadTransaction(tmpBuf)
};
i2cBus.Config = accellConfig;
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x2D, 0x08 }) }, 100);
System.Threading.Thread.Sleep(5);
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x31, 0x08 }) }, 100);
System.Threading.Thread.Sleep(5);
I2CDevice.I2CTransaction[] accelTrans = new I2CDevice.I2CTransaction[] {
I2CDevice.CreateWriteTransaction(new byte[] { 0x32 }),
I2CDevice.CreateReadTransaction(tmpBuf)
};
i2cBus.Config = MagnConfig;
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x00, 0x70 }) }, 100); // 8-average 15hz
System.Threading.Thread.Sleep(5);
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x01, 0x0B }) }, 100); // gain 8.1
System.Threading.Thread.Sleep(5);
i2cBus.Execute(new I2CDevice.I2CTransaction[] { I2CDevice.CreateWriteTransaction(new byte[] { 0x02, 0x00 }) }, 100); // continuous
System.Threading.Thread.Sleep(5);
I2CDevice.I2CTransaction[] magnTrans = new I2CDevice.I2CTransaction[] {
I2CDevice.CreateWriteTransaction(new byte[] { 0x03 }),
I2CDevice.CreateReadTransaction(tmpBuf)
};
// main loop
// gyro and magno are reverse endian order and need to be corrected
for (; ; )
{
byte t;
long thisTick = DateTime.Now.Ticks;
Rb.dt = (uint)(thisTick - lastTick); // better be a uint or we got problems!
i2cBus.Config = accellConfig;
i2cBus.Execute(accelTrans, 100);
System.Threading.Thread.Sleep(5);
Rb.ax = BitConverter.ToInt16(tmpBuf, 0);
Rb.ay = BitConverter.ToInt16(tmpBuf, 2);
Rb.az = BitConverter.ToInt16(tmpBuf, 4);
i2cBus.Config = gyroConfig;
i2cBus.Execute(gyroTrans, 100);
System.Threading.Thread.Sleep(5);
for (int i = 0; i < 6; i += 2)
{
t = tmpBuf[i]; tmpBuf[i] = tmpBuf[i + 1]; tmpBuf[i + 1] = t;
}
Rb.gx = -BitConverter.ToInt16(tmpBuf, 0);
Rb.gy = -BitConverter.ToInt16(tmpBuf, 2);
Rb.gz = -BitConverter.ToInt16(tmpBuf, 4);
i2cBus.Config = MagnConfig;
i2cBus.Execute(magnTrans, 100);
System.Threading.Thread.Sleep(5);
for (int i = 0; i < 6; i += 2)
{
t = tmpBuf[i]; tmpBuf[i] = tmpBuf[i + 1]; tmpBuf[i + 1] = t;
}
Rb.mx = BitConverter.ToInt16(tmpBuf, 0);
Rb.my = -BitConverter.ToInt16(tmpBuf, 4);
Rb.mz = -BitConverter.ToInt16(tmpBuf, 2);
string json = JsonSerializer.SerializeObject(Rb, DateTimeFormat.Default);
client.Publish("/RoboNUC/Netduino/ImuData", System.Text.Encoding.UTF8.GetBytes(json));
lastTick = thisTick;
System.Threading.Thread.Sleep(35); // + 3 X 5 ms = 50ms sleep total = approx 20hz
}
}
Thanks for you detailed reply, I also have a class similar to yours which provides for access to >1 I2C devices on the same bus. (In my sample code I'm using just the I2C API with no wrappers)
My issue is that with 4.3.1 (on my NP2 hardware) I can't read data from the ADXL345 (it is the only device connected).
When I disconnect the ADXL345 and connect a DS1307 in its place I can read data just fine.
The same C# code when used in an NP1 (only the "using" statement changed from .Netduino to .NetduinoPlus) can read from the ADXL345.
The same NP2 and ADXL345 worked fine with a previous version of NetMF 4.2.x
Dang, I looked at your code and totally missed your commenting system, my bad.
In that case you are missing some needed, I call it coffee code;
// required i2c kick
OutputPort p = new OutputPort(Pins.GPIO_PIN_SDA, true); p.Write(false); p.Dispose();
throw that near the beginning of main.
I am also using the ADXL345, on a 9DoF board. I seemed to remember not getting anything out of it without sending some config to the device - and you do not appear to have any (not totally sure, it was one of the devices, but memory on which one isnt quite 100%)
I'm not sure why your one device works without 'coffee', at least its worth a try.
using( OutputPort i2cPort = new OutputPort(Pins.GPIO_PIN_SDA, true))
{
i2cPort.Write(false);
}
which achieves the same thing.
I went back thru source control history and repeated all the options I had explored. The coffee code was one of the earlier options I tried, must have been something else going on at that stage.
You can read the deviceID from an ADXL345 without any setup