Control RGB LED Strips using a MinnowBoard Turbot

By tripzero
All the colors, all the control -- all with a MinnowBoard Turbot
I love LEDs. I love how efficient they are. I love how you get them in almost any color or wavelength you want. Last year, I was inspired by a few youtube videos of people putting LED lights on their stairs or making tables out of them. I decided to do the same, but also make them controllable RGB lights that I could do lots of fun things with. The MinnowBoard Turbot is a perfect board for this. It has a fast CPU with a dual (or quad)-core Intel® Atom™ processor. It also has a lot of I/O to control things like LED strips.
minnowboard

Introduction

Introduction

I love LEDs. I love how efficient they are. I love how you get them in almost any color or wavelength you want. Last year, I was inspired by a few YouTube videos of people putting LED lights on their stairs or making tables out of them. I decided to do the same, but also make them controllable RGB lights that I could do lots of fun things with. The MinnowBoard Turbot is a perfect board for this. It's fast with a dual (or quad)-core Intel® Atom™ processor. It also has a lot of I/O to control things like LED strips.

Here is a short walkthrough on how I got the MinnowBoard Turbot working with Dotstar (APA102) Color LED strip lights.

Step 1. Build the circuit board

I used a breadboard to simplify setup. The level shifter is pretty easy to setup. Connect +5V and GND. SPI Data and CLK from the minnowboard pin 9 (data) and pin 11 (clock) go in the pins marked “nA” (ie 1A) on the 74AHCT125 data sheet. Pins marked “nY” (ie 1Y) goes out to the lights. I have some terminal connectors (green in the image) that attach SPI data, clk, and power to my actual lights.

To power the lights, I have a 5V power supply connected to the +/- rails at the top and have a jumper to carry over the power to the bottom rails as well.

NOTE: The 5V power supply in the bottom right of the board is unused.

In the above, MOSI is SPI data out and SCK is the SPI clock (CLK) pin.

Step 1. Install Ubuntu on minnowboard

I won’t go through the steps on getting Ubuntu installed on the MinnowBoard Turbot. It basically consists of booting the live-usb and installing to a second USB flash stick. You can follow the tutorial on the MinnowBoard.org site for steps on installing Ubuntu 16.01.

Step 2. Install software libraries

Once Ubuntu is installed, we will install the necessary software to get the lights shining. Software setup will have two options: manual software install, or dockerfile install.

Option 1: Install software to use lights

We need the following extra packages on top of the default Ubuntu install:

copy
$
sudo apt install git \ build-essential \ cmake \ libgstreamer1.0-dev \ libgstreamer-plugins-good1.0-dev \ libpython3-dev \ python3-numpy \ swig3.0

We will make a src subdirectory where we will put all the sources to make the lights work:

OpenCV

copy
$ $ $ $ $
mkdir src && cd src git clone https://github.com/Itseez/opencv.git cd opencv mkdir build && cd build && cmake .. make && sudo make install

If all went well you should be able to run the following without any exceptions being raised:

copy
$
python3 -c “import cv2

MRAA

Mraa is for low-level IO on the MinnowBoard Turbot.

copy
$ $ $ $ $ $
cd ~/src git clone https://github.com/intel-iot-devkit/mraa.git cd mraa mkdir build && cd build cmake .. -DBUILDSWIGNODE=n -DCMAKE_INSTALL_PREFIX=/usr make && sudo make install

Test with:

copy
python3 -c “import mraa”

Again, you should not see any exceptions raised.

MinnowBoard Turbot SPI module:

This is required to get SPI (the interface with the lights) working.

copy
$ $ $
git clone https://github.com/MinnowBoard-Projects/minnow-max-extras.git cd minnow-max-extras/low-speed-spidev-1.0 make && sudo make install && sudo make load

Now make sure we can access the SPI device by setting group permissions:

copy
$ $ $
sudo groupadd --system spi sudo adduser $(whoami) spi sudo nano /etc/udev/rules.d/90-spi.rules

Add the following to 90-spi.rules:

copy
SUBSYSTEM=="spidev", GROUP="spi"

Edit /etc/modules and add the line “low_speed_spidev” to the end of the file.

NOTE: The SPI device is /dev/spidev0.0

Python Photons

copy
$ $ $ $ $ $ $
git clone https://github.com/tripzero/python-photons.git git clone https://github.com/tripzero/python-wss.git cd python-wss sudo python3 setup.py install cd .. cd python-photons sudo python3 setup.py install

The python-photons project provides a nice python interface for playing with LED strips. It has promises and animation classes that help with making the lights do fun things like fade in and out of different colors. It has several drivers for working with different LED interfaces and protocols. The one we will be using is the Apa102 driver which communicates over SPI using mraa. Another is a socket protocol for controlling the LEDs over a network.

python-wss is a wrapper around autobahn’s websocket interfaces. It makes it easier to work with websockets and It has some features like auto-reconnect. python-photons uses normal sockets to communicate, but takes advantage of the auto-reconnect classes provided by python-wss.

Option 2: Docker install

Install Docker:

copy
$ $ $ $ $
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt update sudo apt install docker-ce sudo usermod -aG docker $(whoami)

Log out of your user and log back in. Test with:

copy
$ docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 17.06.2-ce

Build “turbotlights” docker image

Create the dockerfile:

