Go Down

Topic: [tuto] WS2812 independent patterns on a single strip (Read 634 times) previous topic - next topic

Hi!  :)

I'm opening this topic to share what I have found on this subject, share my work in progress and get some help if needed  :smiley-wink:

► I would like to display independent patterns on one single strip: the project is to light a pinball.

chasing effect below the ramp
blink target to get bonus
rainbow effect when success
fading effects to illuminate backglass





► list of components:
About LED technologies comparison:
https://www.tweaking4all.com/hardware/arduino/arduino-ws2812-led/

I've bought a WS2812/WS2811 strip of 50 RGB leds


https://fr.aliexpress.com/item/50pcs-Pre-wired-WS2812B-led-Chip-with-Heatsink-DC5V-WS2811-control-individually-Addressable-led-pixel-strip/32582314997.html
9€


I'm using a Arduino Nano 328
https://store.arduino.cc/arduino-nano 20€


and a power supply 5V
50 LEDs: 15 Watts (about 3 Amps at 5 Volts)

https://fr.aliexpress.com/item/1PCS-5V3A-AC-100V-240V-Converter-Adapter-DC-5V-3A-3000mA-Power-Supply-EU-Plug-5/32700939534.html 2€


In order to get independence in the tasks, I followed the hint of "blink without delay"
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

a johnwasser code example "DaftPunkLights"
https://forum.arduino.cc/index.php?topic=105210.msg789378#msg789378

another code example
https://arduino.stackexchange.com/questions/3248/multiple-independent-led-patterns

► libraries
and I found some dedicated libraries
neopixel adafruit https://github.com/adafruit/Adafruit_NeoPixel
and tutorial https://learn.adafruit.com/multi-tasking-the-arduino-part-3/deconstructing-the-loop


FastLEd
https://github.com/FastLED/FastLED/wiki/Multiple-Controller-Examples

Arduino Light Animation (ALA)
http://yaab-arduino.blogspot.fr/p/ala.html

Grumpy_Mike


This tutorial https://learn.adafruit.com/multi-tasking-the-arduino-part-3/deconstructing-the-loop
explains in detail how to drive several strips, each strip with its own pattern

But I would like to spare some pins and drive only a single strip!

I'll try to adapt the code to my use. Or I will rethink cutting the strip in multiple strips...

Thanks Grumpy_Mike, I will look at your code right now!

Grumpy_Mike

Quote
But I would like to spare some pins and drive only a single strip!
Then that is even simpler. Just use a restricted range of LED numbers for each pattern you want to work on.

I did it on a matrix and had each line of the matrix do a different pattern. However the code was in Python so not much point in posting it here.

I did that (but I didn't find it simplier  ::) ... I had to pass sub strips instead of patterns to the functions.

I created a structure to store informations on the sub strips and its associated pattern.

This draft is compiling OK (but untested yet, my hardware is at home)



Code: [Select]

// StrandTest from AdaFruit implemented as a state machine
// pattern change by push button
// By Mike Cook Jan 2016

#define PINforControl   7 // pin connected to 1 single NeoPixels strip
#define NUMPIXELS1      20 // number of LEDs on strip

#include <Adafruit_NeoPixel.h>

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS1, PINforControl, NEO_GRB + NEO_KHZ800);
// Pattern types supported:
enum  pattern_type { NONE, BLINK, RAINBOW, RAINBOW_CYCLE, THEATER_CHASE_RAINBOW, COLOR_WIPE, FADING };

[b]struct subStrips {
  uint16_t startIndex;
  uint16_t nb_LED;
  pattern_type  activePattern;
  unsigned long patternInterval;
  unsigned long lastUpdate;
};[/b]

[b]// declare substrips
// the 20 LED are grouped by 7, 1, 1, 1, 1, 1, 7 (see image in the post)

subStrips stripRamp = {0, 7, THEATER_CHASE_RAINBOW, 20, 0 };
subStrips stripSingle1 = {7, 1, NONE, 20, 0 };
subStrips stripSingle2 = {8, 1, FADING, 20, 0 };
subStrips stripSingle3 = {9, 1, RAINBOW, 20, 0 };
subStrips stripSingle4 = {10, 1, BLINK, 20, 0 };
subStrips stripSingle5 = {11, 1, RAINBOW, 20, 0 };
subStrips stripAmbilight = {12, 7, RAINBOW_CYCLE, 20, 0 };[/b]

