PiFace GungTank v2.0 documentation!

Documentation for the second PiFace GungTank, as constructed at Susi's over the week of May 13th 2019!

Old documentation for the first version from 2013 is here

Quick start

All you need to know

All you need to know (on a technical level)

Hardware

Components

Instead of using an overhead motor to pull a plug like in the first version, v2 uses a linear actuator underneath the bucket to open and close a slide valve. This makes it much easier to reset and fill compared to the tangle of strings and wires that had to be dealt with before.

This diagram will win absolutely no awards, nevertheless:

The aim here is to have one single assembly that can be kept together and have it as easy to set up as possible, without having to connect and plug in a ton of different things in a strict order.

The main components we used are:

ComponentItem NameSourcePrice
ActuatorTS-LD-50Stroke 50mm 2" Inch Electric Linear Actuator DC 12 Volt 100N High Speed 50mm/s$35
ValveValterra RV Sewer - T1002VPMValterra Bladex Waste Valve Body for RV Holding Tank - Aluminum Handle - 2" Diameter$12
MicrocontrollerElement14 Raspberry Pi/PiFaceThe original PiFace is no longer made, so I'm going to have to relearn all this if we ever replace it$67
5V 2.4A power supplyInsignia NS-AC1U2MBest Buy in the phone charger section$25
12V 5A power supplyGenuine LW-065/500/120/00112V 5A 5 amp 60W DC POWER Supply ADAPTER Transformer$7
BucketIt's a bucketJust a Home depot one$18

Assembly

The mechanism is mounted on a 2'x2' plywood board and is made up of a valve mounted to the bottom of a bucket, with its handle connected to a linear actuator that is set up to be controlled remotely through the Pi. The valve is bolted to the base of the bucket with sealant around the bolts and a rubber seal between the valve and the hole.

The actuator is linked to the valve with a wire tied through the actuator's hole and around the valve's handle. It's fastened to the board through the bottom - we replaced a screw that didn't seem to be doing much with a longer one that could reach through the board to the other side. A 1" pipe bracket holds it in place from the top.

We tried to make a more permanent fastener to link the actuator and valve together and Susi got quite far with a small rod to screw into the handle, but the fiddly bit of metal didn't cooperate in the end. An alternative would be to take the handle off and thread it so that we can attach something there.

Wiring

Because the new version uses a linear actuator instead of a simple motor, it has to be able to both pull the valve out and push it back into place. We're also using a 12V wall adaptor instead of relying on batteries, so no need to worry about fiddling with those. The circuit uses both the Pi's relays which are numbered 0 and 1, wired up like this.

The relay has two modes - when not powered (or turned off), the circuit will flow between C (common) and NC (normally closed). It's important to remember here that "closed" in this context means that it allows electricity through it like an open door or gate would, but let's not dwell on this. When turned on, the relays will instead close the circuit between C and NO (normally open), leaving NC open (by which I mean "closed").

This ingenious arrangement came from Shift Automation. To the best of my understanding, this is approximately what's happening here:

In these diagrams, C is on the bottom of the boxes representing the relays, NO is left and NC is right (same as if you were facing them). When both relays are off, the circuit is incomplete and nothing happens. When just relay 0 is on, the arrangement of the circuit causes electricity to flow through the actuator in one direction, and when just relay 1 is on, it flows the opposite way. (Having both relays on also leaves the circuit incomplete).

The positive (red) wire from the actuator is connected to the common terminal of relay 0 here, and the negative (black) wire is connected to common on relay 1. Most of the automation uses the words "push" and "pull" here with the assumption that they're connected this way around, and that pulling will open the valve. If the valve opens with a push, connect the wires the other way around.

Network

Wifi

Oh dear god don't ask. Getting wifi to work with the D-Link Complete Bastard dongle is by far the most painful experience of this entire process - I tried to set it up for ages and in the end gave up and had wicd-curses do it all for me, so I'm still not sure how it works. The entire wlan0 config in /etc/network/interfaces file is commented out - somehow, the Pi is set up on Susi's home network, with the DHCP for the router set up to assign fixed address 192.168.1.13.

So, to set this up again in the future on a different wireless network, attach a keyboard and monitor (or use the direct connection method below), then start it up and type wicd-curses to enter the wifi setup utility. It stores its settings in /etc/wicd/wireless-settings.conf or thereabouts, but don't touch that.

Direct connection

