LuMini 8x8 Matrix Hookup Guide

Pages
Favorited Favorite 4

Light It Up

SparkFun has also written some example code specific to the rings to get you started. These example sketches can be found in the LuMini 8x8 GitHub Repo under Firmware. To download, click on the button below.

Make sure to adjust the pin definition depending on how you connected the LEDs to your microcontroller.

Example 1 --- Matrix Test

Glen Larson invented the Larson Scanner as an LED effect for the TV series Knight Rider. In this example, we'll begin to reproduce it that effect and add in some color for flavor. This sketch is a great way to test all of the LEDs. First, we begin by creating an object for matrix CRGB matrix[NUM_LEDS].

language:c
#include <FastLED.h>

// How many leds in your chain? Change the value of NUM_BOARDS depending on your setup
#define NUM_BOARDS 1
#define NUM_LEDS 64 * NUM_BOARDS //64 LED's per board

// The LuMini matrices need two data pins connected, these two pins are common on many microcontrollers, but can be changed according to your setup
#define DATA_PIN 16
#define CLOCK_PIN 17

// Define the array of leds
CRGB matrix[NUM_LEDS];

We then, initialize the matrix using the LEDS.addLeds function below. Notice the BGR in this statement, this is the color order, sometimes, the manufacturer will change the order in which the received data is put into the PWM registers, so you'll have to change your color order to match. The particular chipset we're using is BGR, but this could change in the future.

language:c
void setup() {
  Serial.begin(115200);
  Serial.println("resetting");
  LEDS.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(matrix, NUM_LEDS);
  LEDS.setBrightness(32);
}

In this sketch, the global brightness is set to 32 LEDS.setBrightness(32);. Although, the full range of this setting is 0 to 255, we've found that 32 is good for testing, as it's easier on the eyes. Even if all the LEDs are set to white, the temperature of the board will idle around (90-95°F... depending on your ambient room temperature).

Our animation is then contained in the fadeAll() function, which loops through every LED and fades it to a percentage of it's previous brightness. Our loop() then set's an LED to a hue, we increment the hue, then show our LEDs. After this we use the fadeAll() function to fade our LED's down so they don't all end up being on.

language:c
void fadeAll() {
  for (int i = 0; i < NUM_LEDS; i++)
  {
    matrix[i].nscale8(250);
  }
}

void loop() {
  static uint8_t hue = 0;
  //Rotate around the circle
  for (int i = 0; i < NUM_LEDS; i++) {
    // Set the i'th led to the current hue
    matrix[i] = CHSV(hue++, 150, 255); //display the current hue, then increment it.
    // Show the leds
    FastLED.show();
    fadeAll();//Reduce the brightness of all LEDs so our LED's fade off with every frame.
    // Wait a little bit before we loop around and do it again
    delay(5);
  }
}

Your code should look like the below gif if you've hooked everything up right. If thing's aren't quite what you'd expect, double check your wiring.

Animation of example 1

You should see this on the LuMini matrix if you have done everything correctly.

As a challenge, see if you can create an actual Larson scanner. It should only take a few modifications to the example code.

Example 2 --- RGB Color Picker

In this second example, we'll use the serial terminal to control the color displayed by the matrix. We initialize everything in the same way. We then listen for data on the serial port, parsing integers that are sent from the Serial Monitor from the Arduino IDE and putting them in the corresponding color (red, green or blue). The code to accomplish this is shown below.

language:c
#include <FastLED.h>

// How many leds in your chain? Change the value of NUM_BOARDS depending on your setup
#define NUM_BOARDS 1
#define NUM_LEDS 64 * NUM_BOARDS //64 LED's per board

// The LuMini matrices need two data pins connected, these two pins are common on many microcontrollers, but can be changed according to your setup
#define DATA_PIN 16
#define CLOCK_PIN 17

CRGB color;
char colorToEdit;

// Define the array of leds
CRGB matrix[NUM_LEDS];

void setup() {
  Serial.begin(115200);
  Serial.println("resetting");
  LEDS.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(matrix, NUM_LEDS);
  LEDS.setBrightness(32);

  //Display our current color data
  Serial.print("Red Value: ");
  Serial.println(color[0]);
  Serial.print("Green Value: ");
  Serial.println(color[1]);
  Serial.print("Blue Value: ");
  Serial.println(color[2]);
  Serial.println();      
}

