Using the PCA9546 I2C multiplexer with Arduino involves wiring up the I2C multiplexer to your Arduino-compatible microcontroller and running the provided example code.
If you're curious why you'd need an I2C multiplexer, be sure to check out this guide that goes in depth on working with multiple copies of the same I2C device, which most likely have the same I2C address.
Wiring
Wire as shown for a 5V board like an Uno. If you are using a 3V board, like an Adafruit Feather, wire the board's 3V pin to the PCA9546 VIN.
Here is an Adafruit Metro wired up to the PCA9546 using the STEMMA QT connector, along with two VL53L4CD STEMMA boards plugged into port 0 and port 1 on the PCA9546:
- Metro 5V to multiplexer VIN (red wire)
- Metro GND to multiplexer GND (black wire)
- Metro SCL to multiplexer SCL (yellow wire)
- Metro SDA to multiplexer SDA (blue wire)
- VL53L4CD 1 to multiplexer STEMMA port 0
- VL53L4CD 2 to multiplexer STEMMA port 1
Library Installation
The Multi-Sensor example uses two VL53L4CD time of flight sensors. You can install the VL53L4CD library for Arduino using the Library Manager in the Arduino IDE.
Click the Manage Libraries ... menu item, search for VL53L4CD, and select the STM32duino VL53L4CD library:
// SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries // // SPDX-License-Identifier: MIT /** * PCA9546 I2CScanner.ino -- I2C bus scanner for Arduino * * Based on https://playground.arduino.cc/Main/I2cScanner/ * */ #include "Wire.h" #define PCAADDR 0x70 void pcaselect(uint8_t i) { if (i > 3) return; Wire.beginTransmission(PCAADDR); Wire.write(1 << i); Wire.endTransmission(); } // standard Arduino setup() void setup() { while (!Serial); delay(1000); Wire.begin(); Serial.begin(115200); Serial.println("\nPCAScanner ready!"); for (uint8_t t=0; t<4; t++) { pcaselect(t); Serial.print("PCA Port #"); Serial.println(t); for (uint8_t addr = 0; addr<=127; addr++) { if (addr == PCAADDR) continue; Wire.beginTransmission(addr); if (!Wire.endTransmission()) { Serial.print("Found I2C 0x"); Serial.println(addr,HEX); } } } Serial.println("\ndone"); } void loop() { }
Upload the sketch to your board and open up the Serial Monitor (Tools -> Serial Monitor) at 115200 baud. You should see the 4 ports print to the Serial Monitor. If an I2C device is plugged into one of the ports, its address will be printed below the port number.
// SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries // // SPDX-License-Identifier: MIT /** * PCA9546 I2C Multi Sensor Example * * Using two VL53L4CD sensors on ports 0 and 1 * */ #include <Arduino.h> #include <Wire.h> #include <vl53l4cd_class.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <assert.h> #define PCAADDR 0x70 #define DEV_I2C Wire #define SerialPort Serial // create two instances of the sensor VL53L4CD tof1(&DEV_I2C, A1); VL53L4CD tof2(&DEV_I2C, A1); void pcaselect(uint8_t i) { if (i > 3) return; Wire.beginTransmission(PCAADDR); Wire.write(1 << i); Wire.endTransmission(); } // standard Arduino setup() void setup() { while (!Serial); delay(1000); Wire.begin(); Serial.begin(115200); Serial.println("\nMultiSensor PCA9546"); // define the port on the PCA9546 for the first sensor pcaselect(0); // setup the first sensor tof1.begin(); tof1.VL53L4CD_Off(); tof1.InitSensor(); tof1.VL53L4CD_SetRangeTiming(200, 0); tof1.VL53L4CD_StartRanging(); // define the port on the PCA9546 for the 2nd sensor pcaselect(1); // setup the 2nd sensor tof2.begin(); tof2.VL53L4CD_Off(); tof2.InitSensor(); tof2.VL53L4CD_SetRangeTiming(200, 0); tof2.VL53L4CD_StartRanging(); } void loop() { uint8_t NewDataReady = 0; VL53L4CD_Result_t results; uint8_t status; char report[64]; // define port on the PCA9546 pcaselect(0); // loop for time of flight sensor 1 do { status = tof1.VL53L4CD_CheckForDataReady(&NewDataReady); } while (!NewDataReady); if ((!status) && (NewDataReady != 0)) { // (Mandatory) Clear HW interrupt to restart measurements tof1.VL53L4CD_ClearInterrupt(); // Read measured distance. RangeStatus = 0 means valid data tof1.VL53L4CD_GetResult(&results); snprintf(report, sizeof(report), "ToF 1 - Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n", results.range_status, results.distance_mm, results.signal_per_spad_kcps); SerialPort.println(report); } // define port on PCA9546 pcaselect(1); // loop for time of flight sensor 2 do { status = tof2.VL53L4CD_CheckForDataReady(&NewDataReady); } while (!NewDataReady); if ((!status) && (NewDataReady != 0)) { // (Mandatory) Clear HW interrupt to restart measurements tof2.VL53L4CD_ClearInterrupt(); // Read measured distance. RangeStatus = 0 means valid data tof2.VL53L4CD_GetResult(&results); snprintf(report, sizeof(report), "ToF 2 - Status = %3u, Distance = %5u mm, Signal = %6u kcps/spad\r\n", results.range_status, results.distance_mm, results.signal_per_spad_kcps); SerialPort.println(report); } }
Upload the sketch to your board and open up the Serial Monitor (Tools -> Serial Monitor) at 115200 baud. You should see readings from the two VL53L4CD time of flight sensors print to the Serial Monitor.
Text editor powered by tinymce.