Go Down

Topic: adding led pattern functions to an array or object for iteration (Read 345 times) previous topic - next topic

tays22

I need to be able to run different patterns simultaneously on 5 separate strips of ws2813's from a nodemcu.  I can effectively use a function pointer that runs a pattern based on user input, but I would like to load an array of sorts with each selected function so that each strip is either assigned a function or is not assigned.  Then I could iterate through the indexs of the array, running the functions assigned.  Could anyone help me with this logic please?


Code: [Select]

#include <Adafruit_NeoPixel.h>

#define NUM_LEDS 21
#define NUM_STRIPS 5
#define  WS1_PIN 16  // TOP    (D0)
#define  WS2_PIN 4   // MIDDLE (D1)
#define  WS3_PIN 5   // DECK   (D2)
#define  WS4_PIN 0   //        (D3)
#define  WS5_PIN 2   //        (D4)
  Adafruit_NeoPixel ws1 = Adafruit_NeoPixel(NUM_LEDS, WS1_PIN, NEO_GRB + NEO_KHZ800);
  Adafruit_NeoPixel ws2 = Adafruit_NeoPixel(NUM_LEDS, WS2_PIN, NEO_GRB + NEO_KHZ800);
  Adafruit_NeoPixel ws3 = Adafruit_NeoPixel(NUM_LEDS, WS3_PIN, NEO_GRB + NEO_KHZ800);
  Adafruit_NeoPixel ws4 = Adafruit_NeoPixel(NUM_LEDS, WS4_PIN, NEO_GRB + NEO_KHZ800);
  Adafruit_NeoPixel ws5 = Adafruit_NeoPixel(NUM_LEDS, WS5_PIN, NEO_GRB + NEO_KHZ800);

////Variables for iteration decoupling///////////////
boolean firstCycle = true;
boolean is_rising = true;
byte last_data = 0;
byte data = 0;
int iter = 0;

const byte numChars = 9;
char receivedChars[numChars];
char tempChars[numChars];

char stripToCommand[numChars] = {0};
//char colorCommanded[numChars] = {0};
int patternCommanded = {0};

boolean newData = false;
 
void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);

    digitalWrite(WS1_PIN, HIGH);
    pinMode(WS1_PIN, OUTPUT);

  // Check for Serial connection
    while(!Serial);

  ws1.begin();
  ws2.begin();
  ws3.begin();
  ws4.begin();
  ws5.begin();

  ws1.setBrightness(80);
  ws2.setBrightness(80);
  ws3.setBrightness(80);
  ws4.setBrightness(80);
  ws5.setBrightness(80);

  ws1.show();
  ws2.show();
  ws3.show();
  ws4.show();
  ws5.show();
  //Serial.flush();
 
 
}
void (*fun_ptr_arr[])(byte, byte, byte) = {FadeInOut, Strobe};
void (*fun_ass[NUM_STRIPS])(byte) = {0,0,0,0,0};

void loop() {
  // put your main code here, to run repeatedly:
  Serial.flush();
  delay(10);
  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();
     
      newData = false;
  }
  cueTheLights(); 
}

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 data into its parts
 
  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars,",");
  strcpy(stripToCommand, strtokIndx); // copy it to stripToCommand
  Serial.println(stripToCommand);
  strtokIndx = strtok(NULL, ",");     // this continues where the previous call left off
  patternCommanded = atoi(strtokIndx);// convert this part to a integer
  Serial.println(patternCommanded);
  //assign_to_strip();
}

void iterate(){
  if(is_rising && iter < 256){
    iter = iter + 4;
    if(iter == 256){
      is_rising = false;
    }
  }
  else if(!is_rising && iter >= 0){
    if(iter == 0){
      is_rising = true;
    }
    else{
      iter = iter - 4;
      is_rising = false;
    }
  } 
}

void cueTheLights()

  if(patternCommanded == 1){ iterate(); (*fun_ptr_arr[0])(0xff, 0x00, 0x00);/* Serial.println(".");*/}

  else if(patternCommanded == 2){ iterate(); (*fun_ptr_arr[0])(0xff, 0xff, 0xff); /*Serial.println("@");*/}     
 
  else if(patternCommanded == 3){ iterate(); (*fun_ptr_arr[0])(0x00, 0x00, 0xff); /*Serial.println("#");*/}     
 
  else if(patternCommanded == 4){ (*fun_ptr_arr[1])(0xff, 0xff, 0xff); iter = 0;/*Serial.println("$");*/}

  else if(patternCommanded == 5){ (*fun_ptr_arr[1])(0xff, 0xff, 0x00); iter = 0; /*Serial.println("%");*/}
 
  delay(2);
}

void FadeInOut(byte red, byte green, byte blue){
  float r, g, b;
  //Serial.flush(); 

  r = (iter/256.0)*red;
  g = (iter/256.0)*green;
  b = (iter/256.0)*blue;
  setAll(r,g,b);
  showStrip();
  delay(1);
}

void Strobe(byte red, byte green, byte blue){
  Serial.flush(); 
 
  setAll(red,green,blue);
  showStrip();
  delay(50);
  setAll(0,0,0);
  showStrip();
  delay(50);
}

robertoxyz20

I'm looking for this too...
To handle several LED strips in different outputs pins you can use the fastled library.

I`m trying to make an object for every led... but I don't know how to do it either

tays22

This ended up being a logic issue for me.  The function pointer array worked like a dream, along with arrays that held properties for the parameters of the functions.  The rest came down to making sure the functions were decoupled enough to be able to handle each strips necessary led state and position.

robertoxyz20

What do you use to communicate with the Arduino? I do it from processing3. We can share the code.

tays22

I am using a nodemcu, and a breakout board that runs sn74lvc244an and a 10k resistor.  As far as user input, I get that from a serial buffer that is integrated into gaming code, and fired as state changes. 

Go Up