Serial bug in loop()

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();
}

that's a blocking call (that can timeout depending on how the bytes are coming in)

have you tried with non blocking code (record the byte as they come in) ➜ I would suggest to study Serial Input Basics to handle this

Thanks I will look into it.

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