Raspberry Pi Pico Matrix Project

by Arnov Sharma in Circuits > Raspberry Pi

897 Views, 8 Favorites, 0 Comments

Raspberry Pi Pico Matrix Project

Pico Matrix Project #raspberrypi #electronic #soldering
10.gif
08.gif
thumb.jpg

Greeting everyone and welcome back.

Here's something fun and bright! The Raspberry Pi Pico, WS2812B LEDs, and an MPU6050 were utilized in the PICO Matrix project, a Matrix Development Board designed for tinkering with WS2812B LEDs.

The goal was to develop a matrix with a dedicated microcontroller board that could be utilized for future RGB matrix-based projects. Additionally, it has an MPU6050 to provide this matrix board with an accelerometer function.

Users can create a wide range of projects with this matrix development board; for instance, we use it to create an RGB light display, a scrolling display, and even a Pixel Control sketch with the MPU6050.

This is the complete build guide for this project, as well as its usage and test sketch, which are included in this article.

Supplies

These are the materials required in this project.

  1. Custom PCB (Provided by HQ NextPCB)
  2. Raspberry Pi PICO
  3. WS2812B LEDs
  4. 100uF Capacitors
  5. Solder Paste
  6. Reflow Hotplate
  7. MPU6050

Circuit Design

SCH_page-0001.jpg
02.PNG
01.PNG

The two primary parts of this project's circuit are the LED matrix itself, which is made up of 100 WS2812B LEDs connected in their typical configuration, which connects the first LED's dout to the second's din, the second LED's dout to the second's din, and so on until the 100th LED. The VCC and GND of every LED are linked in parallel.

The second part of the circuit is made up of a Raspberry Pi Pico and an MPU 6050 accelerometer sensor that is connected to the Pico's GPIO27 and GPIO26. The first LED's Din is connected to the Raspberry Pi Pico's GPIO D0. In order to supply power to the board with a type-C connector, we have included a USB Type-C port with Pico's 5V IN and GND ports.

For each WS2812B LED, we further added 100 decoupling capacitors; however, in the end, we only used 10x 100 nf capacitors, one for each row.

Once the design was complete, we converted it into a board file and arranged all 100 LEDs in a 10x10 row and column grid.

Please take note that we have arranged the LEDs D1 through D10 in a single row. D11 is positioned at the beginning of the new column and extends to D20, followed by D21, which also begins at the beginning of the next column and continues to D100. Another name for this is serpentine matrix or snake matrix pattern.

After finishing the PCB and positioning the Pico and MPU on the left, we exported the Gerber data, which will be sent to a PCB manufacturer for samples.

Downloads

HQ NextPCB Service

aaS.jpg

After completing the PCB design, we export the Gerber data and send it to HQ NextPCB for samples.

Gerber Data was sent to HQ NextPCB, and a Green Solder Mask PCB with White Screen was ordered.

After placing the order, the PCBs were received within a week, and the PCB quality was pretty great.

In addition, I have to bring in HQDFM to you, which helped me a lot through many projects. Huaqiu’s in-house engineers developed the free Design for Manufacturing software, HQDFM, revolutionizing how PCB designers visualize and verify their designs.

HQDFM: Free Online Gerber Viewer and DFM Analysis Tool

Capture.PNG

Also, NextPCB has its own Gerber Viewer and DFM analysis software.

Your designs are improved by their HQDFM software (DFM) services. Since I find it annoying to have to wait around for DFM reports from manufacturers, HQDFM is the most efficient method for performing a pre-event self-check.

Here is what online Gerber Viewer shows me. Would not be more clear. However, for full function, like DFM analysis for PCBA, you, need to download the software. The online version only provides a simple PCB DFM report.

With comprehensive Design for Manufacture (DFM) analysis features, HQDFM is a free, sophisticated online PCB Gerber file viewer.

It provides insights into advanced manufacturing by utilizing over 15 years of industry expertise. You guys can check out HQ NextPCB if you want great PCB service at an affordable rate.

