Serial Communication and LED Strip SK9822

Hello Everyone,

The vision for my project is for python to read my body's position from a webcam, send the coordinate data from my laptop to an Elegoo Uno R3 serial port, which controls the characteristics of my SK9882 light strip using fastLED library.

Problem: Everything works great by itself, but the serial communication and light strip freeze when I run them at the same time. After a few seconds of running the program, the serial monitor stops displaying new data (often cutting off with a backwards question mark) and the LED strip will shut off or stop responding

I thought my problem was interrupts, and switched from the WS2812b to the SK9882 because this blog post said that might be the problem. However, I am still getting the same behavior.

My goal is for serial communication and fastLED can operate smooth and fast so that I can record dances that change the lights in my room. Here is my Arduino Code:

#include <FastLED.h>

#define DATA_PIN 6
#define CLK_PIN 5
#define LED_TYPE SK9822
#define COLOR_ORDER BGR
#define NUM_LEDS 150
#define BRIGHTNESS 5
CRGB leds[NUM_LEDS];

static boolean recvInProgress = false;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

// variables to hold the parsed data
int x = 0;
int y = 0;
int z = 0;

const int rows = 6;
const int cols = 2;
int data[rows][cols] = { { 1, 2}, { 3, 4}, { 5, 6}, { 7, 8}, { 9, 10}, { 11, 12}};

boolean newData = false;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(38400);


  FastLED.addLeds<LED_TYPE, DATA_PIN, CLK_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  FastLED.show();



}

void loop() {

  runLights();
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    showParsedData();
    newData = false;
  }
  
    FastLED.show();
  
  

}

//============

void runLights() {

  for (int j = 0; j < 6; j++) {
    Serial.print(j);
    Serial.print("/");
    Serial.print(data[j][0]);
    Serial.print("/");
    Serial.println(data[j][1]);
  }

  int hue1 = map(data[0][0], 0, 640, 0, 255);
  int hue2 = map(data[1][0], 0, 640, 0, 255);
  int hue3 = map(data[2][0], 0, 640, 0, 255);
  int hue4 = map(data[3][0], 0, 640, 0, 255);
  int hue5 = map(data[4][0], 0, 640, 0, 255);
  int hue6 = map(data[5][0], 0, 640, 0, 255);
  int val = map(data[3][1], 0, 360, 255, 0);



  
  

  leds[0] = CHSV(hue1, 255, 255);
  leds[1] = CHSV(hue1, 255, 255);
  leds[2] = CHSV(hue1, 255, 255);
  leds[3] = CHSV(hue1, 255, 255);
  leds[4] = CHSV(hue1, 255, 255);
  leds[5] = CHSV(hue1, 255, 255);
  leds[6] = CHSV(hue1, 255, 255);
  leds[7] = CHSV(hue1, 255, 255);
  leds[8] = CHSV(hue1, 255, 255);
  leds[9] = CHSV(hue1, 255, 255);
  leds[10] = CHSV(hue1, 255, 255);
  leds[11] = CHSV(hue1, 255, 255);
  leds[12] = CHSV(hue1, 255, 255);
  leds[13] = CHSV(hue1, 255, 255);
  leds[14] = CHSV(hue1, 255, 255);


}



void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

//============

void parseData() {      // split the data into its parts

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars, ",");      // get the first part - the string
  z = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  x = atoi(strtokIndx);     // convert this part to an integer

  strtokIndx = strtok(NULL, ",");
  y = atoi(strtokIndx);     // convert this part to a float

  data[z][0] = x;
  data[z][1] = y;
}

//============

void showParsedData() {
  Serial.print("x: ");
  Serial.println(x);
  Serial.print("y: ");
  Serial.println(y);
  Serial.print("z: ");
  Serial.println(z);
}

The Fast:LED show() function disables interrupts while it runs. If a serial communication occurs while the interrupts are disabled, data loss will occur.

In a project where I used FastLED and serial (actually software serial and Bluetooth) I stop issuing the show() function when the first byte arrives (and discard that byte), receive and act upon the serial communication then go back to using the show() function.

Here is a link to a recent thread where I explain how I did that.

1 Like

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