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.
8 years, 2 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
8 years, 2 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).