Yet Another Matrix

by Arnov Sharma in Circuits > Arduino

4578 Views, 32 Favorites, 0 Comments

Yet Another Matrix

19 (37).gif
17 (42).gif
DIY RGB MATRIX with Mini WS2812 LEDs
Image27.jpg

Hey What's up folks, this is my tiny 8x8 Matrix that is made from 64 WS2812B LEDs that are in the 2020 package.

The Goal for making this matrix was to prepare a custom 8x8 matrix that I could use in small projects, the matrix available in the market uses Addressable LEDs of the 5050 package which would be too big for my application so I prepared my own by using smaller LEDs and a Custom PCB.

The size of this Mini Matrix is 28.6 x 26.4 mm which is crazy small.

This Instructables is gonna be about how I made this matrix from scratch and how we can program it to display all sorts of stuff on it, so let's get started!
Also you can get this display from tindie
https://www.tindie.com/products/maepa/2826-pixel-matrix/

Supplies

IMG_20220410_235927.jpg

The following were the things used in this build-

  • WS2812B 20202 LEDs x64
  • Custom PCB
  • Arduino Nano
  • Stencil for solder paste process
  • Solder Paste
  • Breadboard and jumper wires
  • CON3 Header pins x 2
  • Library for running matrix- https://github.com/FastLED

WS2812 2020 LED

large (1).JPG
4684-00.jpg
HTB12udJtH9YBuNjy0Fgq6AxcXXak.jpg

We all know WS2812B Addressable LEDs that come in the 5050 Package but here's something small and better, WS2812B But in the 2020 package!

This LED is just 2mm x 2mm in size which is mind-blowing as now we can add it to any of our RGB projects and reduce its overall size.

However, because this is a tiny component, it can only be soldered via SMD Technics like using a Hotplate reflow with solder paste.

Technical Specs and other crucial details

  • This LED consumes 12mA operating current per channel which means in total white light it consumes a max current of 32mA which is enough for a single pixel.
  • The refresh rate of this LED is 30fps so yeah, practically speaking, we can make a huge monitor from it and run all sorts of things on it with average FPS.
  • The data transfer protocol uses a single NZR communication mode
  • Each pixel of the three primary colors can achieve 256 brightness display, completed 16777216 colors full-color display, and scan frequency is of 2KHz

Datasheet of This LED.

PCB DESIGN

sch_page-0001 (2).jpg

Step 1 of the PCB Design for making this tiny matrix was to prepare the schematic which consists of 64 LEDs connected in the usual WS2812 Layout.

All LED's VCC and GND are connected in Parallel and the Din of 1st pixel is connected to a CON3 Pin.

Dout of 1st pixel goes to Din of 2nd pixel, Dout of 2nd pixel goes to Din of 3rd pixel and this goes on and on up to 64th pixel.

the Schematic is attached.

Serpentine Layout

Capture.PNG

Now here's something super important, the matrix layout that I'm using is the serpentine layout which is the general use layout, there also exist other layouts like back-and-forth which is also an option in the XY matrix example.

To set this layout, we need to specify the layout in the sketch by changing

const bool    kMatrixSerpentineLayout = true;  //to False


LED PACKAGE

Capture2.PNG
Capture6.PNG

After figuring out the layout, I prepared the custom footprint for the RGB LED by following its footprint given in the datasheet.

I then exported the netlist and converted the schematic into a PCB Design.

(using OrCad here, this process might be different for your CAD Software)

Printed Circuit Board

Capture5.PNG

As for the layout, I knew the size of the LED so I carefully prepared a grid by placing each LED next to it with a minimum gap of 1mm and this gave me a board size of roughly 27mm x 27mm. (i did alter the size a little bit to 28mm x 26mm)

I used 0.3mm Tracks in this design with lots of via, I could prepare a 4 layer PCB for this version but I believe for such a simple led board, why use 4 layer PCB when you can use 2 layers one and get the same work done with it.

After completing the board, I exported its Gerber data and sent it to PCBWAY for samples.

PCB ASSEMBLY

  • Solder paste dispensing
  • Pick and place
  • Hotplate
  • adding con 3 Pins

SOLDER PASTE DISPENSING

Image13.jpg
Capture56.png

Now the first step is to add solder paste to each components pad.

I usually use my good old solder paste dispensing syringe but for this project, I choose to get a stencil instead.

Let me explain why.

Each led had 4 super small pads. (each pad is less than 0.8mm x 0.8mm)

