February 2013

A Raspberry Pi-based State Poster Project

At our daughter's school, all the 2nd graders put together a "state board" project. They are randomly assigned a state (in our daughter's case, Vermont) and the students work to put together a poster on a tri-fold piece of cardboard. From what I've heard, the projects often have 3D aspects like animals and products attached and several over the years have had buttons to play things like the state song. We brainstormed possible elements we might include on the board and thought about sound, light, and even considered EL-wire animated rivers. I wanted to make sure that if we chose a more elaborate design that our daughter would actually carry out most of the work and that we document that -- so I used a flip video recorder to film most of the process. In terms of electronics, our daughter jumped in fairly quickly having learned to solder at the recent Makerfaire in New York. She's built a couple of kits since then. There was a fair amount of soldering required on the Perma-Proto. The video below shows our daughter working on the Perma-Proto and button boards.

In order to have the desired sound and light elements we needed to choose an appropriate controller. I debated whether it would be best to recommend an Arduino-based design or to use a Raspberry Pi. An Arduino approach might use an Arduino and Wave Shield combination. It would have the advantage of faststart upand shutdown and would have clear uninterrupted audio. A Raspberry Pi would potentially be less expensive as it could play the audio off its own filesystem, has networking built in (Model B), and can use Adafruit's WebIDE which would simplify our daughter's Python-based programming tasks (the Arduino wouldn't have been Python). The Pi could multi-task which would make some things easier but would make smooth sound playback more challenging. As the project would be in place at the school for the rest of the year, power management was important also -- so a graceful auto-shutdown would be essential. I'd done many past projects with the Arduino/Wave Shield combination so I really wanted to see how well it could be done with the Raspberry Pi. The WebIDE helped convince me it would be easier for our daughter to work with (and she'd just started working through Python for Kids).We started with a rough idea of how we thought things would come together. First, we would need to have the outline of the state. One of the goals was to avoid having a lot of wires and connections on the back of the tri-fold. To accomplish that, the state boundary outline would have to be a separate piece. That also satisfied creating a 3D look for the state. We could have used foam board but I thought quarter inch plywood would hold up better and allow for more precise cuts. The plan was to use actual state boundary data to generate g-code for our CNC. We would also plan the precise location of the LEDs and drill holes at those locations on the wood. The legend would also be wood and would have holes for LEDs and buttons. The hope was that a single strand of RGB LEDs could be routed around the back side of the state and legend boards and hit all the holes. We planned to use 50 LEDs in total, 15 on the legend and 35 on the map. As it turned out, we should have adjusted the holes somewhat but we did pretty well wasting only 2 on the strand which didn't reach a hole and having to add 2 more to compensate which were plugged into the end of the strand (we wanted to keep the two 25 LED strands we used intact).Other parts of our plan included use of a wireless remote in addition to the 8 buttons we planned on using on the board. Since the remote receiver operated at 5 volts, we needed to introduce a level-converter for use with the 3.3 volt Raspberry Pi. We then needed a switch module which could trigger a full power up from the press of a momentary switch while using very little current to monitor the switch. We also needed to amplify audio from the Pi to drive a small set of speakers. As the Pi audio is not always smooth and has occasional clicks and pops (even with some filtering) -- this can cause problems if the amplifier is driven from the same supply as the Pi as it can draw enough current to crash the Pi. So the amplifier would have to have its own power which could be connected when the main power came up. So all together the hardware needed consisted of:

We used modular 6-conductor modular phones jacks and plugs for connecting with the button panels. The legend panel used all 6 conductors for the 5 buttons and we were able to find 6-conductor modular phone cable at a local Radio Shack (this is harder to come by than 4-conductor). For the power and other buttons we just used two more 4-conductor modular cables. The cheapest jacks were in 10-packs at Home Depot but the modular cable we had was stranded so it wasn't quite so easy as just using a punch down tool -- we had to work to make sure it made contact -- sometimes tinning some of the wire where it came through the channel. It might be easier although slightly more expensive just to use RJ45s and CAT5 for switch wiring.The finished control box, mounted on the bottom back of the center section of the tri-fold, is shown below.

Now that we've covered an overview of the build and given the materials involved, let's discuss some of the major steps in detail.

Planning LED Placement

An important part of the project was planning the placement of all the LEDs on the map as well as what colors they should be to indicate different products on the legend. Since the LEDs can change to any color, single LEDs could be used to indicate different products at different times with different colors. So in planning, one could conserve LEDs by using one LED to represent each region in the state. Here's a video of our daughter's planning process including color selection and RGB value determination:

Cutting Out Your State with a CNC

In our case, we had a small CNC machine we could use to cut the state outline (laser cutting the wood would have been easier). Since the desired size of the state was larger than the CNC, the plan was to cut it in 4 pieces and join them together. Ultimately, it all came down to how to generate the g-code for the CNC. This was accomplished with a mixture of some Python and Java code and could be adapted for other state boundaries. One million scale U.S. state boundaries can be downloaded here. I've also made a local copy of the statep010_nt00798.tar.gz 2012 boundaries file here. The archive file has a shape format file inside with boundary data for all the states. A simple Python program can be used to copy out the latitude, longitude values for the boundary of a given state as follows:

import shapefile
import sys
r=shapefile.Reader("statep010.shp")
sr=r.shapeRecords()
for s in sr:
    if s.record[3]=='Vermont':
        shape=sf=open("vermont.txt",'w')
for pt in shape.shape.points:
    f.write(str(pt[0]))
    f.write(",")
    f.write(str(pt[1]))
    f.write("\n")
f.close()

The Python program above will need the Python shapefile extension to be installed. It finds the record associated with the desired state, in this case Vermont, and writes out the latitude, longitude values for the state outlines to an ASCII datafile called vermont.txt that will be used by our next program. The next set of programs (written in Java and available in vermont.jar) generate g-code for various parts of the project. These all give graphical previews of the parts they will cut. The first program (called Plot.java) plots the state boundary from the vermont.txt file but also uses resource files that have the locations of the lights (as interpolated from a Vermont product map) and some city locations (from the lat/lon) to help in understanding where to place city labels. The holes are roughly to scale which gave us an idea of whether they were too close to the edge or to boundaries of the state quarters. Some polygon intersections were used in Java to produce the 4 smaller polygons for the parts of the state we needed to cut separately. We tweaked the cut boundaries until they didn't cross any of the light hole positions but yet kept the state quarters small enough to cut on the CNC. Ultimately the program produces 4 g-code files, one for each of the state quarters (vermont1.nc, vermont2.nc, vermont3.nc, and vermont4.nc).

plot

The video below shows some examples of pilot holes being cut for the LEDs and the boundaries being cut:

Cutting Title Letters

We also used the CNC to cut the individual letters for Vermont. I tried out NCPlot which worked pretty well for generating g-code for the letters. I had to re-order the cuts though on letters like the "R" and "O" since I discovered a little too late that it didn't cut the holes before it cut the letter boundary itself. Here's a video of the title letters being cut and sanded:

Planning/Cutting the Legend

We sized the legend panel so that it couldaccommodatethe 15 product entries with LED holes spaced sufficiently. It also had to fit in the center cardboard panel to the bottom right of the state. The primary control buttons were also located on the legend panel at the bottom. So mostly the CNC was used to drill the legend pilot holes for all the LEDs as well as for 5 buttons and to cut out the rectangular border for the panel. legend640

And here's the legend panel being cut:

Gluing/Sanding/Painting the Wood Parts

The four quarter pieces of the state were glued together with wood glue. These joins were along straight edges. Thin strips of wood were used along the seams in the back to strengthen the seams (these had to be cut away from a couple of the holes with a dremel). The state, letters, and legend pieces were all sanded and painted. The rivers and water areas on the state were painted with blue glitter paint. Here's a video of the painting process:

Also, before the water features were painted, as shown in the video above, they were traced using a projected overlay as shown below:

Attaching the LEDs

All the LED holes were drilled so the LEDs protrude through the holes and the flat part containing the ICs are flush against the wood on the back side. Hot-melt glue holds each LED in place. The LED chain begins at the bottom of the legend panel where the LEDs fill all the holes from bottom to top and then they jump over to the map where they traverse the 35 holes there. In a couple of cases an LED didn't reach a hole and had to be skipped (since we didn't want to cut the two 25 LED strands). I debated about actually writing some code to search for the best way to cover the holes with a minimum of skipped LEDs (a familiar algorithms problem) -- but missing 2 wasn't so bad. As a result, we need to put together a 2 LED extension (using the other JST plug from the set) and add that to the chain. The photo below shows a top view of the board where you can see the cardboard layer, mounting blocks, and map layer.

vermont-lights640

Buttons

There are 4 areas where buttons are needed: at the bottom of the legend panel, an "on" button at the bottom left of the state (which includes a power LED), and buttons for the song and the bird located to the left of the upper portion of the state. All of these are backed by small proto boards whose buttons and leds extend through either the wood or cardboard and which are hot-melt glued on the back. The 5 legend buttons are connected with a single 6 conductor modular phone cord. The power button/led is connected with a 4 conductor modular phone cord and then bird and song buttons jointly utilize another 4 conductor modular cord.

Mounting the Boards to the Cardboard Tri-Fold

Both the state and legend boards have wood blocks wood-glued to them in the back to allow space for the LED strand (and buttons) behind them but in front of the cardboard. Fender washers and wood screws come through the backside of the cardboard into those wood blocks, holding the boards securely on the cardboard.

Design of the Control Box Enclosure

The electronics control box is attached to the bottom of the central cardboard panel on the back. The box is 24" long (to match the central tri-fold panel). Electronics, batteries, and speakers are laid out linearly along the full 24". To make access easier, an acrylic sliding top is used which can open fully to give access to electronics and batteries. The components themselves are also mounted to aslideable1/4" plywood base which is mounted slightly above the bottom of the box. The bottom of the box can therefore be flat without the various mounting screws for the board and batteries being exposed. It's also convenient to be able to slide the electronics out. One end piece on the box has both a network jack and an external power jack. Originally, we used external power but once the battery circuit was fully in place that became much more convenient and we never used external power again during development. The power jack is wired so that battery power cuts off when external power is applied (but a jumper needs to be removed if you want to provide regulated 5 volt power through the external jack -- otherwise a slightly higher voltage needs to be supplied as the internal 5 volt regulator needs a slightly higher voltage -- as the 5 "D" cells are providing when it's on battery). A dummy plug inserted in the external power jack serves as an effective "safety" so the system isn't accidentally triggered during transport. In a nod to the aviation community, it seemed reasonable to attach a "Remove Before Flight" banner to the dummy plug to clearly show its purpose (and I recently witnessed parents at our daughter's school removing the plug without needed explanation to give it a try). end-rbf640

The photo below shows the end of the enclosure with the network/power connection end removed. This shows the bottom that the components are connected to. You can see the Pi board with the circuit board clips which hold it to the base. Sheet metal screws of the appropriate depth were used with the clips to allow a mount on the 1/4" plywood. The speaker normally occupies the space at the center of the photo. A very short RJ45 male-to-male cable was created to bridge the gap between the Pi and the female-to-female RJ45 which was used as the network connector on the end panel. slide-bottom640

The control box is fastened to the cardboard using the same fender washer and wood screws as the state and legend except they come through from the front side of the board and are covered by stickers and maple leaves. There are three screws, one on the left, one in the middle, and one on the right. The box has a wiring hole that comes out behind the bottom side of the legend. The 6-conductor modular cord and 4-pin JST go through that hole. Here's a clip of our daughter sanding the control box pieces prior to assembly:

One fun detail was to create some sound/ventilation holes in the acrylic slide cover to the enclosure. The AcrylicTop class included in the vermont.jar generates the g-code for the vent holes. Since these were vent hole patterns, the code doesn't actually need to access the strokes for the font characters. The code renders the characters to a small image and then iterates the pixels of the image to determine where the pixels are filled. The location of these are then scaled and translated as desired for the position and location on the cover.

acrylic-cover640

Here's a video of how the sound/ventilation holes were cut in the acrylic:

With the kind of acrylic that we were cutting, the materials tends to melt onto the mill bit. We therefore introduced pauses into the program to allow the bit to be brushed off after each group of holes was drilled. That solved the issue (on our first go around the holes got progressively bigger as the material accumulated on the bit).

Software

The Pi is running the Occidentalis distributionfrom Adafruit (0.2 as of this writing). The project is run from a single Python routine developed using Adafruit's WebIDE. Aside from the Python routine and data files a couple of other changes had to be made to run the code as a service and to perform auto-shutdown. In using the WebIDE, the files for running Vermont reside in /usr/share/adafruit/webide/repositories/my-pi-projects/Vermont on the Pi. Vermont.py is the main program. To run this as a service when the Pi starts up an /etc/init.d/vermont file was added as follows:

#!/bin/sh
# /etc/init.d/vermont
case "$1" in
  start)
    echo "Starting vermont"
    sudo /usr/share/adafruit/webide/repositories/my-pi-projects/Vermont/Vermont.py 2>&1 &
    ;;
  stop)
    echo "Stopping vermont"
    # kill application you want to stop
    LP_PID=`ps auxwww|grep Vermont.py|head -2|awk '{print $2}'`
    kill -9 $LP_PID
    ;;
  *)
    echo "Usage: /etc/init.d/vermont {start|stop}"
    exit 1
    ;;
