Detection problems with Adafruits FXAS21002 & FXOS87000

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
apospraf
 
Posts: 5
Joined: Tue Oct 05, 2021 6:45 am

Detection problems with Adafruits FXAS21002 & FXOS87000

Post by apospraf »

Hello everyone!

I have 6 IMUs (FXAS21002 & FXOS87000) that I'm reading data from, so I use a multiplexer (TCA9548a) to switch between them. I put the readings of the IMUs in a dataframe and the send it to the serial port. The code can be seen below:

Code: Select all

#include <Adafruit_FXOS8700.h>
#include <Adafruit_FXAS21002C.h>
#include <Adafruit_Sensor.h>
#include "Wire.h"

#define TCAADDR 0x70
#define FRAMESIZE (45) //(1 + 4 + 4*3 + 4*3 + 4 + 4*3)
//                accmag timestamp uint long + 3 floats acc + 3 floats mag + gyro timestamp uint long
#define NUMSENSORS 6

/* Assign a unique ID to this sensor at the same time */
Adafruit_FXOS8700 accelmag0 = Adafruit_FXOS8700(0x8700A, 0x8700B);
Adafruit_FXAS21002C gyro0 = Adafruit_FXAS21002C(0x0021002C);
byte dataframe[FRAMESIZE] ={0x00};
unsigned long timestamp;

void tcaselect(uint8_t i) {
  if (i > 7) return;
  
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();

}


void setup(void) {
  
  
  /* Wait for the Serial Monitor */
  while (!Serial) {
    delay(1000);
  }
  
//  Wire.begin();
  Serial.begin(115200);
  for (uint8_t i=0; i<NUMSENSORS; i++) {
    Serial.println("NXPsensor Test Accel+Gyro Test");
    Serial.println("");
    tcaselect(i);
    
    
    /* Initialise the sensor */
    if (!gyro0.begin()) {
      /* There was a problem detecting the FXAS21002C ... check your connections
       */    
      Serial.println("Ooops, no FXAS21002C detected ... Check your wiring!");
      while (1);
    }
    
    /* Initialise the sensor */
    if (!accelmag0.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)
        ;
    }
   
  }
  

  timestamp = micros();
}
// https://arduino.stackexchange.com/questions/60863/print-byte-array-in-serial-monitor-screen-of-arduino-ide
//void printHex(uint8_t num) {
//  char hexCar[2];
//
//  sprintf(hexCar, "%02X", num);
//  Serial.print(hexCar);
//}
void loop(void) {
  

//  // Set sr to 100 Hz.
  if ( micros() - timestamp <10000 - 10) {
    // test micros()-timestamp>10000 ? delay( (micros()- timestamp-1000)/1000 : ; // delay for something less than time remaining only if there is a lot of time left
    return;
  }
  timestamp = micros();
  for (uint8_t i=0; i<NUMSENSORS; i++)  {
    tcaselect(i); //Change sensor
    sensors_event_t aevent, mevent, gevent; //Nikos
    /* Get a new sensor event */
    accelmag0.getEvent(&aevent, &mevent);
    gyro0.getEvent(&gevent);
    
    /* dataframe:
     * |UINT8_T| ULONG | FLOAT | FLOAT | FLOAT | FLOAT | FLOAT | FLOAT | ULONG | FLOAT | FLOAT | FLOAT |
     * |   -   |- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|
     * |sensor | accts | acc.x | acc.y | acc.z | mag.x | mag.y | mag.z | gyrts | gyr.x | gyr.y | gyr.z |
     * |   #   |  μs   | m/s^2 | m/s^2 | m/s^2 |  uT   |  uT   |  uT   |  μs   | rad/s | rad/s | rad/s |
     *
     */
    
    dataframe[0] = i;
    memcpy(&dataframe[1], &aevent.timestamp, 4);
    memcpy(&dataframe[5], &aevent.acceleration, 12);
    memcpy(&dataframe[17], &mevent.magnetic, 12);
    memcpy(&dataframe[29], &gevent.timestamp, 4);
    memcpy(&dataframe[33], &gevent.gyro, 12);
    Serial.println("");
    Serial.write(dataframe, FRAMESIZE);
  }
  
//  delay(10);
}
I calibrated the sensors and saved the values in the EEPROM of the Arduino Mega that I'm using. Then, I created the calibration functions that read from the EEPROM and added them the above code. The new updated script can be seen below:

