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.
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:
I then made blocks of C to run in a loop:
Serial.print(millis() % 1000); Serial.print(",Acc1,"); getAccel_Data(); Serial.print(Axyz); Serial.print(","); Serial.print(Axyz); Serial.print(","); Serial.print(Axyz); 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.
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|
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:
From this, I calculated the following:
|Function||Actual Cycle Cost||Overhead Cost|
- The library should not have “getAccel_data” and “getGyro_data”, rather just combine the two together for optimal performance.
- 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.
- You save 22.4596 milliseconds per cycle by combining gathering the sensor data into one procedure.
- You save 0.0681 milliseconds by running “getDof_data” instead of “getAccelGyro_data” and then “getCompass”.