Gesture Controlled Radio

Our goal was to make an kitchen Internet radio player where we could change the volume and stations without touching the player. For this project we used:

  • Raspberry Pi 3 (or 2 with a Wifi dongle)
  • Pimoroni SkyWriter (~$20US)
  • USB powered portable speaker

The Pimoroni SkyWriter supports both gesture and touch control.


To install the Pimoroni SkyWriter python libraries:

curl -sS | bash

For the internet music interface we used the mpd , Music Player Daemon, it can be installed by:

sudo apt-get install mpd mpc

The SkyWriter can be wrapped in plastic wrap and the gestures can still be picked up. For a more robust project it would probably be best to design a more waterproof enclosure.

Python Code

A few years ago we found that the mpc calls were bullet-proof, but when we did this project we found that the mpd service would often lock up  if a new internet radio station was selected (mpc next). For this reason we used external calls to adjust the volume and we restarted the mpd service when we changed radio stations

We used a gesture of up/down to adjust the volume, and a left/right to change the station.


Below is our final code:

#!/usr/bin/env python
import skywriter
import signal
import os

thevolume = 70 #starting volume
thestation = 1 #starting station

# Some internet radio stations
stations = (('','1.FM Amsterdam Trance Radio'),
            ('','Raggae Roots'),
            ('','Comedy 104'),

def setvolume(voldif):
  global thevolume
  if (thevolume + voldif >= 0) and (thevolume + voldif 0) and (direction + thestation <= len(stations))):
    thestation = thestation + direction
    os.system('mpc clear')
    os.system('sudo service mpd restart')
    os.system('mpc add ' + stations[thestation][0] )
    os.system('mpc play')
    print thestation, stations[thestation][0], stations[thestation][1]

def flick(start,finish):
  print('Got a flick!', start, finish)
  if (finish == 'north'):
  if (finish == 'south'):
  if (finish == 'west'):
  if (finish == 'east'):

# start playing the radio at defaults

signal.pause() # wait for a new gesture

Pi Node-Red Streetcar

For our streetcar design we wanted to :

  • manually control things with a Web interface on a smart phone, and
  • automatically have the streetcar stop at station, wait, then go in the reverse direction.

For this project we built everything in Lego, with Lego Mindstorm components. The programming was done in Node-Red which was running on a Raspberry Pi.

The Lego Mindstorms EV3 and NXT components can be wired into your Pi (or Arduino) projects by using some custom adapters. If you are brave you could cut one end off of the connector cables. We unfortunately didn’t have any extra cables so went the safe route with the adapters. There are a couple of different adapters that are available we used the breadboard version from Dexter Industries.

Using the following parts we were able to make an automated streetcar :

  • 1 Lego Mindstorms motor
  • 1 Lego Mindstorms touch sensors
  • 3 Lego Mindstorms connector cables
  • 3 Dexter Lego Mindstorms bread board adapter
  • 1 small breadboard
  • 1 Pi 3 (or Pi 2 with a network connection)
  • 1 Pimoroni ExplorerPro Hat
  • 2 long pieces of wire
  • lots of Lego blocks

Streetcar Design

Our goal for the streetcar project was to have two stations, then have the streetcar automatically stop and switch directions at each station.


Station 1 had the motor, a touch sensor, and the Raspberry Pi.


Station 2 had a pulley wheel, a touch sensor and a small breadboard that wired back to the Pi at station 1. Our pulley string went above the streetcar. We needed to keep the string quite tight so the pulley would not slip.


The Wiring

All of the Lego Mindstorms wiring used the same pins on the left side of the connector. and they are labeled “ANG” and “GND”. We used an ExplorerHat Pro to connect the Lego Mindstorms Motor and touch sensors to the Raspberry Pi. As we mentioned earlier the station 2 touch sensor was wired into a small breadboard and then from there two wires connected it to the ExplorerPro. For our setup station 1 touch sensor was wired on Explorer Pro input 1, and station 2 was on input 2.


Node-Red Installation

To check that Node-Red is installed and working, go to a Terminal window and enter:

node-red-start &

If you are able to run Node-Red, the next step is to install the Pimoroni ExplorerHat node and a web dashboard node. Depending on your installation you might need to load the Node Package Manager, npm :