Code: Select all

#include <Adafruit_FXOS8700.h>
#include <Adafruit_FXAS21002C.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <EEPROM.h>

#define TCAADDR 0x70
#define FRAMESIZE (45) //(1 + 4 + 4*3 + 4*3 + 4 + 4*3)
//                accmag timestamp uint long + 3 floats acc + 3 floats mag + gyro timestamp uint long
#define NUMSENSORS 6

/* Assign a unique ID to this sensor at the same time */
Adafruit_FXOS8700 accelmag0 = Adafruit_FXOS8700(0x8700A, 0x8700B);
Adafruit_FXAS21002C gyro0 = Adafruit_FXAS21002C(0x0021002C);
byte dataframe[FRAMESIZE] ={0x00};
unsigned long timestamp;

template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}

void getCalibration(int noIMU, double calibration[]){
  unsigned int baseAddrTest = noIMU*12*4;
    for (int i=0; i <= 11; i++){
      double val;
      int addr = (i*4)+baseAddrTest;
      EEPROM_readAnything( addr, val);
      calibration[i];
    }
  return;
}

bool calibrate_mag(sensors_event_t &mag_event, int noIMU){
    double calibration[12];
    getCalibration(noIMU, calibration);
    float mx = mag_event.magnetic.x - calibration[0];
    float my = mag_event.magnetic.y - calibration[1];
    float mz = mag_event.magnetic.z - calibration[2];

    mag_event.magnetic.x = mx * calibration[3] + my * calibration[6] + mz * calibration[7];
    mag_event.magnetic.y = mx * calibration[6] + my * calibration[4] + mz * calibration[8];
    mag_event.magnetic.z = mx * calibration[7] + my * calibration[8] + + mz * calibration[5];
}

bool calibrate_gyro(sensors_event_t &gyro_event, int noIMU){
  double calibration[12];
  getCalibration(noIMU, calibration);
  gyro_event.gyro.x -= calibration[9];
  gyro_event.gyro.y -= calibration[10];
  gyro_event.gyro.z -= calibration[11];
  return true;
}

void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();

}

