0

Arduino Code for FXAS21002C and FXOS8700
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Arduino Code for FXAS21002C and FXOS8700

by Captain_Sly on Sat Nov 11, 2017 11:47 pm

Hello, Im using an Adafruit Precision NXP 9-DOF Breakout Board - FXOS8700 + FXAS21002 (productID: 3463), with a Adafruit Pro Trinket - 5V 16MHz (product ID: 2000). I am using the arduino libraries from https://github.com/adafruit/Adafruit_FXOS8700 and https://github.com/adafruit/Adafruit_FXAS21002C to read acceleration and gyro data and write it to an SD card. I did not realize the gyro tells you rate of change of the angle in the x, y, z directions. What I want to do is get the gyro to tell me the actual angle, preferably in degrees, and use that as my data. Also I will use the gyro data to satisfy a parameter that I am going to write, but that step I can figure out. All I need is the gyro to tell me the angle in which the sensor is at. I have read that you can do this by taking the gyro data and using data from an accelerometer and from that you can calculate angle. The problem is I do not know how I should code this.

Here are my two separate codes, the gyro code and acceleration code respectively...

Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_FXAS21002C.h>
#include <SD.h>
#include <SPI.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_FXAS21002C gyro = Adafruit_FXAS21002C(0x0021002C);
File myFile;
const int ChipSelect = 10;




void setup(void)
{
  Serial.begin(9600);

  /* Wait for the Serial Monitor */
  while (!Serial) {
    delay(1);
  }
  Serial.println("Initializing SD Card...");
  if (!SD.begin(10))
  {
    Serial.println("Initialization Failed!!");
    return;
  }
  Serial.println("Initialization Complete");
  delay(2000);

  Serial.println("Gyroscope Test"); Serial.println("");

  /* Initialise the sensor */
  if(!gyro.begin())
  {
    /* There was a problem detecting the FXAS21002C ... check your connections */
    Serial.println("Ooops, no FXAS21002C detected ... Check your wiring!");
    while(1);
  }
  Serial.println("Gyro working, beginning data in 3 Seconds.");
  delay(3000);

  /* Display some basic information on this sensor */

}

void loop(void)
{
  myFile = SD.open("data.txt", FILE_WRITE);
  /* Get a new sensor event */
  sensors_event_t event;
  gyro.getEvent(&event);
  if (myFile)
  {
      /* Display the results (speed is measured in rad/s) */
  Serial.print("X: "); Serial.print(event.gyro.x); Serial.print("  ");
  myFile.print("X: "); myFile.print(event.gyro.x); myFile.print("  ");
  Serial.print("Y: "); Serial.print(event.gyro.y); Serial.print("  ");
  myFile.print("Y: "); myFile.print(event.gyro.y); myFile.print("  ");
  Serial.print("Z: "); Serial.print(event.gyro.z); Serial.print("  ");
  myFile.print("Z: "); myFile.print(event.gyro.z); myFile.print("  ");
  Serial.println("rad/s ");
  myFile.println("rad/s ");
  myFile.close();
  }
  else
  {
    Serial.println("Error in opening file");
  }
 
  delay(250);
}


Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_FXOS8700.h>
#include <SD.h>
#include <SPI.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_FXOS8700 accelmag = Adafruit_FXOS8700(0x8700A, 0x8700B);
File myFile;
const int ChipSelect = 10;

void setup(void)
{
  Serial.begin(9600);

  /* Wait for the Serial Monitor */
  while (!Serial) {
    delay(1);
  }
  Serial.println("Initializing SD Card...");
  if (!SD.begin(10))
  {
    Serial.println("Initialization Failed!!!");
    return;
  }
  Serial.println("Initialization Complete");
  delay(1000);
 
  Serial.println("FXOS8700 Test"); Serial.println("");

  /* Initialise the sensor */
  if(!accelmag.begin(ACCEL_RANGE_4G))
  {
    /* There was a problem detecting the FXOS8700 ... check your connections */
    Serial.println("Ooops, no FXOS8700 detected ... Check your wiring!");
    while(1);
  }
  Serial.println("Accelerometer working, beginning data in 3 seconds.");
  delay(3000);


}

