Teensy 4.0 Clock speed influences delay and SPI

So i also gave it a try over i2c and it works but the wrong values are still there if i enable the accel, gyro and mag at the same time, thats when i get over 100m/s. The delay seems to work though. As far as i know the FIFO only contains 26 samples because thats the max value when all sensors (except temperature) are enabled.

Code:
The FIFO buffer is 26 samples long.

-110.306496	-42.896702	90.696983

123.820053	-31.878025	-154.453033

123.820053	-31.878025	-154.453033

123.820053	-31.878025	-154.453033

123.820053	-31.878025	-154.453033

123.820053	-31.878025	-154.453033

122.594162	-40.459282	-153.227142

122.594162	-40.459282	-153.227142

122.594162	-40.459282	-153.227142

122.594162	-40.459282	-153.227142

122.594162	-40.459282	-153.227142

122.594162	-40.459282	-153.227142

122.594162	-40.459282	-155.678925

122.594162	-40.459282	-155.678925

122.594162	-40.459282	-155.678925

122.594162	-40.459282	-155.678925

122.594162	-40.459282	-155.678925

122.594162	-40.459282	-155.678925

122.594162	-40.459282	-155.678925

116.464691	-36.781601	154.472183

116.464691	-36.781601	154.472183

116.464691	-36.781601	154.472183

116.464691	-36.781601	154.472183

116.464691	-36.781601	154.472183

116.464691	-36.781601	154.472183

126.271843	-39.233387	-156.904816
 
That makes sense there was a rogue clock driving the system. Does that change the power use at 24 MHz?

OK i think i mixed two different CoreMark sketches. Re-running with Paul's CoreMark -O3 @24mhz, on 1.48 I get 98.77 iterations/sec and 34.44 ma. With 1.49-beta3, I get 98.75 iterations/sec and 33.95 ma. Little difference.

Code:
                  1.48                1.49-beta3
            600   2476.88 104.4 ma  2476.47      104.1 ma
            528   2179.6   84.8     2179.12       84.1
            450   1857.59  79.8     1857.24       79.3 ma
            396   1634.52  75 ma    1634.39       73.4 ma
            150    623.9   51.6      623.79       51.2
             24     98.77  34.44      98.75       33.95 ma
 
Last edited:
but the wrong values are still there if i enable the accel, gyro and mag at the same time, thats when i get over 100m/s.

I'm really glad you spent some time to test. But I'm hoping you can help us just a bit more. When you find a case like this which doesn't work, please post the complete code so anyone reading can just copy it into Arduino and if they have the same hardware, get the same wrong result. Yes, I know this takes a little longer and it may seem redundant. Sometimes the code changes seem trivial. But please, consider how hard this work is, to find and fix these sorts of difficult problems. Please, help us to save a little time and improve the changes we'll actually find the problem. Give us the exact (and complete) program you used, and any other necessary info, so anyone reading your message can copy it into Arduino and reproduce the exact same problem you saw, without any guesswork.
 
Sorry about that. When i test it over the SPI i change the constructor to: MPU9250FIFO IMU(SPI, 33);
Ive tested it with pin 10 as SS but it makes no difference.


Code:
#include "MPU9250.h"

// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250FIFO IMU(Wire, 0x68);
int status;

// variables to hold FIFO data, these need to be large enough to hold the data
float ax[100], ay[100], az[100];
size_t fifoSize;

