Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 10 months ago.
I2C modules conflict
Hi all!
I'm developing an easy gyrocompass with FXOS8700 and FXAS21002 mounted on FRDM-K64F. Sensors are connected to different I2C: PTE24/PTE25 and PTD2/PTD3. When I try to enable both sensors, FXAS21002 falls off and its I2C module always receives NACK. FXOS8700 works properly. When I use only FXAS21002, it works properly.
Mbed version 111. Any clues?
FXAS header
#ifndef FXAS21002_H
#define FXAS21002_H
#include "mbed.h"
#include "Vector3.h"
#define FXAS21002_I2C_ADDRESS 0x40
#define FXAS21002_STATUS 0x00
#define FXAS21002_WHO_AM_I 0x0C
#define FXAS21002_CTRL_REG0 0x0D
#define FXAS21002_CTRL_REG1 0x13
#define FXAS21002_WHO_AM_I_VALUE 0xD7
class FXAS21002
{
public:
FXAS21002(PinName sda, PinName scl);
bool isConnected();
void config(void);
void calibrate();
bool isDataReady();
void read(Vector3 &data);
private:
void readReg( char reg, char * d, int len);
I2C gyroi2c;
Vector3 biases;
};
#endif
FXAS code
#include "FXAS21002.h"
#include "mbed.h"
FXAS21002::FXAS21002(PinName sda, PinName scl) : gyroi2c(sda,scl)
{
}
bool FXAS21002::isConnected()
{
char d = 0;
readReg(FXAS21002_WHO_AM_I, &d, 1);
return d == FXAS21002_WHO_AM_I_VALUE;
}
void FXAS21002::config(void)
{
char d[2];
d[0] = FXAS21002_CTRL_REG1; //Puts device in standby mode
d[1] = 0x08;
gyroi2c.write(FXAS21002_I2C_ADDRESS, d,2);
d[0] = FXAS21002_CTRL_REG0; //sets FS =+/- 2000 dps
d[1] = 0x00;
gyroi2c.write(FXAS21002_I2C_ADDRESS, d, 2);
d[0] = FXAS21002_CTRL_REG1; //Puts device in active mode with ODR 200 Hz
d[1] = 0x0A;
gyroi2c.write(FXAS21002_I2C_ADDRESS, d,2);
}
void FXAS21002::calibrate()
{
int i = 0;
int nsamples = 200;
Vector3 tmp, bias_tmp;
while( i < nsamples)
{
if(isDataReady())
{
read(tmp);
bias_tmp = bias_tmp + tmp;
i++;
}
}
biases = bias_tmp / nsamples;
}
bool FXAS21002::isDataReady()
{
char d = 0;
readReg(FXAS21002_STATUS, &d, 1);
return d & (1 << 3);
}
void FXAS21002::read(Vector3 &data)
{
char data_bytes[7] = {0};
readReg(FXAS21002_STATUS, data_bytes, 7);
data.x = (float)((int16_t)((data_bytes[1]*256) + (data_bytes[2]))) * 0.0625f - biases.x;
data.y = (float)((int16_t)((data_bytes[3]*256) + (data_bytes[4]))) * 0.0625f - biases.y;
data.z = (float)((int16_t)((data_bytes[5]*256) + (data_bytes[6]))) * 0.0625f - biases.z;
}
void FXAS21002::readReg( char reg, char * d, int len)
{
char cmd[1] = {reg};
gyroi2c.write( FXAS21002_I2C_ADDRESS, cmd, 1, true);
gyroi2c.read ( FXAS21002_I2C_ADDRESS, d, len);
}
Question relating to:
1 Answer
9 years, 9 months ago.
Checking the schematic of the board or the datasheet of the K64 will show that both PTE24/PTE25 and PTD2/PTD3 connect to the same I2C engine (I2C_0). The onboard device is connected to PTE24/PTE25. Declaring another I2C object on PTD2/PTD3 will need the same I2C engine and disable the connection to PTE24/PTE25. You either need to connect both devices to PTE24/PTE25 or use I2C_1 to get two independent I2C engines. I2C_1 is connected to pins PTC10 (SCL) and PTC11(SDA).