sudo apt-get update
sudo apt-get install npm

Then to install the added libraries:

\curl -sS | bash
 cd ~/.node-red
 npm install node-red-contrib-explorerhat
 npm install node-red-dashboard

After you install these library nodes you will need to restart your Pi. Once Node-RED restarts, you use a web browser to build applications. If you are working directly on your Pi, enter in the URL address box of your browser.

Node-Red Manual Web Control

To make a web based manual control program, drag three button nodes from the left node panel onto the center panel. Then wire the button nodes to an ExplorerHat output node.


Double click on a button node to open an edit window. The edit window allows you to configure the dashboard, labels and button actions. To control the first ExplorerHat motor the topic is The payload is between -100 and 100, and this corresponds to full reverse and full forward, with 0 being stopped.

After you have finished all your Node-Red configure click the Deploy button at the top right of your browser window. Deploying will run your program and enable the web dashboards. To access the web dashboards enter: http://your-ip-address:1880/ui. If you are unsure of your IP address go to a terminal window and enter : ifconfig.


Node-Red Automatic Control Program

We found the automatic control logic to be a little tricker than the manual logic. Our first step was to see if we could read the Lego Mindstorms touch sensors. For this we connected an ExplorerHAT input node to a debug node. We manually pushed each touch sensor and we used the debug tab to check the results.


To catch when the streetcar hits the touch sensor at station 1 we needed to create a function that looked at the topic explorerhat/input.1. If this topic’s playload is 1 or pushed then the ExplorerHat motor can be stopped by sending a message with the topic of and the payload=0. A similar function is created for the touch sensor at station 2 except the topic explorerhat/input.2 is monitored.


After the streetcar hits a touch sensor we wanted it to pause, and then move in the opposite direction. A delay node was used for the pause. Following this a function node is used to send a message with a payload of the new speed and direction. For our project station 1 restarted with a speed of -70, and station 2 restarted with a speed of 70 (or +70).


Our complete logic with both manual and automatic control is shown below:


Remote Controlled Rocket Launcher

We’ve made a number of different versions of the mobile rocket launcher, and all of them have been fun. The version above is using the a PI 1 with a PiFace Digital module for the motor controls and a wireless keyboard for the controls.

The version shown below is using a PI 3, with an ExploreHAT Pro for the motor controls and a Python Web Server program for the controls. By using some simplified HTML tagging we were able to use an old PSP as a remote interface console.


Rocket Launcher Sample Code

We found the rocket launcher in a sale bin, but they call be purchased at: The rocket launcher comes with it’s own Windows based program.

Below is some Python code that will control the rockets launchers turret and fire a missile. Based on this sample code you should be able to make some cool projects. A couple of notes from our testing:

  • you need to manually stop the turret motion once you start it. So you need to set your own wait time
  • you need 3-4 seconds between each missile firing. It might be a coincident but we damaged our first rocket launcher trying to issue fast firing commands.
 import usb
import sys
import time

device = usb.core.find(idVendor=0x2123, idProduct=0x1010)

# On Linux we need to detach usb HID first
# except Exception, e:
except Exception:

pass # already unregistered


endpoint = device[0][(0,0)][0]

down = 1 # down
up = 2 # up
left = 4 # rotate left
right = 8 # rotate right
fire = 16 # fire
stop = 32 # stop

#device.ctrl_transfer(0x21, 0x09, 0x0200, 0, [signal])

while True:

print('r = right, l = left, u = up, d = down, f = fire ')
key = raw_input ('enter key:')
if (key == 'l'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, left, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'u'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, up, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'r'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, right, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'd'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, down, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'f'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, fire, 0x00,0x00,0x00,0x00,0x00,0x00])
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, stop, 0x00,0x00,0x00,0x00,0x00,0x00]) 




Arduino FM Radio

There are a few FM receiver modules that are available. We used an FM module that is based on the RDA5807M chip and unlike some of the other chips this one supports volume control. To keep our project compact we used the Arduino Nano, but we tested the UNO and Mega and they both worked well.


There are a lot of options on how to control your FM radio. We liked the idea of using an old TV remote because this allowed us to change the volume and radio stations anywhere in the room. For this project we used:

