Hello, I'm working on a device that uses a tca9548apwr multiplexer (MUX) to switch between 4 VL6180X LIDAR TOF sensors. I was having issues, so I went through troubleshooting, including i2c scanning sketches, and I have narrowed my issue down to a very specific condition. I can see the MUX no problem (0x70), and then when I change channels, nothing... UNLESS I soft-reset the ESP32 (pulling the EN pin low) after the channel was changed. Then, the channel actually engages and I can see the LIDAR through it (0x27). I have no problem using other i2c devices, as I am simultaneously using an i2c OLED screen on Wire1, I have tried switching it all around (putting my OLED on Wire and MUX on Wire1) etc. It always does the same thing.
Here is my scanner code. Nothing special, typical MUX code, standard settings for everything except for custom pin selection on the ESP32, but that does not seem to be causing any issues (it's an S3 so there are no longer any read-only pins).
// ESP32 I2C Scanner that also digs into every channel of a multiplexer
// currently set to channels 0-3 only instead of 0-7 because I left 4-7 floating and they take longer for nothing
// Based on code https://www.esp32.com/viewtopic.php?t=4742
#include <Wire.h>
#include <Adafruit_SSD1306.h>
byte count = 0, micount = 0, mccount = 0, snapshot = 0;
int channels = 4; //number of channels to scan, from 0 up to 7 (values 1 to 8; the scanner will stop after channel# channels - 1)
//OLED
#define SCL_1 10 //swap to 9 on V2 hardware version
#define SDA_1 9 //swap to 10 on V2 hardware version
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
//#define OLED_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);
//TCA9548APWR Multiplexer for VL6180 lidars
// https://randomnerdtutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
#define SCL_2 11
#define SDA_2 12
#define MULTIPLEXER_ADDRESS 0x70
void TCA9548A(uint8_t bus){
Wire.beginTransmission(MULTIPLEXER_ADDRESS); // TCA9548A address is 0x70
Wire.write(1 << bus); // send byte to select bus
Wire.endTransmission();
}
void setup()
{
Serial.begin(9600);
Wire1.begin(SDA_1, SCL_1); //OLED
Wire.begin(SDA_2, SCL_2); //Multiplexer
//OLED setup
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println(F("Hello, world!"));
display.display();
delay(1000);
}
void Scanner ()
{
display.clearDisplay();
display.setCursor(0, 0);
display.println ("I2C scanner. Scanning ...");
display.display();
for (byte i = 8; i < 120; i++)
{
Wire.beginTransmission (i); // Begin I2C transmission Address (i)
if (Wire.endTransmission () == 0) // Receive 0 = success (ACK response)
{
display.clearDisplay();
display.setCursor(0, 0);
display.print ("Found address: ");
display.print (i, DEC);
display.print (" (0x");
display.print (i, HEX); // PCF8574 7 bit address
display.println (")");
display.display();
delay(1000);
count++;
for (byte j = 0; j < 4; j++) //dig loop deeper for multiplexer
{
TCA9548A(j);
delay(100);
snapshot = micount;
for (byte k = 8; k < 120; k++)
{
display.clearDisplay();
display.setCursor(0, 0);
display.print ("checking channel: ");
display.print (j);
display.display();
Wire.beginTransmission (j); // Begin I2C transmission Address (i)
if (Wire.endTransmission () == 0) // Receive 0 = success (ACK response)
{
display.clearDisplay();
display.setCursor(0, 0);
display.print ("Found address: ");
display.print (k, DEC);
display.print (" (0x");
display.print (k, HEX); // PCF8574 7 bit address
display.println (")");
display.print ("on channel: ");
display.print (j);
display.display();
delay(1000);
micount++;
}
}
if (snapshot < micount) {mccount++;}
}
}
}
}
void loop()
{
Scanner ();
display.clearDisplay();
display.setCursor(0, 0);
display.print ("Found ");
display.print (count, DEC); // numbers of devices
display.println (" device(s).");
display.print ("Found ");
display.print (micount, DEC); // numbers of devices
display.println (" sub-device(s).");
display.display();
display.print ("On ");
display.print (mccount, DEC); // numbers of devices
display.println (" channel(s).");
display.display();
while(1);
}
Why would my channel change not be taking unless I soft reset the ESP32? I have tried adding a long delay (1 second) after the channel selection, and it changes nothing.
This is how my multiplexer is setup
Thanks in advance!