Genuino Curie autoCalibrateAccelerometerOffset() swinging Value 0g +1g Z axis

I have a Intel Arduino Genuino 101, i tried to implement the autoCalibrateAccelerometerOffset() function, through the code below on Arduino Genuino 101.

In a static test, without any stress or noise, I read the three axis value.

When I see the data on the serial monitor or on my file created with processing, the Z acceleration values jump from 1~0,99 to 0,00 g.

I think there is an error in my code

If i do a test, and i take the raw data the value are not correct, but stable. They don't change (1.13-1.16 is the range, but never 0)
Z is 1,15 and the resultant force is a little bit bigger than 1g, but stable.

I tried to implement the code even whitout connect Arduino 101 to Processing.

#include "SoftwareSerial.h"
#include "CurieIMU.h"

float sensorVals[] = {0,0,0}; 

void setup() {

    Serial.begin(9600); 
    while (!Serial);    

    Serial.println("Inizializzazione del device...");
    CurieIMU.begin();

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

void loop() {

    sensorVals[0] = CurieIMU.readAccelerometerScaled(0);
    sensorVals[1] = CurieIMU.readAccelerometerScaled(1);
    sensorVals[2] = CurieIMU.readAccelerometerScaled(2);

    Serial.print(sensorVals[0]); 
    Serial.print(",");
    Serial.print(sensorVals[1]);
    Serial.print(",");
    Serial.println(sensorVals[2]);
    delay(100);
}

I asked on StackOverflow but i don't have a valid answer yet

Sorry for my bad english, i am improving day by day.

Thanks for your time and patience <3

ps i don't if this is the correct section or is more suitable for "Sensors" section

Variazione Dati.PNG

I have a similar problem. When my Genuino is in a stable position the z value is sometimes 0.00 and sometimes 1.00.

I tested a bit and found out that the "randomly jumping to 0.00 instead of 1.00" happens not only on the z value, but on every value that should be 1.00 and it doesn't matter if I use the calibration before or not.

genuino problem.PNG

..software error the the library? Take a look inside it..

knut_ny:
..software error the the library? Take a look inside it..

Where i can find the library software? I serched on git hub but i can't find it, even on [arduino website](http://Where i can find it? A month ago it was on on git hub but now i can't find it. I can only see https://www.arduino.cc/en/Reference/CurieIMU)!

RapidPanther:
I have a similar problem. When my Genuino is in a stable position the z value is sometimes 0.00 and sometimes 1.00.

I tested a bit and found out that the "randomly jumping to 0.00 instead of 1.00" happens not only on the z value, but on every value that should be 1.00 and it doesn't matter if I use the calibration before or not.

Did you solve your problem?

Here the libray software

Here the autocalibration code from the library code

void CurieIMUClass::autoCalibrateAccelerometerOffset(int axis, int target)
{
    switch (axis) {
        case X_AXIS:
            autoCalibrateXAccelOffset(target);
            break;

        case Y_AXIS:
            autoCalibrateYAccelOffset(target);
            break;

        case Z_AXIS:
            autoCalibrateZAccelOffset(target);
            break;

        default:
            break;
    }

    setAccelOffsetEnabled(true);
}

void CurieIMUClass::noGyroOffset()
{
    setGyroOffsetEnabled(false);
}

void CurieIMUClass::noAccelerometerOffset()
{
    setAccelOffsetEnabled(false);
}

bool CurieIMUClass::gyroOffsetEnabled()
{
    return getGyroOffsetEnabled();
}

bool CurieIMUClass::accelerometerOffsetEnabled()
{
    return getAccelOffsetEnabled();
}

float CurieIMUClass::getGyroOffset(int axis)
{
    int bmiOffset;

    if (axis == X_AXIS) {
        bmiOffset = getXGyroOffset();
    } else if (axis == Y_AXIS) {
        bmiOffset = getYGyroOffset();
    } else if (axis == Z_AXIS) {
        bmiOffset = getZGyroOffset();
    } else {
        return -1;
    }

    return (bmiOffset * 0.061);
}

float CurieIMUClass::getAccelerometerOffset(int axis)
{
    int bmiOffset;

    if (axis == X_AXIS) {
        bmiOffset = getXAccelOffset();
    } else if (axis == Y_AXIS) {
        bmiOffset = getYAccelOffset();
    } else if (axis == Z_AXIS) {
        bmiOffset = getZAccelOffset();
    } else {
        return -1;
    }

    return (bmiOffset * 3.9);
}

void CurieIMUClass::setGyroOffset(int axis, float offset)
{
    int bmiOffset = offset / 0.061;

    if (bmiOffset < -512) {
        bmiOffset = -512;
    } else if (bmiOffset > 511) {
        bmiOffset = 511;
    }

    if (axis == X_AXIS) {
        setXGyroOffset(bmiOffset);
    } else if (axis == Y_AXIS) {
        setYGyroOffset(bmiOffset);
    } else if (axis == Z_AXIS) {
        setZGyroOffset(bmiOffset);
    }

    setGyroOffsetEnabled(true);
}

void CurieIMUClass::setAccelerometerOffset(int axis, float offset)
{
    int bmiOffset = offset / 3.9;

    if (bmiOffset < -128) {
        bmiOffset = -128;
    } else if (bmiOffset > 127) {
        bmiOffset = 127;
    }

    if (axis == X_AXIS) {
        setXAccelOffset(bmiOffset);
    } else if (axis == Y_AXIS) {
        setYAccelOffset(bmiOffset);
    } else if (axis == Z_AXIS) {
        setZAccelOffset(bmiOffset);
    }

    setAccelOffsetEnabled(true);
}

The lib truncates instead of rounding. I'd try adding .5 to the ints or replace ints with floats.
I cannot say for sure that this is what introduces the error

Thanks a lot! :slight_smile: :slight_smile: :slight_smile:

knut_ny:
The lib truncates instead of rounding. I'd try adding .5 to the ints or replace ints with floats.
I cannot say for sure that this is what introduces the error

I am a noob, with a civil engineer background, how can i recognize that the lib truncates instead of rounding?

So i have to change the value in the library and than upload on Arduino 101? How can i do that (I have to find my library directory?)

I changed all the int to float, is correct? :slight_smile:

void CurieIMUClass::autoCalibrateAccelerometerOffset(float axis, float target)
{
    switch (axis) {
        case X_AXIS:
            autoCalibrateXAccelOffset(target);
            break;

        case Y_AXIS:
            autoCalibrateYAccelOffset(target);
            break;

        case Z_AXIS:
            autoCalibrateZAccelOffset(target);
            break;

        default:
            break;
    }

    setAccelOffsetEnabled(true);
}

void CurieIMUClass::noGyroOffset()
{
    setGyroOffsetEnabled(false);
}

void CurieIMUClass::noAccelerometerOffset()
{
    setAccelOffsetEnabled(false);
}

bool CurieIMUClass::gyroOffsetEnabled()
{
    return getGyroOffsetEnabled();
}

bool CurieIMUClass::accelerometerOffsetEnabled()
{
    return getAccelOffsetEnabled();
}

float CurieIMUClass::getGyroOffset(float axis)
{
    float bmiOffset;

    if (axis == X_AXIS) {
        bmiOffset = getXGyroOffset();
    } else if (axis == Y_AXIS) {
        bmiOffset = getYGyroOffset();
    } else if (axis == Z_AXIS) {
        bmiOffset = getZGyroOffset();
    } else {
        return -1;
    }

    return (bmiOffset * 0.061);
}

float CurieIMUClass::getAccelerometerOffset(float axis)
{
    float bmiOffset;

    if (axis == X_AXIS) {
        bmiOffset = getXAccelOffset();
    } else if (axis == Y_AXIS) {
        bmiOffset = getYAccelOffset();
    } else if (axis == Z_AXIS) {
        bmiOffset = getZAccelOffset();
    } else {
        return -1;
    }

    return (bmiOffset * 3.9);
}

void CurieIMUClass::setGyroOffset(float axis, float offset)
{
    float bmiOffset = offset / 0.061;

    if (bmiOffset < -512) {
        bmiOffset = -512;
    } else if (bmiOffset > 511) {
        bmiOffset = 511;
    }

    if (axis == X_AXIS) {
        setXGyroOffset(bmiOffset);
    } else if (axis == Y_AXIS) {
        setYGyroOffset(bmiOffset);
    } else if (axis == Z_AXIS) {
        setZGyroOffset(bmiOffset);
    }

    setGyroOffsetEnabled(true);
}

void CurieIMUClass::setAccelerometerOffset(float axis, float offset)
{
    float bmiOffset = offset / 3.9;

    if (bmiOffset < -128) {
        bmiOffset = -128;
    } else if (bmiOffset > 127) {
        bmiOffset = 127;
    }

    if (axis == X_AXIS) {
        setXAccelOffset(bmiOffset);
    } else if (axis == Y_AXIS) {
        setYAccelOffset(bmiOffset);
    } else if (axis == Z_AXIS) {
        setZAccelOffset(bmiOffset);
    }

    setAccelOffsetEnabled(true);
}

Can you see any effect of the change ?

How ints work

Int a=1; int b=a+0.999 will set b to 1 (truncate always)