0

I'm trying to implement the "BNO055 9 Axes Motion Shield". There is an existing Arduino sketch GitHub that reads out the Euler data, I changed it a bit to print out quaternion data.

#include "NAxisMotion.h"        //Contains the bridge code between the API and the Arduino Environment
#include <Wire.h>

NAxisMotion mySensor;         //Object that for the sensor 
unsigned long lastStreamTime = 0;     //To store the last streamed time stamp
const int streamPeriod = 20;          //To stream at 50Hz without using additional timers (time period(ms) =1000/frequency(Hz))

void setup() //This code is executed once
{    
  //Peripheral Initialization
  Serial.begin(115200);           //Initialize the Serial Port to view information on the Serial Monitor
  I2C.begin();                    //Initialize I2C communication to the let the library communicate with the sensor.
  //Sensor Initialization
  mySensor.initSensor();          //The I2C Address can be changed here inside this function in the library
  mySensor.setOperationMode(OPERATION_MODE_NDOF);   //Can be configured to other operation modes as desired
  mySensor.setUpdateMode(MANUAL);   //The default is AUTO. Changing to MANUAL requires calling the relevant update functions prior to calling the read functions
  //Setting to MANUAL requires fewer reads to the sensor  
}

void loop() //This code is looped forever
{
  if ((millis() - lastStreamTime) >= streamPeriod)
  {
    lastStreamTime = millis();    
    mySensor.updateQuat();        //Update the Quat data into the structure of the object
    mySensor.updateCalibStatus();  //Update the Calibration Status

    Serial.print("Time: ");
    Serial.print(lastStreamTime);
    Serial.print("ms ");

    Serial.print(" W: ");
    Serial.print(mySensor.readQuatW()); 

    Serial.print(" X: ");
    Serial.print(mySensor.readQuatX());

    Serial.print(" Y: ");
    Serial.print(mySensor.readQuatY()); 

    Serial.print(" Z: ");
    Serial.print(mySensor.readQuatZ()); 

    Serial.println();
  }
}

Here is a snippet of the "NAxisMotion.h" header file:

    /*******************************************************************************************
    *Description: This function is used to return the w-axis of the quaternion data
    *Input Parameters: None
    *Return Parameter:
    *   int16_t:    W-axis quaternion data multiplied by 1000 (for 3 decimal places accuracy)
    *******************************************************************************************/
    int16_t readQuatW(void);

    /*******************************************************************************************
    *Description: This function is used to return the x-axis of the quaternion data
    *Input Parameters: None
    *Return Parameter:
    *   int16_t:    X-axis quaternion data multiplied by 1000 (for 3 decimal places accuracy)
    *******************************************************************************************/
    int16_t readQuatX(void);

    /*******************************************************************************************
    *Description: This function is used to return the y-axis of the quaternion data
    *Input Parameters: None
    *Return Parameter:
    *   int16_t:    Y-axis quaternion data multiplied by 1000 (for 3 decimal places accuracy)
    *******************************************************************************************/
    int16_t readQuatY(void);

    /*******************************************************************************************
    *Description: This function is used to return the z-axis of the quaternion data
    *Input Parameters: None
    *Return Parameter:
    *   int16_t:    Z-axis quaternion data multiplied by 1000 (for 3 decimal places accuracy)
    *******************************************************************************************/
    int16_t readQuatZ(void);

I understand that the output data type is signed integer, but what syntax do I need to use to store them in an array? Because it seems the only way to access them is through "mySensor.readQuatX()"

3
  • It would be better if you adopted the habit of including system libs first. The reason behind this is it is theoretically possible (very unlikely) that a header file will include a the system lib header and then redefine a pre-processor variable that the system library uses and so you might get different/conflicting header files for the library. Very very unlikely, unless you work with true coding cowboys. Jan 17, 2018 at 15:50
  • Do you mean in this case Wire.h should come before NAxisMotion.h?
    – mascail
    Jan 18, 2018 at 9:11
  • Yes #include <xxx> before #include "xxx". This also means if you get a duplicate definition int foo = 7 the error will be reported against the code you are more likely to have written rather than suggesting some system library is wrong. Others will argue I'm wrong, but it would be boring if we all thought the same. Jan 18, 2018 at 10:21

1 Answer 1

0

If I understand correctly you want to store a number of signed integers in an array. Arrays have fixed sizes so you need to know the number of values you want to store.

// Global declarations
enum QIndex {WAxis, XAxis, YAxi, ZAxis, MaxIndex};
int16_t qData[MaxValues] = {0};

// Code inside loop
qData[WAxis] = readQuatW();
qData[XAxis] = readQuatX();
qData[YAxis] = readQuatY();
qData[ZAxis] = readQuatZ();

// Pass the array  of values to another function with the declaration
// void SomeFunction (int *ar);
// or
// void SomeFunction (int ar[]);
SomeFunction (qData);

Is that what you mean?

4
  • So basically I tried it out and your code worked, thanks a lot. But now I my problem is, I can't convert the unsigned int sensor data to floats (which would also have to be unsigned) for further proccesing in the program "Processing" for visualization. Is there any way?
    – mascail
    Jan 16, 2018 at 20:30
  • Yes, but it will only give you a whole number, because that's all you have. float fValue = (float)iValue; Jan 17, 2018 at 8:11
  • I want to divide each element of the int16_t data-type array by 1000 and then convert them to float. It works but only gives me whole numbers like you said. What am I doing wrong? I need at least 2 decimal places.
    – mascail
    Jan 17, 2018 at 8:41
  • You are doing integer division, you want float division. float result = ((float)input) / 1000.0f; You have to make both number floats and then divide. Jan 17, 2018 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.