void setup(void) {
  Serial.begin(115200);
  
  /* Wait for the Serial Monitor */
  while (!Serial) {
    delay(1000);
  }
  Wire.begin();
  for (uint8_t i=0; i<NUMSENSORS; i++) {
    delay(100);
    Serial.println("NXPsensor Test Accel+Gyro Test");
    Serial.println("");
    tcaselect(i);
    
    
    /* Initialise the sensor */
    if (!gyro0.begin()) {
      /* There was a problem detecting the FXAS21002C ... check your connections
       */
      Serial.println("Ooops, no FXAS21002C detected ... Check your wiring!");
      while (1)
        ;
    }
    
    /* Initialise the sensor */
    if (!accelmag0.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)
        ;
    }
    
  }
  

  timestamp = micros();
}
// https://arduino.stackexchange.com/questions/60863/print-byte-array-in-serial-monitor-screen-of-arduino-ide
//void printHex(uint8_t num) {
//  char hexCar[2];
//
//  sprintf(hexCar, "%02X", num);
//  Serial.print(hexCar);
//}
void loop(void) {
  

//  // Set sr to 100 Hz.
  if ( micros() - timestamp <10000 - 10) {
    // test micros()-timestamp>10000 ? delay( (micros()- timestamp-1000)/1000 : ; // delay for something less than time remaining only if there is a lot of time left
    return;
  }
  timestamp = micros();
  for (uint8_t i=0; i<NUMSENSORS; i++)  {
    tcaselect(i); //Change sensor
    sensors_event_t aevent, mevent, gevent; //Nikos
    /* Get a new sensor event */
    accelmag0.getEvent(&aevent, &mevent);
    gyro0.getEvent(&gevent);
    calibrate_gyro(gevent, i);
    calibrate_mag(mevent, i);
    /* dataframe:
     * |UINT8_T| ULONG | FLOAT | FLOAT | FLOAT | FLOAT | FLOAT | FLOAT | ULONG | FLOAT | FLOAT | FLOAT |
     * |   -   |- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|- - - -|
     * |sensor | accts | acc.x | acc.y | acc.z | mag.x | mag.y | mag.z | gyrts | gyr.x | gyr.y | gyr.z |
     * |   #   |  μs   | m/s^2 | m/s^2 | m/s^2 |  uT   |  uT   |  uT   |  μs   | rad/s | rad/s | rad/s |
     *
     */
    dataframe[0] = i;
    memcpy(&dataframe[1], &aevent.timestamp, 4);
    memcpy(&dataframe[5], &aevent.acceleration, 12);
    memcpy(&dataframe[17], &mevent.magnetic, 12);
    memcpy(&dataframe[29], &gevent.timestamp, 4);
    memcpy(&dataframe[33], &gevent.gyro, 12);
    Serial.println("");
    Serial.write(dataframe, FRAMESIZE);
  }
  
//  delay(10);
}
After uploading the code, the Arduino Mega cannot identify the sensors and it gets stuck at "Ooops, no FXAS21002C detected ... Check your wiring!". I tried connecting my other Arduino Mega, with the first script (without the calibration functions), and it worked as expected. Then I uploaded the new sketch (with the calibrations functions) and it stopped working again. I tried re-uploading the first sketch but the problem remained.
I checked if the IMUs are visible to the Arduino by using the Adafruit's TCA scanner function and it can detect the sensors. The scanner script and the results are:

Code: Select all

/**
 * TCA9548 I2CScanner.ino -- I2C bus scanner for Arduino
 *
 * Based on https://playground.arduino.cc/Main/I2cScanner/
 *
 */

#include "Wire.h"

#define TCAADDR 0x70

void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}


// standard Arduino setup()
void setup()
{
    while (!Serial);
    delay(1000);

    Wire.begin();
    
    Serial.begin(115200);
    Serial.println("\nTCAScanner ready!");
    
    for (uint8_t t=0; t<8; t++) {
      tcaselect(t);
      Serial.print("TCA Port #"); Serial.println(t);

      for (uint8_t addr = 0; addr<=127; addr++) {
        if (addr == TCAADDR) continue;

        Wire.beginTransmission(addr);
        if (!Wire.endTransmission()) {
          Serial.print("Found I2C 0x");  Serial.println(addr,HEX);
        }
      }
    }
    Serial.println("\ndone");
}

void loop() 
{
*TCAScanner ready!
TCA Port #0
Found I2C 0x1F
Found I2C 0x21
TCA Port #1
Found I2C 0x1F
Found I2C 0x21
TCA Port #2
Found I2C 0x1F
Found I2C 0x21
TCA Port #3
Found I2C 0x1F
Found I2C 0x21
TCA Port #4
Found I2C 0x1F
Found I2C 0x21
TCA Port #5
Found I2C 0x1F
Found I2C 0x21
TCA Port #6
TCA Port #7
*

Any help would be really appreciated.

User avatar
adafruit_support_bill
 
Posts: 88097
Joined: Sat Feb 07, 2009 10:11 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by adafruit_support_bill »

Your tests seem to rule out a connectivity problem. The next suspect is usually memory issues. But I don't see anything there that should tax the memory capacity of a Mega.

I have seen some pretty wild code generated from C++ templates. But your EEPROM_readAnything should not even get called until you start looping.

One diagnostic strategy to try is to start commenting out portions of the added code until the problem goes away. That will identify the specific lines that trigger the problem.

User avatar
apospraf
 
Posts: 5
Joined: Tue Oct 05, 2021 6:45 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by apospraf »

Hey Bill, thanks for the reply,

The thing is, that even when I use the first code, without the calibration functions, I get the same result: "Ooops, no FXAS21002C detected ... Check your wiring!".

I should have also mentioned that I used the code below to write to the EEPROM of the Mega.

Code: Select all

#include <EEPROM.h>


template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        EEPROM.write(ee++, *p++);
    return i;
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}

