Introduction: RPi 3 Starboard / Particle Generator

About: PhD Candidate, English Literature // Inveterate maker


Are you feeling bored with your Raspberry Pi? Are you ready to command the very elemental forces of the universe, summoning and dismissing photons at will? Do you just want something interesting to hang in your living room, or a fancy project to post on facebook to show Denise that you're doing just fine these days, thank you very much? Are you trapped in a computer simulation and whiling away the hours until you're freed or deleted? If any or all of these describe you, then [announcer voice] Welcome!

This tutorial will show you how to assemble and set up a particle generator display using a Raspberry Pi 3 and some RGB matrix panels. It should take you between one and two hours, and the finished product will be approximately 30"x8" (not including the Pi) and wall-mountable. It makes a pretty cool decoration for a living room, office, game room, or wherever else you want to put it.

Before you get started, here's what you'll need, and what the approximate costs are:

  • Rpi 3 + SD Card + Case + Power Supply: $70 (from Canakit, but you can probably get the parts cheaper if you buy them separately.)
  • 4x 32x32 RGB LED Matrix (preferably p6 indoor with 1/16 scan): $80-$100 shipped on Alibaba or Aliexpress; $160 on Adafruit or Sparkfun.
  • Adafruit RGB Matrix hat: $25
  • 5V 4A Power Supply: $15
  • 3D printed clips: $1ish (these are for connecting the panels and hanging them on the wall; if you don't have access to a 3D printer, you can use a furring strip to hold them together and some brackets from the hardware store to hang it from the wall. I tried to find the design files or the .stls for these, but they seem to have passed from the earth. The clips are pretty easy to model, though.)
  • 14x M4x10 bolts: $5ish
  • Four 4x8 IDC cables and three power cables for the RGB matrices (I don't know what these are called!). These should have been included with your LED panels.
  • Total: Around $200, give or take.

The project doesn't require you to solder or have any specific programming knowledge; it does assume you know how to write an image to a microSD card. If you're not sure how to do that, the Raspberry Pi foundation has a good tutorial here.

It also assumes you have a basic knowledge of how to do things from the command line in Linux, and the code walkthrough assumes you know the basics of Python (but - you don't need to follow the code walkthrough to be able to build and run the particle generator.) If you get stuck on any of the steps, feel free to ask a question or post in /r/raspberry_pi (which is also, I'm assuming, the main audience for this instructable)

Step 1: Assemble the LED Board

First, you're going to assemble the individual 32x32 LED panels into one large 128x32 panel. You'll need to look at your boards and find the little arrows that indicate connection order; on mine they're right near the HUB75/2x8 IDC connectors. Make sure you have the arrows pointing from where the Rpi will connect (off to the right in the photo above) down the length of the board.

You'll also need to connect up the power cables. Most of these cables have two female connectors that attach to the boards, and one set of spade terminals that attaches to the power source. The panels I'm working with have the indicators for 5V and GND almost entirely hidden away under the connectors themselves, but the cables only connect in one direction. You'll want to make sure that you're connecting all the 5Vs together and all the GNDs together, because if you power these backwards you're almost certainly going to fry them.

Because the power cables included with my boards were so short, I had to extend one by inserting the prongs of the spade terminal into the connector of another (This is pretty straightforward - you might have to bend the spade terminals slightly inward, but I've included a picture just in case). I ended up with two sets of spade terminals and one 2x8 IDC connector off to the right of my now-elongated LED board.

You'll also notice that I've got two bolts not attached to anything on either end of the board; these will be on the top once the whole thing gets flipped over, and will be used to attach it to the wall.

So - once you've connected all of the panels together with clips, 2x8 IDC cables, and power cables, you're ready to move on to the next step!

Step 2: Prepare the Raspberry Pi

Next, you're going to set the LED board aside (for now) and get the Pi 3 ready to run it. We'll be using Raspbian Stretch Lite and hzeller's RGB matrix library (rather than Adafruit's matrix library, which is older and unmaintained.)

First, you'll want to write the Raspbian Lite image to an SD card; once you've done this, go ahead and connect a monitor and keyboard to the pi and boot it up. (You can also do this headless, either over ssh or a serial connector, but if that's the way you're going you probably don't need me to tell you how to do it.) You'll need an internet connection for this; If you've got wifi, connect the Pi to your wireless network by editing /etc/wpa_supplicant/wpa_supplicant.conf and running wpa_cli -i wlan0 reconfigure. (If you've never done this, you can get instructions here).

Once you're connected to the internet, we'll update the dpkg repository settings and download the libraries we need by running the following commands:

sudo apt-get update

sudo apt-get install git python-dev python-pil

git clone https://github.com/hzeller/rpi-rgb-led-matrix.git

Now we've got to compile and install the matrix code. So you'll go into the folder containing the library:

cd rpi-rgb-led-matrix

and compile it (this might take a minute):

make && make build-python

and install the python bindings:

sudo make install-python

If you get any errors while compiling the library code, go back and make sure you installed python-dev and python-pil correctly! The python bindings won't compile without both of those packages installed.

You'll also need to disable your Pi's sound output (the on-board sound interferes with the matrix code) by editing /boot/config.txt. Look for the line that says dtparam=audio=on and change it to dtparam=audio=off.

If everything compiled OK (you'll get a few warnings about Wstrict-protoypes) your pi should be ready to run the matrix board. Go ahead and shut it down (sudo shutdown now), unplug it, and we'll connect up the light board to the pi in the next step.

Step 3: Connect Pi + Matrix Hat + LED Board

So, now that your Pi is off and unplugged, let's connect the matrix hat to the pi and the LED board to the matrix hat. If your Pi isn't already in it's case, now's a good time to put it in there.

Install the matrix hat by lining it up with the GPIO pins on the Pi and pushing it gently down with even force on both sides. Make sure that the pins are lined up correctly, so that the female headers on the hat exactly cover the GPIO pins on the pi. If you misalign it, it's not a catastrophe; just gently pull it back off and straighten out any pins that got bent.

Once you've got the hat on, put the Pi to the right of the assembled LED board (double check the power connections again, and make sure the arrows are pointing from the Pi down the length of the board) and connect up the IDC cable to the matrix hat.

Next, you'll want to connect the spade terminals for the power into the matrix hat's terminal block. You've got two spade connectors per side, but they should both fit in there fine. Loosen up the screws first and - This should go without saying - make sure you put the 5V terminals in the side labeled + (these should be red, but - again - double check your connectors and don't assume they got manufactured correctly) and the GND terminals (these should be black) in the side labeled -. Once they're in there, tighten the screws on top of the terminal block, and you should have something that looks like the header image for this step.

Now - you may have noticed that this particular configuration leaves one-half of the spade terminal on either side exposed, hovering mere milimeters above the matrix hat (and not very much further from each other.) AND - the spade terminals will very soon be carrying both several volts and several amps of Raw Power. Is this, (I can hear you asking from the other side of the screen) really The Right Way To Do It? Is it, (you lean in closer and whisper), A Good Idea?

And the answer is (I respond, shrugging my shoulders) - no, it is not. The right way to do it would be to strip the spade terminals off the power cables and re-crimp them into the correct connector for that terminal block (or to leave them as bare wires and connect them without a connector into the block). Failing that, you could put some heat shrink tubing around the exposed side of the spade connector or just wrap it in electrical tape. But the world is fallen and man is lazy and vain, so I haven't done that.

But - wrapped or unwrapped - the spade terminals are connected to the terminal block, and we're ready to move on to the next step.

Step 4: Test the RGB Matrix

Now that your Pi is connected up to the light board, flip the board over and power the Pi back on. You can power the matrix hat after the Pi is plugged in; if you power the hat before the Pi, though, the Pi will try to boot with not enough current, and will complain bitterly (and may give you a kernel panic and not boot at all.)

If you're having trouble getting the Pi to boot with the matrix hat on, make sure you're using a beefy enough power supply for the Pi (2A+ should be good) and try plugging both the power supply for the hat and for the Pii into the same power strip or extension cord, and powering them up together.

Once the Pi has booted, we're ready to test the matrices. Go to where the python binding samples are (cd /rpi-rgb-led-matrix/bindings/python/samples) and try out the rotating block generator with the following command:

sudo ./rotating-block-generator.py -m adafruit-hat --led-chain 4

You've got to run it as sudo because the matrix library needs low-level access to hardware at initialization. The -m specifies the way the panels are connected to the pi (in this case, an adafruit hat) and the --led-chain specifies - you guessed it - how many panels we have chained together. Rows and columns per panel both default to 32, so we're good there.

Now - once you've executed the program, one of two (or, really, one of three) things is going to happen:

  • Nothing happens
  • You get a nice rotating block in the middle of your light board.
  • The light board works, uh, I think, but it looks ... weird (half of it is green, some rows aren't lighting up, etc.)

If nothing happens, or if the panel looks weird, hit ctrl+c to exit the sample program, shut down the pi, and check all of your connections (IDC cable, power, make sure both power supplies are plugged in, etc.) Also make sure the hat is connected correctly; if that doesn't fix it, take it down to one panel (make sure to use --led-chain 1 when testing it) and see if one of the panels might be bad. If THAT doesn't work, check out hzeller's troubleshooting tips. if THAT STILL doesn't work, try posting to /r/raspberry_pi (or the Adafruit forums, if you got your panels from Adafruit, or stack exchange, etc, etc.)

If it sort of works but still looks weird (perhaps like the header image for this section) after you've checked the connections, it is possible that you have everything connected correctly, that the panels are functioning properly, but that Something Else is going on. Which will take us to our next step - more a diversion than a step - on multiplexing and scan rates. (If your led board is working fine and you're not interested in the inner workings of these panels, feel free to skip the next step.)

Step 5: Multiplexing and Scan Rates (or: a Momentary Diversion on the Road to the Grave)

So, one of the mistakes I made when I ordered my first set of panels off Alibaba is that I got outdoor panels (why not, I thought - they're waterproof, and brighter!). And, when I wired them up to my matrix hat, things looked.. not right.

To understand why that is, we'll take a minute to look at Phil Burgess from Adafruit's description of how these panels work. You'll note that Burgess points out that the panels don't light up all of their LEDs at once - they light up sets of rows. The relationship between panel height in pixels and the number of rows that light up at once is called scan rate. So, for example - On a 32x32 panel with 1/16 scan, two rows (1 and 17, 2 and 18, 3 and 19, etc) are lit up at once, all the way down the board, and then the controller repeats. Most libraries that drive RGB matrices are built for panels where the scan rate is 1/2 of the height in pixels - that is, they drive two rows of LEDs at once.

Outdoor panels (and some indoor panels - make sure you look at the specs before ordering) have scan rates that are 1/4 of the height in pixels, which means they expect four lines to be driven at once. This makes them brighter (which is good) but makes lots of standard code not work with them (which is bad). In addition to that, they tend to have the pixels out of order internally, which requires transforming the x and y values in software in order to address the right pixels. Why are the made this way? I have no idea. Do you know? If so, please tell me. Otherwise it will just have to remain a mystery.

So, if you've got one of these weirdo outdoor panels, you're (probably) in luck! hzeller recently added support for common configurations of these types of panels to his library. You can read more about it on the github page for the project, but you can pass --led-multiplexing={0,1,2,3} to the sample code (you may also need to pretend like you've got a double-length chain of half-length panels) and it should work.

There are some pixel transformation patterns that aren't supported, though - and (guess what) my panels have one of them! So, I had to write my own transformation code (I also - for whatever reason - have to tell the library to act like i've got eight 16x32 panels chained together). which is as follows:

def transformPixels(j, k):
effJ = j % 32

effK = k % 32

modY = k

modX = j

#modX and modY are the modified X and Y;

#effJ and effK make sure we transform within a 32x32 matrix before pushing

if ((effJ) > 15):

modX = modX + 16

if ((effK) > 7):

modY = modY - 8

modX = modX + 16

if ((effK) > 15):

modX = modX - 16

if ((effK) > 23):

modY = modY - 8

modX = modX + 16

#Then, we push them to the correct location (each x+32 moves one panel)

if (j > 31):

modX += 32

if (j > 63):

modX += 32

if (j > 95):

modX += 32

return (modX, modY)

If you have a panel like mine, this might work for it. If it doesn't, you'll have to write your own - so, you know, good luck and godspeed.

Step 6: The Starboard Program (or: Back on Track and Ready to Pixel)

Now that you've got your matrices operational and ready to go, all you have to do is put the starboard program on your Pi and get it ready to go. Make sure you're in the pi user's home directory (cd /home/pi) and run the following command:

git clone https://github.com/dearner/starboard.git

you should have a new folder, starboard, that contains three files: LICENSE.md, README.md and starboard_s16.py. Try the starboard program out by running it through python:

sudo python ./starboard_s16.py

and you should get a bunch of particles moving at different speeds and decaying at different rates. Every 10,000 ticks or so (you can go into the python script to edit/change this) it will change modes (there are four: RGB, HSV, Rainbow, and Greyscale).

So, now the only thing left to do is make the starboard code run on startup. We'll do that by editing (with sudo) /etc/rc.local. What you want to do is add the following line right before "exit 0" in the script:

python /home/pi/starboard/starboard_s16.py &

After you do that, reboot the pi - once it runs through the bootup sequence, the starboard_s16.py script should start right up!

If you want to poke around in the script, feel free to do so - it's licensed under the GNU GPL 3.0. If the script won't run for you, or you have trouble with it, feel free to let me know or submit a bug on github, and I'll see what I can do to fix it!

The (very) last thing you might want to do is set up SSH on the pi, so that you can remote in and safely shut it down. You'll /definitely/ want to change your password (via the passwd command), and you can find instructions for enabling ssh (also from the command line) here.

Congratulations! You're done! [party emoji]

One quick note, before you leave this instructable (perhaps forever!). This (both the project and the instructable) was a lot of fun to make, and I've got a bunch more I'd love to put up here (and, as always, tons of ideas in the planning stages.) It does take time and effort, though - so if you liked it and would like to show support, consider following me on instagram at library.of.babel, where I post development pictures of things I'm working on; if you *really* liked it, and would like to support the development of future projects and instructables, consider tossing a dollar or two my way over paypal (it's my instructables user name [at] gmail.com) to offset time and materials costs.

Hope you enjoy your new starboard!