About ESP32 I2C pin config

Hi, everyone.
the ESP32 I2C pin config not work, the code below only work when hooked SAD=21, SCL=22, no matter new confided I2C or not. why?
Thanks.
Adam

#include <Wire.h>
#include "Adafruit_MCP23017.h"

#define MCPAddress  0x20   // **** new add for ESP32CAM 
Adafruit_MCP23017 mcp; //default scan address 000=0x20 ,001=0x24
/*
#define I2C_Freq 100000
#define SDA_0 14
#define SCL_0 15
TwoWire I2C_0 = TwoWire(0);
*/
void setup() {
  Serial.begin(115200);

  Serial.print("File   : "), Serial.println(__FILE__);
  const char compile_date[] = __DATE__ " " __TIME__;
  Serial.print("Compile timestamp: ");
  Serial.println(compile_date);

  mcp.begin();      // use default address 0
  setup_gpio_mode();

//  I2C_0.begin(SDA_0 , SCL_0 );
  Wire.setClock(100000); //frequencia
  
  i2c_scan(); // got the address and put it behind the serial to monitor  //ได้ address แล้วปิดไว้ ไว้หลัง serial เพื่อ monitor
}

int i = 0;
void loop() {

  Serial.println("Write 16 IO = 1");
  test_io(1);
  delay(1000);

  Serial.println("Write 16 IO = 0");
  test_io(0);
  delay(1000);

  i++;
  if (i == 6) sleep(); //sleep เพื่อเช็ค status ตอนรันเทสไม่ต้อง sleep
}

void i2c_scan() {
  byte error, address;
  int nDevices;
  Serial.println();
  Serial.println("Scanning...");
  nDevices = 0;
  for (address = 1; address < 127; address++ )  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");
      nDevices++;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000); // wait 5 seconds for next scan
}

void setup_gpio_mode() {
  mcp.pinMode(0, OUTPUT);
  mcp.pinMode(1, OUTPUT);
  mcp.pinMode(2, OUTPUT);
  mcp.pinMode(3, OUTPUT);
  mcp.pinMode(4, OUTPUT);
  mcp.pinMode(5, OUTPUT);
  mcp.pinMode(6, OUTPUT);
  mcp.pinMode(7, OUTPUT);
  mcp.pinMode(8, OUTPUT);
  mcp.pinMode(9, OUTPUT);
  mcp.pinMode(10, OUTPUT);
  mcp.pinMode(11, OUTPUT);
  mcp.pinMode(12, OUTPUT);
  mcp.pinMode(13, OUTPUT);
  mcp.pinMode(14, OUTPUT);
  mcp.pinMode(15, OUTPUT);
}

void test_io(int val) {
  mcp.digitalWrite(0, val);
  mcp.digitalWrite(1, val);
  mcp.digitalWrite(2, val);
  mcp.digitalWrite(3, val);
  mcp.digitalWrite(4, val);
  mcp.digitalWrite(5, val);
  mcp.digitalWrite(6, val);
  mcp.digitalWrite(7, val);
  mcp.digitalWrite(8, val);
  mcp.digitalWrite(9, val);
  mcp.digitalWrite(10, val);
  mcp.digitalWrite(11, val);
  mcp.digitalWrite(12, val);
  mcp.digitalWrite(13, val);
  mcp.digitalWrite(14, val);
  mcp.digitalWrite(15, val);
}

void sleep() {
  Serial.println("Sleeping... 30 sec");
  //  ESP.deepSleep(30 * 1000000, WAKE_RF_DEFAULT);//Sleep for 60 seconds
}

ESP32 - I2C Scanner using Arduino IDE (working) - ESP32 Forum

1 Like

I2C

The ESP32 has two I2C channels and any pin can be set as SDA or SCL. When using the ESP32 with the Arduino IDE, the default I2C pins are:

  • GPIO 21 (SDA)
  • GPIO 22 (SCL)

If you want to use other pins when using the wire library, you just need to call:

Wire.begin(SDA, SCL);

I prefer to use the ESP32's I2C API,

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html

1 Like

Thanks for help.
I did test the:

  1. Wire.begin(4, 2);
  2. used pull-up circuit;
  3. added:
#define I2C_Freq 100000
#define SDA_0 GPIO 14  ///  4 for  another test
#define SCL_0 GPIO 15  /// 2   for another test

TwoWire I2C_0 = TwoWire(0);

setup()
I2C_0.begin(SDA_0 , SCL_0 ); // wire.begin(SDA_0 , SCL_0 ); for another test

none works.

I'd not use a GPIO pin that is connected to the developer board internal LED.

1 Like

thanks.
it was tested not work without GPIO.

I am going through this myself. TwoWire does not work. SoftWire does not work. half of the I2C scanners I try find the OLED and half find nothing. there are no pins on the OLED board that can be traced.

this did not work on 34 and 35

this compiled but did not work
https://rntlab.com/question/troubles-with-i2c-communication-more-devices/

this did not work

the board I'm using:

1 Like

Thank you Geek_Emeritus.
you done a lot of.

I did test ESP32-30pin, ESP32 - 38pin, ESP32CAM.
the 30pin and 38pin works when set (or without set and use default) SDA=21, DCL=22;
the ESP32CAM and ESP32 set other pins all no work.