void setup() {
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}

  // start communication with IMU 
  status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: ");
    Serial.println(status);
    while(1) {}
  }
  // setting DLPF bandwidth to 20 Hz
  IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_20HZ);
  // setting SRD to 19 for a 50 Hz update rate
  IMU.setSrd(19);
  // enabling the FIFO to record just the accelerometers
  IMU.enableFifo(true,true,true,false); //############ changing this causes the errors. in the original sketch its: IMU.enableFifo(true,false,false,false);.
  // gather 50 samples of data
  delay(980);
  // read the fifo buffer from the IMU
  IMU.readFifo();
  // get the X, Y, and Z accelerometer data and their size
  IMU.getFifoAccelX_mss(&fifoSize,ax);
  IMU.getFifoAccelY_mss(&fifoSize,ay);
  IMU.getFifoAccelZ_mss(&fifoSize,az);
  // print the data
  Serial.print("The FIFO buffer is ");
  Serial.print(fifoSize);
  Serial.println(" samples long.");
  for (size_t i=0; i < fifoSize; i++) {
    Serial.print(ax[i],6);
    Serial.print("\t");
    Serial.print(ay[i],6);
    Serial.print("\t");
    Serial.println(az[i],6);
  }
}

void loop() {}
 
So i also gave it a try over i2c and it works but the wrong values are still there if i enable the accel, gyro and mag at the same time, thats when i get over 100m/s. The delay seems to work though. As far as i know the FIFO only contains 26 samples because thats the max value when all sensors (except temperature) are enabled.

Code:
The FIFO buffer is 26 samples long.
...
Just ran it myself with accel, gyro and mag enabled and getting numbers like you are. If you enable just accel and gryo it does get better:
Code:
The FIFO buffer is 42 samples long.
0.474076	10.056160	-0.478865
0.440556	10.070525	-0.526751
0.507597	10.051371	-0.526751
but it looks like its flipping axes. Which is strange.

To be honest this is now an issue with FIFO function itself that you might be better off to ask bolderflight or @brtaylor.
 
Two quick questions

1: Does the problem happen only when Teensy 4.0 runs at 24 MHz? Is there reason to believe it's a bug in Teensy's core lib or SPI or Wire lib? (rather than a bug in the sensor lib)

2: Is this SPI or I2C? The code in msg #32 sure looks like it's using Wire.
 
To be honest this is now an issue with FIFO function itself that you might be better off to ask bolderflight or @brtaylor.

I hooked up sparkfun MPU9250 to T3.6 I2C and ran your sketch. with just accel enabled IMU.enableFifo(true,false,false,false); i get
0.143659 0.325628 -9.620393
0.148448 0.335205 -9.629970
0.148448 0.335205 -9.644336
with IMU.enableFifo(true,true,true,false); i get
42.939800 87.038452 41.685177
39.262119 85.812561 33.103920
35.584438 84.586670 41.685177

so it doesn't seem to be specific to T4. so likely a brtaylor problem.
 
Last edited:
I hooked up sparkfun MPU9250 to T3.6 I2C and ran your sketch. with just accel enabled IMU.enableFifo(true,false,false,false); i get
0.143659 0.325628 -9.620393
0.148448 0.335205 -9.629970
0.148448 0.335205 -9.644336
with IMU.enableFifo(true,true,true,false); i get
42.939800 87.038452 41.685177
39.262119 85.812561 33.103920
35.584438 84.586670 41.685177

so it doesn't seem to be specific to T4. so likely a brtaylor problem.

@manitou
Thanks for checking with the T3.6. I agree that its a brtaylor issue with the bolderflight library. In all our testing with his library we never used the FIFO functionality. Without FIFO it does return the correct values.
 
Thanks to everyone who helped. But the last problem is the when using the SPI bus.
When running the code at 150 mhz everything is fine. Then switching to 600mhz the .begin function is giving me an error (-2) and at 24mhz the program seems to freeze inside the .begin function.
Running the exact same code (except for changing the contructor so it uses the i2c bus) it runs on all frequencies without any problems.

Code:
#include "MPU9250.h"

// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250FIFO IMU(SPI, 33); // changed this to MPU9250FIFO IMU(Wire, 0x68); to use i2c Bus
int status;

// variables to hold FIFO data, these need to be large enough to hold the data
float ax[100], ay[100], az[100];
size_t fifoSize;

