2014/04/14

Command and Control I

The Design Journey

Having decided what we wanted to do in Gethsemane, the next questions were practical. How was this array of technology going to be controlled? Who was going to be available to work it? Where was it all going to be put?

The latter two factors fairly rapidly ruled out several options. The control and sound equipment (other than the loudspeakers) had to go in the bottom of a fitted wardrobe at the back of the room. This, together with volunteer availability, ruled out a full-time human operator. The volunteers available to run the trail (6 classes spread across 3 week days, plus an additional Sunday run) were not theatre or computer technology experts – perfectly happy using their computers and phones for email, but not going to be happy with a copy of MagicQ. So conventional computer control was not a good idea either. What was needed was something much simpler – one button to start things happening, and an emergency stop if needed. This would let one of the helpers press start at the right moment, and not require a dedicated lighting / sound operator.
Sound and Light control equipment in the cupboard
Given this, how? Designed-for-purpose lighting control equipment is a niche market, with correspondingly high prices (even on ebay!). But DMX-512 is ultimately just an RS-485 serial bitstream. How hard could it be to produce this, along with sound playback? Connecting up physical buttons for control of computers has been a rather expensive and difficult business, but the Raspberry Pi single board computer has changed all that – easily accessible pins for connecting buttons and lights to, and lots of help for writing the programs to link it all together. Better still, the Raspberry Pi has a built-in serial port, so we wouldn't even need a USB adaptor to connect the DMX output up!

So the “plan” took shape. All that was left now was to design and build the various bits of hardware and software needed to make it all work. As usual, some things went easily, and others took more work, but in the end it all worked – as seen in the previous Blog post.

Push Button Control

This was actually the second area to be tackled, but it was much simpler so I will describe it first. It is also probably more widely re-usable! The design ended up with two sets of controls and indicators: one set to switch the Raspberry Pi on and off safely (it is still a computer underneath!) and a second one to control the lightning and sound playback. Switching on is easy – because the Pi switches on and boots up a soon as power is applied to the board. So the only control needed was a way to tell it to shut down, and then indicate to the operator that it was safe to turn it off at the mains. The latter is important, because we did not have a monitor or screen, so there was no direct way to tell if the Pi was still running or not.

Power Button
This was relatively easy to solve however, with an LED (and resistor) connected from one of the GPIO pins to ground. These pins default to being inputs when the Pi starts up, so the LED is off. When the Pi is shut down, they go back to being inputs, so the LED is also switched off then. So all our program has to do is make sure that the LED is switched on when the Pi has started up and is ready for action. As we don't need to switch the Pi on with it's power button, our program just needs to start when the Pi is ready and watch the power button. When the button is pressed, it tells the Pi to shut down, and exists. There is no need to go back to watching the power button, because the system is about to shut down!
Lift the lid and press to shut down
The power button I used was a reset switch salvaged from a piece of scrap equipment, hence the transparent hinged cover to prevent it being accidentally pressed (useful!). It was too awkward to cut the large square hole required for the switch in the (temporary) case, which is why it is fixed to the outside of the box (it only has 3.3v across it, so safety is not an issue). The ready LED was fitted through a hole in the case and fixed with some hot glue on the inside. This main box lived in the cupboard with the other equipment, because it only needed switching on at the start of the day and off at the end.
Playback control unit

The rest of the controls (for playback) were fitted to an smaller box, which was hung on the wall in the room (where the helpers could find it) and connected by a length of 4-core cable back to the main Pi controller unit. This box was also made from the available bits, hence the extra holes in the front panel. To make it more user friendly it was re-painted with a left over can of car touch up paint, then rub-down dry transfer lettering (“Letraset”) used for the labels (my packet is not genuine, it came from a clear out, and was originally from RS). The shiny ring round the “Running” LED is simply a washer used because the hole is too big for the LED otherwise! Once the lettering was on and before the components are fitted, a coat of clear spray lacquer (again for car touch-up) stops it rubbing off. The result looks quite retro, but is serviceable.

The Circuit

The circuit diagram shows the connections for both the power control and the remote playback controls. The DIN connector linking the two was chosen simply because I had plenty of them around, and they don't fit anything else, so cross-connection was unlikely!
Circuit diagram for control buttons (pdf | svg)

 
The component values are in the table below:

Part Value
R1, R2, R3, R5 1 kΩ ¼ W
R4 100 Ω ¼ W
R6 10 kΩ ¼ W
D1 5mm Yellow LED “Ready”
D2 5mm Green LED “Running”
S1 Momentary push switch “Shutdown”
S2 Momentary push switch “Start”
S3 Momentary push switch “Stop”
T1 BC184L transistor
C1, C2, C3 100nF ceramic capacitors