• an I2C FM receiver module ($13)
• any Arduino module that has SDA and SCL pins
• an IR receiver ($5)
• a small bread board and some jumpers

The FM receiver module works on the I2C bus that connects to the SDA and SCL pins. Depending on which IR chip you use the wiring will vary slight. The key thing is to connect the data pin correctly. For our example we used pin 11.


FM Module

When we first starting working this project there was no Arduino FM library available, so we started to by talking directly with the I2C bus. However now an Arduino FM library is available.

The RDA5807M chip [3] on the FM receiver module has a number of register addresses that we needed to write to. The key ones were:

  • REGISTER 2 – Initialize the chip (0xC003)
  • REGISTER 2 – Enable radio communications (0xC00D)
  • REGISTER 3 – Set the frequency
  • REGISTER 5 – Set the volume

We needed to pause between initializing and enabling radio communications. Setting the radio frequency is done by offsetting the frequency from the minimum range (870) and then splitting the value into high and low bytes.

The volume on register 5 is adjusted between a value of 0, the lowest, and 15 or 0xF the highest. There are other options on register 5 so our code changed the value from 0x84D0 to 0x84DF.

The Arduino modules uses the wire.h library to read and write to I2C devices. To write to a register the important commands are:

  • Wire.beginTransmission
  • Wire.write
  • Wire.endTransmission

An example using these commands would be:

//This is an example of setting the volume to 1
//This sets up communications to a device
Wire.beginTransmission(0x11); // 0x11 is the RDA5807M chip
Wire.write(0x05); // address 0x05 is where you want to write to
Wire.write(0x84); // write 0x84 to the first byte of address 0x05
Wire.write(0xD1); // write 0xD1 to the second byte of address 0x05
Wire.endTransmission(); // finish the write

We made a simple radio test program (Listing 1) that set up the radio to a local frequency at volume 1.

#include <Wire.h>

int freq;
int freqB;
byte freqH, freqL;

void setup()

// Initialize the RDA5807M chip

Wire.beginTransmission(0x11); // Device address is 0x11
Wire.write(0x02); // Register address 0x02
Wire.write(0xC0); Wire.write(0x03); // Initialize the settings
Wire.endTransmission(); // stop condition
delay(500); // wait 500ms

Wire.beginTransmission(0x11); // Device address is 0x11
Wire.write(0x02); // Register address 0x02
Wire.write(0xC0); Wire.write(0x0D); // Setup the radio for communications

// Define an FM station to listen to

freq = 1079; // 107.9 MHz our local FM station
freqB = freq - 870; // chip needs to have freq offset from lowest freq (870)
freqH = freqB>>2; // you need to break the offset freq into 2 parts (hi/low)
freqL = (freqB&3)<<6; // Shift channel selection for matching register 0x03

Wire.write(freqH); // write High freq byte
Wire.write(freqL + 0x10); // write Low freq byte

// The volume is from 0-F and its the first bytes, leave all the bytes (0x84D0 - 0x84DF)

Wire.write(0x84); Wire.write(0xD1); // set volume to 1

void loop()


Finding TV Remote Codes

We used a small program to find the IR (Infrared) codes from our TV remote. For our program we used the volume up, volume down, channel up and channel down keys. Different TV remotes will have different codes so you will have to find the codes that work with your remote.



RIGHT = 3.3 volts

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
irrecv.enableIRIn(); // Start the receiver
Serial.println("Setup Complete");

void loop()
if (irrecv.decode(&results))
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value



When our IR test program was running we used the Arduino monitor window to show us the different key codes. We manually recorded these codes and used them in our final project.

Using a TV Remote

Our goal was to use a TV remote to change the FM station and to adjust the volume. There are a lot of websites you can use to find nearby radio stations. A good website for this is:

Our final program  used a number of predefined FM stations that would change with channel up and channel down on the TV remote. The remote’s volume up and down would change the radio’s volume. Remember to change the IR codes to match your TV remote, and the FM stations for your area.

// RDA5807M Radio controlled with a TV Remote
#include <Wire.h>
#include <IRremote.h>

