Skip to content

Commit

Permalink
Fix I2C MPU9250
Browse files Browse the repository at this point in the history
  • Loading branch information
qqqlab committed May 27, 2024
1 parent e81da19 commit 1a50d16
Show file tree
Hide file tree
Showing 13 changed files with 306 additions and 167 deletions.
116 changes: 67 additions & 49 deletions extras/I2C_Chip_Scanner/I2C_Chip_Scanner.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,43 @@ I2C: Found address: 0x77 (decimal 119)
I2C: Found 4 device(s)
====================================================================*/

#include "Wire.h"

TwoWire *i2c = &Wire;

#define ESP32_SDA_PIN 23
#define ESP32_SCL_PIN 22

#define RP2040_SDA_PIN 20
#define RP2040_SCL_PIN 21
#define RP2040_SDA_PIN 20 //Wire: 0, 4(default), 8, 12, 16, 20 Wire1: 2, 6, 10, 14, 18, 26(default)
#define RP2040_SCL_PIN 21 //Wire: 1, 5(default), 9, 13, 17, 21 Wire1: 3, 7, 11, 15, 19, 27(default)

#define STM32_SDA_PIN PB9
#define STM32_SCL_PIN PB8

#define I2C_FRQ 400000

#include "Wire.h"



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

//start Wire
//start WIRE
#if defined ARDUINO_ARCH_ESP32
Wire.begin(ESP32_SDA_PIN, ESP32_SCL_PIN, I2C_FRQ);
i2c->begin(ESP32_SDA_PIN, ESP32_SCL_PIN, I2C_FRQ);
#elif defined ARDUINO_ARCH_RP2040
Wire.setSDA(RP2040_SDA_PIN);
Wire.setSCL(RP2040_SCL_PIN);
Wire.setClock(I2C_FRQ);
Wire.begin();
i2c->setSDA(RP2040_SDA_PIN);
i2c->setSCL(RP2040_SCL_PIN);
i2c->setClock(I2C_FRQ);
i2c->begin();
#elif defined ARDUINO_ARCH_STM32
Wire.setSDA(STM32_SDA_PIN);
Wire.setSCL(STM32_SCL_PIN);
Wire.setClock(I2C_FRQ);
Wire.begin();
i2c->setSDA(STM32_SDA_PIN);
i2c->setSCL(STM32_SCL_PIN);
i2c->setClock(I2C_FRQ);
i2c->begin();
#else
#warning "Using default I2C pins"
Wire.begin();
i2c->begin();
#endif
}