esac
exit 0

Remember to use "update-rc.d vermont defaults" to register the service to run on boot.Also, if you're using the IDE you may want to do an "/etc/init.d/vermont stop" in the shell to ensure the service isn't also running as you run another from the IDE. Since our code had timed auto-shutdown built in, we had to be careful to set the timeout higher or to not run the code very long during development or it might shut down if we hadn't hit any buttons. For auto-shutdown use we put a shutdown.py script on the Pi as follows:

#!/usr/bin/python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4,GPIO.OUT)
GPIO.output(4,True)

Since our board uses the GPIO #4 line to tell the Pololu switch to kill power, this script will immediately shut off power. But we want a graceful shutdown first, so we modified the halt routine to invoke it when a power down was requested. The halt script is modified to include the shutdown.py call between the "Will now halt" line and the actual halt call:

...
log_action_msg "Will now halt"
/usr/bin/python /home/pi/shutdown.py
halt -d -f $netdown $poweroff $hddown
...

The call to perform an immediate graceful shutdown with power off is then "shutdown -h now". This is what our application does when the user hits the "Off" button.The full listing of the Vermont.py application is included here. In addition, numerous wav files were recorded for use and are located in a subdirectory called "voice" under the main "vermont" directory. Files were recorded/edited/merged with the excellentAudacitytool. Some of the original songs and sounds were in MP3 format. While the Pi can play those fine with MPG321, it was discovered that performance was a bit better if they were converted to WAV format. The MPG321 tool can actually be used to do the conversion on the Pi itself. Then we uniformly used the "aplay" tool to play the WAV files. For the most part, audio is played asynchronously and is intentionally interrupted should another sound need to play. This is accomplished with a call like:

