Using Brickstuff BrickPixel Controllers with the Adafruit NeoPixel Library in Arduino

(NOTE: this post is intended for experienced Arduino programmers.  We cannot provide specific programming advice or any sample code beyond what it provided here.  If you would like to learn more about how NeoPixels work, Adafruit has published an excellent, in-depth guide here.)

Since the release of our lighting kit for the LEGO Ferris Wheel several years ago, we have used a lighting control technology based on the WS281x protocol commonly found in individually-addressable RGB LEDs known generally as NeoPixels.  Using the WS281x LED control technology, it is possible to control tens or even hundreds of LEDs with a single controller.

We have created our own LED controller boards that use the WS2811 control chip.  These boards have a 3-wire input connector and individual Pico LED connectors for each output.  Each output can control a single LED.  Many of the adapter boards have a 3-wire output connector as well, which allows boards and LEDs to be daisy-chained together in a logical string, while still being controlled by a single "master" controller.

Because our controller boards use the same technology as the NeoPixel LEDs, you can use the Adafruit NeoPixel library to control Brickstuff Pico LEDs as well.  You can control individual brightness of each LED, and you can also write your own lighting effects inside the Arduino IDE.

Unlike traditional NeoPixels, however, our controllers manage individual LEDs.  This means you can't use the Adafruit library directly, since that library was written to manage RGB LEDs (which are actually three individual LEDs-- red, green, and blue-- inside a single LED case).  Don't worry, though!  We've created a small little bit of code you can seamlessly drop into any Arduino sketch to give you full control of any BrickPixel LEDs in your chain.  Read on to learn how.

 

Installing the Adafruit Library

First, make sure you have the Arduino IDE installed and that you have also installed the Adafruit NeoPixel library (see their excellent Überguide for instructions).

Next, create a new Arduino sketch with the core elements of the NeoPixel library included:

#include <Adafruit_NeoPixel.h>
// Which pin on the Arduino is connected to the NeoPixels?
#define LED_PIN    6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 10

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 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)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

(the code above was copied from the Adafruit Überguide)

 

Additional BrickPixel Code

In addition to the base NeoPixel code above, you will need to add a few more variable declarations before the setup() block in your code:

int pixelMax = 30;  // Maximum number of LEDs (not pixel boards) in a string
int numPixels = 10; // Total number of pixel boards (not individual LEDs) in a string (is calculated by dividing pixelMax by 3 and adding one if there's a remainder)

int pixelBright[xx];    // Change "xx" to be the same as your numPixels setting

Looking at the code sample above, pixelMax should be set to the number of total LEDs in your chain.  The example above has pixelMax set to 30, which means there are 30 total individual LEDs in your string.

Next is the numPixels setting.  This should refer to the total number of NeoPixel control chips in your setup.  One control chip has three individual LED outputs, so to get the total for numPixels, just divide pixelMax by three and add one if there is a remainder.  numPixels should also be the same as the LED_COUNT setting in your NeoPixel setup code (remember, the LED_COUNT number refers to the number of RGB LEDs, and just like with our control chips, each RGB LED represents three physical LEDs).

Once you have configured numPixels and pixelMax, you can define the variable pixelBright as an array with the same number of members as your numPixels setting.

pixelBright is where all the magic happens.  Each element in the array refers to a single LED in your chain.  Array element 0 controls LED #1 and so on.

In addition to the code elements above, which should all be placed in your Arduino sketch above the setup() block, you need to add one subroutine after the end of your loop() block.  This is the code to add:

void uStrip()
{
  // Refreshes the entire strip
  int subPixel;

  for(int i=0; i<numPixels; i++)
  {
    strip.setPixelColor(i,strip.Color(pixelBright[subPixel], pixelBright[(subPixel+1)], pixelBright[(subPixel+2)]));
    subPixel++;
    subPixel++;
    subPixel++;
  }
    strip.show();
    subPixel = 0;
}

 This subroutine handles the translation of single-color LEDs into RGB-like code that the NeoPixel library is designed to understand.

 

Controlling LEDs

To set the brightness of any LED in your chain, set the element of pixelBright corresponding to that LED to any value between 0 (off) and 255 (full brightness).

For example, to set the brightness of the 10th LED in your chain to 50%, you would type:

pixelBright[9] = 128;

If you wanted to set the brightness of a range of LEDs in your string, you could use a for/next loop.  For example, to set the brightness of LEDs 10-20 to 100% brightness, you would type:

for(int i=9; i<20; i++)

{

    pixelBright[i] = 255;

}

