CurieIMU problems - Pitch value increases without moving the board

Hi Arduino Forum! Really hope you can help me with this, because I’m stuck! :frowning:

I am doing a project where I want to measure degrees on one axis and notify an Android application (over bluetooth) if the changes/movement exceed more than 10 degrees. For this I am using the Arduino 101 which contains all I need (IMU, Bluetooth…).

But I have a problem! I want the board to be initialized horizontal standing on the long side and then measure movement on what I believe is the z-axis/pitch.

When running the code - without moving the board - the z-value/pitch however just increasing for every loop. The results is this…, and it just keep increasing:

x_value: -0.00 y_value: 0.00 z_value: -0.01…
x_value: -0.00 y_value: 0.00 z_value: -0.02…
x_value: -0.00 y_value: 0.00 z_value: -0.03…
x_value: -0.00 y_value: 0.00 z_value: -0.04…
x_value: -0.00 y_value: 0.00 z_value: -0.06…
x_value: -0.00 y_value: 0.00 z_value: -0.07…
x_value: -0.00 y_value: 0.00 z_value: -0.08…
x_value: -0.00 y_value: 0.00 z_value: -0.09…
x_value: -0.00 y_value: 0.00 z_value: -0.10…
x_value: -0.00 y_value: 0.00 z_value: -0.11…
x_value: -0.00 y_value: 0.00 z_value: -0.12…
x_value: -0.00 y_value: 0.00 z_value: -0.13…

I have calibrated the Arduino in the following way, in order to have it initialized in the position I decribe above (horizontal standing on the long side). Is this right?

    CurieIMU.autoCalibrateAccelerometerOffset(X_AXIS, 0);
    CurieIMU.autoCalibrateAccelerometerOffset(Y_AXIS, 1);
    CurieIMU.autoCalibrateAccelerometerOffset(Z_AXIS, 0);

The whole code is here:

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

#define M_PI   3.14159265358979323846264338327950288

#define runEvery(t) for (static long _lasttime;\
                         (uint16_t)((uint16_t)millis() - _lasttime) >= (t);\
                         _lasttime += (t))

//Set up a timer Variable
uint32_t timer;

BLEPeripheral blePeripheral;
BLEService positionService("180F");
BLEService calibrateService("180E");

BLEIntCharacteristic positionChar("2A19", BLERead | BLENotify);
BLEIntCharacteristic calibrateChar("2A18", BLERead | BLEWrite | BLENotify);

Madgwick filter; // initialise Madgwick object
int ax, ay, az;
int gx, gy, gz;
int false_value = 0;
int true_value = 1;
float yaw, pitch, roll;
float x_value, y_value, z_value;
int factor = 200; // 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 = 1; // int to determine whether calibration takes place or not
long previousMillis = 0;

void setup() {
  // initialize Serial communication
  Serial.begin(9600);

  // initialize device
  CurieIMU.begin();

  CurieIMU.setGyroRate(BMI160_GYRO_RATE_100HZ);
  
  blePeripheral.setLocalName("Gyroskop");
  blePeripheral.setAdvertisedServiceUuid(positionService.uuid());
  blePeripheral.setAdvertisedServiceUuid(calibrateService.uuid());
  blePeripheral.addAttribute(positionService);
  blePeripheral.addAttribute(positionChar);
  blePeripheral.addAttribute(calibrateService);
  blePeripheral.addAttribute(calibrateChar);
  calibrateChar.setValue(10);
  positionChar.setValue(9);
  blePeripheral.begin();
  
  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");
    Serial.println("");

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

void loop() {
  BLECentral central = blePeripheral.central();
  if (central) {
    Serial.println(central.address());
  }
 //while (central.connected()) {
    long currentMillis = millis();
    if (currentMillis - previousMillis >= 200) {
      previousMillis = currentMillis;
        //if (calibrateChar.value() == 1) {
        //calibrate();
        //calibrateChar.setValue(0);
    //}
      checkPosition();
    }
  //}
  
}

void checkPosition() {
  runEvery(10) {
    timer = micros();
  // 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
  yaw = filter.getYaw();
  roll = filter.getRoll();
  pitch = filter.getPitch();

  Serial.println(pitch);

    x_value = ((yaw * 180.0 / M_PI)/2);
    y_value = ((roll * 180.0 / M_PI)/2);

    float pitch_ny = pitch;
    float pitch_multi = pitch * 180.0L;
    double pitch_multi2 = pitch * 180.0;
    z_value = ((pitch * 180L / M_PI)/2);
    /*Serial.println(".............");
    Serial.print(pitch, DEC); Serial.print("  ");
    Serial.print(pitch_ny, DEC); Serial.print("  ");
    Serial.print(pitch_multi, DEC); Serial.print("  ");
    Serial.println(pitch_multi2, DEC);
    Serial.println(".............");*/

    Serial.print("x_value:\t");
    Serial.print(x_value);
    Serial.print("\t y_value:\t");
    Serial.print(y_value);
    Serial.print("\t z_value:\t");
    Serial.print(z_value);
    Serial.println("..");

  // if z_value is higher than 10 degrees send notification signal to mobile phone 
  int false_value = 0;
  int true_value = 1;
  int result = false_value;
  if (abs(z_value) > 10) {
    result = true_value;
  }
  positionChar.setValue(result);
  }
}

Hope you can help me! Been working on this problem for days…