WS2812B Chips, Need help with code.

I am looking for some serious hand holding, or even outright doing it for me :D. I have a couple of projects on the go that involve WS2812B LED's. I have a 8X32 matrix and a hand soldered 7X28 matrix. The thing i wish to accomplish is first of all programming simple animations, a scrolling text, maybe a rainbow, a cylon style red tracer dot, and so on. Adafruit has some great examples of these and I have easily managed to test them out individually, My issue is now a button push to rotate through these animations. fortunately adafruit also has an example of this, but does not exactly do what I would like it to. The program waits until the animation is finished, stops, and then changes and starts a new animation once the button is pressed.

Now normally I would have no problem trying to dredge my way through and monster mash various codes together, but unfortunately I have a bit of a time crunch and due to my work situation I have even less time to work on it.

If anyone is interested in helping out I would really appreciate it, I cannot provide sample code at them moment as I work a 2 week on 2 week off camp job and my internet is severely policed, meaning a lot of my sources are currently blocked. I can however offer some compensation to whomever may want to take on this task for me :slight_smile:

Thanks for reading my long winded post.

Just to clear up any confusion, when I say that compensation I mean money. I had briefly considered baking a cake, but thought that money would suffice.

If anyone is interested I can try and provide more details upon request, I do however have limited resources at the moment but will try my best to accommodate.

My issue is now a button push to rotate through these animations.

That part is actually pretty simple

// adafruit stuff
:
:
byte changeButton = 2; // wire button to connect pin to Gnd when pressed
byte programSelect = 0;

void setup(){
// adafruit stuff
:
:
pinMode (changeButton, INPUT_PULLUP); //
}

void loop(){
if (digitalRead(changeButton == LOW){ // requires user to press & hold button near end of a routine to go on to the next one, otherwise repeat current
programSelect = programSelect +1;
  if (programSelect == 10){  
  programSelect = 0; // reset, assume 10 programs, #0 to #9
  }
}
switch (programSelect){
case 0:
// adafruit routine
break;
case 1:
// adafruit routine
break;
case 2:
// adafruit routine
break;
case 3:
// adafruit routine
break;
case 4:
// adafruit routine
break;
case 5:
// adafruit routine
break;
case 6:
// adafruit routine
break;
case 7:
// adafruit routine
break;
case 8:
// adafruit routine
break;
case 9:
// adafruit routine
break;
} // end switch
} // end loop

but does not exactly do what I would like it to.

Which is what?

The program waits until the animation is finished, stops, and then changes

I believe that's because they are using asm for tight the timing required by the chips, it's built in.

For some ideas, here is a portion of code I used in a project:

  //*****************************
  //Check machine state and do things that must be done accordingly 
  switch(mode)
  {
    //***************************
  case 0: 
    checkSwitch();

    break; 
    //END case stateStart:

    //***************************
  case 1: 
    rainbowCycle(rainbowSpeed,2); 
    checkSwitch();

    break; 
    //END case stateRainbow:

    //***************************
  case 2: 
    knightRider(Cycles, KnightRiderSpeed, Width, 0x0000FF); //Cycles, Speed, Width, RGB Color (Blue)
    checkSwitch();

    break; 
    //END case stateKnightRiderBlue:

    //***************************
  case 3: 
    knightRider(Cycles, KnightRiderSpeed, Width, 0xFF0000); //Cycles, Speed, Width, RGB Color (Red)
    checkSwitch();

    break; 
    //END case stateKnightRiderBlue:

    //***************************
  case 4: 
    ZylonBlue();
    if(pos - 1 < 0) 
    {
      checkSwitch();
    }

    break; 
    //END case stateZylonBlue:

    //***************************
  case 5: 
    ZylonRed();
    if(pos - 1 < 0) 
    {
      checkSwitch();
    }

    break; 
    //END case stateZylonRed:

     //***************************
  case 6: 
    twoSides(0x0000FF); //Blue
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }

    break; 
    //END case Blue twoSides:

 
    //***************************
  case 7: 
    twoSides(0x0000FF); //Blue
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }
    twoSides(0x00FF00); //Green
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }
    twoSides(0xFF0000); //Red
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }
    
    twoSides(0xFF00FF); //Purple
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }

    break; 
    //END case twoSides:


    //***************************
  case 8: 
    middleOut(0x0000FF); //Blue
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }

    break; 
    //END case Blue middleOut


    //***************************
  case 9: 
    middleOut(0x0000FF); //Blue
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }
    middleOut(0x00FF00); //Green
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }
    middleOut(0xFF0000); //Red
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }
    
    middleOut(0xFF00FF); //Purple
    if(digitalRead(modeSwitch) == 0)
    {
      checkSwitch();
      break;
    }

    break; 
    //END case middleOut

    //***************************
  case 10: 
    knightRider(Cycles, KnightRiderSpeed, Width, 0xFFFFFF); // Cycles, Speed, Width, RGB Color (white)
    if(digitalRead(modeSwitch) == 0)
    {
      mode = 0;
      break;
    }

    knightRider(Cycles, KnightRiderSpeed, Width, 0xFF00FF); // Cycles, Speed, Width, RGB Color (purple)
    if(digitalRead(modeSwitch) == 0)
    {
      mode = 0;
      break;
    }

    knightRider(Cycles, KnightRiderSpeed, Width, 0x0000FF); // Cycles, Speed, Width, RGB Color (blue)
    if(digitalRead(modeSwitch) == 0)
    {
      mode = 0;
      break;
    }

    knightRider(Cycles, KnightRiderSpeed, Width, 0x00FF00); // Cycles, Speed, Width, RGB Color (green)
    if(digitalRead(modeSwitch) == 0)
    {
      mode = 0;
      break;
    }

    knightRider(Cycles, KnightRiderSpeed, Width, 0xFFFF00); // Cycles, Speed, Width, RGB Color (yellow)
    if(digitalRead(modeSwitch) == 0)
    {
      mode = 0;
      break;
    }

    knightRider(Cycles, KnightRiderSpeed, Width, 0xFF0000); // Cycles, Speed, Width, RGB Color (red)
    if(digitalRead(modeSwitch) == 0)
    {
      mode = 0;
      break;
    }

    break; 
    //END case knightRiderRainBow:


  } // END of switch(mode)