Once you have set the brightness for each LED you want to change or set using the appropriate elements of the pixelBright array, you should call the uStrip() subroutine:

uStrip();

This will update all variables in the NeoPixel object and refresh the strip.  When using uStrip(), you do not need to call strip.show() as outlined in the Adafruit guide.

That's pretty much all there is to it.  Using the variety of Brickstuff BrickPixel adapters, controller boards, and cables, you can add lights to your model and control them all from your Arduino board.

2replies Oldest first
  • Oldest first
  • Newest first
  • Active threads
  • Popular
    • WRTyler
    • -the National Mall guy-
    • wrTyler
    • 2 yrs ago
    • Reported - view

    For those who are just getting started with programming the Brickstuff Arduino shield (and, like me, need to brush up on their programming skills).  Here is my first successful sketch controlling a set of 5 Brickstuff lights using the BrickPixel system.

    Things I missed when I started.  The example code shown above from AdaFruit has the BrickPixel control pin on the Arduino listed as 6.  Looking at the Brickstuff shield you will see that pins 7 and 8 are the control pins.  Took me a day to figure out that mistake.

    I also couldn't figure out how to combine all the bits and pieces of code listed above into a working sketch, so I wound up grabbing the "Simple" code at https://github.com/adafruit/Adafruit_NeoPixel as a starting point. This is why I have a NeoPixel object called pixel instead of strip.  This is also why I'm not using the subPixel variable shown above.

    I'm sure I'll eventually move back to the variables and processes shown above, but the following approach is what made sense to me just starting out.

    I hope this slightly different approach is helpful for those who need a little guidance to get up and running for the first time.

    Do remember...ping the Brickstuff folks if you need help, they are incredibly knowledgable and supportive.

    -wrtyler-

    // ==========
    #include <Adafruit_NeoPixel.h>

    // BrickPixel controls are on Pin 7 & 8
    //   Pin 7 = PIXEL 1, Pin 8 = PIXEL 2
    #define PIN       7

    // The AdaFruit software is designed to work with triplets
    //   of lights (R,G & B). The Brickstuff hardware is designed
    //   to work with individual lights.
    // To calculate the NUMPIXELS, take the total number of
    //   Brickstuff lights that are connected and divide by 3.
    //   If there is any remainder, increase NUMPIXELS by 1.
    // In this example there are 5 Brickstuff lights attached.
    #define NUMPIXELS 2

    // Declare a NeoPixel object. This is used to control the
    //   individual lights.
    Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);
    // Argument 1 = Number of triplet groups of lights
    // Argument 2 = Arduino pin number of the BrickPixel socket being used
    // Argument 3 = Pixel type flags, add together as needed:
    //    NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
    //    NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    //    NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
    //    NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/ WS2812 LEDs)
    //    NEO_KHZ800  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)

    void setup() {
     // Initialize the NeoPixel object (this is REQUIRED)
     pixels.begin();
    }

    void loop() {
     // Clear out any prior BrickPixel settings
     pixels.clear();

    // Set up the random number generator
     randomSeed(random(10000));

    // In this example, the brightness of the Brickstuff lights is looped from
     //   0 (off) to 255 (maximum brightness) in steps of 4 (to make it faster)
     for(int j=0; j<=255; j+=4) {

    // For each group of light triplets, set the brightness. Multiply the
       //   brightness setting by a random number between 0 and 1 to introduce
       //   flickering. This is to show that each light is independently being
       //   accessed.
       for(int i=0; i<NUMPIXELS; i++) {
         pixels.setPixelColor(i, pixels.Color(j*(random(100)/100.0), j*(random(100)/100.0), j*(random(100)/100.0)));
         // Send the brightness settings to the BrickPixel controller.
         pixels.show();
       }
       // Add a delay so the flickering doesn't happen so fast that you can't see it
       delay(60);
     }

    // Once the lights are at full intensity, smoothly reduce the brightness
     //  until they are all completely dark
     for(int j=255; j>=0; j--) {
       for(int i=0; i<NUMPIXELS; i++) {
         pixels.setPixelColor(i, pixels.Color(j, j, j));
         pixels.show();
       }

    delay(2);
     }

    Like 1
    • WRTyler
    • -the National Mall guy-
    • wrTyler
    • 2 yrs ago
    • Reported - view

    Dang, the code above needs a additional bracket     at the very end.  My cut and paste was a little off.

    Like
Like1 Follow
  • 1 Likes
  • 2 yrs agoLast active
  • 2Replies
  • 186Views
  • 2 Following