Expand All @@ -59,8 +64,8 @@ void loop() {
Serial.printf("I2C: Scanning ...\n");
int num_adr_found = 0;
for (uint8_t adr = 8; adr < 120; adr++) {
Wire.beginTransmission(adr); // Begin I2C transmission Address (i)
if (Wire.endTransmission() == 0) { // Receive 0 = success (ACK response)
i2c->beginTransmission(adr); // Begin I2C transmission Address (i)
if (i2c->endTransmission() == 0) { // Receive 0 = success (ACK response)
Serial.printf("I2C: Found address: 0x%02X (decimal %d)\n",adr,adr);
num_adr_found++;
i2c_identify_chip(adr);
Expand All @@ -76,33 +81,38 @@ struct test_struct{
uint8_t reg;
uint8_t len;
uint32_t expected;
char descr[60];
String descr;
};

//table of addresses, register and expected reply
test_struct tests[] = {
// adr1 adr2 reg len exp descr
{0x0D, 0x0D, 0x0D, 1, 0xFF, "QMC5883L"},
{0x1E, 0x1E, 0x0A, 3, 0x483433, "HMC5883L"}, // ID-Reg-A 'H', ID-Reg-B '4', ID-Reg-C '3'
{0x40, 0x4F, 0x00, 2, 0x399F, "INA219"},
{0x40, 0x4F, 0x00, 2, 0x4127, "INA226"},
{0x48, 0x4F, 0x01, 2, 0x8583, "ADS1113, ADS1114, or ADS1115"},
{0x68, 0x69, 0x00, 1, 0xEA, "ICM-20948"},
{0x0D, 0x0D, 0x0D, 1, 0xFF, "QMC5883L magnetometer"},
{0x1E, 0x1E, 0x0A, 3, 0x483433, "HMC5883L magnetometer"}, // ID-Reg-A 'H', ID-Reg-B '4', ID-Reg-C '3'
{0x40, 0x4F, 0x00, 2, 0x399F, "INA219 current sensor"},
{0x40, 0x4F, 0x00, 2, 0x4127, "INA226 current sensor"},
{0x48, 0x4F, 0x01, 2, 0x8583, "ADS1113, ADS1114, or ADS1115 ADC"},
{0x68, 0x69, 0x00, 1, 0xEA, "ICM-20948 9DOF"},
{0x68, 0x69, 0x00, 1, 0x68, "MPU3050"},
{0x68, 0x69, 0x00, 1, 0x69, "MPU3050"},
{0x68, 0x69, 0x75, 1, 0x19, "MPU6886"},
{0x68, 0x69, 0x75, 1, 0x68, "MPU6000, MPU6050, or MPU9150"},
{0x68, 0x69, 0x75, 1, 0x70, "MPU6500"},
{0x68, 0x69, 0x75, 1, 0x71, "MPU9250"},
{0x68, 0x69, 0x75, 1, 0x72, "FAKE MPU6050, got WHO_AM_I=0x72, real chip returns 0x68"},
{0x68, 0x69, 0x75, 1, 0x19, "MPU6886 6DOF"},
{0x68, 0x69, 0x75, 1, 0x68, "MPU6000, MPU6050, or MPU9150 6/9DOF"},
{0x68, 0x69, 0x75, 1, 0x69, "FAKE MPU6050, got WHO_AM_I=0x69, real chip returns 0x68"},
{0x68, 0x69, 0x75, 1, 0x70, "MPU6500 6DOF"},
{0x68, 0x69, 0x75, 1, 0x71, "MPU9250 9DOF"},
{0x68, 0x69, 0x75, 1, 0x72, "FAKE MPU6050, got WHO_AM_I=0x72, real chip returns 0x68"},
{0x68, 0x69, 0x75, 1, 0x73, "MPU9255 9DOF"},
{0x68, 0x69, 0x75, 1, 0x74, "MPU9515"},
{0x68, 0x69, 0x75, 1, 0x75, "FAKE MPU9250, got WHO_AM_I=0x75, real chip returns 0x71"},
{0x68, 0x69, 0x75, 1, 0x78, "FAKE MPU9250, got WHO_AM_I=0x78, real chip returns 0x71"},
{0x68, 0x69, 0x75, 1, 0x98, "ICM-20689"},
{0x76, 0x76, 0xD0, 1, 0x56, "BMP280"},
{0x76, 0x76, 0xD0, 1, 0x57, "BMP280"},
{0x76, 0x76, 0xD0, 1, 0x58, "BMP280"},
{0x76, 0x76, 0xD0, 1, 0x60, "BME280"},
{0x76, 0x76, 0xD0, 1, 0x61, "BMP680"},
{0x76, 0x77, 0x0D, 1, 0x10, "DPS310 or HP303B"},
{0x77, 0x77, 0xD0, 1, 0x55, "BMP180"},
{0x76, 0x76, 0xD0, 1, 0x56, "BMP280 pressure"},
{0x76, 0x76, 0xD0, 1, 0x57, "BMP280 pressure"},
{0x76, 0x76, 0xD0, 1, 0x58, "BMP280 pressure"},
{0x76, 0x76, 0xD0, 1, 0x60, "BME280 pressure"},
{0x76, 0x76, 0xD0, 1, 0x61, "BMP680 pressure"},
{0x76, 0x77, 0x0D, 1, 0x10, "DPS310 or HP303B pressure"},
{0x77, 0x77, 0xD0, 1, 0x55, "BMP180 pressure"},


{0,0,0,0,0,""} //end
Expand All @@ -125,6 +135,8 @@ adrtest_struct adrtests[] = {
void i2c_identify_chip(uint8_t adr) {
bool found = false;

uint32_t tried[256] = {0};

//try adr,reg,result match
int i = 0;
while(tests[i].adr1) {
Expand All @@ -138,33 +150,39 @@ void i2c_identify_chip(uint8_t adr) {
uint8_t data[4];
i2c_ReadRegs(adr, reg, data, len);
for(int i=0;i<len;i++) received = (received<<8) + data[i];
tried[reg] = received;
if(received == expected) {
Serial.printf(" MATCH (adr=0x%02X reg=0x%02X result=0x%02X): %s\n", adr, reg, received, tests[i].descr);
Serial.printf(" MATCH: reg=0x%02X result=0x%02X -> %s\n", reg, (int)received, tests[i].descr.c_str());
found = true;
}
}
i++;
}

if(!found) {
//show tries
for(int i=0;i<256;i++) if(tried[i]!=0) {
Serial.printf(" tried: reg=0x%02X result=0x%02X\n", i, (int)tried[i]);
}

//try address only match
int i = 0;
while(adrtests[i].adr1) {
int adr1 = adrtests[i].adr1;
int adr2 = adrtests[i].adr2;
if(adr1<=adr && adr<=adr2) {
Serial.printf(" POTENTIAL MATCH (address 0x%02X match only): %s\n", adr, adrtests[i].descr);
Serial.printf(" POTENTIAL MATCH (address 0x%02X match only) -> %s\n", adr, adrtests[i].descr);
}
i++;
}
}
}

void WriteReg( uint8_t adr, uint8_t reg, uint8_t data ) {
Wire.beginTransmission(adr);
Wire.write(reg);
Wire.write(data);
Wire.endTransmission();
i2c->beginTransmission(adr);
i2c->write(reg);
i2c->write(data);
i2c->endTransmission();
}

unsigned int i2c_ReadReg( uint8_t adr, uint8_t reg ) {
Expand All @@ -174,22 +192,22 @@ unsigned int i2c_ReadReg( uint8_t adr, uint8_t reg ) {
}

void i2c_ReadRegs( uint8_t adr, uint8_t reg, uint8_t *data, uint8_t n ) {
Wire.beginTransmission(adr);
Wire.write(reg);
Wire.endTransmission(false); //false = repeated start
uint8_t bytesReceived = Wire.requestFrom(adr, n);
i2c->beginTransmission(adr);
i2c->write(reg);
i2c->endTransmission(false); //false = repeated start
uint8_t bytesReceived = i2c->requestFrom(adr, n);
if(bytesReceived == n) {
Wire.readBytes(data, bytesReceived);
i2c->readBytes(data, bytesReceived);
}
}

void i2c_scan() {
Serial.printf("I2C: Scanning ...\n");
byte count = 0;
Wire.begin();
i2c->begin();
for (byte i = 8; i < 120; i++) {
Wire.beginTransmission(i); // Begin I2C transmission Address (i)
if (Wire.endTransmission() == 0) { // Receive 0 = success (ACK response)
i2c->beginTransmission(i); // Begin I2C transmission Address (i)
if (i2c->endTransmission() == 0) { // Receive 0 = success (ACK response)
Serial.printf("I2C: Found address: 0x%02X (%d)\n",i,i);
count++;
}
Expand Down
72 changes: 0 additions & 72 deletions extras/TestMadflight/imu.ino

This file was deleted.

40 changes: 40 additions & 0 deletions extras/TestMadflight/imu/imu.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//test program for imu.h - used with madflight 1.1.3

#define IMU_USE IMU_USE_I2C_MPU9250
#define IMU_I2C_ADR 0x68

#define MF_TEST MF_TEST_IMU
#include <madflight.h>


void setup() {
Serial.begin(115200);
while(!Serial);

hw_setup(); //hardware specific setup for spi and Wire (see hw_xxx.h)

//IMU: keep on trying until no error is returned (some sensors need a couple of tries...)
while(true) {
int rv = imu.setup(); //request 1000 Hz sample rate, returns 0 on success, positive on error, negative on warning
if(rv<=0) break;
Serial.print("IMU: init failed rv= " + String(rv) + ". Retrying...\n");
i2c->begin();
delay(1000);
}

//start IMU update handler
imu.onUpdate = imu_loop;
while(!imu.waitNewSample()) Serial.println("IMU interrupt not firing.");
}

int imu_loop_cnt = 0;

void imu_loop() {
imu_loop_cnt++;
}

void loop() {
Serial.printf("imu_loop_cnt:%d az:%f gz:%f mz:%f\n",imu_loop_cnt, imu.az, imu.gz, imu.mz);
delay(1000);
}

Binary file added extras/img/RP2040-Zero.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 1a50d16

Please sign in to comment.