@kmin @sterretje @TomGeorge
I tried this setup
6 strips of 60 LEDs on WS2812b ( Powered by PSU 5V 5A)
6 VL53lox Laser ToF sensors via MUX TCA9548A ( powered by 3.3V of ESP32 )
ESP pins used for signaling 13, 12, 14, 27, 25, 32
This is working fine. All LEDs are lite up and as we move hand closer to sensor more LED turn off.
code
#include <Wire.h> // I2C communication library
#include <Adafruit_VL53L0X.h> // VL53L0X distance sensor library
#include <Adafruit_NeoPixel.h> // NeoPixel LED library
// Define multiplexer address
#define MUX_ADDR 0x70
// LED strip settings
#define NUM_LEDS 60 // Number of LEDs per strip
#define BRIGHTNESS 30 // Brightness level (0-255)
#define LED_STEP 5 // Number of LEDs to update per cycle (higher = faster updates)
// Define sensor and LED configurations
const uint8_t sensorChannels[] = {2, 3, 4, 5, 6, 7}; // MUX channels for each sensor
const uint8_t ledPins[] = {13, 12, 14, 27, 25, 32}; // Corresponding LED strip pins
const uint8_t numSensors = sizeof(sensorChannels) / sizeof(sensorChannels[0]); // Total number of sensors
// Sensor and LED objects
Adafruit_VL53L0X sensor = Adafruit_VL53L0X(); // Single VL53L0X sensor instance
Adafruit_NeoPixel strips[numSensors] = { // Array of NeoPixel strips for each sensor
Adafruit_NeoPixel(NUM_LEDS, 13, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, 12, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, 14, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, 27, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, 25, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(NUM_LEDS, 32, NEO_GRB + NEO_KHZ800)
};
// Variables to store previous sensor readings and LED states
int previousDistances[numSensors] = {0}; // Store previous distance values
int previousLedCounts[numSensors] = {0}; // Store previous LED count for smoother updates
// Function to select a specific sensor channel on the multiplexer
void selectMuxChannel(uint8_t channel) {
if (channel > 7) return; // Ensure the channel is within the valid range
Wire.beginTransmission(MUX_ADDR); // Begin communication with MUX
Wire.write(1 << channel); // Select the desired channel
Wire.endTransmission(); // End transmission
}
void setup() {
Serial.begin(115200); // Initialize serial monitor
Wire.begin(21, 22); // Start I2C communication (SDA: 21, SCL: 22)
Serial.println("Initializing VL53L0X sensors...");
// Initialize each sensor one by one through the multiplexer
for (uint8_t i = 0; i < numSensors; i++) {
selectMuxChannel(sensorChannels[i]); // Switch to current sensor channel
delay(50); // Short delay to stabilize sensor
// Try initializing the sensor and print the status
if (sensor.begin()) {
Serial.print("Sensor initialized on channel ");
Serial.println(sensorChannels[i]);
} else {
Serial.print("Failed to initialize sensor on channel ");
Serial.println(sensorChannels[i]);
}
// Reset previous distance and LED count for smooth startup
previousDistances[i] = 0;
previousLedCounts[i] = 0;
}
// Initialize each LED strip
for (uint8_t i = 0; i < numSensors; i++) {
strips[i].begin(); // Start the NeoPixel strip
strips[i].setBrightness(BRIGHTNESS); // Set LED brightness
strips[i].show(); // Ensure LEDs are turned off initially
}
}
void loop() {
// Read and process each sensor
for (uint8_t i = 0; i < numSensors; i++) {
selectMuxChannel(sensorChannels[i]); // Select the sensor
VL53L0X_RangingMeasurementData_t measure; // Structure to store sensor data
sensor.rangingTest(&measure, false); // Get distance measurement
// Process the sensor reading
int distanceCm;
if (measure.RangeStatus != 4) {
distanceCm = constrain((measure.RangeMilliMeter / 10 / 2) * 2, 10, 60);
} else {
distanceCm = 100; // Out of range β Set a high value to turn all LEDs on
}
// Filter out minor fluctuations to make LED changes smoother
if (abs(distanceCm - previousDistances[i]) > 2) {
previousDistances[i] = distanceCm;
} else {
distanceCm = previousDistances[i];
}
// Print the distance value for debugging
Serial.print(distanceCm);
Serial.print("\t");
// Update LED strip based on distance with a gradient color
setLedCountMaxSpeed(i, distanceCm);
}
Serial.println(); // New line in serial output
}
// π FUNCTION: Set LED Count with Multi-Color Gradient π
void setLedCountMaxSpeed(uint8_t stripIndex, int distance) {
int targetLedCount;
if (distance >= 60 || distance >= 100) {
// π When no obstacle (out of range), turn on all LEDs
targetLedCount = NUM_LEDS;
} else {
// π Reverse Mapping: More distance = More LEDs
targetLedCount = map(distance, 10, 60, 2, NUM_LEDS);
}
bool updated = false; // Track if we updated any LED
if (targetLedCount != previousLedCounts[stripIndex]) {
int step = LED_STEP; // Number of LEDs to update per cycle
if (targetLedCount > previousLedCounts[stripIndex]) {
for (int i = 0; i < step && previousLedCounts[stripIndex] < targetLedCount; i++) {
int ledIndex = previousLedCounts[stripIndex];
uint32_t color = getGradientColor(ledIndex);
strips[stripIndex].setPixelColor(ledIndex, color);
previousLedCounts[stripIndex]++;
updated = true;
}
} else if (targetLedCount < previousLedCounts[stripIndex]) {
for (int i = 0; i < step && previousLedCounts[stripIndex] > targetLedCount; i++) {
previousLedCounts[stripIndex]--;
strips[stripIndex].setPixelColor(previousLedCounts[stripIndex], strips[stripIndex].Color(0, 0, 0));
updated = true;
}
}
if (updated) {
strips[stripIndex].show(); // Apply updates only if needed
}
}
}
// π¨ FUNCTION: Generate 4-Color Gradient (Green β Yellow β Red β Deep Red) π¨
uint32_t getGradientColor(int ledIndex) {
float position = (float)ledIndex / (NUM_LEDS - 1); // Normalize position (0 to 1)
int red, green, blue;
if (position <= 0.25) {
// π© Green β Yellow
red = map(position * 100, 0, 25, 0, 255);
green = 255;
blue = 0;
}
else if (position <= 0.66) {
// π¨ Yellow β Bright Red
red = 255;
green = map(position * 100, 25, 66, 255, 50);
blue = 0;
}
else {
// π΄ Bright Red β Deep Red
red = 255;
green = map(position * 100, 66, 100, 50, 0);
blue = 0;
}
return strips[0].Color(red, green, blue);
}
Now I want to expand this to 12 Strips which I was able to do successfully using 5V 5A PSU attached video
Video
The problem is when I replace a 5V 5A PSU with a 5V 20A PSU, all LEDS start blinking randomly and they are lit in random colors.
The reason I am replacing PSU is because I think 5A 5V PSU is stretched to limit when powering these 12 strips as some instability can be seen in 1 strip in video but that has settled down automatically now.
As far as I can say 20A supply will provide only as many amps as is demanded from it so 5A is able to handle it then 20A should be able to handle it comfortable. The funny thing is if I connect a different brand 5A 5V PSU even then the setup becomes unstable!
working 5A 5V PSU output voltage 5.5 to 5.7 5V/5A Maxicom Mini SMPS Metal Power Supply
not working 5A 5V output voltage 5.0 to 5.1
METEK-05V/05A-INDUSTRIAL DRIVER, 25W, Voltage: 24 V at best price in Mumbai
not working 20A 5V output voltage 4.8 to 4.9 5V 20A SMPS Power Supply at βΉ 350/piece | Switch Mode Power Supply in Jalandhar | ID: 2853915916388
Each LED strip is around 1.2 mts long