Using the PCA9548 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 PCA9548 VIN.

Here is an Adafruit Metro wired up to the PCA9548 using the STEMMA QT connector, along with two VL53L4CD STEMMA boards plugged into port 0 and port 1 on the PCA9548:

  • Board 5V to mux VIN (red wire)
  • Board GND to mux GND (black wire)
  • Board SCL to mux SCL (yellow wire)
  • Board SDA to mux SDA (blue wire)
  • VL53L4CD 1 to mux STEMMA port 0
  • VL53L4CD 2 to mux STEMMA port 1

Here is an Adafruit Metro wired up using a solderless breadboard:

  • Board 5V to mux VIN (red wire)
  • Board GND to mux GND (black wire)
  • Board SCL to mux SCL (yellow wire)
  • Board SDA to mux SDA (blue wire)
  • VL53L4CD 1 to mux STEMMA port 0
  • VL53L4CD 2 to mux 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:

I2C Scanner Example Code

/**
 * TCA9548 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 > 7) 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<8; 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 8 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.

Multi-Sensor Example Code

/**
 * PCA9548 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 > 7) 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 PCA9548");
    
    // define the port on the PCA9548 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 PCA9548 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 PCA9584
  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 PCA9548
  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.

This guide was first published on Oct 18, 2022. It was last updated on Jun 17, 2024.

This page (Arduino) was last updated on Mar 08, 2024.

Text editor powered by tinymce.