Speed testing the MPU9150’s functions using a LinkIt ONE

Standard

Background

I am working on a project where I am gathering a lot of data. One of the sources of my data is my 9Dof sensor. Since I am logging at sub-second intervals, I wanted to know how long (the cost of time) each sensor takes to return data, so I make sure to get as many data points, from as many data sources as possible.

I set up this project with the sole intention of determining the cost in milliseconds of the standard example, then try to figure out how to make it faster.

Setup

I grabbed my trusty LinkIt ONE and my 9Dof sensor (MPU9150, connecting over I2C), and looked at the example library. I wanted to get data from each of the sensors as fast as possible, and I will do post-capture processing for heading and orientation. I set my sights on these three programs:

  • getAccel_Data
  • getGyro_Data
  • getCompass_Data

I then made blocks of C to run in a loop:

Serial.print(millis() % 1000);
Serial.print(",Acc1,");
getAccel_Data();
Serial.print(Axyz[0]);
Serial.print(",");
Serial.print(Axyz[1]);
Serial.print(",");
Serial.print(Axyz[2]);
Serial.print(",");
Serial.println(millis() % 1000);


This is my code for checking a single Accelerometer data gathering. I figured all I had to do is try running the same block, with additional runs of “getAccel_Data;” and notations of “”Acc_” so I can to comparisons afterwards. I then take the time difference between the start and end and map it to the sensor read type, and the sensor read count. After that, I subtract the time of the single run to the double and triple run to find how much longer it took for the one or two additional runs.

Accelerometer Tests

Let’s have a look at one set of my results (do note, time is in milliseconds, 1/1000th of a second):

Row Labels Average of Runtime StdDev of Runtime
Acc1 23.307 2.230
Acc2 45.701 3.985
Acc3 68.123 6.254

First thing I see here is that 23.3 + 45.7 does not equal 68.1. This is good, this is what I expect, and am glad to see. My formula for calculating the actual average runtime of getAccel_Data is as follows:

( (Acc2 – Acc1) + (Acc3 – Acc1) ) / 3

This is set up to give a double weight to the difference between Acc3 and Acc1, since there was an additional run compared to Acc2 to Acc1.

Testing All Sensors

I created a few sets of functions besides the stock ones to test out.

  • getAccelGyro_Data: Combined getAccel_Data and getGyro_data, eliminating duplicate runs of accelgyro.getMotion9
  • getDof_Data: Combines getAccelGyro_Data and getCompass_Data
  • getRawDof_Data: getDof_Data without the calculations, just raw values

Ultimately, I let my computer run, and I got 4600 records for each set of sensors. Here’s my results:

Runtime
Function Runs/cycle Average StdDev
getAccel 1 23.307 2.230
getAccel 2 45.701 3.985
getAccel 3 68.123 6.254
getAccelGyro 1 23.364 1.998
getAccelGyro 2 45.844 3.899
getAccelGyro 3 68.235 6.166
getGyro 1 23.303 2.005
getGyro 2 45.729 3.924
getGyro 3 68.192 6.200
getCompass 1 11.231 2.411
getCompass 2 21.774 4.139
getCompass 3 32.368 6.095
getDof 1 33.926 3.493
getDof 2 66.875 7.062
getDof 3 99.803 10.856
getRawDof 1 33.945 3.418
getRawDof 2 66.967 7.083
getRawDof 3 99.951 10.899

From this, I calculated the following:

Function Actual Cycle Cost Overhead Cost
getAccel 22.4038 0.8983
getGyro 22.4380 0.8591
getCompass 10.5597 0.6631
getAccelGyro 22.4504 0.9287
getDof 32.9420 0.9872
getRawDof 33.0094 0.9418

Conclusion

  1. The library should not have “getAccel_data” and “getGyro_data”, rather just combine the two together for optimal performance.
  2. Also, when we look at the ‘getDof” vs. “getRawDof”, by saving the larger values instead of reducing their size before saving, it actually costs time. About 0.0674 milliseconds per cycle.
  3. You save 22.4596 milliseconds per cycle by combining gathering the sensor data into one procedure.
  4. You save 0.0681 milliseconds by running “getDof_data” instead of “getAccelGyro_data” and then “getCompass”.
Advertisements

Running a Xadow OLED with an Arduino UNO

Standard

Background

I have a number of the Xadow modules, and the one that intrigued me the most, was the breakout. It converts the pins in the Xadow ribbon to wire-able connections. I wondered if I could use this to drive Xadow modules instead of drive non-Xadow units.

Wiring

Well, I have been doing some work on the Xadow OLED screen, and figured that would be a fun demo to start with. Looking at the Pinout of the wires, I determined that the voltage should be 3.3v.

Xadow_Breakout_01[1]I connected to the I2C connection in the middle, since the OLED screen was commanded over the I2C. I had 4 pins to connect. Using this diagram, I found where I needed to connect to:

ArduinoUno_R3_Pinouts[1]

SCL: A5

SDA: A4

V: 3.3v power

G: Ground

Code

I used the stock Xadow OLED “Hello World” demo. Absolutely no adjustments. None. And by golly, it worked.

wpid-20150507_125413.jpgThe pin spacing on the internal connections on the breakout board were not the standard spacing, so I had to hold it. I plan to solder some wire on for a permanent Arduino to Xadow connection in the near future.

Wrap up

Thanks all for reading this. I wanted to show off that this is possible, and I hope that I can work with Seeed to make a Xadow to breadboard breakout for much easier prototyping and bridging. This also brings up the major possibility of using an Arduino for the coding, and having the Xadow units be clean hardware extensions. You would only need to switch over to the Xadow mainboards when you needed the smaller size.