New ED Tracker Sketch


User-set values are now at the top of the sketch after the copyright comments etc.

There is now an option (thanks Dan!) to have an exponential response curve for head movement rather than linear.

Uncomment #define EXPONENTIAL to enable it, e.g.



Step one

Lines 50 to 52 –  ensure the Drift Compensation values are all 0.0

    float xDriftComp =0.0;
    float yDriftComp =0.0;
    float zDriftComp =0.0;

Step 2

uncomment the DEBUGOUTPUT line;

    //comment this in if you want so see output to the serial monitor
    #define DEBUGOUTPUT 1

If you have already performed a full calibration skip to step 4

Step 3
Place the ED Tracker with the sensor as horizontal and as still as possible.
Load the Sketch and open the Serial Monitor (ctrl-shift-m)
When you see the word ‘Settling’ scrolling past press the re-calibration button briefly.
After 15 seconds or so you should see the code enter full calibration mode.
This may take several minutes to complete.  The new offsets will be stored in EEPROM and in use.

Step 4
Load the Sketch (with debug still enabled) and open the again.
After 15 seconds you should start to see x/y/z values and drift value being output every second.
Keeping the sensor stationary, press the recalibrate button. Wait 10 seconds. Press it again.

X/Y/Z 1.59 2.86 -5.24 -1.29 -0.4 0.11
X/Y/Z 1.1 4.16 -7.75 -1.26 -0.16 0.14
X/Y/Z   0.58   6.68   -7.69   -1.28   -0.74   0.19
X/Y/Z   1.4     5.41   -7.72   -1.28   -0.65   0.29
X/Y/Z   2.15   6.65   -6.4     -1.27   -0.17   0.15

Allow these value to settle for 5-10 minutes. The fourth number along is yaw drift and should be between -10 and 10.
Take this drift value and set the xDriftComp at line 50 of the sketch, e.g.

float xDriftComp =-1.27;

Step 5.

Turn debug output off;

//#define DEBUGOUTPUT 1

Load the sketch and configure head look toggle and head look axis in the game config settings menu.


At any time you can reset the view by looking straight ahead and pressing the recalibrate button. It only takes 2 seconds to adjust and you should only need to do this at most every 15 minutes and if you’re lucky, every hour.

It’s best to be wearing the ED Tracker when you plug it in but you should keep still, looking ahead, for the 1st 15 seconds while it calibrates. The red led flashes quickly during the initial ‘keep it still’ calibration phase and then slowly (3 times per second) when the device is running normally.

Alternatively if you have it taped to headphone you can place them across your knee or simply hold them steady. The MPU-6050 needs 10-15s to stabilise it’s output and too much movement during this initial phase can cause drift or worse, bouncy axis syndrome.

A good way to play with scaling value in the code is to keep Elite Dangerous running and alt-tab back to the Arduino IDE. You can edit the sketch, re-upload, and back into the game to test the changes. No need to quit or rebind controls.

There are bugs in the code. Please feedback any issues you have so I can fix them 🙂






MPU-6050 Yaw Drift and how to combat

I’m using the MPU-6050 in DMP mode to fuse the gyro and accelerometer data into a single quaternion value representing the orienation of the sensor.  No matter how well calibrated the device is , there will always be some yaw drift. Gravity provides a partial frame of reference so the sensor know which way is down and can accuranty determine pitch and roll.  But yaw has no fixed reference point and tends to drift.

There are multiple ways to combat yaw drift.  A  magnetometer (compass) can be used but that comes with it’s own calibration issues, which is they route Occulus Rift have taken. The newer MPU-9150 chip combines a magnetometer with the existing sensors and there are plenty of alogrithms out there in the wild which will fuse all three sets of data together to provide drift free output.

Another option is to measure the drift over a number of minutes and see how it behaves. This is what I did;


The graph shows yaw output over time. At two points I moved the sensor around to detemine if the yaw value returned to where it should be and also to see if drift rate was effected.  You can see that firstly the yaw value generated by DMP returned to it’s original value (allowing for drift) after movement and also that the rate of drift is constant.

This allows a simple ‘yaw drift compensation’ approach to be implemented in code. If the average yaw drift rate is 0.12 units every  second then simply accumulate this as a growing offset which you apply to the DMP yaw value.  In my code I update the drift offset every second.

float driftComp = 0.00; // more +ve number makes drift more -ve
void loop()

if (now > lastUpdate) {
     lastUpdate = now+ 1000;
     driftOffset += driftComp;

It’s simple and work suprisingly well.

Rob J