CrossRoads:
Which is what?

What I would like to accomplish is to interrupt any current animation to move on to the next, but the adafruit example waits until the animation is complete until it will recognize the button press and then change animations. I am also having problem because most of adafruit's examples are for strings of their neopixels rather than matrices, they do however have an example for this but I am at a loss for how to implement the other examples into the matrix example.

I should also mention that I am completely new to ardunio (new being a retaliative term) I had worked on a project about 3 years ago, managed to get it working as best I could and then dropped arduino almost completely. I have done little to no actual programming, it mostly consists of copy and paste.

Thank you for your quick responses. Please bare in mind that I am working in a remote location at the moment and may not be able to answer in a timely fashion, so I apologize in advance.

I managed to do a bit of a workaround and found some of the adafruit libraries, I just thought I would post the matrix code that I am trying to monster mash with the pixel strip code

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
 #define PSTR // Make Arduino Due happy
#endif

#define PIN 6

// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the matrix; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
//     rows or in vertical columns, respectively; pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
//     in the same order, or alternate lines reverse direction; pick one.
//   See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)


// Example for NeoPixel Shield.  In this application we'd like to use it
// as a 5x8 tall matrix, with the USB port positioned at the top of the
// Arduino.  When held that way, the first pixel is at the top right, and
// lines are arranged in columns, progressive order.  The shield uses
// 800 KHz (v2) pixels that expect GRB color data.
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(5, 8, PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB            + NEO_KHZ800);

const uint16_t colors[] = {
  matrix.Color(255, 0, 0), matrix.Color(0, 255, 0), matrix.Color(0, 0, 255) };

void setup() {
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(40);
  matrix.setTextColor(colors[0]);
}

int x    = matrix.width();
int pass = 0;

void loop() {
  matrix.fillScreen(0);
  matrix.setCursor(x, 0);
  matrix.print(F("Howdy"));
  if(--x < -36) {
    x = matrix.width();
    if(++pass >= 3) pass = 0;
    matrix.setTextColor(colors[pass]);
  }
  matrix.show();
  delay(100);
}

And here is an example of the strip code some of what I want, but I need to try and figure out how to make it work with the matrix instead of the strip, I have unsuccessfully tried to just change all of the strip to matrix

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code


  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
  // Send a theater pixel chase in...
  theaterChase(strip.Color(127, 127, 127), 50); // White
  theaterChase(strip.Color(127,   0,   0), 50); // Red
  theaterChase(strip.Color(  0,   0, 127), 50); // Blue

  rainbow(20);
  rainbowCycle(20);
  theaterChaseRainbow(50);
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();
     
      delay(wait);
     
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
        for (int i=0; i < strip.numPixels(); i=i+3) {
          strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
        }
        strip.show();
       
        delay(wait);
       
        for (int i=0; i < strip.numPixels(); i=i+3) {
          strip.setPixelColor(i+q, 0);        //turn every third pixel off
        }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

There is also a snippet of code that uses the GFX library for image insertion, but I haven't managed to track down a sample of the code. I will try and do so and post back later.

So no takers on coding it for me? Like I said I am willing to pay :slight_smile:

I would really love to learn this myself but I am very strapped for time, collectively I only have about 3 weeks (excluding work) As I move closer and closer to my deadline it seems less likely that I will be able to learn what I need to achieve what I want to do.

I have pictures of my soldered matrix, but my work server is preventing me from attaching them :frowning:

If anyone has any experience with FastSPI (or I guess FastLED now) I would appreciate input on that too. I am flexible on either, I am not married to the idea of using adafruit only. I know that you cannot combine the two codes, but if one will be better/easier than the other I am open to suggestions.

On a side not I am almost done work, so hopefully I can make some progress coding on my days off. I do however still have a lot of work to do on the physical body of the project, and a little bit on the hardware side. I am quickly running out of time to code anything, and the addition of still having to build the rest of the project is getting quite daunting, so the offer is still up for a contract coder!!!

WS2812B does not use SPI, it uses timing variation to send 0/1 info per byte, see timing signal at top of sheet 4.

Too much coding for me, sorry. I'm really a hardware designer.

WS2812B.pdf (381 KB)

CrossRoads:
WS2812B does not use SPI, it uses timing variation to send 0/1 info per byte, see timing signal at top of sheet 4.

Oh sorry, I was under the impression that the FastLED library (formally the FastSPI) could run the WS2812 chips. On their google plus communities page there seems to be quite a few people using the FastLED library to drive the WS2812, could it have recently been adapted?

Anyway thank you for that information, I will continue to try and research what I can and post my findings. Sorry in advance if this post starts to get a little clustered, I will try my best to keep everything relevant.

I was directed towards a good library set for the FastLED, it will drive the WS2812B chip