I2C (INA219) on PICO W & ESP32S3

loosing some days on this
esp. finding out about the DEFAULT PINS for the link
and wiring problems using breadboard...

i want to share a trick / even it looks stupid, it is most effective

  Serial.print("SDA :");
  Serial.println(SDA);
  Serial.print("SCL :");
  Serial.println(SCL);

as it was about a connection of a INA219
i packed scan and device example into one
https://engineering-news.org/kllfusion01/downloads/Wire_Scan_INA219_ino.txt

at the end of code see the outprint for testing of both devices

  • PICO W
  • ESP32S3

hope it helps someone

also worth looking at is esp32-spi-communication-arduino which prints the default SPI pins
I extended it to also print the I2C pins

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-spi-communication-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

//Find the default SPI pins for your board
//Make sure you have the right board selected in Tools > Boards
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(3000);
  Serial.print("MOSI: ");
  Serial.println(MOSI);
  Serial.print("MISO: ");
  Serial.println(MISO);
  Serial.print("SCK: ");
  Serial.println(SCK);
  Serial.print("SS: ");
  Serial.println(SS);  
  Serial.print("SDA: ");
  Serial.println(SDA);  
  Serial.print("SCL: ");
  Serial.println(SCL);  
}

void loop() {
  // put your main code here, to run repeatedly:
}

on a RPi Pico displays

SDA 4
SCL 5
MOSI: 19
MISO: 16
SCK: 18
SS: 17

the program can be extended to print further information, e.g. on a ATtiny85

LED_BUILTIN 1
MOSI: 1
MISO: 0
SCK: 2
SS: 3
SDA: 0
SCL: 2
PB1: 1
PCINT1: 1
PB0: 0
PCINT0: 0
1 Like

Interesting code,

Some boards have more than one Wire (I2C) interface.
Is it possible to extract the actual SDA and SCL from the TwoWire object?
Something like int mySDA = getSDA(Wire1); etc?

1 Like

never heard of such a thing
with a new micro I generally run the code of post 2 to print the SPI and I2C pins but also look at pinouts, e.g. the ESP32 I2C, DAC, VSPI and HSPI pins etc


on the ESP32 it is generally possible to map interfaces to different pins

good question?
but lets dive into Arduino ( whats hides all that settings ) here:

C:/Users/user/AppData/Local/Arduino15/packages/rp2040/hardware/rp2040/4.4.4/variants/rpipicow/pins_arduino.h
// Wire
#define PIN_WIRE0_SDA (4u)
#define PIN_WIRE0_SCL (5u)

#define PIN_WIRE1_SDA (26u)
#define PIN_WIRE1_SCL (27u)
 

C:/Users/user/AppData/Local/Arduino15/packages/esp32/hardware/esp32/3.1.3/variants/esp32s3/pins_arduino.h
static const uint8_t SDA = 8;
static const uint8_t SCL = 9; 

for a way to use other pins, i found:

"You may change these pins before calling Wire.begin() or Wire1.begin() using:

bool setSDA(pin_size_t sda);
bool setSCL(pin_size_t scl);
"
so i try

  Wire.setSDA(4);
  Wire.setSCL(5);
  Wire.begin(); 

what does compile ( but i not fully tested )
esp. as like Adafruit LIB starts Wire.begin() internally ?again?

here is an example of setting I2C pins I used on an ESP-CAM wirh a BMP280

/* Interfacing ESP32-CAM with BMP280 temperature and pressure sensor.
 * Temperature and pressure values are displayed on 16x2 LCD.
 * This is a free software with NO WARRANTY.
 * https://simple-circuit.com/
 */


#include <Wire.h>             // include Wire library, required for I2C devices
#include <Adafruit_Sensor.h>  // include Adafruit sensor library
#include <Adafruit_BMP280.h>  // include adafruit library for BMP280 sensor

// define I2C pins
#define I2C_SDA 16
#define I2C_SCL 0

// define device I2C address: 0x76 or 0x77 (0x77 is library default address)
#define BMP280_I2C_ADDRESS 0x76