void loop()
{
  if (Serial.available()) //Check to see if we have new Serial data.
  {
    colorToEdit = Serial.read();
    switch (colorToEdit)
    {
      case 'R':
      case 'r':
        color[0] = Serial.parseInt();
        break;
      case 'G':
      case 'g':
        color[1] = Serial.parseInt();
        break;
      case 'B':
      case 'b':
        color[2] = Serial.parseInt();
        break;
    }
    //Display our current color data
    Serial.print("Red Value: ");
    Serial.println(color[0]);
    Serial.print("Green Value: ");
    Serial.println(color[1]);
    Serial.print("Blue Value: ");
    Serial.println(color[2]);
    Serial.println();
    for (int i = 0; i < NUM_LEDS; i++)
    {
      matrix[i] = color;
      FastLED.show();
      delay(10);
    }
  }
}

Go ahead and upload this code, then open your Serial Monitor to a baud rate of 115200. It should be displaying the current color value (R:0, G:0, B:0), if not.

Serial monitor entries

Serial monitor entries (for animation below r255 -> r100g50b200 -> r255g255b255).

Changing the value of a color is done be sending the letter of the color (R, G, or B) followed by a value between 0 and 255. For instance, turning red to half brightness would be achieved by sending R127. Play around and look for your favorite color.

Animation of example 2

You should see this on the LuMini matrix if you have done everything correctly.

Troubleshooting Tips:
  • You may get some weird responses using low values for RGB; around 50 or less.
  • The letters for the color entry are not case sensitive.
  • You can also send multiple entries. Try sending r100b50 g200 or r0, b200,g150 in the serial monitor.
  • CRGB is an object defined in the FastLED library. If you look up the object definitions, you play with how it operates in your code. For example, modifying this line of code:
      matrix[i] = CRGB::White;
    will set your entire panel color to white.

Example 3 --- HSV Color Picker

The third example is very similar to the first in that we are picking colors using the serial terminal. However, in this example, we are working with an HSV color space. This sketch works mostly the same as the previous one, only we send h, s or v instead of r, g or b. Upload the below code and play around in search of your favorite color.

language:c
#include <FastLED.h>

// How many leds in your chain? Change the value of NUM_BOARDS depending on your setup
#define NUM_BOARDS 1
#define NUM_LEDS 64 * NUM_BOARDS //64 LED's per board

// The LuMini matrices need two data pins connected, these two pins are common on many microcontrollers, but can be changed according to your setup
#define DATA_PIN 16
#define CLOCK_PIN 17

CHSV color = CHSV(0, 255, 255);
char colorToEdit;

// Define the array of leds
CRGB matrix[NUM_LEDS];

void setup() {
  Serial.begin(115200);
  Serial.println("resetting");
  LEDS.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(matrix, NUM_LEDS);
  LEDS.setBrightness(32);

  //Display our current color data
  Serial.print("Hue: ");
  Serial.println(color.hue);
  Serial.print("Saturation: ");
  Serial.println(color.sat);
  Serial.print("Value: ");
  Serial.println(color.val);
  Serial.println();
}

void loop()
{
  if (Serial.available()) //Check to see if we have new Serial data.
  {
    colorToEdit = Serial.read();
    switch (colorToEdit)
    {
      case 'H':
      case 'h':
        color.hue = Serial.parseInt();
        break;
      case 'S':
      case 's':
        color.sat = Serial.parseInt();
        break;
      case 'V':
      case 'v':
        color.val = Serial.parseInt();
        break;
    }
    //Display our current color data
    Serial.print("Hue: ");
    Serial.println(color.hue);
    Serial.print("Saturation: ");
    Serial.println(color.sat);
    Serial.print("Value: ");
    Serial.println(color.val);
    Serial.println();

    for (int i = 0; i < NUM_LEDS; i++)
    {
      matrix[i] = color;
      FastLED.show();
      delay(10);
    }
  }
}

Once again, play around to try and find your favorite color. I find that HSV is a much more intuitive space to work in than RGB space.

Example 4 --- Mapping Multiple Matrices

The LuMini Matrices can be easily daisy chained to create a screen of a custom size. When dealing with any screen or LED matrix, you'll want to be able to call some sort of function XY(x, y) to return an LED number at any given coordinate. In order to do this, we'll need to outline the path in which we've daisy chained our matrices as well as the orientation of each matrix. First let's look at the path that our matrices take.

Assembly for 2x2 matrices

Completed assembly for 2x2 matrices with matrix map marked. The orientation of third panel should be rotated 90° clockwise (from the front of the panels). Click image to see the soldering connections on the back of the assembly.

