In previous posts I detailed how to:
- Build a Lego marble pump
- Use C# and Pulse Width Modulation to control motors with the Raspberry Pi
- Use C# and OpenCV with the Raspberry Pi Camera Module
Each one of those projects are pretty interesting in their own right but what would be really cool is to combine them all together. So I did. Check it out – I recommend full screen.
The marble pump, motor control and basics of getting OpenCV to run on the Pi are covered in those prior posts. Here I will discuss details particular to this build. Source code for the project is available on GitHub.
Initially, the marble race was built with studs face down. The bottom of Lego plates aren’t perfectly smooth, but flat enough to allow a marble to run down them without having to find flat tile pieces for the whole length of the race. Upside down plates with their uneven bottom would also slow the ball speed down to give the Raspberry Pi more time to detect and react to a red coloured ball.
This inverted plate technique worked well on the first marble race where the balls didn’t have to turn corners but when 90 degree turns were added, the balls would tend to get stuck as they didn’t have enough energy to bounce around and find their way down the next chute.
For the final section before the sweeper arm a (rare!) underside tile was placed in the landing spot to give the marble just enough of a starting boost to make it through the gate and onto the conveyor belt. Without that tile the marbles would land and often stop.
The chimney exit used a pair of inverted 2 x 8 plates. This was a deliberate improvement from a single 4×8 plate becase the seam between the two plates keeps the marble elevated off the uneven underside and velocity up for the first turn.
The long run down toward the final two corners was changed to stud-on-top with tiles, as without the speed boost of the flat tiles, the marbles weren’t making it through the next turn. I could have increased the gradient but that would mean making a taller chimney and more force required to pump balls up the chimney. The 9V Technic motor driving the pump is from a Mindstorms Robotics Invention set, some 10 years old and the step down gear box that drives the axle is 20+ years old so I didn’t want to over strain it.
The conveyor belt stage is built with the tracks from the old mindstorms set. The only trick to this section was mounting mini 2×1 wedges at the end of the belt to help guide the ball into a narrower range to drop from.
A chain link drives the belt with a 1:1 ratio from the gearbox output. I wouldn’t have minded stepping it down for more torque but was a bit short on chain link.
The circuit for controlling the servo is a PCA9685 PWM LED controller connected to the Raspberry Pi via I2C as detailed in this post. A 12V power pack is fed through a UBEC (a switch mode DC-DC regulator often used in model aircraft) to supply 5V to the servo PWM chip and the DC Motor that drives the marble pump and conveyor. The DC motor in this project is not under the control of the Pi and is wired direct to the power supply.
Servo Lego Interface
The Ping Pong Thrower used a large servo that was easily capable of snapping a Lego beam in half if it was commanded to move beyond the limits of the Lego it was attached to. This time I downsized for the more nimble HXT900. The ping pong project used some tie wire to bind the servo to the Lego beam, this time I dremelled out an old (set 8035!) Technic plate and trimmed down the HXT900 horn to fit inside it.
The software for the project is written in C# and runs under Mono on the Raspberry Pi. The main controller (view source) is quite simple to understand, capturing frames from the camera, looking for red in the image and if detected, moving the servo arm to the required position until the red disappears. An interesting thing I had to implement was a debounce as the red ball would appear but then temporarily disappear as it hit the corner of the race and failed to meet minimum detection area. This resulted in the sweeper arm oscillating rapidly as it cycled from detected, not detected and detected again and some balls were getting batted out race. A six-and-out example can be seen at 3:31, of the video.
The keen observer will see I bound the Z, X, C keys to flicking the servo to various positions. It is a fun game to send the undetected green balls down the race and use the keys to try and bat them on to the floor.
For more detail: Raspberry Pi / Lego Ball Machine