LED matrix displays come in a myriad of shapes and sizes, and are constructed utilizing a variety of different technologies. Charlieplexing, as covered here, is one interesting technique. And, for high-performance displays, a grid of dumb RGB LED lights can do a great job. Another technique is arranging addressable LEDs sequentially in rows and columns to create a grid.
Arduino LED matrix
The drawback here is that data must pass from one LED to another, and you may need to run additional power lines as the chain expands. For simplicity, if not raw performance, this configuration is hard to beat. It allows an Arduino Uno and other such boards to control hundreds of multi-colored RGB LEDs with a single output.
LED strip matrix & LED matrix power supply
If you've ever used addressable LEDs, there's a good chance you began with WS2812B LEDs arranged in strips. Input data is sent to the first LED, which passes this information (minus the data for itself) along to the second light in the chain, then to the third, and so on, until it reaches the last light. If you arranged these strips so they snake back and forth, you'd then have a 2D RGB LED matrix that can be programmed to display any 2D image.
Before programming this type of LED matrix, you'll need a sufficient power supply. While not particularly power-hungry on their own, individual RGB LEDs can consume up to 60mA each. For an 8x8 matrix, that's 64 LEDs, or 3.84 amps, and for a 16x16 matrix/256 LEDs, it's a staggering 15.36 amps. In reality, it's rare that every LED is lit up to full brightness on both the R, G, and B channel. As per Adafruit’s NeoPixel Überguide, unless you're planning on an ultra-bright operation, as a rule-of-thumb, 1/3 of this theoretical maximum can be used. For this experimentation, I chose the Adafruit 1466 5V, 4A power supply, which supplies more than enough power for the 8x8 panel that I'm using, even in the brightest-case scenario.
As shown below, I hooked up 5V power to the system via the 5V and GND pins next to the DOUT pin, supplying both the panel and the Arduino board via the 5V and GND pins next to the DIN pin. Data is fed to the DIN pin from the Arduino, and the DOUT pin can pass data along to yet another matrix. While the power input may seem backwards with respect to DIN vs DOUT, the important thing is to get the data “flowing” in the right direction, and to not reverse 5V and GND.
When hooked up this way, once programmed, the USB cable can be disconnected. Note that it's generally recommended to use a 300 to 500 ohm resistor between the DIN and the controlling Arduino, and to use a 1000µF or higher capacitor on the input to provide steady power. It's possible you may not see these in the image, but it's probably a good idea.
Arduino Pixel LED controller
You can test this out on such a matrix with the strandtest example on the Adafruit_NeoPixel library, which can be installed via the library manager, on the Arduino IDE. It's also available on GitHub. With an Arduino Uno, it works mostly without modification, you'll just need to change the LED_PIN value to whatever output you use to control the matrix, and LED_COUNT to the number of total LEDs. For the 8x8 strip I’m using here, that means 64 LEDs. I chose to use Arduino pin 2 for control. Once loaded, you'll see a variety of colors moving across the panel -- a pretty display -- showing your panel is in order.
Pattern-wise, LED panels can take on a variety of different forms
From here, you'll need to figure out how your panel is laid out, including the 0,0 "pixel" orientation, and whether the strip snakes back and forth in a "zig-zag" pattern, or if it's in a "progressive" orientation, where the LEDs always progress from one side to the other. You'll also need to be aware of whether the LEDs are arranged as rows or columns.
If you made something from scratch, you'll know these answers, and hopefully, such information is documented for purchased panels. You can also use a modification of the NeoPixel library "simple" example to plug in values for certain pixels to help determine this. As shown in the image and code snippet below, I set LED 0 in the upper left to red, pixel 7 in the upper right to green, and pixel 63 in the lower-right corner to blue.
Arduino LED control library: Using customized libraries
While it isn't too hard to calculate which pixel goes where, if you want to draw shapes, patterns, or even text, doing the necessary conversions soon becomes prohibitive. Fortunately, it doesn’t have to be. Adafruit also created the NeoMatrix library, which builds upon the NeoPixel library to make using addressable LEDs arranged in a 2D pattern much easier.
This can be found and installed via the Arduino IDE's library manager by searching for Adafruit NeoMatrix. You'll also need to install the NeoPixel library, as well as Adafruit GFX, which is also used for LCD and OLED displays. The NeoMatrix library uses the same coordinate system and drawing functions as the GFX library, which would be very convenient if you're used to using that.
This library contains examples for both a single matrix, matrixtext, and another example called tiletest, which can work with a number of tiles stacked side-by-side. The code above is a snippet from the tiletest example, which instantiates a matrix object using a variety of parameters explained in the lines above that (and even more in the actual code). Line 57 addresses the arrangement of the tiles, while line 58 focuses on the arrangement of LEDs in the matrices themselves.
In the case of the (single) matrixtest example, the line 57 parameters are omitted, as well as the numbers outlining how many matrices are used (just one). In my case, the matrix was arranged with the first pixel in the top left corner, and organized in rows, so those parameters worked without issue. The last parameter had to be changed from NEO_MATRIX_ZIGZAG to NEO_MATRIX_PROGRESSIVE, and the width value was switched from 5 to 8.
The beginning of “Howdy”
Next, it dutifully scrolled the text “Howdy” across the screen. You can easily change the text to whatever you'd like. A third example is the MatrixGFXDemo, which shows off the many other capabilities of the library.
Going further: Bitmap LED matrix & more LED matrix projects
Once you're done generating dots and lines, you may want to move on to working with bitmap images. While certainly possible, this generally takes a bit more work, and potentially more powerful hardware than an Arduino Uno. Another excellent option for LED control is the FastLED library. And while you're at it, you could also check out WLED, for dynamically controlling LEDs with an ESP8266 or ESP32.
Whichever way you control and use your LED matrix, it's guaranteed to add a ton of color to your project. The possibilities are endless!