|
OrCad Cadance |
|
|
arduino IDEArduino
|
Mini Matrix
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 article 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!
MATERIAL REQUIRED
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
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
PCB DESIGN
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.
This was the Schematic that I made.
Serpentine Layout
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
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
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.
PCBWAY
I used PCBWAY PCB Service for this project. I first uploaded the Gerber file of this project on PCBWAY's quote page.
I choose the white soldermask with the black silkscreen.
PCBs arrived in a week and the PCB quality was pretty great, This PCB is very small and I like how the quality of these PCBs was not compromised because of quantity or size.
I used 0.3mm traces and PCB is full of vias, no shorts or production errors were encountered which was a good thing as normally working with these small PCBs can produce production errors but there was non which is overall a good thing.
PCBWAY, you guys rock.
Check out PCBWAY service for great PCB service at less cost!
PCB ASSEMBLY
- Solder paste dispensing
- Pick and place
- Hotplate
- adding con
SOLDER PASTE DISPENSING
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.
So I got a stencil from PCBWAY instead, they offer stencil manufacturing service along with PCB service, you can combine your PCB order with a stencil and get them together.
Here's how we can use the stencil
- 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
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
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
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
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.
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 backwardsuint8_t reverseX = (kMatrixWidth - 1) - x;
i = (y * kMatrixWidth) + reverseX;
} else {
// Even rows run forwards
i = (y * kMatrixWidth) + x;
}
} else { // vertical positioningif ( 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;
This was the result-
Tylor jones's LED MATRIX CONTROL SOFTWARE
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 modefor (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
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
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.
The result is this moving image that is looking like a robot or digital face speaking or saying something.
OTHER FEATURES
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
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.
Thanks PCBWAY for supporting this project, you guys can check them out if you need great PCB and Stencil service for less cost and great quality.
And I'll be back with a new project pretty soon!
#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 );
}
Mini Matrix
*PCBWay community is a sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
- Comments(0)
- Likes(3)
- Engineer Aug 11,2024
- Sam Atkinson May 04,2024
- Engineer May 17,2022
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Arnov Arnov sharma
- Delete Button XL Greetings everyone and welcome back, and here's something fun and useful.In essence, the Delete Butt...
- Arduino Retro Game Controller Greetings everyone and welcome back. Here's something fun.The Arduino Retro Game Controller was buil...
- Super Power Buck Converter Greetings everyone and welcome back!Here's something powerful, The SUPER POWER BUCK CONVERTER BOARD ...
- Pocket Temp Meter Greetings and welcome back.So here's something portable and useful: the Pocket TEMP Meter project.As...
- Pico Powered DC Fan Driver Hello everyone and welcome back.So here's something cool: a 5V to 12V DC motor driver based around a...
- Mini Solar Light Project with a Twist Greetings.This is the Cube Light, a Small and compact cube-shaped emergency solar light that boasts ...
- PALPi V5 Handheld Retro Game Console Hey, Guys what's up?So this is PALPi which is a Raspberry Pi Zero W Based Handheld Retro Game Consol...
- DIY Thermometer with TTGO T Display and DS18B20 Greetings.So this is the DIY Thermometer made entirely from scratch using a TTGO T display board and...
- Motion Trigger Circuit with and without Microcontroller GreetingsHere's a tutorial on how to use an HC-SR505 PIR Module with and without a microcontroller t...
- Motor Driver Board Atmega328PU and HC01 Hey, what's up folks here's something super cool and useful if you're making a basic Robot Setup, A ...
- Power Block Hey Everyone what's up!So this is Power block, a DIY UPS that can be used to power a bunch of 5V Ope...
- Goku PCB Badge V2 Hey everyone what's up!So here's something SUPER cool, A PCB Board themed after Goku from Dragon Bal...
- RGB Mixinator V2 Hey Everyone how you doin!So here's a fun little project that utilizes an Arduino Nano, THE MIXINATO...
- Gengar PCB Art Hey guys and how you doing!So this is the GENGAR PCB Badge or a Blinky Board which is based around 5...
- R2D2 Mini Edition So here's something special, A Mini R2D2 PCB that speaks ASTROMECH.Astromech is a fictional language...
- C-3PO Blinky Board Hey guys and how you doing!So this is the C3P0 PCB Badge or a Blinky Board which is based around 555...
- WALKPi Breadboard Version Greetings everyone and welcome back, Here's something loud and musical.Similar to a traditional walk...
- BOXcilloscope Greetings to everyone, and welcome back.This is BOXcilloscope, a homemade portable oscilloscope that...
-
-
Helium IoT Network Sensor Development board | H2S-Dev V1.2
130 0 0 -
-
-
-
-
-
3D printed Enclosure Backplate for Riden RD60xx power supplies
187 1 1