unsigned long patternInterval = 20 ; // time between steps in the pattern
unsigned long lastUpdate = 0 ; // for millis() when last update occoured
unsigned long intervals [] = { 20, 20, 50, 100 } ; // speed for each pattern
const byte button = 2; // pin to connect button switch to between pin and ground

void setup() {
  strip.begin(); // This initializes the NeoPixel library.
  wipe(); // wipes the LED buffers
  pinMode(button, INPUT_PULLUP); // change pattern
}

void loop() {
  // subStrip Ramp
  if(millis() - stripRamp.lastUpdate > stripRamp.patternInterval) updateSubStripPattern(stripRamp);
  // subStrip Single1
  if(millis() - stripSingle1.lastUpdate > stripSingle1.patternInterval) updateSubStripPattern(stripSingle1);
  //...
}

void  updateSubStripPattern(subStrips &substripOut){ // out parameter
  switch(substripOut.activePattern) {
    case NONE :
    wipeSubStrip(substripOut);
        break;
    case RAINBOW :
        rainbow(substripOut);
        break;
    case RAINBOW_CYCLE:
        rainbowCycle(substripOut);
        break;
    case THEATER_CHASE_RAINBOW:
        theaterChaseRainbow(substripOut);
        break;
    case COLOR_WIPE:
         colorWipe(substripOut, strip.Color(255, 0, 0)); // red
         break;    
    case BLINK:
        blinkEffect(substripOut, 111);
        break;
  }
}

void blinkEffect(subStrips &substrip, uint32_t color) {
    for(int i=substrip.startIndex; i<(substrip.startIndex+substrip.nb_LED) ; i++) {
      if (strip.getPixelColor(i) == 0) { strip.setPixelColor(i, color); }
      else { strip.setPixelColor(i, 0); }
    }
    strip.show();
    substrip.lastUpdate = millis(); // time for next change to the display
}


void rainbow(subStrips &substrip) { // modified from Adafruit example to make it a state machine
  static uint16_t j=0;
    for(int i=substrip.startIndex; i<(substrip.startIndex+substrip.nb_LED) ; i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
     j++;
  if(j >= 256) j=0;
  substrip.lastUpdate = millis(); // time for next change to the display
}

void rainbowCycle(subStrips &substrip) { // modified from Adafruit example to make it a state machine
//
}

void theaterChaseRainbow(subStrips &substrip) { // modified from Adafruit example to make it a state machine
//  
}

void colorWipe(subStrips &substrip, uint32_t c) { // modified from Adafruit example to make it a state machine
//
}


void wipeSubStrip(subStrips &substrip){ // clear all LEDs
    for(int i=substrip.startIndex; i<(substrip.startIndex+substrip.nb_LED) ; i++) {
       strip.setPixelColor(i, strip.Color(0,0,0));
    }
    strip.show();
    // substrip.lastUpdate = millis(); // no need to refresh LED off
 substrip.patternInterval = 10000000; // no need to refresh LED off
}
 
 
void wipe(){ // clear all LEDs
     for(int i=0;i<strip.numPixels();i++){
       strip.setPixelColor(i, strip.Color(0,0,0));
       }
}

uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}




Grumpy_Mike

Quote
I had to pass sub strips instead of patterns to the functions.
That seems an odd and complex way of doing things.

- I'm glad to say it works fine! : multiple simultaneous patterns on my single LED strip!

(just corrected my draft Blink function which didn't blink  :D  i'll edit the previous post)
Code: [Select]
void blinkEffect(subStrips &substrip, uint32_t color) {
    for(int i=substrip.startIndex; i<(substrip.startIndex+substrip.nb_LED) ; i++) {
      if (strip.getPixelColor(i) == 0) { strip.setPixelColor(i, color); }
      else { strip.setPixelColor(i, 0); }
    }
    strip.show();
    substrip.lastUpdate = millis(); // time for next change to the display
}


- Thanks Grumpy_Mike!
In my grand scheme  :-[  it seemed interesting to address orders to sub strip passing pattern as an argument.
Please advice me another way to follow!

Pandora114118

#8
Aug 08, 2018, 01:52 pm Last Edit: Aug 08, 2018, 06:43 pm by Pandora114118
Hi Mat

Did you ever finish this program by adding the extra Modes in?


Thanks for help

P.

Go Up