copy
cat << EOF > turbotlights FROM ubuntu:17.10 # # on minnowboard max, spi is /dev/spidev0.0 # # RUN mkdir -p /home/root/src WORKDIR /home/root/src RUN apt update RUN apt install -y git \ cmake \ swig3.0 \ build-essential \ libpython3-dev \ python3-numpy \ python3-setuptools RUN git clone https://github.com/Itseez/opencv.git opencv RUN mkdir -p opencv/build RUN cd opencv/build && cmake .. && \ make && make install RUN git clone https://github.com/intel-iot-devkit/mraa.git RUN mkdir -p mraa/build RUN cd mraa/build && cmake .. -DBUILDSWIGNODE=n -DCMAKE_INSTALL_PREFIX=/usr && \ make && make install RUN git clone https://github.com/tripzero/python-photons.git RUN git clone https://github.com/tripzero/python-wss.git RUN cd python-wss && python3 setup.py install RUN cd python-photons && python3 setup.py install CMD ["/bin/bash"] EOF

You can now build the Docker image:

copy
$
docker build --rm -t turbotlights .

This will take some time to build. Grab a drink. Take a walk.

Run turbotlights container

copy
$
docker run --privileged --rm -it -v /dev/spidev0.0:/dev/spidev0.0 -v /sys/devices/virtual/dmi/id/board_name:/sys/devices/virtual/dmi/id/board_name turbotlights

NOTE: I couldn’t get this running without --privileged. It should still be possible to do so and should be done.

Step 3. Test python-photons

Let’s use python-photons to see if our physical connection to the LED strip is correct. We’ll launch a python console and import the photon module. If you installed via Docker, connect to the docker instance, otherwise just run this at the Ubuntu prompt.

Launch python3, then type the following:

copy
>>> import photons >>> photons.getDriver(“”) driver not supported supported drivers: Dummy Apa102 LightProtocol Ws2801 OpenCV OpenCVSimple >>> driver = photons.getDriver(“Apa102”)() >>> leds = photons.LightArray2(10, driver)

“10” is the number of individual LEDs in the strip. Change this to the appropriate number for your strip.

Continuing:

copy
#change the color of first LED to red: >>> leds.clear() >>> leds.changeColor(0, (255, 0, 0)) >>> leds.updateNow()

The first LED in the strip should have now become red. If it doesn’t, double check your connections. Trying this didn’t work at first for me. I had my SPI connector on the edison connected to MISO instead of MOSI. After fixing that mistake, it started working.

Changing the color of one light isn’t that interesting. Python-photons can do so much more with its animation system. It comes with a sample app called “screensaver”. It’s a collection of simple animations. Let’s try to use that to do something cool:

copy
$ $
cd src/python-photons/screensaver ./screensaver.py --driver Apa102 --num 10 --fps 60

The --num argument is the number of LEDs in the strip similar to what we had set above. The --fps argument tells LightArray2 how frequently to actually write data to the lights. This will come in handy later when we are sending the light data over a network.

The result of the command should be the LED slowly transitioning to different random colors. The code to do this isn’t very complicated.

Other themes

After you have had enough random colors, you can play around with screensaver a bit and try the other effects:

copy
--rainbow --larson

Step 4. Making our own theme

We can make our own themes using python-photon’s animation classes. Let’s make a theme that transitions between several “aurora”-like colors:

copy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
import random import photons import asyncio photons.getDriver(“”) driver = photons.getDriver(“Apa102”)() leds = photons.LightArray2(10, driver) loop = asyncio.get_event_loop() def transform(): print( "rainbow...") concurrentTransform = photons.ColorTransformAnimation(leds) color = random.choice([(200, 0, 200), (0, 100, 200), (0, 200, 100)]) print("color = {}".format(color)) for i in range(leds.ledArraySize): concurrentTransform.addAnimation(i, color, 5000) concurrentTransform.start().then(loop.call_soon, transform) loop.call_soon(transform) loop.run_forever()

The concurrentTransform.start() call returns a photons.Promise. These work similarly to how JavaScript promises work. They can even be chained together:

copy
concurrentTransform.start().then(foo).then(bar)

In this case, we are just having the loop call our transform again for an endless loop.

Conclusion

We walked you through how to use the Minnowboard Turbot to make your own LED strip light displays. There’s a lot of applications for this from ambient lighting to full LED matrix displays. If you make a cool theme, consider contributing it as an example in the python-photons github project.

Here’s a couple images/videos of how I use my lights:

“Christmas” theme

"Rainbow Transforms” theme video

LED Stairs “Rainbow” theme video

LED Matrix Table “Mouse in Maze” theme video

LED Matrix Table “Stars” theme video

LED Matrix Table “Aurora” theme video

Ingredients

Others
MinnowBoard Turbot
A powerful PC with an extendable IO interface. https://minnowboard.org
3v to 5v level shifter
74AHCT125 3v to 5v level shifter - https://www.adafruit.com/products/1787
5V 10A Power supply
Powers the MinnowBoard Turbot and the LEDs. A 10A supply should be enough for the MinnowBoard Turobt and up to 50 lights. https://www.amazon.com/gp/product/B01M0KLECZ
Breadboard with male-to-male and male-to-female jumper cables
Use the breadboard and cables to build the circuit shown in this article. Male-to-male are used on the breadboard; male-to-female are used to go between the MinnowBoard Turbot's 40-pin expansion header to the breadboard.

Steps

1 total steps
1
DJ Injection