{"id":26749348,"url":"https://github.com/sensirion/arduino-i2c-different-buses-example","last_synced_at":"2026-04-18T06:37:05.824Z","repository":{"id":284701202,"uuid":"951918306","full_name":"Sensirion/arduino-i2c-different-buses-example","owner":"Sensirion","description":"Tutorial how to set up different I2C buses on Arduino platform","archived":false,"fork":false,"pushed_at":"2025-03-27T07:37:17.000Z","size":1311,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-27T08:32:57.282Z","etag":null,"topics":["arduino","arduino-ide","arduino-uno","esp32","example","i2c","nucleo-board","pull-up","pull-ups","resistor","scd41","scl","sda","signal","tutorial","twowire","wire","wire1"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sensirion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-20T12:56:10.000Z","updated_at":"2025-03-26T14:54:46.000Z","dependencies_parsed_at":"2025-03-27T08:43:05.080Z","dependency_job_id":null,"html_url":"https://github.com/Sensirion/arduino-i2c-different-buses-example","commit_stats":null,"previous_names":["sensirion/arduino-i2c-different-buses-example"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sensirion%2Farduino-i2c-different-buses-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sensirion%2Farduino-i2c-different-buses-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sensirion%2Farduino-i2c-different-buses-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sensirion%2Farduino-i2c-different-buses-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sensirion","download_url":"https://codeload.github.com/Sensirion/arduino-i2c-different-buses-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246017724,"owners_count":20710240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arduino-ide","arduino-uno","esp32","example","i2c","nucleo-board","pull-up","pull-ups","resistor","scd41","scl","sda","signal","tutorial","twowire","wire","wire1"],"created_at":"2025-03-28T11:18:52.569Z","updated_at":"2026-04-18T06:37:05.808Z","avatar_url":"https://github.com/Sensirion.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\n\nYou have a micro controller and two identical sensors, meaning that they have the same I2C address. Without a multiplexer\nor the possibility to configure the I2C address of the sensor, you cannot attach them to the same I2C bus. However, on a\nboard that provides the ability to configure any GPIO pin pairs as an I2C bus, you can connect the two sensors to their\nown individual I2C buses. In this article, we will explain how to set up separate I2C buses for each sensor for a few different boards.\n\n# General working principle\n\nThe two SCD41 sensors we want to connect have an I2C address of 0x62, which cannot be changed. Therefore, to communicate\nwith both sensors from the micro controller, we will use a separate I2C bus for each. Each I2C bus requires one pin for\nthe SDA line and one for the SCL line. Depending on the board and library implementation, we can either use pre-configured\ninstances of the `Wire` library or we need to create our own instances of the `TwoWire` class and assign the pins used for \nSDA and SCL lines. As a final step, we will create two instances of our sensor driver class and\ninitialize one with the first I2C bus and the other with the second I2C bus.\n\n# ESP32 DevKitC\n\n## Wiring\n\nFirst, we need to define the pins we will use for the two I2C buses. For I2C bus A, we can use the default I2C pins\nof the board. For the ESP32 DevKitC, these are pin 21 (SCL) and pin 22 (SDA). For I2C bus B, we can choose any two\nGPIO (General Purpose Input Output) pins.\n\nIf you are using a different board, it is important to check the specifications to determine if any pins have special\nconfigurations that prevent them from being used as GPIO pins. In our case, we have selected pins 17 and 16 for\nI2C bus B.\n\n### Pull-up resistors\n\nHaving pull-up resistors in place on the I2C data (SDA) and clock (SCL) lines is important to have a good signal quality and robust communication.\nYou can read more about it on [I2C Pull-Up Resistors Intro](i2c-pull-up-resistors-intro.md)\n\nThe ESP32 DevKitC Board ensures that GPIO lines are automatically pulled to a high state. Therefore, there is no need to\nmanually wire or configure pull-up resistors for the pins you intend to use.\n\n### Wiring diagram\n\nSince the SCD41 sensor is compatible with both 3.3V and 5V, we can connect one sensor to the 3.3V pin and the other to\nthe 5V pin. If both sensors require the same voltage, they can be connected through a breadboard.\n\nFor this example, the wiring should be carried out as follows:\n\n![Wiring diagram SEK SCD41 to ESP32 DevKitC](images/wiringTwoSCD41ToESP.png)\n\n\n| Sensor board        | ESP32  | Cable color | Description |\n|---------------------|--------|-------------|-------------|\n| SEK-SCD41 A - Pin 1 | Pin 22 | yellow | SCL    |\n| SEK-SCD41 A - Pin 2 | GND    | black | Ground |\n| SEK-SCD41 A - Pin 3 | 3V3    | red | Sensor supply voltage 3-5V | \n| SEK-SCD41 A - Pin 4 | Pin 21 | green | SDA |  \n| SEK-SCD41 B - Pin 1 | Pin 17 | yellow | SCL |\n| SEK-SCD41 B - Pin 2 | GND | black | Ground |\n| SEK-SCD41 B - Pin 3 | 5V | red | Sensor supply voltage 3-5V | \n| SEK-SCD41 B - Pin 4 | Pin 16 | green | SDA |\n\nWhen configuring the software later on, it is important to remember the pins allocated for the second I2C bus.\nSpecifically, we used pin 17 for the I2C clock (SCL) and pin 16 for the I2C data (SDA).\n\n## Software setup\n\nFirst, you need to include the Wire library:\n\n```\n#include \u003cWire.h\u003e\n```\n\nWe are using the Arduino ESP32 platform, which includes the `Wire` library, that is already configured for\nthe default I2C bus on pins 21/22.\nWe can use the `Wire` instance without any modification for the sensor attached to the \"I2C bus A\" (default I2C bus).\nWe just need to initialize the bus with:\n\n```\nWire.begin();\n```\n\nFor the \"I2C bus B\" we need to configure a custom `TwoWire` instance. There is a predefined instance named `Wire1` we\ncan configure to use the pins we defined with the following lines of code within the `setup()` function:\n\n```\nconst int sda_B = 16;\nconst int scl_B = 17;\nWire1.begin(sda_B, scl_B);\n```\n\nThen, the code sending the commands to the sensors over the I2C bus needs to know which bus to use for which sensor.\nThus, you need to configure the sensor instances accordingly. First, create a driver instance per sensor.\nTheir scope should be global, such that those can be referred to from within `setup()` and `loop()`.\n\n```\nSensirionI2cScd4x sensorA;\nSensirionI2cScd4x sensorB;\n```\n\nThen, in the `setup()` function, assign the I2C buses to the sensors:\n\n```\nsensorA.begin(Wire, SCD41_I2C_ADDR_62);\nsensorB.begin(Wire1, SCD41_I2C_ADDR_62);\n```\n\nLook out that you really have `Wire1` assigned for sensorB, so that it uses the custom set-up I2C bus.\n\nYou can now send any I2C command to the sensor, such as initiating the measurement and retrieving values.\n\n```\nsensorA.startMeasurement();\nsensorB.startMeasurement();\n...\n```\n\nYou can find more details and options how to configure several I2C buses on the ESP32 platform using the Arduino IDE under [ESP32 I2C Tutorial](https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/)\n\n\n## Example sketch\n\nYou find a complete example under [exampleESP32DevKitCV4](exampleESP32DevKitCV4/exampleESP32DevKitCV4.ino)\n\n# STM32 Nucleo 64 Board\n\n## Wiring \n\nThe STM32 Nucleo 64 F401RE board has predefined I2C pins. \nWe connect to the Arduino Pin Header of the board and use the predefined pins for I2C1 and I2C2.\nMore info about the STM32 Nucleo 64 F401RE Board can be found on st.com.\n\n### Pull Ups\n\nHaving pull-up resistors in place on the I2C data (SDA) and clock (SCL) lines is important to have a good signal quality and robust communication.\nYou can read more about it on [I2C Pull-Up Resistors Intro](i2c-pull-up-resistors-intro.md)\n\nThe Nucleo board nor the development kit board has pull-up resistors built in.\nThus, we need to wire a resistor into each of the I2C communication lines. Four 8.26kOhm resistors were used in\nthis example and the wiring was done using a bread board so that no soldering was needed.\n\n### Wiring diagram\n![Wiring diagram SEK SCD41 to STM32 Nucleo 64 DevKitC](images/wiringTwoSCD41ToSTM32Nucleo64.png)\n\nNames R.1 to R.4 stand for resistors with a value of 8.26kOhm.\n\n| Sensor Board / Resistor   | STM32 Nucleo 64 Arduino Connector / Resistor | Cable color | Description |\n|--------------------------------|----------------------------|-------------|-------------|\n| SEK-SCD41 A Pin 1 | R.1 | yellow | SCL |\n| R.1 | Pin 15 | yellow | SCL |\n| R.1 | 3V3 |  | Reference Voltage |\n| SEK-SCD41 A Pin 2 |  GND | black |Ground |\n| SEK-SCD41 A Pin 3 |  3V3 | red | Sensor Supply Voltage 3-5V | \n| SEK-SCD41 A Pin 4 | R.2 | green | SDA |\n| R.2 | Pin 14 | green | SDA |\n| R.2 | 3V3 | | Reference Voltage |\n| SEK-SCD41 B Pin 1 | R.3 | yellow | SCL |\n| R.3 | Pin 6 | yellow | SCL |\n| R.3 | 3V3 | | Reference Voltage |\n| SEK-SCD41 B Pin 2 |  GND | black | Ground |\n| SEK-SCD41 B Pin 3 |  5V | red | Sensor supply voltage 3-5V |\n| SEK-SCD41 B Pin 4 | R.4 | green | SDA |\n| R.4 | Pin 3 | green | SDA|\n| R.4 | 3V3 | | Reference Voltage |\n\nWhat we have to remember for the configuration in the software later is the pins we used for the I2C buses.\n\n## Software setup\n\nFirst, you need to include the Wire library:\n\n```\n#include \u003cWire.h\u003e\n```\n\nFor configuring the I2C buses with the correct pins, we need to instantiate two TwoWire instances and pass \nthe pins to be used for the I2C communication.\nTheir scope should be global, thus the definition is outside `setup()` and `loop()`.\n\n```\n// I2C Bus A on Pins 14 (SDA) / 15 (SCL)\nconst int sda_A = 14;\nconst int scl_A = 15;\nTwoWire i2cBusA(sda_A, scl_A);\n\n// I2C Bus B on Pins 3 (SDA) / 6 (SCL)\nconst int sda_B = 3;\nconst int scl_B = 6;\nTwoWire i2cBusB(sda_B, scl_B);\n```\n\nThen, the code sending the commands to the sensors over the I2C Bus needs to know which bus to use for which sensor.\nThus, you need to configure the sensors instances accordingly. First, create a driver instance per sensor.\nTheir scope should be global, such that they can be referred to from within `setup()` and `loop()`.\n\n```\nSensirionI2cScd4x sensorA;\nSensirionI2cScd4x sensorB;\n```\n\nThen, in the `setup()` function, assign the I2C Buses to the sensors:\n\n```\nsensorA.begin(i2cBusA, SCD41_I2C_ADDR_62);\nsensorB.begin(i2cBusB, SCD41_I2C_ADDR_62);\n```\n\nYou can now send any I2C command to the sensor, such as initiating the measurement and retrieving values.\nThe complete example code is provided in the link.\n\n```\nsensorA.startMeasurement();\nsensorB.startMeasurement();\n...\n```\n\n## Example sketch\n\nYou find a complete example under [exampleSTM32Nucleo64](exampleSTM32Nucleo64/exampleSTM32Nucleo64.ino).\n\n# Arduino Uno R4 WIFI\n\n## Wiring\n\nThe Arduino Uno R4 WIFI provides one I2C bus on the pin header, which has no pull-ups on the board.\nThus, we need to connect a pull up resistor between SDA and VDD and SCL and VDD. \nIn the example two 2.2kOhm resistors were used.\n\nThe second I2C bus is on the Qwiic. We use here the breakout board from Adafruit.\nThe board includes 10K pull-up on SDA and SCL.\n\n### Pull Ups\n\nHaving pull-up resistors in place on the I2C data (SDA) and clock (SCL) lines is important to have a good signal quality and robust communication.\nYou can read more about it on [I2C Pull-Up Resistors Intro](i2c-pull-up-resistors-intro.md)\n\nThe Arduino Uno R4 WIFI provides no pull-ups on the board.\n\nThe SEK SCD41 board we are going to connect to the I2C Bus on the pin header has no pull-up resistors built in.\nThus, we need to connect a pull-up resistor between SDA and VDD and SCL and VDD. Two 8.26kOhm resistors were used in\nthis example and the wiring was done using a bread board so that no soldering was needed.\n\nThe second sensor is on a Adafruit breakout board. This one includes a pull-up resistor. Thus,\nno pull-up resistors have to be wired into this connection, for which a Qwiic cable is used.\n\n### Wiring diagram\n\n![Wiring diagram SEK SCD41 and Adafruit SCD41 to Arduino Uno R4](images/wiringTwoSCD41ToArduinoUnoR4.png)\n\nThe list below describes the wiring, where R.1 and R.2 are resistors with a value of 8.26kOhm.\n\n| Sensor board / Resistor | Arduino / Resistor  | Cable color | Description |\n|-------------------------|---------------------|-------------|-------------|\n| SEK-SCD41 Pin 1 | R.1 | yellow | SCL |\n| R.1 | Arduino Pin SCL |yellow | SCL |\n| R.1 | Arduino 3V3 | | I2C reference voltage |\n| SEK-SCD41 Pin 2 | Arduino GND | Ground |\n| SEK-SCD41 Pin 3 | Arduino 3V3 | Sensor supply voltage 3-5V |\n| SEK-SCD41 Pin 4 | R.2 | green | SDA |\n| R.2 | Arduino Pin 14 | green | SDA |\n| R.2 | Arduino 3V3 | | I2C reference voltage |\n| Adafruit SCD41 (includes Pull-Ups) | Arduino Qwiic connector | | Qwiic cable with SCL, GND, VDD, SDA lines |\n\n\n## Software setup\n\nFirst, you need to include the Wire library:\n\n```\n#include \u003cWire.h\u003e\n```\n\nFor the Arduino Uno R4, this library defines two I2C buses. The first, \"Wire\" is configured \nfor the SDA/SCL pins on the pin header, where \"Wire1\" is configured for the Qwiic connector.\nWe can use those two instances without any further configuration. You just need to initialize them:\n\n```\nWire.begin();\nWire1.begin();\n```\n\nThen, the code sending the commands to the sensors over the I2C bus needs to know which bus to use for which sensor.\nThus, you need to configure the sensor instances accordingly. First, create a driver instance per sensor.\nTheir scope should be global, such that those can be referred to from within `setup()` and `loop()`.\n\n```\nSensirionI2cScd4x sensorOnPins;\nSensirionI2cScd4x sensorOnQwiic;\n```\n\nNext, in the `setup()` function, assign the I2C buses to the sensors:\n\n```\nsensorOnPins.begin(Wire, SCD41_I2C_ADDR_62);\nsensorOnQwiic.begin(Wire1, SCD41_I2C_ADDR_62);\n```\n\nLook out that you really have `Wire1` assigned for `sensorOnQwiic`.\n\nYou can now send any I2C command to the sensor, such as initiating the measurement and retrieving values.\nThe complete example code is provided in the link.\n\n```\nsensorOnPins.startMeasurement();\nsensorOnQwiic.startMeasurement();\n...\n```\n\n\n## Example sketch\n\nYou find a complete example under [exampleArduinoUnoR4](exampleArduinoUnoR4/exampleArduinoUnoR4.ino).\n\n# Other Arduino Boards\n\nDocumentation for Arduino boards can be found under [Arduino Wire Library](https://docs.arduino.cc/language-reference/en/functions/communication/wire/).\n\nNote that not all boards support multiple I2C buses and that it is recommended to use a custom pull-up resistor configuration,\nas the built in resistors are likely not strong enough (resistor value is too big).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsensirion%2Farduino-i2c-different-buses-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsensirion%2Farduino-i2c-different-buses-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsensirion%2Farduino-i2c-different-buses-example/lists"}