Gyroroscope thingy not working - how to tell if its my code, or my hardware?

Hey guys!

I bought the Arduino 101 last week and have been battling with it ever since… Ive gotten as far as using the Madgwick’s algorithm calculating pitch, roll and yaw and then making it read values from the IMU and parsing/plotting the values in that wonderful serial plotter!

The ultimate goal is to make one of those ‘inverted pendulum’ 2 wheeled robots but right now im just looking at the data.
ultimately ill want this data to be in a range of 360 degrees in order to use trig functions on them(preferably -179 to 180).

My question for right now is:
I am only rotating the board by maybe 30 Degrees, and then the number hits a maximum amplitude and looks like it overflows that variable.
so Where is this limitation coming from?

Heres a pic of the plotter

Any help is GREATLY appreciated!!! :smiley:
Thanks for your time!

I have my code down here too (derived from the orientation visualizer so a few things arent needed):

#include <CurieIMU.h>
#include <MadgwickAHRS.h>

Madgwick filter; // initialise Madgwick object
int ax, ay, az;
int gx, gy, gz;
float yaw;
float pitch;
float roll;
int factor = 100; // variable by which to divide gyroscope values, used to control sensitivity
// note that an increased baud rate requires an increase in value of factor

int calibrateOffsets = 0; // int to determine whether calibration takes place or not

int ave = 0;
float Ayaw[3];
float Apitch[3];
float Aroll[3];

void setup() {
// initialize Serial communication
while (!Serial) ; 

// initialize device

if (calibrateOffsets == 1) {
  // use the code below to calibrate accel/gyro offset values
  Serial.println("Internal sensor offsets BEFORE calibration...");
  Serial.print(CurieIMU.getAccelerometerOffset(X_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(Y_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(Z_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getGyroOffset(X_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getGyroOffset(Y_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getGyroOffset(Z_AXIS)); Serial.print("\t");

  // To manually configure offset compensation values, use the following methods instead of the autoCalibrate...() methods below
  //    CurieIMU.setGyroOffset(X_AXIS, 220);
  //    CurieIMU.setGyroOffset(Y_AXIS, 76);
  //    CurieIMU.setGyroOffset(Z_AXIS, -85);
  //    CurieIMU.setAccelerometerOffset(X_AXIS, -76);
  //    CurieIMU.setAccelerometerOffset(Y_AXIS, -235);
  //    CurieIMU.setAccelerometerOffset(Z_AXIS, 168);

  //IMU device must be resting in a horizontal position for the following calibration procedure to work correctly!

  Serial.print("Starting Gyroscope calibration...");
  Serial.println(" Done");
  Serial.print("Starting Acceleration calibration...");
  CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0);
  CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 0);
  CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 1);
  Serial.println(" Done");

  Serial.println("Internal sensor offsets AFTER calibration...");
  Serial.print(CurieIMU.getAccelerometerOffset(X_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(Y_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(Z_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(X_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(Y_AXIS)); Serial.print("\t");
  Serial.print(CurieIMU.getAccelerometerOffset(Z_AXIS)); Serial.print("\t");


void loop() {
// read raw accel/gyro measurements from device
CurieIMU.readMotionSensor(ax, ay, az, gx, gy, gz); 

// use function from MagdwickAHRS.h to return quaternions
filter.updateIMU(gx / factor, gy / factor, gz / factor, ax, ay, az);

// functions to find yaw roll and pitch from quaternions

   if ( ave == 2){
    ave = 0;
    }else{  ave = ave + 1;}
  Ayaw[ave] = filter.getYaw();
  Aroll[ave] = filter.getRoll();
  Apitch[ave] = filter.getPitch();

  yaw = (Ayaw[0] + Ayaw[1] + Ayaw[2] ); ///3;
  roll = (Aroll[0] + Aroll[1] + Aroll[2] ); ///3;
  pitch = (Apitch[0] + Apitch[1] + Apitch[2] ); ///3;

    Serial.print(","); // print comma so values can be parsed
    Serial.print(","); // print comma so values can be parsed
    //Serial.print(","); // print comma so values can be parsed
    //Serial.println(ave);//for debugging

Gimbal lock?

I took some time to research and it seems that Madgwicks library should not be susceptible to this type of a problem since its based on quaternions. Thats from the wiki page on gimbal lock

All of thees spikes seem to be repeating every 6/pi or 8/pi and its in every axis, but they look a little different depending on the axis. For instance the yellow axis in that picture looks like a tangent function, and the others kind of look like sine, just as an observation.

I went ahead and plotted around 30 seconds of data from my board sitting on my desk and here is what I found.

That is an abnormal amount of sensor drift that is very consistent,
any ideas where its from?
or how to deal with it?
or if its normal?

I wont be able to utilize this board if this is normal :frowning:

Ive read about sensor drift because of no reference to zero but what im seeing would be in all axes

Has anyone ever seen anything like this
or did I get a defective board?

As an aside, I don’t know why all of my projects are filled with so many problems, but I digress

any ideas?

Could you expound upon the gimbal lock situation in case I am missing something?
I did not mean to shoot that idea down in the least!

I'm not sure what it means and to what i googled about it it seems like it gets circumvented in Madwick's so i am wondering if it applies a little differently in this case?

Thank you much for your reply!