I've got the direct connection to a place where it sort of works, although I'm not sure how (the intricacies of Linux networking escape me). To use it, you have to connect the pi directly to your PC with an ethernet cable, set your ethernet settings as below (somewhere in Adapter Settings in Windows) so that you're on the same subnet or something, and then access the Pi at address 169.254.0.2. It should be responsive exactly one minute after plugging it in, for reasons described below.

The way this works is ramshackle at best - I couldn't find a way to initialize eth0 properly at startup, so what I've done is to add a line to the crontab to run sudo /gt/networkup.sh on boot. This script will sleep for one minute, then run sudo ifdown eth0 and sudo ifup eth0 to kick it into working. Monumentally stupid as it is, I couldn't find the exact bit of network interface configuration that would just do this at startup in a cleaner way, so that's how it's going to work for now.

Software

Stack diagram

Python

All the scripts from the first version are now deprecated, and have been moved to /gt/v1. Instead of having to execute individual Python scripts to carry out commands, the Pi now just runs just one script on boot that will listen for commands being sent and react to each one. With the service already running, this means that there's no delay while a Python instance starts up - reaction is instantaneous!

The listening script is started by the shell script /gt/runlistener.sh, which is run on startup with a @reboot line in the root's crontab. Switch to root and use crontab -e to see it.

The shell script will initialize the PiFace somehow with some lines about modprobe and setting ownership and I can't remember what they do, then run /gt/listener.py in the background. This is the script that will stay alive and listen - it will flash the LEDs on the Pi in a pattern to acknowledge that it's started up, and then watch for changes to the modified date of file /gt/signal. When this modified date changes, it will check the contents of the file and react according to the string inside.

You can write a command to the signal file and have it picked up by the listening script by using echo "commandhere" > /gt/signal - this is how the endpoints do it.

Commands

These are the strings that you can pass into the signal file to tell it to do something.

CommandEffect
toggle0Toggles relay 0
toggle1Toggles relay 1
toggleToggles both relays (so if currently opening it'll close and vice versa)
openSets relay 0 on and 1 off, making the actuator pull and open the valve.
closeSets relay 1 on and 0 off, making the actuator push and close the valve.
burstSets the valve opening, delays 1 second and then closes it.
stopTurns both relays off, leaving the actuator where it is.
pingTurns LED 7 on and then off again, to check response.
ping2Run the sequence of LED toggles that happens at startup - a more elaborate ping!

HTTP

Endpoint

The Pi is running an apache2 server with PHP to provide HTTP endpoints for interacting with the tank remotely. The www root directory is /var/www - going to the index here by typing the IP of the Pi in your address bar will land you on a leftover test page that prints out bananas.

The really interesting bit is [ipaddress]/gt/sendcommand.php, which is the endpoint to call to send a signal. The script looks at the query parameter c and writes its contents to the signal file described above - therefore, hit the endpoint [ipaddress]/gt/sendcommand.php?c=open to open the valve, or replace "open" with any of the other commands. A safeguard of checking the string against the list of possible choices is provided, to avoid making it possible to execute arbitrary shell commands here and format your hard drive.

Frontend

The index page of /gt has a single button which will open the valve when pressed and close it when released - this calls the relevant commands by firing off AJAX requests to sendcommand.php when the button is touched or clicked. This is the most straightforward way to activate the tank, but the endpoint allows any kind of game to be hooked up to it.

/gt/eyespy.html is a start to the booths game from Eyespy.

/gt/initlistener.php is a script that runs the runlistener.sh shell script in case the listener is no longer listening. I think I just set this up temporarily while I worked out how to get the real listener going on reboot - I haven't ever had to use this.

Tests and notes for improvement

Test 1 on May 16th 2019: Basically a great success! The actuator mechanism allows the valve to be pulled open and pushed closed with no signs of leakage when a full tank of water is used. The only flaw is from water splashing on to the wood (and, more to the point, the electronics) around the centre hole after dropping from the valve. We could try expanding the hole in the wood, but a pipe attached to the bottom of the valve might be even better.

Some notes on things I'd like to do to improve the interface - I'd like to make some games for this on the phone without having to use an external program

Use Websockets - https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API - to keep a connection open between the client and the server

With a monitor connected, the Pi could open a page that consults with the backend to display the current status of the game. At its simplest, display a page that just reacts to the current status of the valve (opening or closing). The page could just listen to the same signal file that we use to transmit the open/close command.

Use a "mode" file to tell the screen what game loop it should be running. Each game loop should check occasionally for this "mode" changing and go back to awaiting a new mode if it changes (clear the screen)