This is a PID controlled ball on a plate machine with the sole goal of keeping the ping pong ball bouncing for as long as possible. I have been trying to build ball bouncing machines for a while now. This is the newest iteration!

How does it work?

The location of the ball is calculated from the time difference when the ball’s noise is hitting the mics. This time difference is calculated for each mic pair separately (one pair for each axis on the 2-dimensional plate). The noise from the ball hitting the plate is a very loud one; It was surprisingly easy to distinguish it from other sounds. You can talk casually nearby the machine and it won’t be affected.

There is a small analogue circuit to process the signals from the mics. Each mic sets a flip-flop (a thing to store either a “1” or a “0”, digitally speaking) if it’s amplitude surpasses an adjustable voltage level. An Arduino Nano is watching all the flip-flops and resets them after they all got set (the blue LEDs in the video show the current flip-flop states). The Arduino checks the states as fast as possible, this allows for a reasonable accuracy. As soon as, for instance, the left mic on the x-Axis registers a load noise and sets the flip-flop the Arduino will start counting the cycles (literally cycles of a the mic-check-loop in code) until the opposing mic registers the load noise as well. After both of the mics registered a sound, the cycle count might be at 183 (the range goes from -200 to 200. 0 is when both mics register the noise simultaneously). This is used as position data. The same cycle counting is going on for the other mic pair, thus we are able to extract 2-dimensional data about where on the plate the ball hit.

The gathered position data is then sent to another Arduino (via serial) that uses this data to tilt the plate in such a way that the ball will – hopefully – not fall down. The plate tilting business is done by using the results of 2 separate PID controllers. One for each axis.

The PID Controller

I am using these three things to control the tilt on each axis (the plates x- and y-axis):

How far away is the ball from the center? Correct in such a way that the ball will go towards the center proportional to the distance measured from the center.

Where is the ball moving? Correct in such a way, that the movement can be stopped. The amount of correction is proportional to the measured distance the ball was moving in the last 2 data points.

Does the ball show a tendency to stay in a certain spot on the table? Add a little correction proportional to the distance from the center to get rid of such tendencies (this should get the table centered over time). And this value will compound over time.

Those 3 things essentially are all the parts of a PID controller (the P-part, the I-part and the D-part). All of these 3 things are done for the x-axis and the y-axes separately. The PID code is in here.

One of the struggles with the PID is that I am not able to apply the calculated correction tilt the same time the ball hits the plate. Because when the ball hits the plate I finally know where it is NOW, and in which direction it is moving. So this data has to be used on the next bounce. Applying the correction is 1 bounce delayed. I think I could get better results if it wasn’t for this delay. But with this setup the delay is inevitable.

Another problem, of course, is that the data is so scarce. The ball might move in 3 bounces from one end of the table to the other. Considering that the tilt correction is delayed by 1 bounce there are only 2 bounces to get the ball to stop.

The ball might also gain a bit of spin. This is also hard to handle.

Air moves in every which way. That ping pong ball is moving through the air above a 30cm/30cm plate which is moving up and down constantly! Even in a room without any wind, the table alone creates quite some air flows.

The Pulse Generation

It’s worth mentioning that I didn’t use a library to generate the pulses for the stepper drivers. I programmed an algorithm to produce pulses which result in a sin-like acceleration followed by an immediate sin-like deacceleration of the stepper. There are many great Arduino stepper libraries out there. The only problem was that the ones I found all accelerate linearly and take their sweet time whenever a change in direction occurs. Time is precious. This machine has to go up, stop, and almost instantly start going down again. It makes sense to use a linear acceleration for CNC applications of course, but this PID controlled ball on plate machine needed a smoother, faster pulse-generating-algorithm.

Code

Here’s the Github repo with all the code for this project:

github.com/T-Kuhn/Stepper-Juggler

Fotos



Did you like this PID controlled Bouncing Ball on Plate machine? Click here for more.