Go Down

Topic: drift between millis() readings on serial monitor (Read 153 times) previous topic - next topic

inkosi

Hi.

I have a BNO 055 accelerometer used to collect linear acceleration data for a project of mine. Here is the code, mostly taken from the sample library:

Code: [Select]
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

/* This driver reads raw data from the BNO055

   Connections
   ===========
   Connect SCL to analog 5
   Connect SDA to analog 4
   Connect VDD to 3.3V DC
   Connect GROUND to common ground

   History
   =======
   2015/MAR/03  - First release (KTOWN)
*/

/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (20)

Adafruit_BNO055 bno = Adafruit_BNO055();

/**************************************************************************/
/*
    Arduino setup function (automatically called at startup)
*/
/**************************************************************************/
void setup(void)
{
  Serial.begin(9600);
  Serial.println("Orientation Sensor Raw Data Test"); Serial.println("");

  /* Initialise the sensor */
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }

  delay(1000);

  /* Display the current temperature */
  int8_t temp = bno.getTemp();
  Serial.print("Current Temperature: ");
  Serial.print(temp);
  Serial.println(" C");
  Serial.println("");

  bno.setExtCrystalUse(true);

  Serial.println("Calibration status values: 0=uncalibrated, 3=fully calibrated");
}

/**************************************************************************/
/*
    Arduino loop function, called once 'setup' is complete (your own code
    should go here)
*/
/**************************************************************************/
void loop(void)
{
  // Possible vector values can be:
  // - VECTOR_ACCELEROMETER - m/s^2
  // - VECTOR_MAGNETOMETER  - uT
  // - VECTOR_GYROSCOPE     - rad/s
  // - VECTOR_EULER         - degrees
  // - VECTOR_LINEARACCEL   - m/s^2
  // - VECTOR_GRAVITY       - m/s^2
  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_GRAVITY);
  imu::Vector<3> euler2 = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
 
  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(euler.x());
  Serial.print(" Y: ");
  Serial.print(euler.y());
  Serial.print(" Z: ");
  Serial.print(euler.z());
  Serial.print(" ");
    Serial.print(millis());
  Serial.println("\t\t");
  //Serial.print("\t\t");

 //   Serial.print("X: ");
//  Serial.print(euler2.x());
//  Serial.print(" Y: ");
//  Serial.print(euler2.y());
//  Serial.print(" Z: ");
//  Serial.print(euler2.z());
//  Serial.print(" ");
//  Serial.print(millis());
//  Serial.println("\t\t");

  /*
  // Quaternion data
  imu::Quaternion quat = bno.getQuat();
  Serial.print("qW: ");
  Serial.print(quat.w(), 4);
  Serial.print(" qX: ");
  Serial.print(quat.y(), 4);
  Serial.print(" qY: ");
  Serial.print(quat.x(), 4);
  Serial.print(" qZ: ");
  Serial.print(quat.z(), 4);
  Serial.print("\t\t");
  */

  /* Display calibration status for each sensor. */
  //uint8_t system, gyro, accel, mag = 0;
 // bno.getCalibration(&system, &gyro, &accel, &mag);
 // Serial.print("CALIBRATION: Sys=");
 // Serial.print(system, DEC);
 // Serial.print(" Gyro=");
 // Serial.print(gyro, DEC);
 // Serial.print(" Accel=");
//  Serial.print(accel, DEC);
 // Serial.print(" Mag=");
 // Serial.println(mag, DEC);

//  delay(BNO055_SAMPLERATE_DELAY_MS);
}


The problem is, because I integrate this data numerically, twice, to obtain displacement data I need to make sure it is accurate. The acceleration values are OK for my testing but the delta T is not constant and that's generating huge errors because I continuously integrate. For example here is a sample set of data

Code: [Select]
X: 0.94 Y: 0.14 Z: -9.75 583048
X: 0.94 Y: 0.14 Z: -9.75 583084
X: 0.94 Y: 0.14 Z: -9.75 583120
X: 0.94 Y: 0.14 Z: -9.75 583156
X: 0.94 Y: 0.14 Z: -9.75 583193
X: 0.94 Y: 0.14 Z: -9.75 583230


the delta T's between the readings are (in ms) 36, 36, 36, 37, 37. I mean the variation is usually only +/- 1 but it's significant enough to affect my results especially over a very long time.

What causes this error and how can I mitigate it? I am assuming it is something to do with the serial transmission but I'm not sure. I had the same problem with my LSM9DS0 accelerometer and the sample rates are fixed.

MarkT

Use micros(), not millis() - millis jumps by 2 occassionally and has 1ms of jitter, its not a timebase.

Call micros() at the time you sample, not in the middle of the Serial.print's, that will create
huge jitter.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up