CIRCUIT ASSEMBLY

02.gif
03.gif
04.gif
13.gif
05.gif
06.gif
07.gif
  1. Using a solder paste dispenser needle, we apply solder paste to each component pad to begin the circuit assembly process. In this case, we are using 63/37 Sn/PB Solder paste.
  2. After that, we pick each WS2812B LED and place it into their correct position.
  3. The PCB is then heated from below to the solder paste melting temperature by placing the circuit on the Reflow Hotplate, which causes all of the SMD LEDs to be connected to their pads.
  4. After reflow, we place the THT components, which consist of female header pin connectors for the Raspberry Pi Pico and MPU6050 along with a USB type C port.
  5. Using a soldering iron, we solder the leads of every through-hole component from the bottom side of the board.
  6. Finally, we position the MPU6050 and Raspberry Pi Pico on the header pins, and the assembly is now complete.

"MPU Control Pixel" Sketch

09.gif

We start testing this matrix by uploading a sketch we created, which is essentially a pixel control sketch that makes use of the MPU6050. In this sketch, a bright pixel in the center moves in response to the MPU6050's orientation, simulating a particle of sand. For a future hourglass project that senses movement and controls pixel particles that travel around like sand particles, our goal is to refine this sketch further.

#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Wire.h>
#include <MPU6050_light.h>
#define MATRIX_PIN 0
#define MATRIX_WIDTH 10
#define MATRIX_HEIGHT 10
#define NUMPIXELS (MATRIX_WIDTH * MATRIX_HEIGHT)
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS,
NEO_GRB + NEO_KHZ800);
MPU6050 mpu(Wire1);
int prevX = MATRIX_WIDTH / 2;
int prevY = MATRIX_HEIGHT / 2;
void setup() {
matrix.begin();
matrix.setBrightness(50);
// Initialize I2C1 with pins 26 (SDA) and 27 (SCL)
Wire1.setSDA(26);
Wire1.setSCL(27);
Wire1.begin();
mpu.begin();
mpu.calcOffsets(true, true); // Calculate and apply offsets
// Display initialization success
matrix.fillScreen(0);
matrix.show();
}
void loop() {
mpu.update();
// Normalize accelerometer values
float axNorm = -mpu.getAccX() * 5; // Invert X-axis sensitivity
float ayNorm = mpu.getAccY() * 5; // Adjust sensitivity
// Clear the previous pixel
matrix.drawPixel(prevX, prevY, matrix.Color(0, 0, 0));
// Calculate the new position
int centerX = MATRIX_WIDTH / 2;
int centerY = MATRIX_HEIGHT / 2;
int newX = constrain(centerX + (int)ayNorm, 0, MATRIX_WIDTH - 1); // Horizontal movement
int newY = constrain(centerY - (int)axNorm, 0, MATRIX_HEIGHT - 1); // Vertical movement
// Update the matrix with the new position
matrix.drawPixel(newX, newY, matrix.Color(255, 0, 0)); // Display influenced pixel
matrix.show();
// Update the previous position
prevX = newX;
prevY = newY;
delay(20); // Reduce delay for smoother movement
}

These are the libraries that you first need to install before using the sketch.

#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <MPU6050_light.h>

SCROLLING TEXT

10.gif
11.gif

The scrolling text animation was the next interesting thing we tried. It was made up of a humorous statement that we put to our sketch and that said the following: "Why don't scientists trust atoms? Because they make up everything!"

Here's the sketch we used.