void setup() {
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}

  // start communication with IMU 
  Serial.println("Attempting to initialize...");
  status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: ");
    Serial.println(status);
    while(1) {}
  } else {
    Serial.println("Initialization was successful");
  }
  // setting DLPF bandwidth to 20 Hz
  IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_20HZ);
  // setting SRD to 19 for a 50 Hz update rate
  IMU.setSrd(19);
  // enabling the FIFO to record just the accelerometers
  IMU.enableFifo(true,false,false,false); //############ changing this causes the errors. in the original sketch its: IMU.enableFifo(true,false,false,false);.
  // gather 50 samples of data
  delay(980);
  // read the fifo buffer from the IMU
  IMU.readFifo();
  // get the X, Y, and Z accelerometer data and their size
  IMU.getFifoAccelX_mss(&fifoSize,ax);
  IMU.getFifoAccelY_mss(&fifoSize,ay);
  IMU.getFifoAccelZ_mss(&fifoSize,az);
  // print the data
  Serial.print("The FIFO buffer is ");
  Serial.print(fifoSize);
  Serial.println(" samples long.");
  for (size_t i=0; i < fifoSize; i++) {
    Serial.print(ax[i],6);
    Serial.print("\t");
    Serial.print(ay[i],6);
    Serial.print("\t");
    Serial.println(az[i],6);
  }
}

void loop() {}


Using the SPI bus isnt critical for my project, but i wanted to use it for the speed in order to get values from the gyro at 4 or 8khz for an autonomous drone. But i2c doesnt leave the proccessor much time to do other things.
 
Thanks to everyone who helped. But the last problem is the when using the SPI bus.
When running the code at 150 mhz everything is fine. Then switching to 600mhz the .begin function is giving me an error (-2) and at 24mhz the program seems to freeze inside the .begin function.
Running the exact same code (except for changing the contructor so it uses the i2c bus) it runs on all frequencies without any problems.

,,,,,,


Using the SPI bus isnt critical for my project, but i wanted to use it for the speed in order to get values from the gyro at 4 or 8khz for an autonomous drone. But i2c doesnt leave the proccessor much time to do other things.

I will confirm the issue with the 9250 above 150Mhz.. I did get it to work at 396Mhz by adding delay(1) after the writeReg's or readregs in the begin function for the MPU-9250. However above that the issue seems to be with reading the AK8963 whoiam register - always returns error. The communication with the Mag is over the internal i2c bus of the 9250 at 400Khz which does say it is initialized. Why the 8963 is failing a this point I don't know. I did try to adjust spi speeds in the .h but no luck. Just keeps getting stuck there.

EDIT: I just tested an unmodified version on the T3.6 at 250Mz and it did work.
 
Last edited:
mjs513 tests are getting close -- T4 "too fast", delays needed. My MPU9250 is soldered to I2C, so I can't test the sketch. I ran simple SPI loopback tests on T4 with both 1.48 and 1.49-beta3 and SPI CLK at either 1MHz or 15MHz (that's what used by MPU9250 lib). All is good at 600mhz and 150 mhz. For 1.48, actual data rate for 15mhz test is 11.82 mbs (SPI CCR is 12.6mhz). For 1.49-beta3 data rate is 14.77mbs (CCR is 15 mhz). At 24mhz, SPI@15mhz only provides 4.77 mbs, but loopback is working.
 
Thanks to everyone who helped. But the last problem is the when using the SPI bus.
When running the code at 150 mhz everything is fine. Then switching to 600mhz the .begin function is giving me an error (-2) and at 24mhz the program seems to freeze inside the .begin function.
Running the exact same code (except for changing the contructor so it uses the i2c bus) it runs on all frequencies without any problems.

Code:
#include "MPU9250.h"

// an MPU9250 object with the MPU-9250 sensor on SPI bus 0 and chip select pin 10
MPU9250FIFO IMU(SPI, 33); // changed this to MPU9250FIFO IMU(Wire, 0x68); to use i2c Bus
int status;