I used 64 LEDs in this which makes total pads 256, now imagine adding solder paste to 256 pads.

If I missed a single pad, the led won't glow and I have to do rework which would not be ideal as these leds are fragile and providing it heat for more than 1 time might damage the chip's body.

Here's How We Can Use the Stencil

05 (55).gif
06 (54).gif
07 (58).gif
08 (54).gif
IMG_20220410_234210.jpg
  • we first tape three matrix PCBs in a cluster so they would each hold the PCB which is in the center from three sides.
  • after making sure that the middle PCB is placed properly and isn't moving, we add the stencil to it and try to locate the pads by moving the stencil over the PCB.
  • when you get a proper and clear view of pads from the stencil, we then tape it to the ground so it won't move from its place.
  • next, we add solder paste to one side of the stencil and use a scraping tool to apply solder paste through stencil openings, solder paste will get in the stencil cutout and fill out each exposed pad.
  • At last, we remove the PCB from its stencil setup and examine if each pad has been covered with solder paste or not.

Pick and Place Process

09 (51).gif
IMG_20220411_000422.jpg

After applying Solderpaste we move on to the next step which is to add componenets to their assigned location.

I used an ESD Tweezer to place each LED in its place.

One main thing to keep in mind doing this process is the polarity of the LED, placement of each LED should be according to the polarity mark which is below the LED and also on the PCB.

HOTPLATE REFLOW

10 (58).gif
11 (58).gif

After the "Pick & Place Process", I carefully lifted the whole circuit board and place it on my DIY SMT Hotplate.

the hotplate heats the PCB from below up to the solder paste melting temp, as soon as the PCB reaches that temp, solder paste melts and all the components get soldered to their pads, we lift the PCB and then place it on a cooler surface for a little bit, to cool down the heat of PCB.

Adding CON3 on the Bottom Side

12 (53).gif
13 (53).gif
14 (46).gif

I have added two connector pins at the backside of the PCB to which we connect two CON3 Header Pin that lets us connect this board onto a breadboard.

Generally, the connector pin requires a hole pad but I added an SMD rectangular pad on which we can mount these pins horizontally.

Arduino Nano Matrix Setup

Fabulous Kup.png
Image26.jpg

To drive this Mini Matrix, I used an Arduino Nano board which I added to a breadboard and connected the matrix with it according to the following wiring diagram.

  • VCC of LEDs to 5V of Arduino
  • Din to D3 of Arduino
  • GND to GND

Libraries

Capture10.PNG
Capture11.PNG

To drive the matrix, we can use two separate libraries like adafruit's neopixel library or the FastLED library.

I prefer the FastLED library as it offers a bunch of example sketches that are easy to edit and use.

I used the XY Matrix Sketch that you can find in FastLED example sketches.


#include <FastLED.h>

#define LED_PIN  3

#define COLOR_ORDER GRB
#define CHIPSET     WS2811

#define BRIGHTNESS 64

// Params for width and height
const uint8_t kMatrixWidth = 8;
const uint8_t kMatrixHeight = 8;

// Param for different pixel layouts
const bool    kMatrixSerpentineLayout = false; 
const bool    kMatrixVertical = false;
// Set 'kMatrixSerpentineLayout' to false if your pixels are 
// laid out all running the same way, like this:
//
//     0 >  1 >  2 >  3 >  4
//                         |
//     .----<----<----<----'
//     |
//     5 >  6 >  7 >  8 >  9
//                         |
//     .----<----<----<----'
//     |
//    10 > 11 > 12 > 13 > 14
//                         |
//     .----<----<----<----'
//     |
//    15 > 16 > 17 > 18 > 19
//
// Set 'kMatrixSerpentineLayout' to true if your pixels are 
// laid out back-and-forth, like this:
//
//     0 >  1 >  2 >  3 >  4
//                         |
//                         |
//     9 <  8 <  7 <  6 <  5
//     |
//     |
//    10 > 11 > 12 > 13 > 14
//                        |
//                        |
//    19 < 18 < 17 < 16 < 15

uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  
  if( kMatrixSerpentineLayout == false) {
    if (kMatrixVertical == false) {
      i = (y * kMatrixWidth) + x;
    } else {
      i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
    }
  }

  if( kMatrixSerpentineLayout == true) {
    if (kMatrixVertical == false) {
      if( y & 0x01) {
        // Odd rows run backwards
        uint8_t reverseX = (kMatrixWidth - 1) - x;
        i = (y * kMatrixWidth) + reverseX;
      } else {
        // Even rows run forwards
        i = (y * kMatrixWidth) + x;
      }
    } else { // vertical positioning
      if ( x & 0x01) {
        i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
      } else {
        i = kMatrixHeight * (kMatrixWidth - x) - (y+1);
      }
    }
  }
  
  return i;
}


