Go Down

Topic: Updating 100 WS2801 's pretty slow (Read 815 times) previous topic - next topic

thgie

Hi ino forum

I have a setup running (photos attached for good measurements, description below) and it's running fine. Except for the time it takes to update the pixels. It takes too long. And since it's my first arduino project I don't know if I'm asking for too much. Here is the current sketch:

Code: [Select]

#include "FastLED.h"
#define NUM_LEDS 100

const byte switchPin = 8;
byte oldSwitchState = HIGH;

// 0 = normal
// 1 = transition to circle
// 2 = circle
// 3 = transition to normal
// 10 = crazy shit
int sequence;
int stepper;

CRGB leds[NUM_LEDS];

// 0 = up or down state
// 1 = hue
// 2 = saturation
// 3 = value
int meta[NUM_LEDS][4];

// fade steps size
int steps;
int megasteps;

void setup() {
  delay(2000);
  Serial.begin (115200);
  pinMode (switchPin, INPUT_PULLUP);
  FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);

  sequence = 0;
  stepper = 0;

  steps = 7;
  megasteps = 250;

  // setting up meta array
  for(int i = 0; i < NUM_LEDS; i = i + 1) {

    meta[i][0] = random(1);
    meta[i][1] = random(255);
    meta[i][2] = 200;
    meta[i][3] = random(255);

    leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
    FastLED.show();
  }
}

void loop() {

  int threshold;

  byte switchState = digitalRead (switchPin);
  if (switchState != oldSwitchState)
  {
    oldSwitchState = switchState;
    if (switchState == LOW)
    {
      Serial.println ("Switch closed.");
      sequence = 0;
    }
    else
    {
      Serial.println ("Switch opened.");
      sequence = 1;
    }
  }

  if(sequence == 1){
    stepper = stepper + 1;
    if(stepper > 6) {
      stepper = 0;
      sequence = 2;
    }
  }

  if(sequence == 2 ){
    stepper = stepper + 1;

    Serial.println (stepper);

    if(threshold > NUM_LEDS){
      // stepper = 0;
      // sequence = 3;
    }
  }

  if(sequence == 10 ) {

    int rand = random(NUM_LEDS);

    // Now turn the LED off, then pause
    leds[rand] = CRGB::White;
    FastLED.show();
    delay(50);
    leds[rand] = CRGB::Black;
    FastLED.show();
    delay(50);
  }
  else {

    for(int i = 0; i < NUM_LEDS; i++) {
      if(sequence == 0){

        if(meta[i][0] == 1){
          if(meta[i][3] + steps < 150) {
            meta[i][3] = meta[i][3] + steps;
          }
          else {
            meta[i][0] = 0;
          }
        }
        else {
          if(meta[i][3] - steps > 0) {
            meta[i][3] = meta[i][3] - steps;
          }
          else {
            meta[i][0] = 1;
          }
        }

        //delay(5);
      }

      if(sequence == 1) {
        if(meta[i][3] - megasteps > 0) {
          meta[i][3] = meta[i][3] - megasteps;
        }
        else
        {
          meta[i][3] = 0;
          meta[i][2] = 0;
        }
      }

      if(sequence == 2 ) {
        if(i < stepper){
          if(meta[i][3] + megasteps < 250) {
            meta[i][3] = meta[i][3] + megasteps;
          }
          if(meta[NUM_LEDS - i][3] + steps < 250) {
            meta[NUM_LEDS - i][3] = meta[i][3] + megasteps;
          }
        }
      }

      leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
      FastLED.show();
    }
  }
}


I guess running through all 100 pixels in every main loop is just to much. My idea is to limit to a smaller set of pixels to work with. Like only 10 pieces. But is there something else that can be done to make the whole thing a bit quicker?

Thanks and happy holidays

Adrian

Quote
Setup:

white: grnd + pin 8 = magnetic reed switch
red: pin 13 = clock
green: pin 11 = data
black: ws2801 grnd

robtillaart


you should get rid of the delay() calls first. These are blocking and you do not want that

Look at the blink without delay sketch how to do that.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

PaulRB