os.system("killall aplay;aplay mysound.wav &")

Basically, this kills any current instances of aplay and backgrounds a new one. A synchronous version would just omit the ampersand and would block until the audio is played. We do that in a few places to simplify the logic.The ability to background thread the audio makes it possible for us to poll buttons and cause LED changes while the audio is playing (an alternative would have been to use interrupts to service buttons). In some places we simplified the audio to be backgrounded by merging clips into a single file (often with "combo" in the name). That avoided need to background a sequence of play operations.The application has 4 modes of operation controlled by the "Mode" button: manual, automatic, quiz, and settings. In manual mode, the up and down arrows and select can be used to highlight elements on the legend and to show where those are on the map. Pressing select plays audio associated with the item. Automatic mode will automatically cycle through the legend. Select will still work but hitting up or down will jump back to manual mode. Quiz mode will quiz users on Vermont facts and they need to use the up and down and select to choose one of the legend items to answer each question. Settings mode allows the auto shutoff time to be change from 5 minutes up to 60 minutes. The default is 5 minutes to conserve power. The state song and bird song buttons can be selected in manual or automatic mode. The "Off" button shuts the project down (giving you a couple chances to bail out before the real shutdown starts). The "On" button is used to power up (but it actually will perform an emergency shutdown if pressed again -- an artifact of the way the Pololu switch module works).The application is highly data driven with a "highlights" list giving the sounds, colors, and associated lights to play together. A "quiz" list gives a list of quiz questions and answers.Structuring the Python so that most customizations can be performed through editing the data makes it more accessible to kids who can create the details themselves (our 2nd grader did, see the video below as she uses the Adafruit WebIDE to enter her custom data). Keeping the rest of the code modular (we could have probably done better) makes it easier for kids to contribute some of the logic (say for the quiz section) without needing to think about all the more complex interactions.