void loop(void)
{
  myFile = SD.open("data.txt", FILE_WRITE);
  sensors_event_t aevent, mevent;

  /* Get a new sensor event */
  accelmag.getEvent(&aevent, &mevent);
if (myFile)
{
  /* Display the accel results (acceleration is measured in m/s^2) */

  Serial.print("X: "); Serial.print(aevent.acceleration.x, 8); Serial.print("  ");
  myFile.print("X: "); myFile.print(aevent.acceleration.x, 8); myFile.print("  ");
  Serial.print("Y: "); Serial.print(aevent.acceleration.y, 8); Serial.print("  ");
  myFile.print("Y: "); myFile.print(aevent.acceleration.y, 8); myFile.print("  ");
  Serial.print("Z: "); Serial.print(aevent.acceleration.z, 8); Serial.print("  ");
  myFile.print("Z: "); myFile.print(aevent.acceleration.z, 8); myFile.print("  ");
  Serial.println("m/s^2");
  myFile.println("m/s^2");
  myFile.close();
}
else
{
  Serial.println("Error in opening file");
}

  delay(125);
}


So as of now, I have the acceleration code giving me acceleration, which is fine. I have the gyro code giving me rate of change in radians/second and I want it to give me just radians, or degrees.

Any tips on coding and or how I should tackle this problem is much appreciated.

Thanks

Captain_Sly
 
Posts: 8
Joined: Sun Oct 29, 2017 3:39 am

Re: Arduino Code for FXAS21002C and FXOS8700

by adafruit_support_bill on Sun Nov 12, 2017 6:57 am

A gyro cannot give you an absolute angle. It can only tell you the rate of rotation. From that you can estimate the relative angular displacement by integrating the rotation rate over time, but be aware that this is subject to drift.

The accelerometer can give you an absolute angle relative to vertical, since there is a constant 1G acceleration in the vertical axis due to gravity.

The Magnetometer can give you an absolute angle relative to magnetic north due to the (relatively) stable magnetic field of the earth.

To determine orientation in real-time, an IMU generally combines the outputs of the accelerometer, magnetometer and gyro.

https://learn.adafruit.com/adafruit-bno ... ion-sensor

adafruit_support_bill
 
Posts: 63384
Joined: Sat Feb 07, 2009 10:11 am

Re: Arduino Code for FXAS21002C and FXOS8700

by Captain_Sly on Sun Nov 12, 2017 7:07 am

Thank you, I am aware that a gyro only gives rate of rotation. I know you can get better results by fusing the gyro data with acceleration and magnetic direction data. The question is, how do I do this? How do I take gyro, acceleration, and magnetic direction and transform that data into an angle? I’m really only trying to get the angle in the X and Y directions, the Z axis I do not care about. So how would I code an algorithm to give me an angle in the X and Y directions from the gyro, acceleration, and magnetic direction data???

Thanks.
Last edited by Captain_Sly on Sun Nov 12, 2017 7:22 am, edited 2 times in total.

Captain_Sly
 
Posts: 8
Joined: Sun Oct 29, 2017 3:39 am

Re: Arduino Code for FXAS21002C and FXOS8700

by adafruit_support_bill on Sun Nov 12, 2017 7:21 am

We do not have any AHRS tutorials for the sensors you are using. This one is targeted to some of our 9 and 10 DOF IMU boards.
https://learn.adafruit.com/ahrs-for-ada ... troduction

adafruit_support_bill
 
Posts: 63384
Joined: Sat Feb 07, 2009 10:11 am

Re: Arduino Code for FXAS21002C and FXOS8700

by Captain_Sly on Sun Nov 12, 2017 6:52 pm

Alright so I have been looking at the 9 dof breakout tutorials and have been reading the ahrs mahony and calibration code and in these codes they are getting raw gyro and accelmag data. I am now trying to calibrate my sensors using the ahrs calibration code using my "precision" 9DOF board. I can get raw gyro data but am unable to get raw accelmag data. I am trying to calibrate it and then enter the calibration data into the mahony code so I can get euler angles for orientation.

Thanks

Captain_Sly
 
Posts: 8
Joined: Sun Oct 29, 2017 3:39 am

Re: Arduino Code for FXAS21002C and FXOS8700

by adafruit_support_bill on Mon Nov 13, 2017 7:35 am

The accel_raw x, y and z values are public members of the Adafruit_FXOS8700 class. You can get the raw values from these immediately after a call to getEvent.