The GPIO pins used are summarised in the table below. They are chosen to avoid using any pins which might be wanted for peripherals in the future (UART, I2C and so on) and to stick to the ones which didn't change between the original model B and subsequent versions of the Raspberry Pi (because I have one of each!).
Broadcom GPIO Header Pin Function
GPIO 23 16 Shutdown Button (pulled low)
GPIO 24 18 Start Button (pulled low)
GPIO 25 22 Stop Button (pulled low)
GPIO 4 7 Play LED
GPIO 22 15 Ready LED

Basic Pi


I'm assuming you can get your Raspberry Pi powered up and running without help from me – there are lots of much better guides out there on the web.

I used the standard Raspbian distribution for the Raspberry Pi because it was the easiest route to get things working. This had pretty much everything I needed, and it was easy to install the extras: WiringPi (following Gordon's instructions) and mplayer (with apt-get). I plugged in a WiFi dongle to connect the Pi to my home network and then logged in that way, but you could equally use a screen and keyboard, or a wired network connection.

Programming the Buttons

With the hardware design in place (or at least on solder-less breadboard!) we need some software to make it work. The path of least effort seemed to be to adopt the gpio program from Gordon Henderson's WiringPi project, and write some simple shell scripts to go with it, as I don't really do Python and C is far too much like hard work for such simple tasks.

The resulting scripts are on my Github. They are all intended to be put into /home/pi/. Just doing this won't make anything work, because they aren't running. As each of the scripts waits for a single button to be pressed, they all need to be started when the Pi boots up, and stay running in the background until you press a button. Because they use the “Wait for Interrupt” mode to wait for the button to be pressed, they very very little resources (unlike many of the examples, which keep checking (“polling”) the button, which can make everything else on the Pi go sluggish – which we can't afford).

To start the scripts when the Pi starts up, we add some lines to the /etc/rc.local script. This is a script which is included in the standard Raspbian distribution specifically for end users to customise with commands that they want to run when the system starts. Note they run before anyone is logged in to the system, which is good for what we are doing, but means there will not necessarily be anyone around to see what they do. If something here doesn't run correctly, there isn't an easy way to stop it running next time you start you Pi, so you might have to do some complex tricks to get your Pi back. Be careful!

First off, we want to run our shutdown.sh script, and we need to do it as the root user, so it has the permissions to be able to shut down the Pi (so we don't need to use sudo). This is easy, because the rc.local script is run as root. Any commands added to this script must complete before the system is considered ready, so we have to put our shutdown.sh script in the background, where it can keep running. So we add a line to /etc/rc.local like this:

/home/pi/shutdown.sh &

The & character is important – it makes the script run in the background, like we need it to.

The other scripts, for playing and stopping, need to run as the pi user (the default login), so we need to switch user before running them, so their lines go:
su pi -c '/home/pi/stop.sh' &
su pi -c '/home/pi/play.sh' &
The su command switches user (to the pi user) before executing the specified command. Again, the & makes them run in the background.

The other file is buttonsets.sh. This is important because it contains the settings (like which GPIO has which button connected to it) and file names (what sound file should we be playing) which all the scripts need to know about. This file needs to be put at /home/pi/buttonsets.sh so that the other scripts can find it.

Anything you are likely to need to change, should be in here, so you only have to edit one file to customise your Pi controller. The thing you are most likely to need to change is the soundtrack file, which needs to be the name of a sound file stored on your Pi so that it can be played back. You can ignore the rest for the moment.

Try it out

Hopefully you have already got mplayer to play some sound back, and set up some way to hear it (like some speakers plugged in to the audio out jack on your Pi). With this done, shut down your Pi, turn it off, and switch it back on again. After 30 seconds or so (which will seem like much longer!) it should have started back up, and you will see D1, the yellow “Ready” LED, flashing. Why is it flashing? Because some of the files listed in the buttonsets.sh file are not available on your controller, and the lighting control won't work. We will deal with that in a little while.

The sound should be ready to go (assuming you loaded a sound file and put it's name in the right place), so press the “Start” button. The green “Running” LED will come on, and you should hear the sound playing! You can let it play to the end (when the “Running” light will go out), or you can press “Stop”, which will cut the sound off, and put the “Running” light out straight away. Once playback has stopped, you can start it again, but you can't start playback more than once at the same time – the scripts have a lock to make sure that doesn't happen by accident.

The next post will look at how the DMX-512 lighting control was achieved.

No comments:

Post a Comment