// variables to hold FIFO data, these need to be large enough to hold the data
float ax[100], ay[100], az[100];
size_t fifoSize;

void setup() {
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}

  // start communication with IMU 
  Serial.println("Attempting to initialize...");
  status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: ");
    Serial.println(status);
    while(1) {}
  } else {
    Serial.println("Initialization was successful");
  }
  // setting DLPF bandwidth to 20 Hz
  IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_20HZ);
  // setting SRD to 19 for a 50 Hz update rate
  IMU.setSrd(19);
  // enabling the FIFO to record just the accelerometers
  IMU.enableFifo(true,false,false,false); //############ changing this causes the errors. in the original sketch its: IMU.enableFifo(true,false,false,false);.
  // gather 50 samples of data
  delay(980);
  // read the fifo buffer from the IMU
  IMU.readFifo();
  // get the X, Y, and Z accelerometer data and their size
  IMU.getFifoAccelX_mss(&fifoSize,ax);
  IMU.getFifoAccelY_mss(&fifoSize,ay);
  IMU.getFifoAccelZ_mss(&fifoSize,az);
  // print the data
  Serial.print("The FIFO buffer is ");
  Serial.print(fifoSize);
  Serial.println(" samples long.");
  for (size_t i=0; i < fifoSize; i++) {
    Serial.print(ax[i],6);
    Serial.print("\t");
    Serial.print(ay[i],6);
    Serial.print("\t");
    Serial.println(az[i],6);
  }
}

void loop() {}


Using the SPI bus isnt critical for my project, but i wanted to use it for the speed in order to get values from the gyro at 4 or 8khz for an autonomous drone. But i2c doesnt leave the proccessor much time to do other things.

Yes,
Now Looks like Delay problem has been fixed. But still SPI is not working same with all CPU Speed. 24MHz it just stuck in begin itself. I will test with MPU as well and update here.
 
mjs513 tests are getting close -- T4 "too fast", delays needed. My MPU9250 is soldered to I2C, so I can't test the sketch. I ran simple SPI loopback tests on T4 with both 1.48 and 1.49-beta3 and SPI CLK at either 1MHz or 15MHz (that's what used by MPU9250 lib). All is good at 600mhz and 150 mhz. For 1.48, actual data rate for 15mhz test is 11.82 mbs (SPI CCR is 12.6mhz). For 1.49-beta3 data rate is 14.77mbs (CCR is 15 mhz). At 24mhz, SPI@15mhz only provides 4.77 mbs, but loopback is working.

@manitou - @chrissteffen
Thanks - figured it out after you I read you post. Did something I had to done for Arducam when I was using SPI. Modified readReadReg and writeRegs and added a 500nanosecond delay after cs_low and cs_high and used digitalwritefast. Now it works at 600Mhz.

Here is the new .cpp file if you want to give it a try.

EDIT: PLease NOTE that this will only work for the T4 - don't try it with the T3x or anyother board.
 

Attachments

  • MPU9250.zip
    6.8 KB · Views: 66
@manitou - @chrissteffen

Made a slight change to delayNanoseconds: went from 500 to 250 and still works. Unfortunately @24Mhz does not work, works from 150 to 600Mhz. @24Mhz seems problematic for some reason.
 
@manitou - @chrissteffen - @PaulStoffregen

