Introduction: Big Ball Maze Game
Runner Up in the
Make It Real Challenge
The machine is an over-sized (1200mm (48”) diameter) version of the traditionally hand-held game where the object is to tilt a circular disc to move one or more balls though to the center of a maze. The circular board is supported by a stand with a centrally mounted gimbal, and controlled by either a wired hand-held contoller, an Android phone, or by body movements.
An Arduino microcontroller is used to monitor the player's actions and then adjust the tilt of the board to match. The wired controller uses an accelerometer module. The Android phone controller uses the in-built accelerometer and a custom app made with Processing to communicate via bluetooth with the Arduino. The body controller uses two sonar proximity sensors to detect how far the operator is from a central position to determine how much to tilt the board.
The board is tilted using two gearmotors pulling on strings attached to the underside of the board – one for front and back, and one for left and right. An accelerometer is attached to the underside of the board to provide the position feedback to the Arduino.
Step 1: The Board
Cut the circular board out of a 1200mm x 1200mm (48” x 48”) sheet of 19mm (¾”) plywood using the attached design (disk.eps). The 3.175mm (1/8”) wide circular slots are cut 6.35mm (¼”) deep to locate the acrylic walls of the maze. I made it at TechShop using the ShopBot and the attached Vcarve file (disk.crv). You could do it manually using a hand-held router and a piece of string.
The outer maze wall is 57.15mm (2¼”) wide strips of 3.175mm (1/8”) thick clear acrylic. These are screwed at regular intervals around the edge of the board with wood screws and washers, and positioned so that the lower edge is flush with the underside of the board. The inner maze walls are 44.45mm (1¾”) wide strips of the same acrylic, so that once they are bedded into the 6.35mm (¼”) deep slots, they are the same height as the outer wall.
The inner two rings of walls have to be softened in an oven before they can be bent enough to fit the tighter radii of the slots. This can be a tricky operation. I placed the acrylic strips (one at a time) on a baking sheet and kept the oven at a low temperature and continually checked so that the acrylic didn’t get too soft. Make sure you’re wearing gloves when you get the acrylic out of the oven.
The walls need to be glued into their slots. Even if they are a snug fit, the banging of the ball eventually pops them out.
Step 2: The Stand
I’ve attached the 123D project file I used to design the stand (BigBallMaze.123d)
Cut the main leg pieces out of a 1200mm x 1200mm (48” x 48”) sheet of 19mm (¾”) plywood using the attached design (legs.eps). If you have access to a CNC router, I’ve also attached the Vcarve file (legs.crv). Cut the rectangular pieces out of 6.35mm (¼”) MDF using the attached design (quarterInchBoard.eps, quarterInchBoard.crv).
Assemble each of the four pulley shafts by sliding the pulley onto the (108mm) 4¼” x (7.94mm) 5/16” shaft, and then the 38mm (1½”) long tubing onto each side of the pulley. Add a drop of light oil so the pulley spins nicely.
Assemble the parts according to the pictures.
Step 3: The Shaft and Gimbal
For the shaft, cut a 250mm (10”) length of 1¼” (nominal) PVC pipe.
Drill two holes at about 6mm (¼”) from one end of the shaft, and exactly opposite each other. These holes should be just big enough to let the screws used in the gimbal to spin freely but with minimal play. I used #10-32 x ¾” screws and drilled 3/16” holes. Use a drill press if possible and be as precise as possible in getting these two holes exactly 180° apart and equal distance from the end of the shaft.
As shown in the photos, cut wide slots down from the end of the shaft between the drill holes to allow room for the movement of the nuts on the tilting rings of the gimbal.
For the gimbal inner ring, cut a 12.7mm (1/2”) wide ring from a 1½” (nominal) PVC coupling. For the gimbal outer ring, cut a 19mm (3/4”) wide ring from a 2” (nominal) PVC coupling.
In the inner ring, drill two countersunk holes exactly 180° apart, small enough so the #10 screws can be threaded snugly into the holes. At right angles to these holes, drill two more holes at the same larger diameter used for the holes in the shaft.
In the outer ring, drill two holes exactly 180° apart, small enough so the #10 screws can be threaded snugly into the holes. Countersink these hole on the outside of the ring. At right angles to these holes, drill two more holes at the same larger diameter used for the holes in the shaft. Countersink these holes on the inside of the ring.
Assemble the gimbal on the shaft as shown in the photo, using nylon lock nuts tightened only enough to minimize any lateral play, but still allowing free movement of the rings. Check that the slots in the shaft are big enough so that the nuts in the gimbal don’t come in contact with the shaft.
Remove the rings from the shaft and push them into the hole in the board. Use woods screws to secure the outer ring to the board.
Attach the gimbal to the shaft and test that the board moves freely in all directions.
Step 4: The Motor Housings
Two motors housings are needed. The second image shows the parts needed for each.
The wooden frame pieces are cut from 6.35mm (¼”) MDF using the design attached to Step 2 (quarterInchBoard.eps). The slots need to be 1.6mm (1/16”) deep. Adjust the positioning of the motor mounting holes to match the motors you’re using. If you happen to be using the same motors that I did, and have access to a CNC router, I’ve also attached the Vcarve file in Step 2 (quarterInchBoard.crv).
The skateboard bearings are just a press fit into the wood.
The shafts were cut from 7.9mm (5/16”) steel rod and a flat ground at one end to accommodate the gear hub set screws. Wrap the shaft with grip tape and cut the tape so that it fits perfectly between the bearings. The tape will be enough to stop lateral movement of the shaft. I wrapped a thin piece of wire around each end of the grip tape to stop it pealing away from the shaft.
When mounting the gears to the gear hubs it can take some patience to get them centrally aligned to the hub and shaft. If the gears are slightly out of alignment they will tend to bind slightly during part of their rotation. Keep adjusting the alignment until you get free, even movement throughout the whole rotation.
It’s easier to solder the wires to the motors before assembling the housings.
Once the housings are completed, use some small wood screws to hold the wooden pieces together.
Check that the housings can slide down into the vertical slots in the legs of the stand.
Step 5: Electronics
The drawing shows how I wired up the electronic components. I have attached the Fritzing circuit file BigBallMaze.fzz.
None of the components need to be exactly what I used. Any 2-axis (or 3-axis) accelerometers should be OK. Most Arduino compatible boards will be sufficient. Any rangefinders that can give meaningful readings between about 3 feet and 10 feet should work.
I used a 12V 10Ah SLA battery that lasted a full day of near continuous fairground use, and occasional use over a couple of months since then and it’s still going strong on the first charge. So, you could get away with using a much smaller capacity battery. The battery voltage should be within the Arduino Vin recommended range of 7V to 12V.
I used 6 wire telephone (RJ11) cables and sockets to connect the hand-held controller to the Arduino. I plan to do this for the rangefinder connections too. I used 16AWG speaker wire for the battery and motor connections.
I used a prototyping shield to make all the connections to the Arduino, so the connections are solid and the Arduino itself can be easily removed if necessary.
The gearmotors I used are overkill for this purpose, but work very well since the high torque and speed make the board very responsive. I figured that if I used an 8mm (5/16”) shaft as the drum pulling the string, I would want it to spin at up to 1000 rpm to get a good board tilt speed. I got a motor that spun at 500RPM at 12V, so added 1:2 gearing to get the string drum speed. To get that speed, I figured the motor would need around 1 kg-cm (16 oz-in) torque. The gear motors I used could put out up to 5 kg-cm (84 oz-in). I’ve attached my quick-and-dirty speed/torque/gearing calculator spreadsheet that might be helpful if you want to use different motors (motor_calcs.xls).
Step 6: Arduino Code
The arduino code is attached (ballmaze06.pde).
You will need to make modifications to the code to account for the particular accelerometers, and rangefinders you use.
Below is a list of the variables that will need to be adjusted to suit your system. Explanations of these variables can be found in the comments in the code.
Kp, Ki, Kd – These need to be set for each of the three controllers: hand-held (wired), android, body position. A good explanation of how to tune PID systems can be found here.
Step 7: Android Code
The Android app was created with Processing, and the code is attached (ballmaze02.zip). This is based on the work by Oscar from C.l.r.E for the Bluetooth management, and by Antoine Vianey for the Accelerometer management. You run the Processing sketch on a PC with your Android device connected, and when you select ‘Run on Device’ from the ‘Sketch’ menu it leaves behind a standalone app on the Android device. Then you can run the app on the device like any other app.
In the first screen you choose your Bluetooth module as the device to connect to.
Then you have the option of choosing between the three modes of operation – hand-held wired controller, Android controller, or body position controller.
Step 8: Setup
The machine needs to be positioned on level ground, with all four legs solidly on the ground. I found that if one leg was slightly off the ground, the whole system would go unstable and the board would start shaking.
Test the electricals
It is possible that the wiring of the accelerometers and the motors results in the motors turning in the opposite direction to what they should when the controller is tilted. This is best tested without the strings connecting the motor shafts to the board.
1. Hold the board as close to horizontal as possible, and tilt the controller until the motors stop. If the controller is not horizontal then you should adjust the flat accelerometer values in the Arduino code.
2. Tilt the controller slightly in just the X or Y plane and the corresponding motor should start turning. Tilt the board in the same direction and the motor should slow down and stop when the board is at about the same tilt as the controller. If the motor actually speeds up, then you need to swap the values of the variables tableXmin, tableXmax or tableYmin, tableYmax.
3. Repeat in the other direction
4. With the board and the controller horizontal so the motors aren’t turning, tilt the controller in one direction and watch the spin direction of the shaft that will be pulling the string. If the string was being wound onto the underside of the shaft, would it be pulling the board in the correct direction? If not, reverse the wire connections on either the motor or the motor driver board.
5. Repeat in the other direction
Attach the string
1. Tie a hook to one end of the string.
2. Attach it to the loop on the underside of one edge of the board.
3. Thread it under the pulley and then around the shaft in the motor housing. The string should feed onto the shaft from the underside of the shaft.
4. Wind three loops around the shaft and then out to the pulley at the other side.
5. Hold the board level and position the three loops around the shaft so that they are in the middle of the length of the shaft. This will avoid the string getting jammed at one end of the shaft when the board reaches full tilt.
6. Tilt the board to add tension to end of the string already attached to the board.
7. Pull the string with similar tension at the other end, and attach a hook at a suitable place on the string to keep a solid tension.
8. Attach the second hook to the loop on the underside of the board.
9. Manually tilt the board up and down to check that the tension is enough to move the motor shaft without slipping, but not too tight.
10. Repeat with the other string.
Adjust PID factors
Now, connect the battery and test the responsiveness of the system. The board should follow the movement of the controller with minimal lag or overshoot. To speed up the movement of the board, increase the Kp (proportional) factors in the Arduino code. If Kp is too high, the board will start to oscillate. The increase in speed will result in some overshoot on rapid movements. This can be reduced by increasing the Kd (differential) factors. If Kd is too high, the board will oscillate wildly. You’ll probably need to experiment with Kp and Kd factors for a while to get the optimal performance. The Ki (integral) factors are not needed in this case since they are more for helping to achieve exact absolute positioning. Since the board is always moving, we can ignore these so they are set to zero.
Setup the body controller
The rangefinders should be attached to stands at between 900mm and 1200mm (3 to 4 feet) off the ground. One is positioned on the other side of the board from where the operator will be standing. The other is about 900mm (3 feet) off to one side of the operator, orthogonal to the first.
Press the Mode switch to change to body controller mode, and adjust either the position of the rangefinders, or the distanceXflat, distanceYflat variables in the Arduino code until the board is flat when the operator is standing in a central position.
There are a separate set of PID variables in the Arduino code that will need to be adjusted for optimal performance.
Setup the Android controller
There is another set of PID variables in the Arduino code associated with the movement of the Android controller. These will need to be adjusted for optimal performance.
Step 9: Materials
Arduino microcontroller – Uno or compatible (Sparkfun DEV-11021)
Arduino prototyping shield – (Adafruit #51)
Bluetooth module – Bluetooth Mate Gold (Sparkfun WRL-09358)
Accelerometer modules (2) – 2 axis (or 3 axis) (Sparkfun SEN-00849 and Modern Device MD0500)
Ultrasonic Rangefinders (2) – Maxbotix XL-Maxsonar EZ0 (Sparkfun SEN-09491)
Motor drivers (2) - Dual VNH2SP30 (Pololu #708)
Battery – 12V 10Ah SLA (Universal S3BATT)
Battery charger – 12V 4A 3 stage (Energizer 84028)
RJ11 cables (3) – 6 conductor, 6 foot long (Startech RJ6FT)
RJ11 jacks (6) – 6 conductor (6P6C) (Jameco #124039)
DC power cable – 16AWG speaker wire, 3’ total
Resistor – 560ohm 1/4watt
LED - any old LED
Stripboard – prototyping circuit board
Jumper wire – 22AWG multiple colors
Switch – momentary SPST
Switch – DPDT pushbutton ON-OFF
Gear motors (2) – 12volt, 19:1gear ratio, 500rpm, 5kg-cm (84oz-in) torque (Pololu #1102)
Gears 60 tooth (2) - 32 pitch acetal hub gears (ServoCity #RHA32-36-60)
Gears 30 tooth (2) - 32 pitch acetal hub gears (ServoCity #RHA32-36-30)
Set Screw Hubs (2) – 6mm bore (ServoCity #3472H)
Set Screw Hubs (2) – 5/16” bore (ServoCity #3466H)
Hex key – 3/32” (ServoCity #7122A16)
Hub screws (16) - #5-40 3/8” panhead (ServoCity #90272A126)
Screws – motors (12) – M3 x 10mm panhead (ServoCity #92005A120)
Screws (8) – flat head ½”long brass wood screws
Shafts (2) – 5/16” x 90mm
Bearings (4) – 5/16” ID skateboard bearings
Non-slip tape – 300mm length
Plywood – ¾” x 1220mm (48”) x 1220mm (48”)
Acrylic strips (7) – 1220mm (48”) x 1¾” clear
Acrylic strips (3) - 1220mm (48”) x 2¼” clear
Screws (30) – small ½” long panhead with washers
Screw rings (4)
Plywood – ¾” x 1220mm (48”) x 1220mm (48”)
MDF – ¼” x 610mm (24”) x 410mm (16”)
Shafts (4) – 5/16” x 108mm
Pulleys (4) – 5/16” shaft, 1 15/16” OD (McMaster-Carr #3434T39)
Bushings (8) – 5/16” ID x 38mm (1½”) Aluminium tube
Threaded rod (4) – 5/16”-18 x 150mm (6”)
Lock nuts (8) – 5/16”-18
Washers (8) – 5/16”
Cord – 3mm (1/8”) cord, 3700mm (12’)
Wire hooks (4) – to attach to the ends of the cord
The Shaft and Gimbal
PVC pipe – 1¼” x 10”
PVC coupling – 1½”
PVC coupling – 2”
Screws (4) - #10-32 x ¾” flathead
Lock nuts (4) - #10-32
Screws (2) - #10 x ¾” flathead wood screws
Balls – 57mm diam Bocce Pallinos (Epco)
We have a be nice policy.
Please be positive and constructive.