I'm having trouble trying to sample I2C slave devices using a dsPIC33f microcontroller.
I am using the PICs internal timer1 timer to 'tick' over at a defined sampling rate and grab the necessary data. Unfortunately the results aren't being obtained fast enough and I'm not sure why. One of my slave devices is the ADXL345 accelerometer which has a maximum output data rate of 3600Hz. I don't need nearly this high, but I don't seem to be successfully sampling anywhere above around 50Hz.
The I2C is set up at 'fast mode' of 400KHz. The absolute max I would want to sample the accelerometer at is 1KHz, although this would be overkill, I'm really more interested around 128Hz. The parameters for the accelerometer that I've set are:
- Data format (0x31) - self test off, interrupt inverted off, full resolution on, justify bit off, range bit +/-16g.
- Data rate (0x2C) - low power mode off (normal mode), output data rate mode 400Hz (I have read in the datasheet that 400KHz I2C will only support as high as 800Hz, so I'm playing it safe with 400Hz).
- Power control (0x2D) - autosleep off, measurement mode on, sleep bit off, sleep mode sampling rate 8Hz (although not used, so can be ignored).
- Interrupts (0x2E) - data ready interrupt enabled, everything else off.
I'm using timer1 to sample at a specified sampling rate, I know the sampling rate is working sufficiently as I have a counter which outputs a message after the counter reaches one minute; I use a stopwatch to make sure it's right. For example, at 100Hz sampling rate I wait for the counter to count to 6,000 (100 * 60) and display a message, if the stopwatch is at 1 minute when I see that message I know it's sampling at least to some accuracy.
When I attempt to sample just from the accelerometer (I2C multiple byte read mode, read all six bytes in one call), it's not performing fast enough. Using my stopwatch method it seems to be taking about a minute and 15 seconds to do a job that should take one minute (sampling at 100Hz), i.e. it's not processing the I2C command fast enough. Higher sampling rates adds more to the delay.
I have a feeling it's something to do with the I2C clock and timer1 not being synchronised and therefore there's unnecessary waiting involved in my call for accelerometer data. I can't image that the 400KHz clock for I2C is insufficient, but please correct me if I'm wrong.
How should I be reading data from I2C slave devices correctly? I also have a gyroscope and magnetometer that I want to be reading at a sufficiently high sampling rate, the magnetometer has a limit of 160Hz, so as I say, 128Hz sampling rate would be fine for allk three devices. Trying to read from all three devices at once obviously adds to the slower than expected sampling.
I will also be collecting analogue data from 4 pins simultaneously (ADC 10bit). This code is already implemented and I can read the analogue data at 1KHz with the sampling rate working as expecting, it's just the I2C devices that are acting slow!
I would expect the accelerometer to be fine when trying to sample at 100Hz, when I can output at 3600Hz (800Hz max for I2C) but it's really struggling and I don't know what else to try.
Cheers!