I added code to change the arm clock to 30mhz within the sketch and the MPU-9250 started working in SPI mode:
Code:
0.129293	0.938575	-10.056160	0.000714	-0.001918	-0.004677	4.068265	11.217307	-9.064278	25.885136
0.134082	0.924209	-10.046582	-0.000218	-0.001918	-0.002546	2.830098	13.175885	-8.893254	25.870159
0.138871	0.938575	-10.046582	0.000714	-0.001252	-0.003744	2.830098	13.175885	-8.893254	25.873154
It will even work at 25Mhz but just not at 24Mhz. Just out of curiosity I tried 24.5Mhz:
Code:
0.086196	1.015193	-10.037005	0.001008	0.001204	-0.000886	5.306433	8.902625	-8.209158	25.966005
0.071830	1.029559	-10.056160	0.000342	0.000671	0.000446	6.367720	9.614835	-7.183013	25.969000
0.076618	1.039137	-10.037005	0.000475	0.001736	-0.000752	6.013958	8.902625	-8.209158	25.971996
0.071830	1.034348	-10.037005	0.000209	0.001736	0.000979	6.013958	8.902625	-8.209158	25.963009

So something strange is going on at 24Mhz. Not sure if its the MPU-9250 or the T4 SPI?
 
@mjs513 and others - Not sure if I can help here or not? I am not sure I have an MPU-9250 and if I did where it might be hiding?

I personally have not done much testing at other clock speeds, especially really slow speeds... I wonder if some issue of PLL3/PFD0?
Have you tried changing SPI back to PLL2 and see if that makes any differences?

I assume you have looked at the signals coming out of SPI to see what their speeds are?
 
@manitou - @chrissteffen
Thanks - figured it out after you I read you post. Did something I had to done for Arducam when I was using SPI. Modified readReadReg and writeRegs and added a 500nanosecond delay after cs_low and cs_high and used digitalwritefast. Now it works at 600Mhz.

Here is the new .cpp file if you want to give it a try.

EDIT: PLease NOTE that this will only work for the T4 - don't try it with the T3x or anyother board.

Looks like this modification is working. I started observing data is changing for all 9 DOF. Not sure along with this fix we need 1.49 Beta#3 or 1.48 is also good enough to go with this fix.
 
@mjs513 and others - Not sure if I can help here or not? I am not sure I have an MPU-9250 and if I did where it might be hiding?

I personally have not done much testing at other clock speeds, especially really slow speeds... I wonder if some issue of PLL3/PFD0?
Have you tried changing SPI back to PLL2 and see if that makes any differences?

I assume you have looked at the signals coming out of SPI to see what their speeds are?

@KurtE - @PaulStoffregen
Just changed
Code:
CCM_CBCMR_LPSPI_PODF(2) | CCM_CBCMR_LPSPI_CLK_SEL(1); // pg 714
to
Code:
CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714
and that fixed the issue at 24Mhz. With that change it runs at all available clock speeds. Still need the other modifications for delayNanoseconds and digitalwritefast. So do we recommend changing back?

Check https://forum.pjrc.com/threads/5868...-delay-and-SPI?p=224094&viewfull=1#post224094, @manitou did some testing.
 
Looks like this modification is working. I started observing data is changing for all 9 DOF. Not sure along with this fix we need 1.49 Beta#3 or 1.48 is also good enough to go with this fix.

All my testing is being done with 1.49 Beta#3 since it has the fix for millis to work correctly and the latest SPI changes. Please not that this may not the final form for the change to library on GitHub. Will have to do an additional testing and propose a change to @brtaylor for incorporation into his lib.
 
@chrissteffen - @HallMark - @KurtE - @manitou

Broke the code on getting fifo to work. Here is summary what you are able to do with fifo and its very dependent on what you select to go into the fifo, the more you data you select to go into the FIFO the less max samples you are going to get - note only tested at 600Mhz and using I2C instead of SPI:

Code:
  //gather 50 samples at 980ms for accel

  //gather 50 samples at 980ms for accel/temp

  // gather 40 samples of data @800ms for accel/gyro

  // gather 35 samples of data @700ms for accel/gyro/temp

  // gather 25 samples of data @500ms for accel/gyro/mag

  // gather 23 samples of data @450ms for accel/gyro/mag/temp
where the X-ms shown is what you use for the delay. As an example if you want accel/gyro/mag the delay would be:
delay(500); instead of delay(980);
 
Last edited:
Back
Top