#2
Dec 29, 2014, 11:20 am Last Edit: Dec 29, 2014, 11:25 am by PaulRB
Rob, I don't think that's the problem. Those delays are only used in sequence 10 ("crazy shit"). There are no delays in the other sequences (I see one but it is commented-out).

Adrian, have you tried increasing the value of "steps". Its currently 7, try 14...

Paul

robtillaart

probably the meta array can have a smaller datatype, I see only values 0..255 assigned ...

int meta[NUM_LEDS][4];

==>

uint8_t meta[NUM_LEDS][4];
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

thgie

Thanks for your replies.

I will definitely have a look at the data types. I'm a webdeveloper. So usually I only care if it's a number or a string ;)

Here is the sketch that did the trick. The WS2801 apparently has a very low data rate. So instead of looping and updating through all 100 led-pixels at the same time I just worked with a subset of 10 at a time.

Code: [Select]
#include "FastLED.h"
#define NUM_LEDS 100
#define NUM_SET 10

const byte switchPin = 8;
byte oldSwitchState = HIGH;

// 0 = normal
// 1 = transition to circle
// 2 = circle
// 3 = transition to normal
// 10 = crazy shit
int sequence;

CRGB leds[NUM_LEDS];

// 0 = up or down state
// 1 = hue
// 2 = saturation
// 3 = value
int meta[NUM_LEDS][4];
int set [NUM_SET];

// fade steps size
int steps;
// count loops
int loop_count;
int stepper;

int from;
int to;

void setup() {

    delay(2000);

    Serial.begin(115200);
    pinMode(switchPin, INPUT_PULLUP);
    FastLED.addLeds < WS2801, 11, 13, BGR, DATA_RATE_MHZ(2) > (leds, NUM_LEDS);

    sequence = 0;
    steps = 2;
    loop_count = 1;
    stepper = 1;

    from = 46;
    to = 57;

    // setting up meta array
    for (int i = 0; i < NUM_LEDS; i++) {

        if(i > from && i < to) { continue; }

        meta[i][0] = random(1);
        meta[i][1] = random(255);
        meta[i][2] = 200;
        meta[i][3] = 0;

        leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
    }

    FastLED.show();

    // setting up set
    for (int i = 0; i < NUM_SET; i++) {

        int rand = random(NUM_LEDS);

        if(rand > from && rand < to) {
            i--;
            continue;
        }

        set [i] = random(NUM_LEDS);
    }
}