#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
CRGB* const leds( leds_plus_safety_pixel + 1);

uint16_t XYsafe( uint8_t x, uint8_t y)
{
  if( x >= kMatrixWidth) return -1;
  if( y >= kMatrixHeight) return -1;
  return XY(x,y);
}


void loop()
{
    uint32_t ms = millis();
    int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));
    int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));
    DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
    if( ms < 5000 ) {
      FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
    } else {
      FastLED.setBrightness(BRIGHTNESS);
    }
    FastLED.show();
}

void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
  byte lineStartHue = startHue8;
  for( byte y = 0; y < kMatrixHeight; y++) {
    lineStartHue += yHueDelta8;
    byte pixelHue = lineStartHue;      
    for( byte x = 0; x < kMatrixWidth; x++) {
      pixelHue += xHueDelta8;
      leds[ XY(x, y)]  = CHSV( pixelHue, 255, 255);
    }
  }
}


void setup() {
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  FastLED.setBrightness( BRIGHTNESS );
}

The above sketch is for testing the LED Matrix, I changed the LED Pin number in it first.

#define LED_PIN  3

Then I edited the matrix Height and width

// Params for width and height
const uint8_t kMatrixWidth = 8;
const uint8_t kMatrixHeight = 8;

At last, I selected the serpentine layout as false

const bool    kMatrixSerpentineLayout = false; 
const bool    kMatrixVertical = false;


Example Sketch XY Matrix Result

15 (47).gif
16 (44).gif

Result!

Tylor Jones's LED MATRIX CONTROL SOFTWARE

26 (17).gif
27 (12).gif

By searching for Matrix control software, I found this LED MATRIX CONTROL SOFTWARE by Tylor jones, and this software is a good one.

Here's how this software works.

#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 64

byte pixelType = 0;
char drawIn[4];
char frameIn[768];


// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 3
//#define CLOCK_PIN 13

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

void setup() {
  // Uncomment/edit one of the following lines for your leds arrangement.
  // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
  //FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);

  // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);

  // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(500000);
}

void loop() {

}

void serialEvent() {
  pixelType = Serial.read();

  switch (pixelType) {
    case 0:
    //draw mode
      Serial.readBytes(drawIn, 4);

      leds[drawIn[0]] = CRGB(drawIn[1], drawIn[2], drawIn[3]);

      FastLED.show();
      Serial.flush();
      break;

    case 1:
      //clear mode
      for (int i = 0; i < NUM_LEDS; i++)
      {
        leds[i] = CRGB::Black;
      }

      FastLED.show();
      Serial.flush();
      break;

    case 2:
    //frame in mode
      Serial.readBytes(frameIn, (NUM_LEDS * 3));
      for (int i = 0; i < NUM_LEDS; i++)
      {
        leds[i] = CRGB(frameIn[i * 3], frameIn[(i * 3) + 1], frameIn[(i * 3) + 2]);
      }

      FastLED.show();
      Serial.flush();
      break;

    case 3:
      int brightnessLED = Serial.read();
      FastLED.setBrightness(brightnessLED);
      Serial.flush();

      break;
  }
}
  • We open up the main sketch and declare the number of LEDs in our matrix which is 64.
  • Then we upload the sketch to the Arduino board and open up the control software.
  • In the control software, we first select the COM Port, and then the software will get paired with Arduino nano in real-time.
  • By Real-time, I mean we can interact with this display.
  • We first set the matrix size to 8x8 and then select the mode we want to run which would be drawing mode.
  • We then select any color by changing the RGB Slider and just start drawing on the matrix, left click will fill the pixel with the selected color and right-click will erase that color.
  • by this, we can draw anything and export its main code.


Displaying the Image We Just Made

24 (21).gif

After exporting out the code for an image we just made, we copy the code and paste it inside the void loop section and reupload the whole sketch. that will display a standalone image on this matrix.

Animation With Custom Image

01 (58).gif

Here's a short example of how can we use this display at its best, I drew two identical images of a face which contains two eyes and a mouth that is close in the first image and open in the second.

I exported its code and copied it into the main sketch's loop function and added them both in a blinking sequence kind of way by placing a delay between them.

