WS2812B LED visualiser problems

Hi, I am working on an audio visualiser based on a sparkfun project linked here: Interactive LED Music Visualizer - learn.sparkfun.com

The original project used one LED strip, but I need the arduino to send signal to 3 strips. As this is part of a college project being graded, I had to come up with my own code or a variation or expansion of someone else’s code, otherwise I would have just wired the strips in parallel. I managed to change the code so that it would send signal to 3 output pins instead of one, but when the code is uploaded and audio is fed to the arduino, there is severe lag and the pattern of the music is almost unrecognisable.

I have tried the code on both an Arduino Nano as well as an Arduino Mega 2560, but I had the same results with both

I have linked my altered code below and please feel free to tell me how to improve this and how to eliminate the lag.

also, I am very new to coding

sparkfun_visualizer_3rd_attempt.ino (6.07 KB)

What happens if you take out the delay()?

They don’t write the best code at these shops…

analogRead() returns an int. What data you feed the strip is integers, 3 bytes in those .Color() functions.

You do NOT want to use floating point to work those numbers because Arduinos have no FPU.
Working with floats on Arduino is a major speed kill and frankly a waste of time.

Brush up on your integer math and your sketch can run faster.

This code below ---- I can’t believe it does what you think.
Do you understand that return causes the function to exit?

uint32_t Rainbow(unsigned int i) {
  if (i > 1529) return Rainbow(i % 1530);
  if (i > 1274) return strand.Color(255, 0, 255 - (i % 255));   
  if (i > 1019) return strand.Color((i % 255), 0, 255);         
  if (i > 764) return strand.Color(0, 255 - (i % 255), 255);   
  if (i > 509) return strand.Color(0, 255, (i % 255));         
  if (i > 255) return strand.Color(255 - (i % 255), 255, 0);   
  return strand.Color(255, i, 0);   //  <<=================== this line ALWAYS returns                            
  if (i > 1019) return strand2.Color((i % 255), 0, 255);  // <<==== this line to the last NEVER runs.       
  if (i > 764) return strand2.Color(0, 255 - (i % 255), 255);    
  if (i > 509) return strand2.Color(0, 255, (i % 255));          
  if (i > 255) return strand2.Color(255 - (i % 255), 255, 0);    
  return strand2.Color(255, i, 0);                               
  if (i > 1274) return strand3.Color(255, 0, 255 - (i % 255));   
  if (i > 1019) return strand3.Color((i % 255), 0, 255);        
  if (i > 764) return strand3.Color(0, 255 - (i % 255), 255);   
  if (i > 509) return strand3.Color(0, 255, (i % 255));         
  if (i > 255) return strand3.Color(255 - (i % 255), 255, 0);   
  return strand3.Color(255, i, 0);                              
}

That delay() just makes timing worse.

I will try and work on my integer math and see if I can change those floats.

Another question I had was if I could define multiple output pins as one output, for example, in my code I have this:

#define LED_PIN 3

is there a way this could be changed so that you can add multiple pins? something like this:

#define LED_PIN 3, 5, 7

What you can do is called direct port manipulation where you write and read the hardware registers for a port of IO pins and set or get bits in one to few cycles.

https://www.arduino.cc/en/Reference/PortManipulation

Check the pinmap of your AVR to see what pins on what ports are already taken. Serial uses 2. On an Uno you can work with 6 pins on more than one port. You only need 3.

Do you know bitwise logic? How to mask bits? With 3 bits the possibilities are 0 to 7. Do you know switch-case statements?

If all you need to do is feed the leds colors, why not pre-store color tables in flash using PROGMEM?
Then the MCU needs do no math at all.

I have used the FASTLED library to run WS2811 leds. I fill the array and run show() then do it again at FPS speed (every 20 to 40 ms). That code has time to run as many led strings in between as RAM to hold the arrays. 50 led string needs 150 bytes, there's time to do a string every 5ms easy.