I started thinking about ball juggling machines in the year 2015. I wrote about my first few attempts at creating them in this blog post from the year 2017. In 2018 I wrote another post about my then newest build. We’re now in the year 2020. And finally, the quest to get a machine to juggle a ping pong ball reliably has come to an end (as this current build is able to keep the ball bouncing for hours.)

Components

This machine requires the following things to work:

1x Teensy 4.0 Microcontroller running this code

4x StepperOnline DM442S stepper motor drivers

4x Nema 17 Stepper Motors with 5:1 planetary gearbox

1x 48V 8A power supply

1x e-con Systems See3CAM_CU135 camera

1x Windows Computer with OpenCV installed on it

All the parts defined in this Fusion360 project

This custom Windows Application (made with Unity)

Why A Teensy 4.0?

Because 600 MHz. That’s the clock speed of the Teensy 4.0. Compare that to the 16 MHz you get with most Arduino boards. But why so much emphasis on clock speed anyway? Because we need to generate pulses with a frequency of up to 250 kHz for each of the 4 stepper motors. And since we want the stepper motors to start and stop smoothly, the spacing between the pulses needs to increase/decrease in a sinusoidal pattern. And yes, it doesn’t need to be sinusoidal – you could also go for a sigmoid – but the point is if you want very fast, smooth movements linearly increasing speed-curves probably won’t cut it. And because this is quite a lot of calculations to do on a 16 Mhz microcontroller I went for the Teensy 4.0.

By the way, this microcontroller also comes with a FPU (Floating Point Unit) which both supports 64bit doubles and 32bit floats. As if the crazy 600 MHz clock speed in and itself wasn’t enough, now we also get an FPU!

Do we really need 600 Mhz?

But maybe you’re still not convinced. “Why do we need to generate 250 kHz pulse signals? The motors aren’t really rotating that fast are they? Won’t 10 kHz do it?” Good question. Here’s what I found out while trying to get my steppers to move as fast as possible:

the more microsteps the better

the higher the voltage the better

So more microsteps is better. I set the microstep setting on my drivers to 25600 steps/rev. That’s a lot of pulses for 1 single revolution. And remember that we’re using stepper motors with a 5:1 gearbox attached. So it’s really 128’000 steps per revolution. We’re getting pretty high up in the numbers already and maybe you can see now why 250 kHz isn’t that unreasonable at all.

Here’s an actual image of the first 9 milliseconds of a 150 milliseconds long pulse signal.

You can clearly see how the pulses are getting narrower towards the right side. The frequency is increasing smoothly. Starting slow but picking up speed as the signal progresses. Keep in mind that we’re only able to see the first 9 milliseconds of this signal. The frequency will go way up and then start to decrease again.

What exactly is the microcontroller doing?

The Teensy 4.0’s job in this project is simple.

Listen for movement commands on the serial bus Generate pulses for the stepper motors

The data we’re listening for on the serial bus looks basically like this:



0.11941:0.11941:0.11941:0.11941:0.15000



There are 5 values all separated by colons. The first 4 values are absolute motor positions (in radians) and the last one is the move time. So with this instruction, we are telling the machine to move all it’s motors to the absolute position 0.11941 in 0.15000 seconds.

We’re also able to string multiple movement commands together. The machine will work through the movement commands one at the time in the order the commands came in.

What’s the desktop Application doing?

I told you that I’ve built an Application with Unity for this machine. So why did I do that? What about all that talk about that crazy fast 600 Mhz microcontroller?

The reason I ended up writing this application is that I wanted to do 120 FPS real-time image processing of 640×480 image data. So here’s what the computer application ended up doing:

Setting up the camera (120 FPS 640×480 data stream, gain, exposure, contrast, ISO, saturation) via OpenCV

Execute OpenCVs Hough Transform circle recognition algorithm

Get 3D position of ping pong ball using the results of above-mentioned circle recognition algorithm

Calculate ball velocity

Use ball position and velocity in PID control code to calculate correction-tilt of plate

Execute Inverse Kinematic code to figure out how much each motor needs to rotate in order to get the plate to a certain height with a specific tilt.

Send result of IK calculation to the microcontroller via serial interface

Render machine position and movements

Also render image processing data

How did you make all those aluminium parts?

This machine is made of 150+ aluminium parts. And producing all these parts took A LOT of patience.

I basically ran my Benbox CNC 1310 (almost) nonstop for multiple weeks. “Multiple weeks? You must be kidding.” Well, I’m not. The total machining time for all the parts was about 160 hours.



“Why is your CNC mill so slow?” you might wonder. It’s because the spindle isn’t quite as powerful as I’d like it to be. We’re looking at an 80W spindle here. Updating the spindle is one of the things I’d like to do in the near future.

I made a sound-absorbing box for the CNC mill in order to preserve my sanity.

I used a 1.5mm endmill on 6061 Aluminium with a thickness of 3mm. As you can see in the image above, I fixed my workpiece with 4 screws to ensure that it is both held in place securely and the surface is as plain as possible.

Some pics I took while working on the machine

What follows are some pictures I took while working on this project.

One thing worth mentioning is that I used ball bearings for all the joints. If you look closely at some of the pics above you should be able to see them.