Traditional Poster Work of Captioning and Gluing Elements to the Board

Beyond the electronic elements, the poster had all the traditional aspects of mounting photos and printed materials to the board. We inkjet printed the labels onto either white or transparent full page sticker paper and then cut those up for the legend and product labels. Our daughter also came up with the idea of gluing Maple Leaves onto the poster (due to the Sugar Maple and Maple Syrup in Vermont). This helped to hide a couple of the screw holes on the bottom and where the wires bridge from the legend to the map. Here's a condensed video of some of the elements of pasting/gluing elements to the board:

Looking at the Electronics in More Details

Let's take a look at the layout of components in the enclosure first. On the left is the mounting position for the Pi which directly connects with the network jack on the outside -- which is handy for adjusting the program with the WebIDE. The right speaker also fits there (it'll be the right as you face the front of the board). The external power jack is tucked under the speaker opposite the network jack. You can also see the hole that carries the LED cable and the 6-conductor button cord to just under the legend panel.

box-left640

In the center is the Perma-Proto board which comprised most of the soldering work. We'll look at it's layout below. You can see on the left is the ribbon cable connected to the Pi.

box-center640

On the right side we have the two battery packs. The 5 "D" cells power the Pi and the LED strand. The 3 "AA" cells power the audio amplifier (so as to be isolated from the main supply). On the far right is the left speaker. Altogether it's a pretty tight fit but it nicely keeps the poster stable -- as a counter-weight to the wood and LEDs on the front -- and keeps the center of gravity low.