Adafruit_BMP280 bmp280;

void setup() {
  Serial.begin(115200);
  Serial.println(F("ESP32-CAM + BMP280"));
  Wire.begin(I2C_SDA, I2C_SCL);           // <<<<<<<< set I2C pins
  if (!bmp280.begin(BMP280_I2C_ADDRESS)) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1)
      ;
  }
  Serial.println("Found BMP280 sensor!");
}

void loop() {
  // get temperature, pressure and altitude from library
  float temperature = bmp280.readTemperature();    // get temperature
  float pressure = bmp280.readPressure();          // get pressure
  float altitude_ = bmp280.readAltitude(1013.25);  // get altitude (this should be adjusted to your local forecast)
  // print data on the serial monitor software
  // 1: print temperature
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.println(" °C");
  // 2: print pressure
  Serial.print("Pressure    = ");
  Serial.print(pressure / 100);
  Serial.println(" hPa");
  // 3: print altitude
  Serial.print("Approx Altitude = ");
  Serial.print(altitude_);
  Serial.println(" m");

  Serial.println();  // start a new line
  delay(2000);       // wait 2 seconds
}

serial monitor output

ESP32-CAM + BMP280
Found BMP280 sensor!
Temperature = 20.81 °C
Pressure    = 1006.52 hPa
Approx Altitude = 56.21 m

Temperature = 20.84 °C
Pressure    = 1006.48 hPa
Approx Altitude = 56.55 m

Temperature = 21.91 °C
Pressure    = 1006.36 hPa
Approx Altitude = 57.55 m

Temperature = 21.87 °C
Pressure    = 1006.37 hPa
Approx Altitude = 57.40 m

Temperature = 23.89 °C
Pressure    = 1007.74 hPa
Approx Altitude = 43.99 m

Temperature = 24.87 °C
Pressure    = 1006.06 hPa
Approx Altitude = 60.36 m

Temperature = 24.68 °C
Pressure    = 1006.02 hPa
Approx Altitude = 60.74 m
1 Like

i try to follow your example:

  //Wire.setSDA(4);
  //Wire.setSCL(5);
  Wire.begin(4,5); 

but see: ( for board: PICO W )
Compilation error: no matching function for call to 'TwoWire::begin(int, int)'

but work with old ESP32 board???

setSDA() etc works on works on the Raspberry Pi PICO RP2040

// RP20040 Basic demo for accelerometer readings from Adafruit MPU6050

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

// define I2C1 RP2040 pins for MPU6050
#define SDA 18
#define SCL 19

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  delay(2000);
  while (!Serial)
    delay(10);  // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("\n\nAdafruit MPU6050/BME280 test!");
  Wire1.setSDA(SDA);  // <<<<<<< setup SDA and SCL pins
  Wire1.setSCL(SCL);
  Wire1.begin();

  // Try to initialize!
  if (!mpu.begin(0x68, &Wire1, 0)) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }

  Serial.println("");
  setup_BME280();
  delay(100);
}

void loop() {

  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(1000);
  loop_BME_280();
  delay(2000);
}

results

Adafruit MPU6050/BME280 test!
MPU6050 Found!
Accelerometer range set to: +-8G
Gyro range set to: +- 500 deg/s
Filter bandwidth set to: 21 Hz


BME280 test
BME280 found -- Default Test --

Acceleration X: -1.96, Y: 0.53, Z: 8.19 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.68 degC

Temperature = 21.27 *C
Pressure = 1030.30 hPa
Approx. Altitude = -140.98 m
Humidity = 48.46 %

Acceleration X: -1.98, Y: 0.51, Z: 8.18 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.01 rad/s
Temperature: 22.79 degC

Temperature = 21.31 *C
Pressure = 1030.32 hPa
Approx. Altitude = -141.14 m
Humidity = 48.41 %

Acceleration X: -1.97, Y: 0.53, Z: 8.17 m/s^2
Rotation X: 0.15, Y: 0.03, Z: 0.00 rad/s
Temperature: 22.88 degC

1 Like