• Skip to main content
  • Skip to primary sidebar

RNTLab.com

The Ultimate Shortcut to Learn Electronics and Programming with Open Source Hardware and Software

  • Courses
  • Forum
    • Forum
    • Ask Question
  • Shop
  • Account
  • Blog
  • Login

Use Different I2C Pins

Q&A Forum › Category: ESP32 › Use Different I2C Pins
0 Vote Up Vote Down
David Fenner asked 1 month ago

Hi readers.
I am trying to connect two sensors SI7021 and HTU21d to a ESP32_6 mini therefore I need to assign I2C as my understanding is that it doesn’t have default I2C pins like the ESP32 does.
So my first project with this board was using a BME280 sensor using the information supplied by Rui Santos. Use Different I2C Pins with ESP32 (change default I2C pins)

ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals (Arduino IDE)


 
I am a bit lost now when I look at the respective Adafrult CPP files . Therefore I would appreciate some expert assistance in how I use the information in the CPP files.
So I know the commands to use in my  configuration/ setup of my respective sketchs

Question Tags: Use Different I2C Pins ESP32 6 mini
13 Answers
0 Vote Up Vote Down
Sara Santos Staff answered 1 month ago

Hi.
You don’t need to modify any library files.
In the tutorial, we’re just taking a look at the library files to see that the only way to use custom pins with the library is to use a TwoWire instance.

You can use this code as a starting point: https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/ESP32/I2C/ESP32_BME280_Set_I2C_Pins.ino
 
You can adjust the pins you want to use in these lines:

#define I2C_SDA 33
#define I2C_SCL 32

Regards,
Sara

0 Vote Up Vote Down
David Fenner answered 1 month ago

Hi Sara
Thank you for your reply. I am using your example as a starting point as you suggested, however I have run into a problem.
Below is the error I am being presented with  followed by my  sketch could you comment on where I am going wrong.
 
