LED Array Lamp Part 5

In the previous a part of this series I gave an overview of the lamp. In this part I’ll get to the point where it’s possible to write to the LED’s. This won’t be the final form of the LED but it’ll be good for testing that it’s electrically correct.

Installing Additional Software

The plan is to have the lamp running a Python service that listens for connections. The remote software will send a message containing what the LED lamp will display. Ideally, the message will be able to contain a number of frames so a short animation can be displayed. I’d also like to be able to pick from a number of built in animations. Anyway, that’s getting a bit ahead of myself. For now it’s necessary to install Python 3 if it isn’t already installed. Shell into the machine an run:

sudo apt install python3

I think all the Pi OSes come with it pre-installed but it won’t hurt to make sure. Later on it’ll be necessary to install some libraries which are managed with Pip so install that now.

sudo apt install python3-pip

Setting up the Development Environment

Developing on the Pi Zero is technically possible but it’s a painful experience compared to working on a proper desktop computer. I want to develop in PyCharm (from JetBrains) as I already have a license for it, I’ll be working on a Debian 12 based machine. The problem with this set up is you can’t run the Pi code on the Debian machine as it doesn’t have access to the GPIO hardware. Any code using the Pi’s GPIO that you run on the Debian machine will just crash when it encounters any GPIO instructions. So, while development can happen on the Debian machine, all testing will need to take place on the Pi Zero.

What this means is that I need some way to quickly get the code from the development environment to the Pi Zero. The solution I’ve settled on is rsync as it’s basically built to solve this problem. Rsync is required to be installed on both the source and destination machine. It is probably already installed but if not it can be installed with: sudo apt install rsync.

Start by shelling into the Pi Zero and create a projects directory under the home directory.

cd ~
mkdir projects

doozer@ledpi:~ $ ls
projects

This isn’t strictly necessary but I like to keep my code separate. Now rsync the project onto the Pi Zero with the follow command:

rsync -avzP ~/PycharmProjects/LedArrayDriver doozer@ledpi:~/projects

The source is ~/PycharmProjects/LedArrayDriver which is directory of the project I’m developing. Note that there isn’t a trailing /, this causes rsync to create the project directory at the destination which is what I want. The destination is the projects folder I just created. The only flag that is really required here is -a which stands for archive, this is the same as setting the -rlptgoD flags separately. Essentially it tells rsync to mirror the directory at the destination. The -v flag is for verbose mode. The -z flag is for compression although that’s hardly needed here. Finally, -P is for progress and again this isn’t really needed as the transfer is so quick. After running the above command you should see something like this.

...snip...

LedArrayDriver/venv/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/__init__.cpython-39.pyc
            200 100%    0.71kB/s    0:00:00 (xfr#1981, to-chk=2/2388)
LedArrayDriver/venv/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/_typing.cpython-39.pyc
          1,495 100%    5.31kB/s    0:00:00 (xfr#1982, to-chk=1/2388)
LedArrayDriver/venv/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/tags.cpython-39.pyc
         18,550 100%   65.63kB/s    0:00:00 (xfr#1983, to-chk=0/2388)

sent 11,805,292 bytes  received 39,805 bytes  1,393,540.82 bytes/sec
total size is 31,604,266  speedup is 2.67

Subsequent executions of this command will be much faster as the bulk of the transfer is in the venv folder which won’t change.

First Test Run

Before I can run any Neopixel code the libraries mentioned in part 2 of this series need to be installed on the Pi Zero.

sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
sudo python3 -m pip install --force-reinstall adafruit-blinka

I freely admit that I’m not 100% sure what is happening here. I know it’s installing the libraries but I think they are being installed globally which is not desirable generally. For now, until I can learn more about Python, this will work.

With the libraries install, in the root of the project folder I created a new file called basic_function_test.py into which I added the following code.

import time
import board
import neopixel
import random

pixel_pin = board.D18
num_pixels = 256
ORDER = neopixel.GRB

with neopixel.NeoPixel(
    pixel_pin, num_pixels, brightness=0.1, auto_write=False, pixel_order=ORDER
) as pixels:

	for pixel in range( 0, num_pixels ):
		pixels[ pixel ] = (random.randint(0,255), random.randint(0,255), random.randint(0,255) )
		pixels.show()
		time.sleep(0.1)

	for pixel in range(0, num_pixels):
		pixels[pixel] = (0,0,0)
		pixels.show()
		time.sleep(0.01)

This simply steps through the pixels each one a random colour and then turns them all off before exiting. I’ve kept the brightness low because I’m sitting right next to the lamp, this thing is going to be bright! Rysnc this code over to the Pi Zero and shell into the machine. Switch to the project directory and then run the code as shown below.

cd ~/projects/LedArrayDriver/
sudo python basic_function_test.py 

I couldn’t go without making a short video of this first run. It doesn’t seem worth putting this up on YouTube so here’s a potato quality version.

I’m really pleased with this although maybe you can spot the same problem as I did as soon as it started running…

The pixels all light up exactly as I wanted but they start going left to right and then the next row up is right to left and so on. This was a real doh moment. I built it so that the LED strip snakes it’s way up the lamp but that’s not really what I wanted. I wanted a grid with the coordinates (0,0) at the bottom left and (15,15) at the top right.

Surprisingly this isn’t as much of a problem as you might think and I can fix it in software. It’s more of a frustration that I’ll have to insert a translation layer to pack the data for the way the lamp is built. Essentially you’ll provide a 16×16 bitmap file and the driver software will just reverse every other row before sending it to the lamp.

I’ll leave it there for now as this feels like quite a success and also because I’m not 100% sure how I’ll proceed from here. As I mentioned earlier I would like to have the driver software running on the Pi Zero and then be able to make remote connections to it to send it what I’d like displayed. In my head I have visions of an all singing all dancing web-app sending REST messages to the lamp. Perhaps I’m biting off more than I can chew. I think I should start by looking around to see if anyone has already written something I can use.