void loop() {

    byte switchState = digitalRead(switchPin);
    if (switchState != oldSwitchState) {
        oldSwitchState = switchState;
        if (switchState == LOW) {
            Serial.println("Switch closed.");
            // sequence = 0;
        } else {
            Serial.println("Switch opened.");
            sequence = 1;
        }
    }

    // 0: default sequence
    if (sequence == 0) {

//        if (loop_count % 100 == 0) {
//            for (int i = 0; i < NUM_SET / 3; i++) {
//                int rand = random(NUM_SET);
//
//                meta[set [rand]][3] = 0;
//                leds[set[rand]].setHSV(meta[set [rand]][1], meta[set [rand]][2], meta[set [rand]][3]);
//                FastLED.show();
//
//                set [rand] = random(NUM_LEDS);
//            }
//        }

        for (int i = 0; i < NUM_SET; i++) {

            if (meta[set [i]][0] == 1) {
                if (meta[set [i]][3] + steps < 150) {
                    meta[set [i]][3] = meta[set [i]][3] + steps;
                } else {
                    meta[set [i]][0] = 0;
                }
            } else {
                if (meta[set [i]][3] - steps > 0) {
                    meta[set [i]][3] = meta[set [i]][3] - steps;
                } else {
                    meta[set [i]][0] = 1;

                    int rand = random(100);

                    if(rand > from && rand < to) {
                        i--;
                        continue;
                    }

                    meta[set [i]][3] = 0;

                    leds[set[i]].setHSV(meta[set [i]][1], meta[set [i]][2], meta[set [i]][3]);
                    FastLED.show();

                    set [i] = random(NUM_LEDS);
                }
            }

            leds[set[i]].setHSV(meta[set [i]][1], meta[set [i]][2], meta[set [i]][3]);
            FastLED.show();
        }
    }

    // 1: fade out sequence
    if(sequence == 1) {
        for (int i = 0; i < NUM_SET; i++) {

            meta[set [i]][0] = 1;
            meta[set [i]][2] = 0;
            meta[set [i]][3] = 0;

            leds[set [i]].setHSV(meta[set [i]][1], meta[set [i]][2], meta[set [i]][3]);
            FastLED.show();
        }

        for (int i = 0; i < NUM_LEDS; i++) {

            meta[i][0] = 1;
            meta[i][2] = 0;
            meta[i][3] = 0;

            leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
            FastLED.show();
        }

        stepper = 1;
        sequence = 2;

        delay(500);
    }

    // 2a: white fade in
    if(sequence == 2) {

        int offset = 0;

        if(stepper > NUM_SET) {
            offset = stepper - NUM_SET;
        }

        for(int i = offset; i < stepper; i++){

            if(i > from && i < to) { continue; }

            if(meta[i][3] + 250 / NUM_SET < 250) {
                meta[i][3] = meta[i][3] + 250 / NUM_SET;
            }

            leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
            FastLED.show();

            if(meta[NUM_LEDS - i][3] + 250 / NUM_SET < 250) {
                meta[NUM_LEDS - i][3] = meta[NUM_LEDS - i][3] + 250 / NUM_SET;
            }

            leds[NUM_LEDS - i].setHSV(meta[NUM_LEDS - i][1], meta[NUM_LEDS - i][2], meta[NUM_LEDS - i][3]);
            FastLED.show();
        }

        stepper++;

        if(stepper == 51) {
            stepper = 1;
            sequence = 3;

            delay(100);
        }
    }
    // 2b: white fade out
    if(sequence == 3) {

        int offset = 0;

        if(stepper > NUM_SET) {
            offset = stepper - NUM_SET;
        }

        for(int i = offset; i < stepper; i++){
            if(meta[i][3] - 250 / NUM_SET > 0) {
                meta[i][3] = meta[i][3] - 250 / NUM_SET;
            } else {
                meta[i][3] = 0;
            }

            leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
            FastLED.show();

            if(meta[NUM_LEDS - i][3] - 250 / NUM_SET > 0) {
                meta[NUM_LEDS - i][3] = meta[NUM_LEDS - i][3] - 250 / NUM_SET;
            } else {
                meta[NUM_LEDS - i][3] = 0;
            }

            leds[NUM_LEDS - i].setHSV(meta[NUM_LEDS - i][1], meta[NUM_LEDS - i][2], meta[NUM_LEDS - i][3]);
            FastLED.show();
        }

        stepper++;

        if(stepper == 51) {
            stepper = 1;
            sequence = 4;
        }
    }

    // 4: crazy ass blitz
    if(sequence == 4){
        if(stepper < 25) {
            int rand = random(NUM_LEDS);

            if(rand > from && rand < to) {
                stepper--;
            } else {

                meta[rand][3] = 255;
                leds[rand].setHSV(meta[rand][1], meta[rand][2], meta[rand][3]);
                FastLED.show();

                meta[NUM_LEDS - rand][3] = 255;
                leds[NUM_LEDS - rand].setHSV(meta[NUM_LEDS - rand][1], meta[NUM_LEDS - rand][2], meta[NUM_LEDS - rand][3]);
                FastLED.show();

                delay(50);

                meta[rand][3] = 0;
                leds[rand].setHSV(meta[rand][1], meta[rand][2], meta[rand][3]);
                FastLED.show();

                meta[NUM_LEDS - rand][3] = 0;
                leds[NUM_LEDS - rand].setHSV(meta[NUM_LEDS - rand][1], meta[NUM_LEDS - rand][2], meta[NUM_LEDS - rand][3]);
                FastLED.show();

                delay(50);
            }
        } else {
            for (int i = 0; i < NUM_LEDS; i++) {

                meta[i][0] = random(1);
                meta[i][1] = random(255);
                meta[i][2] = 200;
                meta[i][3] = 0;

                leds[i].setHSV(meta[i][1], meta[i][2], meta[i][3]);
            }

            delay(2000);

            stepper = 1;
            sequence = 0;
        }

        stepper++;
    }

    loop_count++;
}

boolrules

WOW. Someone who knows how to format code. It's a pleasure to read!

Go Up