C:\Users\Me\Documents\Arduino\ESP32_6_HTU21D\ESP32_6_HTU21D.ino: In function ‘void setup()’: C:\Users\Me\Documents\Arduino\ESP32_6_HTU21D\ESP32_6_HTU21D.ino:15:19: error: no matching function for call to ‘Adafruit_HTU21DF::begin(int, TwoWire*)’ 15 | status = htu.begin(0x40, &I2Chtu); | ~~~~~~~~~^~~~~~~~~~~~~~~ In file included from C:\Users\Me\Documents\Arduino\ESP32_6_HTU21D\ESP32_6_HTU21D.ino:2: C:\Users\Me\Documents\Arduino\libraries\Adafruit_HTU21DF_Library/Adafruit_HTU21DF.h:36:8: note: candidate: ‘bool Adafruit_HTU21DF::begin(TwoWire*)’ 36 | bool begin(TwoWire *theWire = &Wire); | ^~~~~ C:\Users\Me\Documents\Arduino\libraries\Adafruit_HTU21DF_Library/Adafruit_HTU21DF.h:36:8: note: candidate expects 1 argument, 2 provided C:\Users\Me\Documents\Arduino\ESP32_6_HTU21D\ESP32_6_HTU21D.ino:17:1: error: ‘If’ was not declared in this scope 17 | If (!status) { | ^~ exit status 1 Compilation error: no matching function for call to ‘Adafruit_HTU21DF::begin(int, TwoWire*)’
 
My work in progress sketch:-
 
#include <Wire.h>
#include “Adafruit_HTU21DF.h”
#define I2C_SDA 1
#define I2C_SCL 2
 
TwoWire I2Chtu = TwoWire(0);
Adafruit_HTU21DF htu;
void setup() {
  Serial.begin(9600);
I2Chtu.begin(I2C_SDA, I2C_SCL, 100000);
bool status;
status = htu.begin(0x40, &I2Chtu);
 
If (!status) {
    Serial.println(“Couldn’t find sensor!”);
    while (1);
  }
delay(1000);
Serial.println();
}
void loop() {
    float temp = htu.readTemperature();
    float rel_hum = htu.readHumidity();
    Serial.print(“Temp: “); Serial.print(temp); Serial.print(” C”);
    Serial.print(“\t\t”);
    Serial.print(“Humidity: “); Serial.print(rel_hum); Serial.println(” \%”);
    delay(500);
}

0 Vote Up Vote Down
Sara Santos Staff answered 1 month ago

Hi.
 
You must always take a look at the library files for the specific sensor you’re using.
If you take a look at the library file: https://github.com/adafruit/Adafruit_HTU21DF_Library/blob/master/Adafruit_HTU21DF.cpp
 
You’ll see that the begin method only accepts the TwoWire instance and not the I2C address. See line 45.
 
In this case, you need to modify this line:

status = htu.begin(0x40, &I2Chtu);

to 

bool status = htu.begin(&I2Chtu);

Also, you have a capitalized If statement. It should be if.

 
 
I hope this helps.
 
 
Let me know if you can make it work.
 
 
Regards,
 
Sara

0 Vote Up Vote Down
David Fenner answered 1 month ago

Hi Sara,
Thank you, your fix corrected my problem.
If I may take a bit more of your time I do have a few further questions on this topic:-

Could you confirm whether the following two code snippets are the same:-
Adafruit_HTU21DF sensor;
Adafruit_Si7021 sensor = sensor ();
I can see the point yore were making regarding the following items in the library files:-
bool Adafruit_BME280::begin(uint8_t addr, TwoWire *theWire) {
bool Adafruit_HTU21DF::begin(TwoWire *theWire) {

However, on my finial sensor a si7021 the sensor Adafruit_Si7021 library file shows:
Adafruit_Si7021::Adafruit_Si7021(TwoWire *theWire) {
Could you provide an example to work with for this statement like you did with the HTU21D. My work in progress sketch is blow:-
#include “Adafruit_Si7021.h”
bool enableHeater = false;
uint8_t loopCnt = 0;
#define I2C_SDA 1
#define I2C_SCL 2
TwoWire I2Csensor = TwoWire(0);
//Adafruit_HTU21DF ABC;
Adafruit_Si7021 sensor = Adafruit_Si7021();
void setup() {
  Serial.begin(115200);
I2Csensor.begin(I2C_SDA, I2C_SCL, 100000);
//
// Could you provide an example of required code
//
  // wait for serial port to open
  while (!Serial) {
    delay(10);
  }
  Serial.println(“Si7021 test!”);
 
  if (!sensor.begin()) {
    Serial.println(“Did not find Si7021 sensor!”);
    while (true)
      ;
  }
  Serial.print(“Found model “);
  switch(sensor.getModel()) {
    case SI_Engineering_Samples:
      Serial.print(“SI engineering samples”); break;
    case SI_7013:
      Serial.print(“Si7013”); break;
    case SI_7020:
      Serial.print(“Si7020”); break;
    case SI_7021:
      Serial.print(“Si7021”); break;
    case SI_UNKNOWN:
    default:
      Serial.print(“Unknown”);
  }
  Serial.print(” Rev(“);
  Serial.print(sensor.getRevision());
  Serial.print(“)”);
  Serial.print(” Serial #”); Serial.print(sensor.sernum_a, HEX); Serial.println(sensor.sernum_b, HEX);
}
void loop() {
  Serial.print(“Humidity:    “);
  Serial.print(sensor.readHumidity(), 2);
  Serial.print(“\tTemperature: “);
  Serial.println(sensor.readTemperature(), 2);
  delay(1000);
  // Toggle heater enabled state every 30 seconds
  // An ~1.8 degC temperature increase can be noted when heater is enabled
  if (++loopCnt == 30) {
    enableHeater = !enableHeater;
    sensor.heater(enableHeater);
    Serial.print(“Heater Enabled State: “);
    if (sensor.isHeaterEnabled())
      Serial.println(“ENABLED”);
    else
      Serial.println(“DISABLED”);
       
    loopCnt = 0;
  }
}
 
It also would be most appreciated, If you could provide or direct me to information regarding interpreting the outcome needs from the library file statements we have been discussing. This is so if I have a need to use a different sensor in the future and it’s not one you have provided the way forward for, I can interpret the instruction by myself.
 
Best Regard
Dave

0 Vote Up Vote Down
David Fenner answered 1 month ago

Hi Sara,
Thank you, your fix corrected my problem.
If I may take a bit more of your time I do have a few further questions on this topic:-

Could you confirm whether the following two code snippets are the same:-
Adafruit_HTU21DF sensor;
Adafruit_Si7021 sensor = sensor ();
I can see the point yore were making regarding the following items in the library files:-
bool Adafruit_BME280::begin(uint8_t addr, TwoWire *theWire) {
bool Adafruit_HTU21DF::begin(TwoWire *theWire) {

However, on my finial sensor a si7021 the sensor Adafruit_Si7021 library file shows:
Adafruit_Si7021::Adafruit_Si7021(TwoWire *theWire) {
Could you provide an example to work with for this statement like you did with the HTU21D. My work in progress sketch is blow:-
#include “Adafruit_Si7021.h”
bool enableHeater = false;
uint8_t loopCnt = 0;
#define I2C_SDA 1
#define I2C_SCL 2
TwoWire I2Csensor = TwoWire(0);
//Adafruit_HTU21DF ABC;
Adafruit_Si7021 sensor = Adafruit_Si7021();
void setup() {
  Serial.begin(115200);
I2Csensor.begin(I2C_SDA, I2C_SCL, 100000);
//
// Could you provide an example of required code
//
  // wait for serial port to open
  while (!Serial) {
    delay(10);
  }
  Serial.println(“Si7021 test!”);
 
  if (!sensor.begin()) {
    Serial.println(“Did not find Si7021 sensor!”);
    while (true)
      ;
  }
  Serial.print(“Found model “);
  switch(sensor.getModel()) {
    case SI_Engineering_Samples:
      Serial.print(“SI engineering samples”); break;
    case SI_7013:
      Serial.print(“Si7013”); break;
    case SI_7020:
      Serial.print(“Si7020”); break;
    case SI_7021:
      Serial.print(“Si7021”); break;
    case SI_UNKNOWN:
    default:
      Serial.print(“Unknown”);
  }
  Serial.print(” Rev(“);
  Serial.print(sensor.getRevision());
  Serial.print(“)”);
  Serial.print(” Serial #”); Serial.print(sensor.sernum_a, HEX); Serial.println(sensor.sernum_b, HEX);
}
void loop() {
  Serial.print(“Humidity:    “);
  Serial.print(sensor.readHumidity(), 2);
  Serial.print(“\tTemperature: “);
  Serial.println(sensor.readTemperature(), 2);
  delay(1000);
  // Toggle heater enabled state every 30 seconds
  // An ~1.8 degC temperature increase can be noted when heater is enabled
  if (++loopCnt == 30) {
    enableHeater = !enableHeater;
    sensor.heater(enableHeater);
    Serial.print(“Heater Enabled State: “);
    if (sensor.isHeaterEnabled())
      Serial.println(“ENABLED”);
    else
      Serial.println(“DISABLED”);
       
    loopCnt = 0;
  }
}
 
It also would be most appreciated, If you could provide or direct me to information regarding interpreting the outcome needs from the library file statements we have been discussing. This is so if I have a need to use a different sensor in the future and it’s not one you have provided the way forward for, I can interpret the instruction by myself.
 
Best Regard
Dave

0 Vote Up Vote Down
Sara Santos Staff answered 1 month ago

Hi.
As I mentioned you need to take a look at the library files and see which arguments each function requires.
 
In this case, it accepts the TwoWire instance when creating the Adafruit_Si7021 instance.
 
So, you need to pass the TwoWire instance like this:
 
TwoWire I2Csensor = TwoWire(0);
//Adafruit_HTU21DF ABC;
Adafruit_Si7021 sensor = Adafruit_Si7021(I2Csensor);
 
The rest of the code should remain the same.
 
I hope this helps.
 
Regards,
Sara
 

0 Vote Up Vote Down
David Fenner answered 1 month ago

Hi Sara,
Thank you for your reply, I have updated my sketch as per your suggestion (see below) unfortunately I get the following error.
Could you further help me. 
C:\Users\Me\Documents\Arduino\ESP32_C6_2025_SI7021_Example_Temp\ESP32_C6_2025_SI7021_Example_Temp.ino:11:51: error: no matching function for call to ‘Adafruit_Si7021::Adafruit_Si7021(TwoWire&)’ 11 | Adafruit_Si7021 sensor = Adafruit_Si7021(I2Csensor); | ^ In file included from C:\Users\Me\Documents\Arduino\ESP32_C6_2025_SI7021_Example_Temp\ESP32_C6_2025_SI7021_Example_Temp.ino:1: C:\Users\Me\Documents\Arduino\libraries\Adafruit_Si7021_Library/Adafruit_Si7021.h:81:3: note: candidate: ‘Adafruit_Si7021::Adafruit_Si7021(TwoWire*)’ 81 | Adafruit_Si7021(TwoWire *theWire = &Wire); | ^~~~~~~~~~~~~~~ C:\Users\Me\Documents\Arduino\libraries\Adafruit_Si7021_Library/Adafruit_Si7021.h:81:28: note: no known conversion for argument 1 from ‘TwoWire’ to ‘TwoWire*’ 81 | Adafruit_Si7021(TwoWire *theWire = &Wire); | ~~~~~~~~~^~~~~~~~~~~~~~~ C:\Users\Me\Documents\Arduino\libraries\Adafruit_Si7021_Library/Adafruit_Si7021.h:79:7: note: candidate: ‘constexpr Adafruit_Si7021::Adafruit_Si7021(const Adafruit_Si7021&)’ 79 | class Adafruit_Si7021 { | ^~~~~~~~~~~~~~~ C:\Users\Me\Documents\Arduino\libraries\Adafruit_Si7021_Library/Adafruit_Si7021.h:79:7: note: no known conversion for argument 1 from ‘TwoWire’ to ‘const Adafruit_Si7021&’ C:\Users\Me\Documents\Arduino\libraries\Adafruit_Si7021_Library/Adafruit_Si7021.h:79:7: note: candidate: ‘constexpr Adafruit_Si7021::Adafruit_Si7021(Adafruit_Si7021&&)’ C:\Users\Me\Documents\Arduino\libraries\Adafruit_Si7021_Library/Adafruit_Si7021.h:79:7: note: no known conversion for argument 1 from ‘TwoWire’ to ‘Adafruit_Si7021&&’ exit status 1 Compilation error: no matching function for call to ‘Adafruit_Si7021::Adafruit_Si7021(TwoWire&)’
 
My sketch:
 

#include “Adafruit_Si7021.h”
bool enableHeater = false;
uint8_t loopCnt = 0;
#define I2C_SDA 1
#define I2C_SCL 2
TwoWire I2Csensor = TwoWire(0);
Adafruit_Si7021 sensor = Adafruit_Si7021(I2Csensor);
void setup() {
  Serial.begin(115200);
I2Csensor.begin(I2C_SDA, I2C_SCL, 100000);
  // wait for serial port to open
  while (!Serial) {
    delay(10);
  }
  Serial.println(“Si7021 test!”);
 
  if (!sensor.begin()) {
    Serial.println(“Did not find Si7021 sensor!”);
    while (true)
      ;
  }
  Serial.print(“Found model “);
  switch(sensor.getModel()) {
    case SI_Engineering_Samples:
      Serial.print(“SI engineering samples”); break;
    case SI_7013:
      Serial.print(“Si7013”); break;
    case SI_7020:
      Serial.print(“Si7020”); break;
    case SI_7021:
      Serial.print(“Si7021”); break;
    case SI_UNKNOWN:
    default:
      Serial.print(“Unknown”);
  }
  Serial.print(” Rev(“);
  Serial.print(sensor.getRevision());
  Serial.print(“)”);
  Serial.print(” Serial #”); Serial.print(sensor.sernum_a, HEX); Serial.println(sensor.sernum_b, HEX);
}
void loop() {
  Serial.print(“Humidity:    “);
  Serial.print(sensor.readHumidity(), 2);
  Serial.print(“\tTemperature: “);
  Serial.println(sensor.readTemperature(), 2);
  delay(1000);
  // Toggle heater enabled state every 30 seconds
  // An ~1.8 degC temperature increase can be noted when heater is enabled
  if (++loopCnt == 30) {
    enableHeater = !enableHeater;
    sensor.heater(enableHeater);
    Serial.print(“Heater Enabled State: “);
    if (sensor.isHeaterEnabled())
      Serial.println(“ENABLED”);
    else
      Serial.println(“DISABLED”);
       
    loopCnt = 0;
  }
}

 

0 Vote Up Vote Down
Sara Santos Staff answered 1 month ago

Hi,

Change this line

Adafruit_Si7021 sensor = Adafruit_Si7021(I2Csensor);

To

Adafruit_Si7021 sensor = Adafruit_Si7021(&I2Csensor)

Let me know if this fixes the issue.

Regards,
Sara

0 Vote Up Vote Down
David Fenner answered 1 month ago

Hi Sara,
Thank you that resolved my issue.
Regarding my comment last week could you confirm whether the following two code snippets are interchangeable :-
Adafruit_HTU21DF sensor;
Adafruit_Si7021 sensor = sensor (); 
 
Also regarding the link you provided  in one of your previous responses
https://raw.githubusercontent.com/RuiSantosdotme/Random-Nerd-Tutorials/master/Projects/ESP32/I2C/ESP32_BME280_Set_I2C_Pins.ino 
 
In the context of the command delayed time, out of interest Is there an advantage over using delayed time rather than just delay?
Thank you for your assistance.
 
Best Regards
 

0 Vote Up Vote Down
Sara Santos Staff answered 1 month ago

No.
They are not interchangeable. Those are two different things. It depends on the library. And those are referring to different sensors.
 
As for the other question, I didn’t understand… Can you better explain your question?
 
Regards,
Sara

0 Vote Up Vote Down
David Fenner answered 1 month ago

Hi
Sorry for my confusion regarding the questions I asked in my last message.
My first question should have read:-
Adafruit_HTU21DF ABC;
Adafruit_ HTU21DF ABC = Adafruit_ HTU21DF (); 
Regarding my 2nd question:
Now I have carried out more research on the topic of delaytime I can be more focused in my question. This is in the respect of a comment I have read regarding using a time delay of for example 60 seconds when using the BME280 operationally, shorter delay can be used when testing the sensor out. As I understand this is to alleviate any overheating problems due to rapidly switching the sensor on and off and getting inaccurate readings.
Other delays I have seen are 30 seconds what value would be seen as good practice?
Best Regards 

0 Vote Up Vote Down
Sara Santos Staff answered 1 month ago

Hi.
 
Even though those two lines are different and make the compiler do different things, the result is the same, which is initializing an instance of the ADafruit_HTU21DF with the default parameters.
In this case, since you’ll be initializing the sensor with the default parameters, you can use either of them.
 
 
As for the delay, I don’t think there is a better delay time. It will depend on your project application.
 
Regards,
Sara
 

0 Vote Up Vote Down
David Fenner answered 1 month ago

Thank you 

Primary Sidebar

Login to Ask or Answer Questions

This Forum is private and it’s only available for members enrolled in our Courses.

Login »

Latest Course Updates

  • [eBook Updated] Learn LVGL: Build GUIs for ESP32 Projects – Version 1.5 July 7, 2025
  • [eBook Updated] Learn Raspberry Pi Pico/Pico W with MicroPython eBook – Version 1.2 May 26, 2025

You must be logged in to view this content.

Contact Support - Refunds - Privacy - Terms - MakerAdvisor.com - Member Login

Copyright © 2013-2025 · RandomNerdTutorials.com · All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.