Creating a NodeJs LED Matrix display framework with Raspberry Pi

Danny Lum
codeburst
Published in
7 min readJan 25, 2018
LED Matrix displaying clock

Overview

There are a lot of good resources online for building a led matrix display panel to show weather, news ticker, etc. However, most of the resources out there are either doing one very specific thing or not as easily configurable to do other things. So, I decided to build a simple led matrix display framework using my favorite programming language, JavaScript. The framework should be easy to configure. I will focus on setting up the framework on your raspberry pi instead of going into the details from assembly the hardware to getting the led matrix board to display, but links to the resources for setting it up will be provided.

Putting the hardware together

All the hardware needed

Before getting on the programming part, we need to assemble the hardware. Here are some of the parts you will need:

  • Raspberry Pi 3 B (recommended) older versions are fine but you will need to configure on the settings
  • Adafruit 32x16 LED Matrix panel
  • Adafruit RGB Matrix HAT
  • MicroSD card 8GB or higher
  • 5v Power Supply Adaptor
  • Soldering tool (you need this to solder the 2x20 socket header on the RGB Matrix HAT)

First you need to create the Raspbian image on the MicroSD card. You can do the wiring for the RGB Matrix HAT to your raspberry pi but it will be easier to just soldering the pins and connect your pi to it. For this project, I am soldering the 2x20 socket header to the RGB Matrix HAT. You can follow the full instruction here to get the hardware assembled and the led matrix display panel connected.

For casing, I just use a small box and cut some holes for wiring. You can print one using 3D printer or woodcraft it if you wish.

Using a small box as case

Getting it up and running

Before you proceed, you should have the hardware assembled and verify the led matrix display is working correctly. Make sure you tested it to work with rpi-rgb-led-matrix as this project is using this library as dependency. Since we will be running javascript, we will need to install NodeJS.

Architecture Design

CactusPi Architecture

There are two parts of the framework, server side and client side. The server will serve as api end points and receive commands to send messages to the client. The client, on the other hand, is subscribed to the channel and listen for the server. When a message arrived, the client will convert text messages into ppm images before sending it to the display panel. Since the server and client are separated, you can setup as many servers and/or as many clients as you wish. You can also keep it minimal and run both server and client on the same raspberry pi.

Setting up PubNub

Instead of creating a realtime subscribe/publish service from scratch, we are going to use PubNub. The free tier of PubNub is enough for our project. After sign up, you can create a new project in PubNub, and copy the publisher and subscriber keys and set them in the config.json on both cactuspi-client and cactuspi-server projects.

Client side

The client service is subscribed to the PubNub channel our server is pushing messages to. There are two major tasks our client is doing, generate messages to ppm format image and send it to the led matrix board for display. The client LED Matrix will display the clock when there is no messages arrive.

The client maintains a queue of messages which by default will be first in first out (FIFO). However, the priority of the message can be configured by the server. When a new message arrives, we will either put the message into the queue depends on its priority setting. The message will then wait for its turn to be generated into .ppm image (since it is the best format for displaying text without losing pixels), and to be displayed on the board.

When it reaches the last message of the queue, the clock will be displayed until new messages arrive.

Source code for cactuspi-client.

After git clone https://github.com/dannielum/cactuspi-client.git, make a copy of config.json.sample and rename it to config.json in the root directory of the project.

{
“logo”: “./cactuspi.ppm”,
”initMessage”: “Cactus Pi”,
”pubnub”: {
“subscribeKey”: “”,
”secretKey”: “”,
”channels”: [“cactuspi”]
}
,
”ledMatrix”: {
“path”: “/path/to/rpi-rgb-led-matrix”,
”options”: {
“ledGpioMapping”: “adafruit-hat”,
”ledNoHardwarePulse”: true,
”ledRows”: 32,
”ledChain”: 2
}
}
}