OR MAYBE THE ESP32 CAN'T DO ANY THING ABOUT I2C PIN!!!!!!!!!!!!!!!!!!!!!!!

I found two clues, but don't know how to use them, need help please:

  1. this link said 0x100 is the magic number to disconnect the I2C signal from the previous pins.
    I2C doesn't work properly if reconfigure the gpios used - ESP32 Forum
    how to use it?
  2. [pins_arduino.h] seems be able to edit pins, how to do it please?
    ArduinoCore-avr/pins_arduino.h at master · arduino/ArduinoCore-avr · GitHub
    Thanks
    Adam

Try studying this.

1 Like

Thanks.
I checked that page before, and did't figular out how to set other than default pins into I2C pin yet.

Show a complete code where you used:

Wire.begin(SDA, SCL);

and it "didn't work". Then specifically and completely describe what you mean by "didn't work".

1 Like

Funny thing is when I give reassigning I2C pins a shot, it works. And when I use both I2C ESP32's interfaces, it works.

1 Like

Thank you Idahowalker.
what sketch did you used please.

I used the same principle you indicate that is not working for you.

1 Like

@shanren, please post your complete code and description of "doesn't work" as I requested.

1 Like

Thanks.
the code is in #1.
it works when comment out the picture content and // I2C_0.begin(SDA_0 , SCL_0 ); ; did't work when remove comment out lines, actually it still works on default I2C pins in this situation.
p1.1

I'll ask one more time, then I'm done trying to help you. Make a new post with the complete code that doesn't work using:

Wire.begin(SDA, SCL);
1 Like

here is the code works on pin21/22 with Wire.begin(SDA, SCL); even with new setting pin14/15.
also same result with Wire.begin(SDA_0, SCL_0); instead of Wire.begin(SDA, SCL);

#include <Wire.h>
#include "Adafruit_MCP23017.h"

#define MCPAddress  0x20   // **** new add for ESP32CAM 
Adafruit_MCP23017 mcp; //default scan address 000=0x20 ,001=0x24

#define I2C_Freq 100000
#define SDA_0 14
#define SCL_0 15
TwoWire I2C_0 = TwoWire(0);

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

  Serial.print("File   : "), Serial.println(__FILE__);
  const char compile_date[] = __DATE__ " " __TIME__;
  Serial.print("Compile timestamp: ");
  Serial.println(compile_date);

  mcp.begin();      // use default address 0
  setup_gpio_mode();

//  I2C_0.begin(SDA_0 , SCL_0 );
  Wire.setClock(100000); //frequencia

  Wire.begin(SDA, SCL);
  
  i2c_scan(); // got the address and put it behind the serial to monitor  //ได้ address แล้วปิดไว้ ไว้หลัง serial เพื่อ monitor
}

int i = 0;
void loop() {

  Serial.println("Write 16 IO = 1");
  test_io(1);
  delay(1000);

  Serial.println("Write 16 IO = 0");
  test_io(0);
  delay(1000);

  i++;
  if (i == 6) sleep(); //sleep เพื่อเช็ค status ตอนรันเทสไม่ต้อง sleep
}

void i2c_scan() {
  byte error, address;
  int nDevices;
  Serial.println();
  Serial.println("Scanning...");
  nDevices = 0;
  for (address = 1; address < 127; address++ )  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");
      nDevices++;
    } else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000); // wait 5 seconds for next scan
}

void setup_gpio_mode() {
  mcp.pinMode(0, OUTPUT);
  mcp.pinMode(1, OUTPUT);
  mcp.pinMode(2, OUTPUT);
  mcp.pinMode(3, OUTPUT);
  mcp.pinMode(4, OUTPUT);
  mcp.pinMode(5, OUTPUT);
  mcp.pinMode(6, OUTPUT);
  mcp.pinMode(7, OUTPUT);
  mcp.pinMode(8, OUTPUT);
  mcp.pinMode(9, OUTPUT);
  mcp.pinMode(10, OUTPUT);
  mcp.pinMode(11, OUTPUT);
  mcp.pinMode(12, OUTPUT);
  mcp.pinMode(13, OUTPUT);
  mcp.pinMode(14, OUTPUT);
  mcp.pinMode(15, OUTPUT);
}

void test_io(int val) {
  mcp.digitalWrite(0, val);
  mcp.digitalWrite(1, val);
  mcp.digitalWrite(2, val);
  mcp.digitalWrite(3, val);
  mcp.digitalWrite(4, val);
  mcp.digitalWrite(5, val);
  mcp.digitalWrite(6, val);
  mcp.digitalWrite(7, val);
  mcp.digitalWrite(8, val);
  mcp.digitalWrite(9, val);
  mcp.digitalWrite(10, val);
  mcp.digitalWrite(11, val);
  mcp.digitalWrite(12, val);
  mcp.digitalWrite(13, val);
  mcp.digitalWrite(14, val);
  mcp.digitalWrite(15, val);
}

void sleep() {
  Serial.println("Sleeping... 30 sec");
  //  ESP.deepSleep(30 * 1000000, WAKE_RF_DEFAULT);//Sleep for 60 seconds
}

If all that works, what doesn't work?