WS2812B FastLED, Arduino Leonardo,serial communication controlling leds with serial data.
I'm adding a new mode to my Arduino project. The issue is with serial aspect of it.
I don't know what to change to make it work. I have working demo with using only if (Serial.available() > 0) {} You can look at Visualizer() as main loop. It actually is main loop in my working demo...
Oh I think FastLED.show at the end of might be the issue. Since this is already called in my main loop at the end lets test without this line.. Edit: It works without that line so its not needed but the lights still cut of as if the data is not fully processed and shown with leds...
Main loop:
Visualizer.h and Visualizer.ino:
void loop() {
currentTime = millis();
int bufferSize = Serial.available();
byte buffer[bufferSize];
Serial.readBytes(buffer, bufferSize);
boolean commandByte1Arrived = false;
boolean commandByte2Arrived = false;
for (int bufIdx = 0; bufIdx < bufferSize; bufIdx++) {
int command = (unsigned int)buffer[bufIdx];
switch (command) {
case COMMAND_BYTE1:
{
debugLightOn(1);
commandByte1Arrived = true;
break;
}
case COMMAND_BYTE2:
{
debugLightOn(2);
if (commandByte1Arrived) {
commandByte2Arrived = true;
}
commandByte1Arrived = false;
break;
}
//other commands omitted..
case COMMAND_SET_LED_VISUALIZER:
{
commandByte1Arrived = false;
if (!commandByte2Arrived) break;
debugLightOn(13);
selectedEffect = buffer[++bufIdx];
MODE = COMMAND_SET_LED_VISUALIZER;
break;
}
default:
{
break;
}
}
}
//slowing it down with interval
if (currentTime - previousTime >= interval) {
for (int i = 0; i < numEffects; i++) {
if (effects[i]->finished()) {
delete effects[i];
removeEffect(effects[i]);
} else {
effects[i]->nextStep();
}
}
previousTime = currentTime;
}
if (currentTime - previousFadeTime >= fadeInterval) {
if (numEffects > 0 || generalFadeRate > 0) {
fadeCtrl->fade(generalFadeRate);
}
previousFadeTime = currentTime;
}
//LED Audio Visualizer
if (MODE == COMMAND_SET_LED_VISUALIZER) {
Visualizer(selectedEffect);
}
FastLED.show();
}
Visualizer.h
#ifndef VISUALIZER_H
#define VISUALIZER_H
#include "FastLED.h"
void Visualizer(int selectedEffect);
#endif
Visualizer.ino
#include "Visualizer.h"
// Variables for the Colorful Wave effect
#define WAVE_FREQUENCY 2
#define WAVE_AMPLITUDE 20
// Variables for the Bouncing Balls effect
#define NUM_BALLS 1
#define BALL_RADIUS 21
#define BALL_SPEED 8
// STANDARD VISUALIZER VARIABLES
int loop_max = 0;
int k = 255; // COLOR WHEEL POSITION
int decay = 0; // HOW MANY MS BEFORE ONE LIGHT DECAY
int decay_check = 0;
long pre_react = 0; // NEW SPIKE CONVERSION
long react = 0; // NUMBER OF LEDs BEING LIT
long post_react = 0; // OLD SPIKE CONVERSION
// RAINBOW WAVE SETTINGS
int wheel_speed = 3;
int selectedAnimationIndex;
// Function prototypes for animation effects
CRGB SpectrumFlow(int pos);
CRGB BouncingBalls(int pos);
CRGB Wave(int pos);
CRGB ColorfulWave(int pos);
CRGB SpectrumFlow(int pos) {
int hue = pos + k * NUM_LEDS / 255;
int audio_level = react * 255 / NUM_LEDS;
hue = constrain(hue + audio_level, 0, 255);
return CHSV(hue, 255, 255);
}
CRGB BouncingBalls(int pos) {
int hue = pos + k * NUM_LEDS / 255;
int audio_level = react * 255 / NUM_LEDS;
int brightness = audio_level;
int ballPos[NUM_BALLS];
for (int i = 0; i < NUM_BALLS; i++) {
ballPos[i] = (millis() / BALL_SPEED + i * NUM_LEDS / NUM_BALLS) % NUM_LEDS;
}
int minDist = NUM_LEDS;
for (int i = 0; i < NUM_BALLS; i++) {
int dist = abs(ballPos[i] - pos);
if (dist < minDist) {
minDist = dist;
}
}
int ballBrightness = map(minDist, 0, BALL_RADIUS, brightness, 0);
return CHSV(hue, 255, ballBrightness);
}
CRGB Wave(int pos) {
int hue = pos * 255 / NUM_LEDS;
int audio_level = react * 255 / NUM_LEDS;
hue = constrain(hue + audio_level, 0, 255);
return CHSV(hue, 255, 255);
}
CRGB ColorfulWave(int pos) {
int hue = (pos * WAVE_FREQUENCY + k) * 255 / NUM_LEDS;
int audio_level = react * 255 / NUM_LEDS;
int brightness = audio_level;
int offset = pos * WAVE_AMPLITUDE / NUM_LEDS;
return CHSV(hue, 255, brightness - offset);
}
// Function pointer array for different animation effects
CRGB (*animationFunctions[])
(int pos) = { SpectrumFlow, BouncingBalls, Wave, ColorfulWave };
void Visualizer(int selectedAnimation) {
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n');
int audioInputValue = data.toInt();
react = map(audioInputValue, 0, 1023, 0, NUM_LEDS);
}
animation();
k = k - wheel_speed;
if (k < 0)
k = 255;
decay_check++;
if (decay_check > decay) {
decay_check = 0;
if (react > 0)
react--;
}
}
void animation() {
int center = NUM_LEDS / 2;
int scroll_position = (millis() / wheel_speed) % 256;
int audio_threshold = 0; // You can adjust this value based on your experimentation
float scalingFactor = 1.1; // Adjust this value to control the boost level
if (react <= audio_threshold) {
fill_solid(leds, NUM_LEDS, CRGB::Black);
} else {
int boostedReact = react * scalingFactor;
CRGB(*currentAnimation)
(int pos) = animationFunctions[selectedAnimationIndex];
for (int i = center; i < NUM_LEDS; i++) {
if (i < center + boostedReact)
leds[i] = currentAnimation(i - center);
else
leds[i] = CRGB::Black;
}
for (int i = center - 1; i >= 0; i--) {
if (center - i < boostedReact)
leds[i] = currentAnimation(center - i);
else
leds[i] = CRGB::Black;
}
}
FastLED.show();
}