Hello to all and thank you for any advices in advance.
I am attempting to pull 510 bytes from FIFO buffer of MPU9250 sensor. I know from its datasheet that it is capable of comunicating up to 20MHz. I am using Arduino Uno so max. SPI speed is 8MHz for me. But from my calculations transfering 510 bytes from FIFO shoul take:
(1/8000000)*510 = 63 microsec. but from my measurement which is illustrated in the code below I get 1124 microsec. So I tried different speeds and none was right. Here is a table
SPI spd| usec | real calculated Freq.
1Mhz | 4700 | 108510
2MHz | 2656 | 192018
4MHz | 1636 | 311735
8MHz | 1124 | 453736
16MHz| 1132 | 450530
I Tried even 16MHz just for fun. I just do not know how it is possible that the transfer speeds are so slow??
Any Help apprecitated.
Thank you very much
P.S.: The code is not complete, there are a lot of variables unused because it is part of bigger program witch does not affect this issue and would only cluter the code more. But all used methodes are declared and defined. The program jst waits until the sensor has 510 bytes in buffer and I am very sure they are really there when beginning the transfer. Then e just attemt to transfer them to our array... and that takes that long..
#include "SPI.h"
#include "MPU9250.h"
// pins
byte CS_PIN = 3;
//Flags
byte READ_FLAG = 0x80;
//SRAM
byte SRAM_CS_PINS[] = {4,5,7,6};
byte numOfSrams = sizeof(SRAM_CS_PINS);
byte SRAM_READ = 0x03;
byte SRAM_WRITE = 0x02;
//SRAM register addresses
byte RDMODE = 0x05;
byte WTMODE = 0x01;
//SRAM config values
uint32_t SPISPEED = 8000000;
byte PAGEMODE = 0x80;
byte SEQMODE = 0x40;
byte BYTEMODE = 0;
//SRAM variables
byte currentSram;
byte sramData[32];
byte in[1];
byte sramAddress[4];
byte byteArray[4];
uint32_t lastAddress = 0x1FFFF;
//Registers
byte CONFIG = 0x1A;
byte ACCEL_CONF_2 = 0x1D;
byte WHO_AM_I = 0x75;
byte USER_CTRL = 0x6A;
byte INT_PIN = 0x37;
byte PWR_MGMT_2 = 0x6C;
byte SAMPLE_DIV = 0x19;
// FIFO registers
byte FIFO_EN = 0x23;
byte FIFO_COUNTH = 0x72; // first read High bits it latches low bits for read
byte FIFO_COUNTL = 0x73;
byte FIFO_R_W = 0x74;
byte FIFO_MODE = 0x1A;
//Register Vals.
byte ACCEL_FCHOICE_B = 0x08;
byte I2C_IF_DIS = 0x10;
byte BYPASS_EN = 0x02;
byte LN_MODE = 0x07;
byte F_5HZ = 0xC7;
byte F_10HZ = 0x63;
byte F_100HZ = 0x09;
// FIFO register vals.
byte FIFO_ACCEL = 0x08;
byte FIFO_NO = 0;
//variables
uint32_t sramCurrentAddress = 0;
uint16_t currentFifoByteCount = 0;
uint16_t savedFifoByteCount = 0;
int16_t fifoState;
int16_t x,y,z;
int32_t spi_low_speed = 1000000;
int32_t spi_high_speed = 8000000;
int status;
bool fifoFlag = false;
bool saveDataFlag = false;
bool newFifoDataFlag = false;
bool sramFullFlag = false;
// buffers
int8_t regData[2];
int8_t data[7];
byte fifoDataBuffer[510];
int16_t accel[3];
byte fifoLoadedData[6];
byte byteSizedData[10];
byte byteSizedAnalogData[10];
byte byteSizedLoadedData[10];
uint32_t t;
uint16_t samplesCount = 0;
int T = 500;
bool timerFlag = false;
int32_t t_old, t_new;
int16_t analogX,analogY,analogZ;
int16_t q = 1;
// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250 IMU(SPI,CS_PIN);
void setup(){
SPI.begin();
Serial.begin(1000000); // So it is able to transfer 4000*3*16 = 192 000 bit/s
status = IMU.mybegin();
if (status < 0) {
Serial.println(F("IMU initialization unsuccessful"));
Serial.println(F("Check IMU wiring or try cycling power"));
Serial.print(F("Status: "));
Serial.println(status);
while(1) {}
}
// resetting FIFO to empty at the beginning
// fifoReset();
Serial.println(F("Start"));
}
void loop(){
// checks how many bytes are in FIFO buffer
byte hbyte,lbyte;
int16_t count;
readRegister(FIFO_COUNTH,1,&hbyte,1000000);
readRegister(FIFO_COUNTL,1,&lbyte,1000000);
count = hbyte << 8 | lbyte;
currentFifoByteCount = count;
// sets flag when 510 bytes are present in FIFO
if(savedFifoByteCount < currentFifoByteCount){
savedFifoByteCount = currentFifoByteCount;
if (currentFifoByteCount == 510){
newFifoDataFlag = true;
}
}
if (newFifoDataFlag){
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE3));
digitalWrite(CS_PIN,LOW); // select the MPU9250 chip
SPI.transfer(FIFO_R_W | 0x80); // specify the starting register address
t_old = micros();
for(uint16_t i = 0; i < 510; i++){
fifoDataBuffer[i] = SPI.transfer(0x00); // read the data
}
t_new = micros() - t_old;
digitalWrite(CS_PIN,HIGH); // deselect the MPU9250 chip
SPI.endTransaction(); // end the transaction
Serial.println(t_new);
while(1);
}
}
int readRegister(uint8_t subAddress, uint16_t count, uint8_t* dest, int32_t spi_speed){
SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3));
digitalWrite(CS_PIN,LOW); // select the MPU9250 chip
SPI.transfer(subAddress | 0x80); // specify the starting register address
for(uint16_t i = 0; i < count; i++){
dest[i] = SPI.transfer(0x00); // read the data
}
digitalWrite(CS_PIN,HIGH); // deselect the MPU9250 chip
SPI.endTransaction(); // end the transaction
return 1;
}
int writeRegister(uint8_t subAddress, uint8_t data, int32_t spi_speed){
/* write data to device */
SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3)); // begin the transaction
digitalWrite(CS_PIN,LOW); // select the MPU9250 chip
SPI.transfer(subAddress); // write the register address
SPI.transfer(data); // write the data
digitalWrite(CS_PIN,HIGH); // deselect the MPU9250 chip
SPI.endTransaction(); // end the transaction
// Now test if write was succesfull
delayMicroseconds(10);
byte writtenData;
/* read back the register */
readRegister(subAddress,1,writtenData,spi_speed);
/* check the read back register against the written register */
if(writtenData == data) {
return 1;
}
else{
return -1;
}
}