box-right640

The photo below shows an enlarged view of the Perma-Proto board. Just to the right of the ribbon connector is the level converter. The RF receiver board which sits vertically right above it operates at 5 volts and the level shifter converts the 4 digital outputs of the RF receiver board to the 3.3 volt level for the Pi. The pinouts match pretty well so a 7 pin socket can share the same pins with the level converter (see the second photo of the Perma-Proto with RF receiver, amplifier, and voltage regulator removed).In the center of the board is the Pololu switch module which lets a momentary switch power up the system. It operates directly off the voltage provided by either the external power or the 5 "D" cells. A 5 volt regulator is optionally patched in through a jumper and PCB terminals (green board at the top). The only case you wouldn't use it is if you had a regulated external 5 volt supply. Mainly because it was handy a 5 volt relay (to the right of the power module) is used to trip power on to the audio amplifier through it's separate supply when the main power comes up. This is basically providing isolation so the audio amplifier's potential power spikes don't bring down the Pi. The amplifier itself fits into a socket to the right of the relay at the far right side of the board. Socketing the amplifier makes it easy to remove the speakers and amp as a unit. The amplifier also includes a jumper to control gain. proto-closeup640In the photo, the RF antenna is coiled up. Reception was improved by stretching out the antenna to the full length of the box -- but range was still fairly weak. I'm not sure we'd include the RF receiver if we were to do this again. It would be useful to design a board for the Pi with this combination of features (power, LED strands, amplifier, and possibly RF).

protoboard640

Since the project is already on exhibit at the school, I don't have it handy as I'm writing this. I put together a high-level Fritzing breadboard diagram below to clarify some of the layout. I substituted a Pi Cobbler for what is really a unified Pi Perma-Proto board (but isn't in the Fritzing library yet). It doesn't include all of the modular switch wiring for the buttons. The two PCB screw terminals on the upper left are for the audio channels from the Pi. The other two on top are for the external 5 volt regulator. The two on the bottom left are for the LED ribbon (although the one we used has the 5V next to the GND line hence our screw terminal layout). The next terminal is where the 5 "D" cell pack connects. The next 3 wires are where the external power connects -- when nothing is plugged in, the green wire is connected to ground and enables the 7.5 volt battery. The last two wires are where the amplifier power connects. The diagram also doesn't show the Pololu #750 switch wires which come from the middle of the module (where a switch might normally be mounted). The SPDT relay pinout is such that when the main 5 volt power comes up the relay trips and the 4.5V supply is connected to the amplifier power. The amplifier is elevated from the board on a couple of female headers so it can be easily removed. The RF receiver module docks in the terminal strip shown above the level converter. The last pin of the module is not used and is bent away so as not to contact the board.

Vermont_pp_layout640

Well that concludes one of my longest writeups. I hope I've provided enough detail for those who might want to tackle something similar. Working with our daughter on a complex project like this was a pretty amazing experience -- I still marvel at the variety of work she did in looking back on the videos we took -- but it really is possible if the work is spread over a number of weeks.