code-

#include "FastLED.h"


// How many leds in your strip?
#define NUM_LEDS 64


byte pixelType = 0;
char drawIn[4];
char frameIn[768];




// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 3
//#define CLOCK_PIN 13


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


void setup() {
  // Uncomment/edit one of the following lines for your leds arrangement.
  // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
  //FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  // FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);


  // FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);


  // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  Serial.begin(500000);
}


void loop() {
leds[0] = CRGB(0, 0, 0);
leds[1] = CRGB(0, 0, 0);
leds[2] = CRGB(0, 0, 0);
leds[3] = CRGB(0, 0, 0);
leds[4] = CRGB(0, 0, 0);
leds[5] = CRGB(255, 0, 0);
leds[6] = CRGB(255, 0, 0);
leds[7] = CRGB(255, 0, 0);
leds[8] = CRGB(0, 0, 0);
leds[9] = CRGB(255, 0, 0);
leds[10] = CRGB(255, 0, 0);
leds[11] = CRGB(255, 0, 0);
leds[12] = CRGB(0, 0, 0);
leds[13] = CRGB(255, 0, 0);
leds[14] = CRGB(0, 0, 0);
leds[15] = CRGB(255, 0, 0);
leds[16] = CRGB(0, 0, 0);
leds[17] = CRGB(255, 0, 0);
leds[18] = CRGB(0, 0, 0);
leds[19] = CRGB(255, 0, 0);
leds[20] = CRGB(0, 0, 0);
leds[21] = CRGB(255, 0, 0);
leds[22] = CRGB(255, 0, 0);
leds[23] = CRGB(255, 0, 0);
leds[24] = CRGB(0, 0, 0);
leds[25] = CRGB(255, 0, 0);
leds[26] = CRGB(0, 0, 0);
leds[27] = CRGB(255, 0, 0);
leds[28] = CRGB(0, 0, 0);
leds[29] = CRGB(0, 0, 0);
leds[30] = CRGB(0, 0, 0);
leds[31] = CRGB(0, 0, 0);
leds[32] = CRGB(0, 0, 0);
leds[33] = CRGB(255, 0, 0);
leds[34] = CRGB(0, 0, 0);
leds[35] = CRGB(255, 0, 0);
leds[36] = CRGB(0, 0, 0);
leds[37] = CRGB(0, 0, 0);
leds[38] = CRGB(0, 0, 0);
leds[39] = CRGB(0, 0, 0);
leds[40] = CRGB(0, 0, 0);
leds[41] = CRGB(255, 0, 0);
leds[42] = CRGB(0, 0, 0);
leds[43] = CRGB(255, 0, 0);
leds[44] = CRGB(0, 0, 0);
leds[45] = CRGB(255, 0, 0);
leds[46] = CRGB(255, 0, 0);
leds[47] = CRGB(255, 0, 0);
leds[48] = CRGB(0, 0, 0);
leds[49] = CRGB(255, 0, 0);
leds[50] = CRGB(255, 0, 0);
leds[51] = CRGB(255, 0, 0);
leds[52] = CRGB(0, 0, 0);
leds[53] = CRGB(255, 0, 0);
leds[54] = CRGB(0, 0, 0);
leds[55] = CRGB(255, 0, 0);
leds[56] = CRGB(0, 0, 0);
leds[57] = CRGB(0, 0, 0);
leds[58] = CRGB(0, 0, 0);
leds[59] = CRGB(0, 0, 0);
leds[60] = CRGB(0, 0, 0);
leds[61] = CRGB(255, 0, 0);
leds[62] = CRGB(255, 0, 0);
leds[63] = CRGB(255, 0, 0);
FastLED.show();
delay(500);
leds[0] = CRGB(0, 0, 0);
leds[1] = CRGB(0, 0, 0);
leds[2] = CRGB(0, 0, 0);
leds[3] = CRGB(0, 0, 0);
leds[4] = CRGB(0, 0, 0);
leds[5] = CRGB(255, 0, 0);
leds[6] = CRGB(255, 0, 0);
leds[7] = CRGB(255, 0, 0);
leds[8] = CRGB(0, 0, 0);
leds[9] = CRGB(0, 0, 0);
leds[10] = CRGB(255, 0, 0);
leds[11] = CRGB(0, 0, 0);
leds[12] = CRGB(0, 0, 0);
leds[13] = CRGB(255, 0, 0);
leds[14] = CRGB(0, 0, 0);
leds[15] = CRGB(255, 0, 0);
leds[16] = CRGB(0, 0, 0);
leds[17] = CRGB(0, 0, 0);
leds[18] = CRGB(255, 0, 0);
leds[19] = CRGB(0, 0, 0);
leds[20] = CRGB(0, 0, 0);
leds[21] = CRGB(255, 0, 0);
leds[22] = CRGB(255, 0, 0);
leds[23] = CRGB(255, 0, 0);
leds[24] = CRGB(0, 0, 0);
leds[25] = CRGB(0, 0, 0);
leds[26] = CRGB(255, 0, 0);
leds[27] = CRGB(0, 0, 0);
leds[28] = CRGB(0, 0, 0);
leds[29] = CRGB(0, 0, 0);
leds[30] = CRGB(0, 0, 0);
leds[31] = CRGB(0, 0, 0);
leds[32] = CRGB(0, 0, 0);
leds[33] = CRGB(0, 0, 0);
leds[34] = CRGB(255, 0, 0);
leds[35] = CRGB(0, 0, 0);
leds[36] = CRGB(0, 0, 0);
leds[37] = CRGB(0, 0, 0);
leds[38] = CRGB(0, 0, 0);
leds[39] = CRGB(0, 0, 0);
leds[40] = CRGB(0, 0, 0);
leds[41] = CRGB(0, 0, 0);
leds[42] = CRGB(255, 0, 0);
leds[43] = CRGB(0, 0, 0);
leds[44] = CRGB(0, 0, 0);
leds[45] = CRGB(255, 0, 0);
leds[46] = CRGB(255, 0, 0);
leds[47] = CRGB(255, 0, 0);
leds[48] = CRGB(0, 0, 0);
leds[49] = CRGB(0, 0, 0);
leds[50] = CRGB(255, 0, 0);
leds[51] = CRGB(0, 0, 0);
leds[52] = CRGB(0, 0, 0);
leds[53] = CRGB(255, 0, 0);
leds[54] = CRGB(0, 0, 0);
leds[55] = CRGB(255, 0, 0);
leds[56] = CRGB(0, 0, 0);
leds[57] = CRGB(0, 0, 0);
leds[58] = CRGB(0, 0, 0);
leds[59] = CRGB(0, 0, 0);
leds[60] = CRGB(0, 0, 0);
leds[61] = CRGB(255, 0, 0);
leds[62] = CRGB(255, 0, 0);
leds[63] = CRGB(255, 0, 0);
FastLED.show();
delay(500);


}