I've soldered together 4 LuMini matrices in the below picture. Each number represents which number the matrix is in the chain. I like to start at the bottom left, but you can lay out your matrix however you want. We'll then have to edit our matrixMap[moduleHeight][moduleWidth] object to tell our code where each matrix is. Notice how the numbers in the table identically map to the numbers on the matrices in the above picture.

language:c
#include <FastLED.h>

const int moduleHeight = 2; //The Height of our display, measured in numbers of LuMini matrices
const int moduleWidth = 2; //The Width of our display, measured in numbers of LuMini matrices

//The following matrix represents our entire LED display, with the number that each module is in the chain. My data flows in to the bottom left matrix (matrix 0 in my chain),
//then it goes right to the bottom right matrix (matrix 1 in my chain) then up to the top right matrix (matrix 2) then to the remaining matrix 3
//The below table should have identical matrix numbers/positions as that of the full multi-matrix module   
int matrixMap[moduleHeight][moduleWidth] = {
  {3, 2},
  {0, 1}
};

We'll then need to adjust the orientation of each matrix in code so that any physically rotated matrix gets it's pixels rotated in code as well. The easiest way to check the orientation is to first change the values of the int orientation[moduleHeight * moduleWidth] to 0, which is the default orientation when a LuMini matrix is facing straight up and down. Go ahead and upload your code. The last matrix should have a line going from top to bottom instead of left to right.

If your entire module was properly oriented, you would see a line of color swiping from left to right. If any of your matrices have a line swiping in a different direction, take note of the direction the line is swiping on the problem module. Use the below table to match the direction you're seeing to the necessary orientation in the int orientation[moduleHeight * moduleWidth] object.

Swipe Direction (Orientation 0)Orientation Number
Left to Right0
Top to Bottom1
Right to Left2
Bottom to Top3

Since the last matrix has a line swiping from top to bottom due to its orientation, I'll change the orientation of the last matrix like so.

language:c
int orientation[moduleHeight * moduleWidth] = { 0, 0, 0, 1 };

Animation of example 4

You should see this on the 2x2 matrices if you have done everything correctly.

Example 5 --- Using Gradients

In this final example, we'll leverage FastLED's palette object (CRGBPalette16) to create and visualize a color palette on our matrix. We have much the same initialization as our previous examples, only this time we also initialize a CRGBPalette16 object which will be full of colors along with a TBlendType which will tell us whether or not to blend the colors together or not. This can be either LINEARBLEND or NOBLEND. To populate this gradient, we use examples 2 and 3 to find the colors we want to put into our gradient. The gradient included is a bunch of colors created in HSV space, but you can easily change to RGB space if you prefer. You can also use any of the preset palettes by uncommenting the line that sets it equal to currentPalette.

language:c
TBlendType    currentBlending = LINEARBLEND;
CRGBPalette16 currentPalette = {
  CHSV(5, 190, 255),
  CHSV(0, 190, 255),
  CHSV(245, 255, 255),
  CHSV(235, 235, 255),
  CHSV(225, 235, 255),
  CHSV(225, 150, 255),
  CHSV(16, 150, 255),
  CHSV(16, 200, 255),
  CHSV(16, 225, 255),
  CHSV(0, 255, 255),
  CHSV(72, 200, 255),
  CHSV(115, 225, 255),
  CHSV(40, 255, 255),
  CHSV(35, 255, 255),
  CHSV(10, 235, 255),
  CHSV(5, 235, 255)
};

//currentPalette = RainbowColors_p;
//currentPalette = RainbowStripeColors_p;
//currentPalette = OceanColors_p;
//currentPalette = CloudColors_p;
//currentPalette = LavaColors_p;
//currentPalette = ForestColors_;
//currentPalette = PartyColors_p;

We then use the ColorFromPalette function to put the colors from our gradient onto our LED matrix.

language:c
void loop() {
  for (uint8_t x = 0; x < matrixWidth; x++)
  {
    uint8_t gradientIndex = (x * 2) + rotation;//Multiply by 2 to show more of the gradient on the matrix
    for (uint8_t y = 0; y < matrixHeight; y++)
    {
      matrix[XY(x, y)] = ColorFromPalette(currentPalette, gradientIndex, brightness, currentBlending);
    }
  }
  FastLED.show();
  rotation++;
  delay(30);
}

Play around with the colors in your palette until you're satisfied. If all is hooked up correctly your LED matrix should look something like the below gif.

Animation of example 5

You should see this on the LuMini matrix if you have done everything correctly.

Additional Examples

There are quite a few additional examples contained in the FastLED library. These can be obtained by opening up File -> Examples -> Examples From Custom Libraries -> FastLED