My project is to use an TCA9548A Multiplexer to get readings from six (6) Adafruit_VCNL4040s - the VCNL4040 that is returning the strongest signal I will change what is displayed of my Adafruit_SSD1306 OLED. I am currently using SPI pinout for the OLED display.
In my sample of the code, I can use ANY combination of 2 Sensors (0 to 7 with NO ISSUES. Both the Serial Display and the OLED display works fine. But whenever I uncomment the MORE THAN two tselect() statements in the void setup() section - the code freezes and the Serial Monitor message displayed is: "Got good device ID, returning true from _init()"
Also, if I eliminate the SSD1306 OLED I can read all 6 of my VCNL4040 sensors using the TCA9548A Multiplexer and display the proximity values to the Serial Monitor.
CODE SAMPLE:
Code: Select all
// SPDX-FileCopyrightText: 2022 Carter Nelson for Adafruit Industries
// SPDX-License-Identifier: MIT
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_VCNL4040.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define i2c_Address_Proximity 0x60 //initialize with the I2C addr 0x60
#define TCAADDR 0x70
// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI 9
#define OLED_CLK 10
#define OLED_DC 11
#define OLED_CS 12
#define OLED_RESET 13
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
//#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
// For each device, create a separate instance.
Adafruit_VCNL4040 vcnl0; // vcnl4040 #0
Adafruit_VCNL4040 vcnl1; // vcnl4040 #1
Adafruit_VCNL4040 vcnl2; // vcnl4040 #2
Adafruit_VCNL4040 vcnl3; // vcnl4040 #3
Adafruit_VCNL4040 vcnl4; // vcnl4040 #4
Adafruit_VCNL4040 vcnl5; // vcnl4040 #5
Adafruit_VCNL4040 vcnl6; // vcnl4040 #6
Adafruit_VCNL4040 vcnl7; // vcnl4040 #7
// Helper function for changing TCA output channel
void tcaselect(uint8_t channel) {
if (channel > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << channel);
Wire.endTransmission();
}
void setup() {
Serial.begin(115200);
// Serial.begin(9600);
delay(250); // wait for the OLED to power up
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// NOTE!!! VERY IMPORTANT!!!
// Must call this once manually before first call to tcaselect()
Wire.begin();
// CODE WORKS FINE WITH ANY 2 PROXIMITY SENSORS BUT ADDING MORE THAN 2 SENSORS THE CODE FREEZES -
// VCNL Proximity
tcaselect(1); // TCA channel for vcnl1
vcnl1.begin(); // use the default address of 0x77
tcaselect(3); // TCA channel for vcnl3
vcnl3.begin(); // use the default address of 0x77
// If you uncomment the lines to use more the 2 proximity sensors the code freezes...
// When the code Freezes the message "Got good device ID, returning true from _init()" is displayed in the Serial Monitor screen
// tcaselect(6); // TCA channel for vcnl6
// vcnl6.begin(); // use the default address of 0x77
}
void loop() {
float distance0, distance1, distance2, distance3, distance4, distance5, distance6;
distance0 = 0;
distance1 = 0;
distance2 = 0;
distance3 = 0;
distance4 = 0;
distance5 = 0;
distance6 = 0;
display.clearDisplay(); // Clear the buffer.
// Read each device separately
tcaselect(1);
{
distance1 = vcnl1.getProximity();
if (distance1 >= 5 && distance1 < 200) {
Serial.print("#1 Distance = ");
Serial.println(distance1);
Serial.println(" ");
display.fillRoundRect(10, 10, 20, 5, 5, SSD1306_WHITE); //OLED display will change size and position
display.display();
delay (500);
display.clearDisplay(); // Clear the buffer.
}
}
tcaselect(3);
{
distance3 = vcnl3.getProximity();
if (distance3 >= 5 && distance3 < 200) {
Serial.print("#3 Distance = ");
Serial.println(distance3);
Serial.println(" ");
display.fillRoundRect(10, 20, 50, 5, 5, SSD1306_WHITE); //OLED display will change size and position
display.display();
delay (500);/
display.clearDisplay(); // Clear the buffer.
}
}
tcaselect(6);
{
distance6 = vcnl6.getProximity();
if (distance6 >= 5 && distance6 < 200) {
Serial.print("#6 Distance = ");
Serial.println(distance6);
Serial.println(" ");
display.fillRoundRect(10, 50, 80, 5, 5, SSD1306_WHITE); //OLED display will change size and position
display.display();
delay (500);
}
}
}
void testdrawroundrect(void) {
for (int16_t i = 0; i < 29; i += 16) {
display.invertDisplay(false);
display.drawRoundRect(i, i, display.width() - 2 * (i), display.height() - 2 * (i), display.height() / 2, SSD1306_WHITE);
}
}