unsigned int noIMU = 5;
double calibration[12] = {13.73, -33.57, -44.06, 0.0975, 0.964, 1.067, 0.033, -0.026, 0.024, -0.0082, -0.0164, -0.0003};
byte noElem = 12;
unsigned int baseAddr = noIMU*12*4;
unsigned int baseAddrTest;
unsigned int n = 0;

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

////  // write data to eeprom 
//  for (int i=0; i <= noElem-1; i++){
//    n = EEPROM_writeAnything( (i*4)+baseAddr, calibration[i]);
//  }

  // read data back
  for (int NI=0; NI<=5; NI++){
    Serial.print("Number of IMU:");
    Serial.println(NI);
    baseAddrTest = NI*12*4;
    for (int i=0; i <= noElem-1; i++){
      double val;
      int addr = (i*4)+baseAddrTest;
      n = EEPROM_readAnything( addr, val);
      Serial.println(val,4);
    }
  }
  
}

void loop() {
}
After using this code I started having problems.

User avatar
adafruit_support_bill
 
Posts: 88097
Joined: Sat Feb 07, 2009 10:11 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by adafruit_support_bill »

The thing is, that even when I use the first code, without the calibration functions, I get the same result:
So you are saying that you have never successfully communicated with the IMUs through the multiplexer - other than via the i2c scanner?

User avatar
apospraf
 
Posts: 5
Joined: Tue Oct 05, 2021 6:45 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by apospraf »

So you are saying that you have never successfully communicated with the IMUs through the multiplexer - other than via the i2c scanner?
After I ran the code that writes to the EEPROM, yes.

I just tested connecting only one IMU directly to the I2C bus of the mega and I get the readings as expected. So, I think the problem is between the Adafruit's library and the multiplexer.

User avatar
adafruit_support_bill
 
Posts: 88097
Joined: Sat Feb 07, 2009 10:11 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by adafruit_support_bill »

I don't see how the existence of data in EEPROM could have any effect on i2c communication. Please post some clear photos showing all of your soldering and connections.

User avatar
apospraf
 
Posts: 5
Joined: Tue Oct 05, 2021 6:45 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by apospraf »

The issue remains with the simple connection of the following pictures

Picture 1: 5V and Ground TCA
multi_ard_source.jpg
multi_ard_source.jpg (331.04 KiB) Viewed 230 times
Picture 2: I2C connection Arduino and TCA
multi_ard_i2c.jpg
multi_ard_i2c.jpg (398.1 KiB) Viewed 230 times
Picture 3: 5V Ground and I2C IMU to TCA
imu_i2c.jpg
imu_i2c.jpg (363.4 KiB) Viewed 230 times

User avatar
adafruit_support_bill
 
Posts: 88097
Joined: Sat Feb 07, 2009 10:11 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by adafruit_support_bill »

Please show the soldering on the sensors also.

User avatar
apospraf
 
Posts: 5
Joined: Tue Oct 05, 2021 6:45 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by apospraf »

The soldering on the IMU and TCA
multi.jpg
multi.jpg (303.4 KiB) Viewed 228 times
imu.jpg
imu.jpg (263.38 KiB) Viewed 228 times

User avatar
adafruit_support_bill
 
Posts: 88097
Joined: Sat Feb 07, 2009 10:11 am

Re: Detection problems with Adafruits FXAS21002 & FXOS87000

Post by adafruit_support_bill »

It's hard to see from a top-down angle, but it looks like the solder on some of the senor header pins has not flowed well onto the solder pads. If you can post one from a slightly elevated angle, we can better see the profile of the solder joints.


https://learn.adafruit.com/adafruit-gui ... t-418531-2
Image

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”