int RECV_PIN = 11; //Connect the IR data pin in 11
IRrecv irrecv(RECV_PIN);
decode_results results;

int volume = 0; // start with the volume low
int channellist[]= {999,1029,1021,1079}; // Define some radio stations
int maxc = 4; // Define the number of radio stations used
int channel = 2; // Start with a favorite station

void setup()


irrecv.enableIRIn(); // Start the receiver


void loop() {
if (irrecv.decode(&results)) {

switch (results.value) {
case 0xE0E0E01F:
Serial.println("vol up");
if (volume < 15) {
case 0xE0E0D02F:
Serial.println("vol down");
if (volume > 0) {
case 0xE0E048B7:
Serial.println("chan up");
if (channel < maxc) {
case 0xE0E008F7:
Serial.println("chan down");
if (channel > 0) {
Serial.println(results.value, HEX);
irrecv.resume(); // Receive the next value
void setvolume(int thevolume)
byte volbyte;

volbyte = thevolume + 0xD0;
Wire.write(0x84); Wire.write(volbyte);
void setfreq(int thefreq)
int freqB;
byte freqH, freqL;

freqB = thefreq - 870;
freqH = freqB >> 2;
freqL = (freqB & 3) <<6;

Wire.write(freqH); // write frequency into bits 15:6, set tune bit
Wire.write(freqL + 0x10);
void radio_init()
Wire.beginTransmission(0x11); // Device address 0x11 (random access)
Wire.write(0x02); // Register address 0x02
Wire.write(0xC0); Wire.write(0x03); // Initialize the settings
delay(500); // wait 500ms to finalize setup

Wire.beginTransmission(0x11); // Device address 0x11 (random access)
Wire.write(0xC0); Wire.write(0x0D); // Setup radio settings
delay(500); // wait 500ms to finalize settings

Packaging our Project

We wanted to make our radio project portable, so we came up with two ideas. The first idea was to put all the electronics into a plastic container. For this we used a soap dish ($1) that we drilled three holes in. The first two holes were for the power and speaker cords. The last hole was for the IR receiver. To power our project we used a solar charger ($10), so we could listen to music outside.


Our second idea was to place the electronics inside the pocket of a cooler bag. It is important to have the IR receiver poking out of the pocket.


There are also some fun projects where you could use LCD Keyboard Shields or Touchscreens.




Arduino Sailboat

To build the sailboat we used

  • Arduino Uno [1]
  • Prototype shield with bread board ($5)
  • Wireless RF module and remote ($6)
  • Small servo ($6)
  • 6x AA batteries with case and plug
  • K’Nex building pieces
  • 4 plastic bottles
  • 1 small plastic container with a lid
  • String, Duct tape, and a garbage bag (white if you have it)

The boat construction used the 4 bottles for flotation and a K’Nex frame.


Mounting the rudder will probably require some trial and error, our design used some Lego pieces, duct tape and wire to hold it in place.


For the electronics we had some good success with a wireless RF (Radio Frequency) module. The wireless RF modules are relatively low cost ($6), and they do not require any fancy programming. remote1


The final Arduino code is :

// sailboat1.ino - use a wireless RF motor to move a servo on a sailboat
// RF buttons:
// A = straight (90deg), B = turn left (10deg), C = turn right (10deg)
// Limit rudder turning from 60-120 degrees
#include <Servo.h> 
Servo myservo; 
int pos;

void setup() {
 pinMode(5, INPUT); // A button - D0 pin on RF module
 pinMode(6, INPUT); // B button - D1 pin on RF module 
 pinMode(7, INPUT); // C button - D2 pin on RF module 
 pinMode(8, INPUT); // D button - D3 pin on RF module 

void loop(){

if (digitalRead(5) == HIGH) { 
 Serial.println("Button A");
 pos = pos + 10;
 if (pos > 120) { pos = 120;} 
 if (digitalRead(6) == HIGH) { 
 Serial.println("Button B"); 
 pos = 90;
 if (digitalRead(7) == HIGH) { 
 Serial.println("Button C");
 pos = pos - 10;
 if (pos < 60) { pos = 60;} 
 if (digitalRead(8) == HIGH) { 
 Serial.println("Button D"); 


Android Controlled Robot Arm

Create a mobile robot arm that you can control from an Android smart phone.

We found a used robot arm (OWI-535) on Kijiji, but you could buy a new one for $30-$60.  We then mounted it on an Arduino car chassis ($20) with some duct tape. Luckily the OW-535 robot arm has all its wiring exposed and it comes with a good wiring document.


For this project we used:

  • 1- OWI-535 robot arm
  • 1- Car chassis ($17)
  • 1- Four motor Arduino shield ($10)
  • 1- Two motor Arduino shield ($10)
  • 1- JY-MCU Bluetooth module ($7)
  • 1- Arduino Mega
  • Duct tape, jumpers and 4 alligator clips
  • 1- Small USB charger
  • 1- Small Box (to house all the components)



The biggest challenge is to control the 5 robot motors and 2 wheel motors. For this we used an Arduino Mega and 2 motors shields. Depending on the motor shields that you use you probably won’t be able stack the motor shields. We stacked one motor shield and we had the second motor shield floating.


Some of the key wiring connections were:

  • Mega Pin 44 -> Floating Motor Shield pin 4
  • Mega Pin 45 -> Floating Motor Shield pin 5
  • Mega Pin 46 ->Floating Motor Shield pin 6
  • Mega Pin 47 -> Floating Motor Shield pin 7
  • Mega Pin 5V -> Floating Motor Shield pin 5V and VIN
  • Mega Pin 19 RX1 -> Bluetooth module TX
  • Mega Pin 18 TX1 -> Bluetooth module RX

To power this project we found that a portable USB charger was enough. If however you find that a USB charger does not deliver enough power the OWI-535 robot arm has a built in power pack with exposed power connections.

The motor terminals on the car chassis are a little fragile, so rather than soldering wires we used alligator clips. We also duct taped the wires under the car chassis to keep them secure.

The Arduino wiring was pretty ugly so we stuffed all the loose components into a small box. The box was duct taped to the back of the robot arm, and 2 cuts were made to feed the wires through.



For the Arduino code you’ll need to add the appropriate motor libraries. For our motor shields  we used the Adafruit V1 motor shield (

Because the first motor shield blocked the RX0/TX0 pins, we used RX1 and TX1 on pins 19 and 18. For the Bluetooth communications it meant the Serial1 was used in the Anduino code instead of Serial.

For our commands we used:

  • 0 = Hand open (motor 1 forward)
  • 1 = Hand closed (motor 1 backward)
  • 2 = Wrist down (motor 2 forward)
  • 3 = Wrist up (motor 2 backward)
  • 4 = Elbow down (motor 3 forward)
  • 5 = Elbow up (motor 3 backward)
  • 6 = Shoulder up (motor 4 forward)
  • 7 = Shoulder down (motor 4 backward)
  • g = Go forward (pins: 44/46=HIGH, 45/47=255)
  • s = Stop (pins: 44/46=HIGH, 45/47 =0)
  • r = Right turn (pins: 44/46=HIGH, 45=0, 47 =255)
  • l = Left turn (pins: 44/46=HIGH, 45=255, 47 =0)
  • b = Go backward (pins 44/46= LOW, pins 45/47 =255)
  • o = Light ON, (pin 50 = HIGH)
  • f = Light OFF, (pin 50 = LOW)

Our final Arduino code is:

// Bluetooth control of a mobile robot arm

char inByte;
// Define remapped pins for 'floating' motor shield
int E1 = 45; 
int M1 = 44; 
int E2 = 46; 
int M2 = 47; 
int LIGHTpin = 50;

// DC motor on M1
AF_DCMotor motor1(1); // hand
AF_DCMotor motor2(2); // wrist
AF_DCMotor motor3(3); // elbow
AF_DCMotor motor4(4); // shoulder

void setup() {
 pinMode(M1, OUTPUT); 
 pinMode(M2, OUTPUT);

pinMode( 19, INPUT_PULLUP ); // For better Bluetooth stability
 Serial1.println("Robot Commands");
 Serial1.println("Enter: 0-7 for robot arm, g/s/l/r/b for wheels ");

void loop() {
 if (Serial1.available() > 0) {

// read the incoming byte:
 inByte =;
 if (inByte == '0') { runmotor(motor1,FORWARD); }
 if (inByte == '1') { runmotor(motor1,BACKWARD); }
 if (inByte == '2') { runmotor(motor2,FORWARD); }
 if (inByte == '3') { runmotor(motor2,BACKWARD); }
 if (inByte == '4') { runmotor(motor3,FORWARD); }
 if (inByte == '5') { runmotor(motor3,BACKWARD); }
 if (inByte == '6') { runmotor(motor4,FORWARD); }
 if (inByte == '7') { runmotor(motor4,BACKWARD); }
 if (inByte == 'g') { runwheels(HIGH,HIGH,255,255); } 
 if (inByte == 's') { runwheels(HIGH,HIGH,0,0); } 
 if (inByte == 'r') { runwheels(HIGH,HIGH,0,255); } 
 if (inByte == 'l') { runwheels(HIGH,HIGH,255,0); } 
 if (inByte == 'b') { runwheels(LOW,LOW,255,255); } 
 if (inByte == 'o') { digitalWrite(LIGHTpin, HIGH); }
 if (inByte == 'f') { digitalWrite(LIGHTpin, LOW); } 
void runwheels (int M1dir,int M2dir,int E1speed, int E2speed) {
 // For control of wheels direction and speed
 digitalWrite(M1, M1dir); 
 digitalWrite(M2, M2dir); 
 analogWrite(E1, E1speed);
 analogWrite(E2, E2speed); 
void runmotor(AF_DCMotor themotor, int direction) {
 // Robot Arm motor control

Android App

MIT’s App Inventor is free and it’s a great way to quickly make Android apps:

For this app we used:

  • 1 TableArrangement
  • 1 Listpicker
  • 15 Buttons
  • 7 Labels
  • 1 BluetoothClient (non-visible)


A TableArrangement component with 3 columns and 11 rows is used to position all of the buttons and labels. After a component is positioned into the table, select the component and then use the Properties window to change its text, color, or sizing. The Components window is used to rename the component.

In the Blocks screen, blocks are dragged from the left Blocks section to the main viewer section. The following key blocks were used:

  • when Screen1.Initialize. This is called when the app is opened and it will show a list of all the phone’s paired Bluetooth device. This list is generated by connecting the blocks: BluetoothClient1.AddressesAndNames to set ListPicker1.Elements
  • when ListPicker1.BeforePicking. This block is called after the JY-MCU Bluetooth module (typically HC-06) is selected. Inside this block ListPicker1.Selection is an input to the Call BluetoothClient1.Connect block.
  • when .Click. This block is called when a “command” button is clicked. This block will send the required Bluetooth text command, so for example “g” is sent to go forward, and “s” is sent to stop.


The full AppInventor code is:


Once all the logic is created, you can download the app (APK file) or use a QR quick code to put it on your phone.


The final step is to power up your Arduino project. When you do this the JY-MCU Bluetooth module will start to blink. This is telling you the module is ready to pair with your phone. On your phone’s SETUP->BLUETOOTH SETTINGS scan for new devices and you should see the JY-MCU Bluetooth module (it’ll probably be called HC-06). The pairing code is: 1234.

Now you are ready to open your new Android app. A dialog will ask you which device to connect to. Select your HC-06 device.


For this point on you will be able to control the robot with your phone.


littleBits Motor Boat

To create the wireless remote for the a motor boat we needed to control the left and right motors , for this we used the following components:

  •  1- littleBits mounting plate (comes with base set)
  • 1 – littleBits fork module ($12)
  • 2 – littleBits dimmer($8) or slide switches ($10)
  • 1 – littleBits wireless transmitter
  • 1-  littleBits power module with battery ($6)

We connected the power module to a fork module and then the fork module powered our dimmer modules. We mounted all the components on a littleBits mounting plate, and we taped the battery to the back.

To build the boat we used 2 empty water bottles for flotation. We built a frame with K’Nex (and a little duct tape). The motors we held in place by feeding the motor shafts through a K’Nex support and then we used elastic bands to secure the motors to the frame.

The basic circuit for that boat is shown below. To keep things dry we put all the boat’s littleBits components into a Tupperware container.