This guide will cover the basic functionality of the GlowBit Python library when driving a GlowBit Matrix 8x8 module.
To follow along, it's best to have:
- A GlowBit Matrix 8x8
- A Raspberry Pi Pico or Raspberry Pi
- Some Pin Headers
- Three jumper wires (eg Female-Female, Male-Male, or Female-Male, as appropriate)
- Appropriate wire for a power cable, rated to at least 2A per GlowBit Matrix 8x8 module
- Function Listing
- Soldering a Pin Header and Pinout
- Connecting the GlowBit Matrix 8x8
- Download MicroPython Modules
- Creating a GlowBit Matrix "Object"
- Running a Test Demo
- GlowBit Colours
- Lighting up Individual Pixels
- The Colour Wheel
- Scrolling Static Text
- Filling All Pixels With a Solid Colour
- Lines, Rectangles, Triangles, and Circles
- Bar Graphs
- Animation Guidelines
- Tiling Multiple GlowBit Matrix 8x8 Modules
A full listing of the available functions can be found in the documentation.
The GlowBit Matrix 8x8 is sold without a pin header to allow maximum flexibility and allow solder bridges to tile multiple modules.
For maximum neatness you can cut a strip of 7 pin headers and use pliers to remove the 4 pins which don't align with holes on the GlowBit Matrix 8x8. This allows connection of the three critical pins: Vcc, Din, and GND. Note that any pair of Vcc and GND pads are sufficient to power a single GlowBit Matrix 8x8 module to full brightness.
Alternatively, you can cut and solder 2 or 3 individual pin headers, as shown below, or solder wires directly to the pads.
Note that all 6 holes are on a 2.54mm (100 mil) grid so the module can easily be soldered to (and tiled on) standard perfboard as well.
The GlowBit Matrix 8x8 also contains two very large pads for Vcc and two equally large pads for GND. These are intended for providing power to large tiled arrays and are rated to 18A - enough to power 9 modules in a 3x3 array, at full brightness, from only the central module's large power pads.
The pads around the edge of the module are connected internally as follows:
- All four pads labeled as "Din" connect to the data-in pin of the first LED (top left, when viewed from the front)
- All four pads labeled as "Dout" connect to the data-out pin o fthe last LED (bottom right, when viewed from the front)
- All Vcc pads are shaped with a circular internal edge
- All remaining pads are rectangular and connected to GND
To complete this guide the GlowBit Matrix 8x8 requires three wires to be connected to the Raspberry Pi or Raspberry Pi Pico:
- Vcc: The positive power supply pin
- Din: The data input
- GND: The negative power supply pin
At maximum brightness the GlowBit Matrix 8x8 can consume up to approximately 2A. As such, powering the module from a 5V pin (eg: the VBUS pin on the Raspberry Pi Pico or a 5V pin on a Raspberry Pi) is only possible at low brightness. To drive the display to full brightness an external power supply is required, eg: a 5V, 2A fixed voltage Plugpack and Female 2.1mm jack to Screw Terminal Block.
If using an external power supply a GND connection is required to both the Raspberry Pi and external power supply.
Note: The default brightness level is intentionally low and will consume about 100 mA when every LED is displaying white. See Creating a GlowBit Matrix Object for information about changing the global brightness setting.
The GlowBit library defaults to using pin 18 for data on both the Raspberry Pi and Raspberry Pi Pico. On the Raspberry Pi data can be connected to either GPIO18 or GPIO12. If using a Raspberry Pi Pico any GPIO pin can be used.
If using a data pin other than GPIO18 it will need to be specified when creating the GlowBit Matrix object with the pin= keyword argument. eg: matrix = glowbit.matrix4x4(pin=12).
The Dout connection allows multiple modules to be joined together by connecting the Dout of one module to the Din of the next. See Tiling Multiple GlowBit Matrix 4x4 Modules for more information.
The GlowBit MicroPython module requires two files:
The GlowBit module can also be installed through the Thonny package manager.
If you are running from a Raspberry Pi you will also need the low-level rpi-ws281x module. It can be found through Thonny's package manager or you can install it from the console with sudo pip3 install rpi-ws281x.
The glowbit.matrix8x8() object contains all the functionality required to create fun projects with your GlowBit Matrix 8x8 module.
For greater flexibility, the glowbit.matrix8x8() object takes several keyword arguments which modify how the GlowBit behaves. The most crucial ones, with their default values, are:
- brightness = 20
- rateLimitFPS = 30
- pin = 18
The brightness argument can either be an integer between 1 and 255 or a decimal value between 0.0 and 1.0. The brightness of the entire display is scaled by this value.
The rateLimitFPS argument allows the update rate of the display to be limited so that delays don't need to be manually programmed.
For example, to drive a GlowBit at full brightness with an update rate of 5 frames per second the following code can be used:
import glowbit matrix = glowbit.matrix4x4(brightness = 255, rateLimitFPS = 5)
To make sure the GlowBit module and Python libraries are all configured correctly you can run this 3-line program to display a series of demonstration patterns:
import glowbit matrix = glowbit.matrix8x8() matrix.demo()
While executing, the following output will be printed to the Python shell:
matrix.textDemo() matrix.circularRainbow() matrix.rain() matrix.lineDemo() matrix.bounce()
These functions can be called individually and you can study their code in glowbit.py by searching for fireworks(), circularRainbow(), etc.
When specifying colours for GlowBit library functions a 32-bit GlowBit colour value is required. This is an integer which contains the red, green, and blue intensity "packed" into a single number.
In order to easily create colour values the function stick.rgbColour(r,g,b) is provided. It accepts red, green, and blue (RGB) intensity values scaled from 0 to 255 (inclusive) and returns a GlowBit colour value which can be used wherever colour is needed in the GlowBit library.
For convenience, the following functions are provided and return commonly used colours:
matrix.red() matrix.green() matrix.blue() matrix.yellow() matrix.purple() matrix.cyan() matrix.white() matrix.black()
The GlowBit Matrix library contains the function matrix.pixelSetXY(x,y,colour) for setting the colour of individual pixels at a particular location on the display.
The x and y coordinates start at x=0, y=0 in the upper left corner of the display. Increasing x moves to the right and increasing y moves downwards.
For example, the following code sets the upper left pixel to white and the pixel at x=1, y=2 to a custom RGB value:
import glowbit matrix = glowbit.matrix8x8() colour = matrix.white() x = 0 y = 0 matrix.pixelSetXY(x,y, colour) matrix.pixelSetXY(1,2,matrix.rgbColour(100,200,50)) matrix.pixelsShow()
Note the use of the function matrix.pixelsShow(). The GlowBit drawing functions only change an internal frame buffer which only exists in memory until matrix.pixelsShow() copies the frame buffer data to the physical LEDs.
The GlowBit library provides the function matrix.wheel() which returns a full-intensity pure colour from the colour wheel. The function takes a single argument which is a colour wheel "angle" from 0 to 255. Both 0 and 255 are aligned with red, with the wheel returning red-yellow-green-cyan-blue-magenta-red for other values.
The following example uses the matrix.wheel() and matrix.putPixelXY() functions to display a colour gradient on the GlowBit Matrix 8x8:
import glowbit matrix = glowbit.matrix8x8() for x in range(8):
for y in range(8): c = matrix.wheel(18*(x y)) matrix.pixelSetXY(x, y, c) matrix.pixelsShow()
You don't need to be too careful about keeping the matrix.wheel() argument between 0 and 255 - if it is outside this range it will still "wrap" to an angle within the [0,255] range.
The GlowBit Matrix 8x8 is large enough to display a single 8x8 pixel text character. The GlowBit library supports static text display with matrix.drawChar() and matrix.printTextWrap() along with animated scrolling text with matrix.addTextScroll() and matrix.updateTextScroll().
Scrolling text is perhaps the most useful of these functions as it allows the display of long strings of text on a single GlowBit Matrix 8x8 display.
Producing scrolling text, as with most animated GlowBit library objects, is a two step process:
- Call matrix.addTextScroll(string) to add a scrolling text string to an internal list inside the matrix object
- Call matrix.updateTextScroll() each time the scrolling text animation needs to be updated
Separating scrolling text into these two steps allows text scrolling to be synchronised with other animated elements using matrix.pixelsShow().
There also exists the variable matrix.scrollingText which is set to True while at least one scrolling text object is still animating and False otherwise.
Given all this, we can now look at a full example:
import glowbit matrix = glowbit.matrix8x8(rateLimitCharactersPerSecond = 1) matrix.addTextScroll("Hello there!") while matrix.scrollingText == True: matrix.updateTextScroll() matrix.pixelsShow()
Note the use of the keyword argument rateLimitCharactersPerSecond=1 when creating the matrix object. Scrolling text moves one pixel each frame, and each character is 8 pixels wide, so this argument sets the frame rate so that 1 character scrolls past the screen each second.
Common keyword arguments to use with matrix.addTextScroll(), with their default values, are:
- colour = matrix.white() - Specifies the colour of the text characters; a GlowBit colour value
- blocking = False - If this is set to True the scrolling text animation will happen automatically and the function will "block" (ie: not return) until it is finished
For example, the following code displays light green scrolling text and animates automatically:
import glowbit matrix = glowbit.matrix8x8(rateLimitCharactersPerSecond = 1) matrix.addTextScroll("Hello there!", colour = matrix.rgbColour(100, 250, 0), blocking = True)
Automatic animations are convenient, but prohibit other graphical elements to be drawn while the text is animating.
If you're after an RGB light source with a single colour the matrix8x8.pixelsFill(colour) function can be used to avoid needing to set every pixel individually.
The following example uses a single loop, and a frame rate limit of 80 frames per second, to create an animated "rainbow" light source:
import glowbit matrix = glowbit.matrix8x8(rateLimitFPS = 80) for i in range(512): c = matrix.wheel(i) matrix.pixelsFill(c) matrix.pixelsShow()
Note that the argument to matrix.wheel(i) can be larger than 255 and the colour wheel just repeats itself. In this example it goes all the way to 512 so colour wheel is cycled twice.
Drawing basic shapes is done with the GlowBit library functions shown in the table below.
All x and y arguments are in units of pixels and all colour arguments are GlowBit colour values.
|matrix.drawLine(x0, y0, x1, r1, colour)||Draws a line from (x0, y0) to (x1, y1)|
|matrix.drawRectangle(x0, y0, x1, y1, colour)
matrix.drawRectangleFill(x0, y0, x1, y1, colour)
Draws a rectangle with opposite corners at (x0, y0) and (x1, y1).
The drawRectangle() version only draws an outline while drawRectangleFill() draws a solid rectangle.
|matrix.drawCircle(x0, y0, r, colour)||Draws a circle outline centered at (x0, y0) with radius r|
|matrix.drawTriangle(x0, y0, x1, y1, x2, y2, colour)||Draws a triangle outline with vertices (corners) at (x0,y0), (x1, y1), and (x2, y2).|
For example, the following code uses matrix.drawRectangle() to draw an outline around the edges of a single GlowBit Matrix 8x8 module:
import glowbit matrix = glowbit.matrix8x8() matrix.drawRectangle(0,0, 7,7, matrix.white()) matrix.pixelsShow()
The matrix.graph1D() object allows drawing of a single pixel wide bar graph with a length set by some given value.
When creating a new graph object you will typically need to specify several keyword arguments which control how the graph is drawn. The object is optimised for the GlowBit Matrix 8x8 module but also works with the GlowBit Matrix 4x4.
You can think of a graph1D() object as a section of the "number line" with left and right edges specified by the minValue and maxValue keyword arguments. When plotting a new value it will illuminate all pixels less than where that value falls on the number line.
The commonly required keyword arguments, with their default values, are as follows:
|originX||0||The x coordinate (pixel location) of the graph's origin|
|originY||7||The y coordinate (pixel location) of the graph's origin|
|length||8||The total number of pixels in the graph - typically set this to 4 for a 4x4 pixel display|
|direction||"Up"||The direction the graph is drawn away from the origin. Can be "Up", "Down", "Left", or "Right".|
|minValue||0||The number "mapped" to the origin pixel.|
|maxValue||255||The number "mapped" to the end pixel|
|colour||matrix.white()||The colour of the graph|
Creating and drawing a matrix.graph1D() object is a 2 step process:
- Call graph = matrix.graph1D() to create a new graph object
- Call matrix.updateGraph1D(graph,value) to update the graph with a new value
A call to matrix.pixelsShow() is also required to draw the graph on the physical LEDs.
For example, the code below will plot a matrix.graph1D() object with a value created in a loop. If the hardware is available, you can experiment with plotting data from a sensor like an ADC or digital thermometer.
import glowbit matrix = glowbit.matrix8x8(rateLimitFPS = 100) graph = matrix.graph1D(originX = 4, originY = 7, length = 8, direction = "Up", minValue = 0, maxValue = 255) for i in range(255): matrix.updateGraph1D(graph, i) matrix.pixelsShow() for i in range(255, 0, -1): matrix.updateGraph1D(graph, i) matrix.pixelsShow()
Advanced: Graph objects can also be coloured with a colour map. This is a function which changes the pixel's colour depending on the value being shown. You can start by experimenting with the colourMap="Rainbow" keyword argument or check out more details in the documentation.
Note: The matrix.newGraph1D() "wrapper" function exists purely to make the documentation easier to follow. Calling is exhibits the same behaviour as creating a graph1D object with matrix.graph1D().
The GlowBit Matrix library allows for the plotting of 2D graphs with the matrix.graph2D() object. These plots show a "time series" where each time a new value is drawn to the plot it appears on the right side and previous values move 1 pixel to the left. They are great for, say, creating a plot of temperature or ADC voltage against time.
The commonly required keyword arguments, with their default values, are as follows:
|originX||0||The x coordinate (pixel location) of the lower left corner of the plot|
|originY||7||The y coordinate (pixel location) of the lower left corner of the plot|
|width||8||The total width of the plot area in pixels|
|height||8||The total height of the plot area in pixels|
|minValue||0||The number "mapped" to the bottom pixel|
|maxValue||255||The number "mapped" to the top pixel|
|colour||matrix.white()||The colour of the plot|
|bars||False||If set to False only a single dot per column is drawn. If set to True then all pixels from originY to the "value point" are turned on|
Creating and drawing a matrix.graph2D() object is a 2 step process:
- Call graph = matrix.graph2D() to create a new graph object
- Call matrix.updateGraph1D(Graph, value) to update the graph with a new value. Old values are automatically forgotten.
A call to matrix.pixelsShow() is also required to draw the graph on the physical LEDs.
For example, the following code animates a sine wave and displays it with a matrix.graph2D() object.
import glowbit from math import sin, pi matrix = glowbit.matrix8x8(rateLimitFPS = 2) graph = matrix.graph2D(minValue = -1.1, maxValue = 1.1, bars = True) frame = 0 while True: matrix.updateGraph2D(graph, sin(2*pi*frame/5)) frame = frame 1 matrix.pixelsShow()
To produce animations using the GlowBit library the following template is recommended:
import glowbit matrix = glowbit.matrix8x8() frame = 0 while True: matrix.pixelsFill(matrix.black()) # Make display black # --- Draw a frame --- # frame = frame 1 matrix.pixelsShow()
The call to matrix.pixelsFill(matrix.black()) is generally required because most drawing functions (eg: matrix.pixelSetXY(), matrix.drawLine(), etc) only illuminate where something should be drawn now, they don't turn off pixels where an object was in the past. If it is omitted, then animating an object will leave behind a "trail" of illuminated pixels.
If an animation sets the value of every pixel (eg: the matrix.circularRainbow() function) then matrix.pixelsFill() is not required
The frame variable is included as it is an easy way to change things between frames. For example, the code below will draw a single yellow dot that uses the frame variable as its x and y location, moving it diagonally down the screen:
import glowbit matrix = glowbit.matrix8x8(rateLimitFPS = 3) frame = 0 while True: matrix.pixelsFill(matrix.black()) # Make display black matrix.pixelSetXY(frame, frame, matrix.yellow()) frame = frame 1 if frame == 8: frame = 0 matrix.pixelsShow()
Note how the frame variable is reset after 4 frames, creating a 4 frame long repeating animation.
The GlowBit Matrix 8x8 is designed to tile horizontally and vertically to create large square or rectangular displays. When tiling there are some extra best practice considerations that can increase the lifespan of the matrices Adafruit's Neopixel Überguide breaks down the extra considerations in this section, but the whole guide is excellent and worth a read if you have time.
Quite large displays can be built by tiling with the main limitation being power consumption. Each GlowBit Matrix 8x8 will consume approximately 2A at full brightness, so if creating a large, rectangular, bright, display we recommend running at least one power cable per 9 modules. If building a "long and thin" array a power connection every 4th module is recommended.
The GlowBit library assumes that the data signal "snakes" (or "zig-zags") left-right between rows. In the example shown below, data is connected, as seen from rear, to the top right module then loops around anti-clockwise.
The data protocol can support approximately 1000 LEDs (16 modules) at around 30 FPS. Note that with large displays both the data protocol and calculation overhead will limit frame rate.
To support tiling in software the tileRows= and tileCols= keyword arguments can be used when creating a matrix object. For example, a string of 2x2 array of GlowBit Matrix 8x8 displays can be specified with:
matrix = glowbit.matrix8x8(tileRows = 2, tileCols = 2)
The library will then automatically map all GlowBit functions to the large tiled display. For example, matrix.pixelSetXY() would be able to take x and y coordinates up to 15 with a 2x2 module display. X-Y coordinates are automatically mapped to the correct pixel.
The example below demonstrates the display of a diagonal rainbow gradient on a 2x2 tiled matrix display:
import glowbit matrix = glowbit.matrix8x8(tileRows = 2, tileCols = 2) for x in range(24): for y in range(24): matrix.pixelSetXY(x,y, matrix.wheel(15*(x y))) matrix.pixelsShow()