#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#define MATRIX_PIN 0 // GPIO pin connected to the LED matrix data pin
#define MATRIX_WIDTH 10
#define MATRIX_HEIGHT 10
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS,
NEO_GRB + NEO_KHZ800);
int x = 0; // Initialize position
void setup() {
Serial.begin(115200);
Serial.println("Matrix scrolling text display setup...");
matrix.begin();
matrix.setTextWrap(false);
matrix.setBrightness(50);
matrix.setTextColor(matrix.Color(0, 0, 255)); // White color for text
matrix.setTextSize(1); // Ensure text size is appropriate
x = matrix.width(); // Start cursor position at the matrix width
}
void loop() {
matrix.fillScreen(0); // Clear screen
const char *text = "Why don't scientists trust atoms? Because they make up everything!";
matrix.setCursor(x, 0);
matrix.print(text);
Serial.print("Cursor X position: "); Serial.println(x);
Serial.print("Text to display: "); Serial.println(text);
int textWidth = 6 * strlen(text); // Calculate the width of the text
if (--x < -textWidth) {
x = matrix.width();
Serial.println("Resetting cursor position.");
}
matrix.show();
delay(110); // Adjust the delay to control the scrolling speed
}

You need these following libraries before using this sketch.

#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>

FIRE

12.gif

Next, we use one of the FastLED Library's example sketches, Fire, which imitates Flame's color palette, which is composed of red, orange, and white. This sketch is simple to use if you want to create a digital fire or fireplace project. For more intense animation, you may use a diffuser to spread the LED glow, which will make the setup look more realistic.

#include <FastLED.h>
#define LED_PIN 0
#define COLOR_ORDER GRB
#define CHIPSET WS2811
#define NUM_LEDS 100
#define BRIGHTNESS 100
#define FRAMES_PER_SECOND 60
bool gReverseDirection = false;
CRGB leds[NUM_LEDS];
void setup() {
delay(3000); // sanity delay
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
}
void loop()
{
// Add entropy to random number generator; we use a lot of it.
// random16_add_entropy( random());
Fire2012(); // run simulation frame
FastLED.show(); // display this frame
FastLED.delay(1000 / FRAMES_PER_SECOND);
}
// Fire2012 by Mark Kriegsman, July 2012
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
////
// This basic one-dimensional 'fire' simulation works roughly as follows:
// There's a underlying array of 'heat' cells, that model the temperature
// at each point along the line. Every cycle through the simulation,
// four steps are performed:
// 1) All cells cool down a little bit, losing heat to the air
// 2) The heat from each cell drifts 'up' and diffuses a little
// 3) Sometimes randomly new 'sparks' of heat are added at the bottom
// 4) The heat from each cell is rendered as a color into the leds array
// The heat-to-color mapping uses a black-body radiation approximation.
//
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
//
// This simulation scales it self a bit depending on NUM_LEDS; it should look
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
//
// I recommend running this simulation at anywhere from 30-100 frames per second,
// meaning an interframe delay of about 10-35 milliseconds.
//
// Looks best on a high-density LED setup (60+ pixels/meter).
//
//
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 50, suggested range 20-100
#define COOLING 55
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
#define SPARKING 120
void Fire2012()
{
// Array of temperature readings at each simulation cell
static uint8_t heat[NUM_LEDS];
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( int k= NUM_LEDS - 1; k >= 2; k--) {
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
}
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
if( random8() < SPARKING ) {
int y = random8(7);
heat[y] = qadd8( heat[y], random8(160,255) );
}
// Step 4. Map from heat cells to LED colors
for( int j = 0; j < NUM_LEDS; j++) {
CRGB color = HeatColor( heat[j]);
int pixelnumber;
if( gReverseDirection ) {
pixelnumber = (NUM_LEDS-1) - j;
} else {
pixelnumber = j;
}
leds[pixelnumber] = color;
}
}


CONCLUSION

IMG_20241108_195114.jpg
IMG_20241109_004953.jpg

Overall, this project was a success and required no further revision.

Making a matrix test board that can be used to explore with WS2812B to run various demo sketches and create our own—the sand particle sketch we are working on right now—was the aim of our project. We will be sharing a future project soon that includes an hourglass demo sketch.

This is it for today, folks, all the documents related to this project are attached, which you can checkout in this article. If you need any additional information, feel free to leave a comment, and I will be happy to assist you.

Special thanks to HQ NextPCB for providing components that I've used in this project; check them out for getting all sorts of PCB or PCBA-related services for less cost.

Thanks for reaching this far, and I will be back with a new project soon.