Trouble Starting 2 I2C buses QT PY RP2040

I am attempting to use two I2C buses on a QT PY RP2040 w/ Arduino IDE. I can get one bus to start. However, I cant seem to find the correct command(s) to start both Wire and Wire1 at the same time.

I tested my wiring with adafruit code successfully (I2CScan). I just cant get my code to work. Please see below code.


#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_MPL3115A2.h>

Adafruit_MPL3115A2 mpl;
Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  delay(5000);
  while (!Serial) {
    delay(10); 
  }

  Wire.begin(); 
  delay(1000);            
  Wire1.begin();     
  
  // the MPL is wired to GPIO 24&25. I can see this one.
  if (!mpl.begin()) {
    Serial.println("Could not find sensor mpl. Check wiring.");
    while(1);
  }
  
  //program always tanks here. The MPU breakout is on the STEMMA (GPIO22&23)
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }

there is more to the code but it is not relevant as we never get that far...
I get the "Failed to find MPU6050 chip" in the serial monitor.

Thanks for any help
K

Welcome to the forum.

One has I2C address 0x60 and the other has 0x69. You can connect them to the same I2C bus.

Thanks for the welcome...

I am not sure I understand. the devices are not on the same bus..... Below is some example code provided by adafruit that works great... and show the devices are not on the same bus. I used it to do a few things like: ensure devices communicate, wiring is correct, show the buses the devices are on, etc...

here is the output:

Default port (Wire) I2C scan: 0x60, 
Secondary port (Wire1) I2C scan: 0x68,

Here is the code the generated it:

#include <Adafruit_TestBed.h>
extern Adafruit_TestBed TB;

#define DEFAULT_I2C_PORT &Wire

// Some boards have TWO I2C ports, how nifty. We should scan both
#if defined(ARDUINO_ARCH_RP2040) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) \
    || defined(ARDUINO_SAM_DUE)
  #define SECONDARY_I2C_PORT &Wire1
#endif

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

  // Wait for Serial port to open
  while (!Serial) {
    delay(10);
  }
  delay(500);
  Serial.println("Adafruit I2C Scanner");

#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
    defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
    defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) || \
    defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
  // ESP32 is kinda odd in that secondary ports must be manually
  // assigned their pins with setPins()!
  Wire1.setPins(SDA1, SCL1);
#endif

#if defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
  // turn on the I2C power by setting pin to opposite of 'rest state'
  pinMode(PIN_I2C_POWER, INPUT);
  delay(1);
  bool polarity = digitalRead(PIN_I2C_POWER);
  pinMode(PIN_I2C_POWER, OUTPUT);
  digitalWrite(PIN_I2C_POWER, !polarity);
#endif

#if defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT)
  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
#endif

#if defined(ADAFRUIT_FEATHER_ESP32_V2)
  // Turn on the I2C power by pulling pin HIGH.
  pinMode(NEOPIXEL_I2C_POWER, OUTPUT);
  digitalWrite(NEOPIXEL_I2C_POWER, HIGH);
#endif
}

void loop() {
  Serial.println("");
  Serial.println("");

  Serial.print("Default port (Wire) ");
  TB.theWire = DEFAULT_I2C_PORT;
  TB.printI2CBusScan();

#if defined(SECONDARY_I2C_PORT)
  Serial.print("Secondary port (Wire1) ");
  TB.theWire = SECONDARY_I2C_PORT;
  TB.printI2CBusScan();
#endif

  delay(3000); // wait 3 seconds
}

If there is no reason for two I2C buses, then use one I2C bus. That is the best way to stay out of trouble. Follow the KISS rule.

However, if you prefer to do things the hard way and learn from the experience, then it should work on two different I2C buses.
Some libraries allow a pointer to the Wire object.
Adafruit_MPL3115A2 here:

boolean begin(TwoWire *twoWire = &Wire);

Adafruit_MPU6050 here:

bool begin(uint8_t i2c_addr = MPU6050_I2CADDR_DEFAULT, TwoWire *wire = &Wire, int32_t sensorID = 0);

That's good, they both support it. You tell the library which bus to use (which Wire object).

if (!mpl.begin(&Wire)) {
  ...

if (!mpu.begin(MPU6050_I2CADDR_DEFAULT, &Wire1)) {
  ...

If that works, then that was fun, but please put them both on the same I2C bus :pleading_face:

Why did you choose the QT Py RP2040 ? Adafruit QT Py RP2040 : ID 4900 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits
It is a very small, affordable and available board with USB-C connector and it seems that it does not need a custom bootloader. Nice!
Does it have both I2C buses on its pins ?

[UPDATE]
I saw the pinout: https://learn.adafruit.com/assets/107201
So the first I2C bus is on the pins and the second I2C bus is on the STEMMA QT connector. Okay :thinking: a bit weird. It allows to use two I2C devices that have the same I2C address. Not every library can use the second I2C bus.

Thanks much... the key was in the begin I only needed to swap some simple code...

Old:

 if (!mpu.begin()) {

New:
if (!mpu.begin(0x68, &Wire1)) {

and magic it works.

thanks again for helping me solve this one.
K

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.