"Echo" Effect Using Multiple Led Strips Question

Hello, I am using an Uno R3 with an external 5v power supply going to 3 separate WS2813 strips. Using a heart beat sensor and Fast.Led I have the working code posted below where the LEDS "blink" to the heartbeat input.

I want to further this by having one LED strip blink to the heartbeat as it does currently in the code and the outer two strips then "echo" the middle LED strip or show the heartbeat blink delayed. I am newer and had a friend help me with the initial code so I am not entirely familiar with the best way to do this.

////////////////////////////////////////////////////////////
/* PACKAGES */
////////////////////////////////////////////////////////////
#include "FastLED.h"
#include <Wire.h>
#include "MAX30105.h"

////////////////////////////////////////////////////////////
/* GLOBAL VARIABLES */
////////////////////////////////////////////////////////////
 
#define MIN_BRIGHTNESS  20
#define LED_TYPE    WS2813
#define COLOR_ORDER GRB
#define NUM_LEDS  288
#define num_strips  3
CRGB leds[NUM_LEDS];

uint8_t current_brightness = 40;
byte brightness_decrement = 40;

uint8_t color_at_index_on_strip[NUM_LEDS];
int led_offset_difference = 0;
int count_of_loop_iterations = 0;

uint8_t palette_switcher_index = 0;

MAX30105 particleSensor;
int most_recent_heartbeats[10];
int current_heartbeat_index = 0;


////////////////////////////////////////////////////////////
/* GRADIENTS */
////////////////////////////////////////////////////////////

DEFINE_GRADIENT_PALETTE( blue_gp ) { 
    0,    0,  218,  67,      //
   46,    0,    203,  107,   //
  176,   0,  159,   152,     //
  255,    33,  44,  190      //
};

DEFINE_GRADIENT_PALETTE( white_gp ) { 
    0,    255,  255,  255,     //
   46,    186,    202,  220,   //
  176,   120,  150,   185,     //
  255,    58,  95,  150        //
};

DEFINE_GRADIENT_PALETTE( red_gp ) { 
    0,    6,  255,    0,     //
   71,    0,  255,  153,     //
  122,  200,  200,  200,     //
  181,  110,   61,    6,     //
  255,    6,  255,    0      //
};

CRGBPalette16 currentPalette(blue_gp);
CRGBPalette16 targetPalette(white_gp);

////////////////////////////////////////////////////////////
/* LED FUNCTIONS */
////////////////////////////////////////////////////////////

void reset_leds() {
  uint8_t middle = 16 / 2;
  bool direction = false;
  
  for (int i = 0; i < NUM_LEDS; i++) {
    if (i % middle == 0) direction = !direction;

    if (direction) color_at_index_on_strip[i] = i % middle;
    else color_at_index_on_strip[i] = middle - (i % middle);
  }

  LEDS.setBrightness(MIN_BRIGHTNESS);
  // for (uint8_t num : color_at_index_on_strip) Serial.println(num);
}
 

int get_array_size() {
  return sizeof(most_recent_heartbeats) / sizeof(int);
}

int get_average() {
  long sum = 0;
  int length = get_array_size();
  //Serial.println(length);
  for (int i = 0; i < length; ++i) {
    sum += most_recent_heartbeats[i];
  }

  int average = sum / length;
  return average;
}

void set_next_most_recent(int value) {
  most_recent_heartbeats[current_heartbeat_index] = value;
  current_heartbeat_index = (current_heartbeat_index + 1) % get_array_size();
}

void set_next_palette() {
  ++palette_switcher_index;
  if (palette_switcher_index > 2) palette_switcher_index = 0;

  switch(palette_switcher_index) {
    case 0:
      currentPalette = blue_gp;
      targetPalette = white_gp;
      break;
     case 1:
      currentPalette = white_gp;
      targetPalette = blue_gp;
      break;
  }
}
 

void setup() {
  Serial.begin(9600);
  delay(1000);

  FastLED.addLeds <WS2813, 9>(leds, NUM_LEDS); 
  FastLED.addLeds <WS2813, 10>(leds, NUM_LEDS); 
  FastLED.addLeds <WS2813, 11>(leds, NUM_LEDS); 

  reset_leds();

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
    Serial.println("MAX30105 was not found. Please check wiring/power.");
    return;
  }

  //Setup to sense a nice looking saw tooth on the plotter
  byte ledBrightness = 0x1F; //Options: 0=Off to 255=50mA
  byte sampleAverage = 8; //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 3; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  int sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411; //Options: 69, 118, 215, 411
  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
} 
 
void loop() {
  EVERY_N_MILLIS(25) {
    for (int i = 0; i < NUM_LEDS; i++) leds[(i + led_offset_difference) % NUM_LEDS] = ColorFromPalette(currentPalette, i);

    nblendPaletteTowardPalette(currentPalette, targetPalette, 500);

    if (count_of_loop_iterations == 500) {
      count_of_loop_iterations = 0;
      set_next_palette();
    }

    LEDS.setBrightness(current_brightness);
    if (current_brightness <= MIN_BRIGHTNESS) current_brightness = MIN_BRIGHTNESS;
    else current_brightness -= brightness_decrement;

    ++led_offset_difference;
    ++count_of_loop_iterations;
  }
  
  long current_scan = particleSensor.getIR() / 10;
  
  set_next_most_recent(current_scan);
  int average = get_average();

  if (average > 9000) {
  //  Serial.print(average);
  //  Serial.print(" ");
  //  Serial.println(particleSensor.getIR() / 10);

    if (current_scan - average > 3) current_brightness = 255;
  }
  
  LEDS.show(); 
} 

Post a simple schematic showing how you have it wired. Be sure to show all connections, power, ground, and power supplies. Also post links if other hardware devices are used.

You could remove this delay by simply connecting all strips to the same output pin. Anything between 200R to 470R.

It is recommended that a series resistor be placed between the Arduino and data input.
Also it is recommended to put a large capacitor between power and ground on each strip.

Your wiring diagram shows no connection to ground or 5V on the strips. I can't tell which it is because of the lack of resolution on each strip.

The big problem that you have is the code you have is known as blocking code, it will only do one thing at a time. We get this problem almost every day.

So search the forum for
LEDs blocking code to see how to write none blocking code. This is a technique that while bing simple is often beyond an absolute beginner, without a bit of study.

At NUM_LEDS 288 for each strip you need a lot of current. Each LED takes about 60mA for full white brightness or 20mA for a single colour at full brightness. Have you calculated what you need? I am not sure you can get a bench supply for so much current.

1 Like

I am not trying to remove a delay, I am trying to add it to the outer strips. I don’t think delay was the right term to use when I was typing all this up but I have All 3 strips up in a row on the wall. They all flash to my heart beat according to the heart beat sensor. I want to still have the middle LED flash and the outter 2 LEDs “echo” the middle LEDS flashes, just a few milliseconds later.

“Your wiring diagram shows no connection to ground or 5V on the strips. I can't tell which it is because of the lack of resolution on each strip.”

Yes I quickly threw the diagram together, the 5v power is ran from the power supply to each strip. The power supply has 3 outputs, all rated at 5v, 70a each which is what the strips are said to pull at peak.

I will look into blocking code, thank you.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.