void serialEvent() {
  pixelType = Serial.read();


  switch (pixelType) {
    case 0:
    //draw mode
      Serial.readBytes(drawIn, 4);


      leds[drawIn[0]] = CRGB(drawIn[1], drawIn[2], drawIn[3]);


      FastLED.show();
      Serial.flush();
      break;


    case 1:
      //clear mode
      for (int i = 0; i < NUM_LEDS; i++)
      {
        leds[i] = CRGB::Black;
      }


      FastLED.show();
      Serial.flush();
      break;


    case 2:
    //frame in mode
      Serial.readBytes(frameIn, (NUM_LEDS * 3));
      for (int i = 0; i < NUM_LEDS; i++)
      {
        leds[i] = CRGB(frameIn[i * 3], frameIn[(i * 3) + 1], frameIn[(i * 3) + 2]);
      }


      FastLED.show();
      Serial.flush();
      break;


    case 3:
      int brightnessLED = Serial.read();
      FastLED.setBrightness(brightnessLED);
      Serial.flush();


      break;
  }
}


The result is this moving image that is looking like a robot or digital face speaking or saying something.

OTHER FEATURES

20 (38).gif
21 (32).gif
22 (26).gif

One of the big features of this software is that it had a few modes that we can use.

like here's a cool one, you can display your desktop window onto the matrix.

then we have a webcam display mode that lets us display webcam video onto the matrix.

We can also display images like I added an image of the moon I clicked with my amateur telescope, it's not clear but it works.

What's Next

23 (24).gif
25 (17).gif

So here's what I'm gonna do next, I will prepare a big matrix at least 16x16 or even bigger, and use this software to project some video onto the matrix, the goal would be to see the video or image projecting on the matrix clearly by adding more pixels.

In short, I will be making an RGB TV Monitor with these fancy LEDs.

This is it for today folks, thanks for reading this article and i'll be back with a new project soon!

Peace