https://github.com/adafruit/Adafruit_FX ... FXOS8700.h
Code: Select all | TOGGLE FULL SIZE
class Adafruit_FXOS8700 : public Adafruit_Sensor
{
  public:
    Adafruit_FXOS8700(int32_t accelSensorID = -1, int32_t magSensorID = -1);

    bool begin           ( fxos8700AccelRange_t rng = ACCEL_RANGE_2G );
    bool getEvent        ( sensors_event_t* accel );
    void getSensor       ( sensor_t* accel );
    bool getEvent        ( sensors_event_t* accel, sensors_event_t* mag );
    void getSensor       ( sensor_t* accel, sensor_t* mag );

    fxos8700RawData_t accel_raw; /* Raw values from last sensor read */
    fxos8700RawData_t mag_raw;   /* Raw values from last sensor read */

  private:
    void        write8  ( byte reg, byte value );
    byte        read8   ( byte reg );

    fxos8700AccelRange_t _range;
    int32_t              _accelSensorID;
    int32_t              _magSensorID;
};


adafruit_support_bill
 
Posts: 63384
Joined: Sat Feb 07, 2009 10:11 am

Re: Arduino Code for FXAS21002C and FXOS8700

by Captain_Sly on Thu Nov 16, 2017 10:47 pm

So I have tried taking the code you wrote out in the last reply and all I am getting is the following error...

accel_raw:9: error: redefinition of 'class Adafruit_FXOS8700'

class Adafruit_FXOS8700 : public Adafruit_Sensor

^

In file included from C:\Users\######\Documents\Arduino\accel_raw\accel_raw.ino:3:0:

C:\Users\######\Documents\Arduino\libraries\Adafruit_FXOS8700/Adafruit_FXOS8700.h:90:7: error: previous definition of 'class Adafruit_FXOS8700'

class Adafruit_FXOS8700 : public Adafruit_Sensor

^

exit status 1
redefinition of 'class Adafruit_FXOS8700'




here is the code I have in Arduino...
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_FXOS8700.h>
#include <SD.h>
#include <SPI.h>

Adafruit_FXOS8700 accelmag = Adafruit_FXOS8700(0x8700A, 0x8700B);

class Adafruit_FXOS8700 : public Adafruit_Sensor
{
  public:
    Adafruit_FXOS8700(int32_t accelSensorID = -1, int32_t magSensorID = -1);

    bool begin           ( fxos8700AccelRange_t rng = ACCEL_RANGE_2G );
    bool getEvent        ( sensors_event_t* accel );
    void getSensor       ( sensor_t* accel );
    bool getEvent        ( sensors_event_t* accel, sensors_event_t* mag );
    void getSensor       ( sensor_t* accel, sensor_t* mag );

    fxos8700RawData_t accel_raw; /* Raw values from last sensor read */
    fxos8700RawData_t mag_raw;   /* Raw values from last sensor read */

  private:
    void        write8  ( byte reg, byte value );
    byte        read8   ( byte reg );

    fxos8700AccelRange_t _range;
    int32_t              _accelSensorID;
    int32_t              _magSensorID;
};


I apologize for having so many issues about arduino code, I have very little coding experience and have been researching problems myself but have had little success, that is why I am asking here.

Thanks.

Captain_Sly
 
Posts: 8
Joined: Sun Oct 29, 2017 3:39 am

Re: Arduino Code for FXAS21002C and FXOS8700

by adafruit_support_bill on Fri Nov 17, 2017 6:34 am

The code I posted is an excerpt from the Adafruit_FXOS8700 library. I posted it to illustrate that those data members are declared as 'public', so you can reference them directly in your code.

If you have a sensor object 'accelmag' declared in your code - (as in the sensorapi example), the raw accelerometer and magnetometer values will be accessible after a call to getEvent()

Code: Select all | TOGGLE FULL SIZE
  /* Get a new sensor event */
  accelmag.getEvent(&aevent, &mevent);
 
  Serial.println(accelmag.accel_raw.x);
  Serial.println(accelmag.accel_raw.y);
  Serial.println(accelmag.accel_raw.z );
  Serial.println(accelmag.mag_raw.x);
  Serial.println(accelmag.mag_raw.y);
  Serial.println(accelmag.mag_raw.z) 0;

adafruit_support_bill
 
Posts: 63384
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.