Replace the pubnub’s subscribeKey and secretKey with what you obtain when creating a new project in pubnub. You can change the ledMatrix settings depending on your setup. For ledMatrix.path, make sure you set the path to the directory of rpi-rgb-led-matrix project you tested previously. The setup above is for a raspberry pi 3b using an adafruit led matrix hat with one 32x16 led panel.

Run npm install and verify all dependencies are installed, then run npm start to start the client node.

Server side

The server is an api endpoints running on express. The brain of the framework will be on the server side. Each end point is pushing a message to the PubNub channel our client is subscribed to. Therefore, we can add a weather service to fetch weather data from a third party api and push the result to the client. Or add a bustime service to fetch the bus time data to inform me to leave my house on time in order to catch the bus.

You can setup cactuspi-server on the same raspberry pi for client. You can also setup another pi as the server or even run it on a cloud based server on any machine that runs nodejs.

Source code for cactuspi-server.

After git clone https://github.com/dannielum/cactuspi-server.git, make a copy of config.json.sample and rename it to config.json in the root directory of the project just like you did for the client project.

{
"pubnub": {
"subscribeKey": "",
"publishKey": "",
"secretKey": "",
"channel": "cactuspi"
},
"weather": {
"apiKey": "weather api key",
"city": "city",
"unit": "metric"
},
"bustime": {
"apiKey": "bustime api key",
"lineRef": "MTA NYCT_<BUS NUMBER>",
"directionRef": 0,
"monitoringRef": 0,
"maximumStopVisits": 5
}
}

Do the same for the pubnub config settings as you did for the client project, except here you also need to specify the publishKey because our server is a publisher that push messages to our client.

We will use OpenWeatherMap to fetch real time weather info, you will have to setup and account and obtain an api key and set it in the config file. For MTA bus time, I am using the mta-bustime library which fetch data from the official MTA-Bustime SDK. You have to create a free account and set your api key in the config file. Change the settings to your bus line, direction, and bus stop.

Run npm install and verify all dependencies are installed, then run npm start to start the server node. If you are running both client and server in the same hardware, make sure you run them in two separate terminals.

To test if your setup is working. You can simply ping the end points.

Weather: http://localhost:8081/weather

Bustime: http://localhost:8081/bustime

Message: http://localhost:8081/message/Some message

If you want to trigger it from a different device, just change localhost to the ip address or name of your raspberry pi.

Fetching weather info

User Interface

We can create a web app for user to interact with the server. Or we can create buttons which will ping our server. I will cover this part in the future post.

Start script on boot

It is annoying to have to always ssh into the pi and manually start the script. We can auto start our script as a service when the pi boot. cd /etc/systemd/system and add a new service file nano ledmatrix.service. Copy and paste below into the file:

[Service]
WorkingDirectory=/home/pi/path/to/project
ExecStart=/usr/bin/npm start
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=ledmatrix
User=root
Group=root
[Install]
WantedBy=multi-user.target

Make sure you change the WorkingDirectory to the project directory. Then run the following command to enable the program.

sudo systemctl enable ledmatrix

Restart your pi after that with sudo reboot, the program should automatically started when restarted.

Plug in the power adapter and wait for a few seconds to see the start up screen

Shutdown button

You can make shutting down your raspberry pi safely by pushing a button.

Hanging it on the wall

I put it in a picture frame and hang it on a wall.

Final words

Hope you find this project fun and learn from doing it. It should also be easy to fork the project and add your own end points to cactuspi-server to display your own custom messages. If you follow along and make your own led display panel, I would be happy to hear about it. Please feel free to leave your comments below.

Setting up for Christmas tree

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Responses (7)

What are your thoughts?

Awesome project, Danny!

--

Hi Danny! I have been putting this project off for so long, it’s sad.
I am making a reminder display for my boyfriend, entrepreneur extraordinaire. He has a million projects and it’s always great to have a nice visual reminder from time to time, amirite?
Thanks for this!

--

Thanks for this Dan!
I am having an issue with the program actually displaying a message or anything after the initial Cactus.ppm display. It is receiving the commands on the correct channel and parsing it out, but the display shows the cactus only…

--