Using a PID Controller
Servo control is just one area where microcontrollers shine. In this article, see how these two Cornell students designed and built a ball-balancing platform based on PIC32 MCU, using a resistive touchscreen and servo motors attached to a gimbal mount. A PID control algorithm is used to balance the ball.
While it may seem a simple task, balancing on one foot is no small feat. It requires a constant cycle of observation and adjustment. Getting an electronic device to perform a similar task in just a few weeks is not easy and takes quite a bit of tuning—just as it takes us time to learn to balance as children.
In this article, we present a ball-balancing platform that uses a touchscreen and a Microchip PIC32 microcontroller (MCU) to keep a steel ball bearing stable on its surface. A proportional, integral, derivative (PID) control algorithm and two servos are used. This project was designed to inspire interest in control theory and its applications, and to motivate deeper thought about the physics at play in this system. Our end result is shown in Figure 1.
A ball rolling on a perfectly flat plate is technically metastable, since, if there are no forces applied, the ball will remain static. Of course, this assumption is terrible, and a real ball sitting on a real plate is going to fall off unless we do something about it. A ball rolling on a tilted platform roughly follows a linear relation between angle of the platform and acceleration along the surface (Figure 2). The no-slip condition makes this linearizing assumption possible, because we essentially assume that each rolling direction is totally independent.
In this analysis, m represents the mass of the ball, I is the moment of inertia of a rotating sphere, and a is the acceleration of the ball parallel to the surface. At small angles, sin (θ)≈θ, so we show a linear relation at the end between angle and acceleration. We tilted the platform over a range of about ±15 degrees, or about ±0.3 radians, which gives a maximum error of approximately 1.5% due to the small angle approximation.
Given a relatively heavy, 1″ steel ball, we knew we needed servos that could hold their position with the mass of the ball (0.07kg) at the servo arm’s maximum distance from the pivot (8cm). This meant we needed servos that have about 0.56 kg-cm torque, which translates to around 8oz-in. The servos we chose had a 4.8V stall torque of 9.4kg-cm or over 125oz-in. Although we planned to run on 5V power and thought we might be underestimating the maximum torque on the motor, this was plenty strong. The main trade-off is between strength and precision of the motors. As it turns out, our servos were extremely strong for this task, causing a precision issue in the tuning stage.
The main pieces of the platform were the base plate, pedestal, top plate, servo and pivot hinges, and the servo mounting brackets. By securing the servos to the base plate, we hoped that the structure was rigid enough to handle rapid movement. When starting this project, the biggest decision to make was to first choose a resistive touchscreen. The dimensions of that piece of hardware largely determine the rest of the design, and it is the most unique item on the supply list. Our project used a medium-sized, rectangular, 7″ diagonal resistive touchscreen overlay from Adafruit , and we cut our top plate to match its dimensions (165mm × 105mm).
From here it makes sense to do a bit of math to answer the following questions: How far off the table does the plate need to be to accommodate two servos and the table’s full range of motion? How powerful does each servo have to be to accelerate the ball when it is moving quickly toward the edge? A good estimate can go a long way—even if it means the design is tweaked at the end.
The resistive touchscreen sits on an acrylic plate, which is mounted to a base using a partially 3D-printed Cardan joint (Figure 3). This allows the plate to pivot around its hinge in two directions independently. Each direction is controlled by a servo motor, which is attached to the underside of the plate with a ball socket connection.
We used 1/8″ acrylic for all pieces, and attached them with acrylic cement. In our implementation, the platform had an approximately 32-degree range of motion in the short direction, and 36 degrees in the long direction. Placing the pivot mechanism at the center of the plate, while easy to build, did not allow for rotations outside of this range. This mechanism has the only 3D-printed part: a cross-shaped connector that joins the top plate and pedestal.
We first laser cut the acrylic and glued together all the supports, noting the order of operations for attaching the pivot mechanism. The pedestal and cross piece were assembled first, and the servo joint attachment points (shown in red in Figure 3) were glued to the top plate separately. Then the center supports were attached to the top plate, while simultaneously joining them to the cross piece. The ball joint attachments to the servo motors were then easy to attach to the top plate and were snapped onto the servos mounted to the bottom plate at their minimum or maximum extent. To do this, we first zeroed the servos and then set the angle of the platform to our desired zero angle.
The success of this project was heavily dependent on the care with which the mechanical integration was performed. Tightly fitting each joint to the servo motors, and making sure the pivot point didn’t wobble, both yielded better performance in the final design.
The main electrical components include a Microchip PIC32 MCU , two servo motors, the resistive touchscreen and a serial connection to a separate computer monitor for the tuning step (see the schematic in Figure 4).
The touchscreen generates a voltage proportional to the X (long dimension) and Y (short dimension) position of an input touch. Using Adafruit’s touchscreen control chip to receive data proved time consuming, but there were several options for making the job easier. The touchscreen uses four pins to set the voltage of strips of conductive material that line the outer perimeter of the screen.
By holding a 5V potential across the screen in one direction, the voltage read by one of the perpendicular pins makes the screen essentially a potentiometer. The value read by that pin changes based on where you press on the screen. The fourth pin is left to float, since it must be used for the other direction’s touch. By performing this process for one direction and then the other, the position of a point of pressure on the screen is located .
The servo control used a standard pulse-width-modulated (PWM) signal. The Tower Pro MG995 took a 50Hz pulse with an on time between 1ms and 2.5ms. The serial connection to a computer and monitor was purely a convenience for tuning parameters. This is highly recommended to make tuning less time consuming.
By watching the acceleration of the ball at maximum tilt, we estimated that we needed at least a 1kHz sampling rate for an accurate reading of the ball’s position. Because we can only measure the ball’s position in one direction at a time, this means that each direction must be sampled at that 1kHz frequency. We then update the servo position as fast as possible.
The program structure runs on two threads and one interrupt service routine (ISR), with a few other helper functions. The meat of the functionality is in the ISR, which runs at 2kHz and toggles between reading the X and Y positions. After each read, the PWM signal to the corresponding servo is also set. The two scheduled threads are for writing output to a screen or exchanging serial information with our command structure. Both of them can be implemented in many different ways, depending on what is convenient. We used code and explanations from Bruce Land’s MCU design class  to use Adam Dunkels’ Protothreads library  for the high-level design of our code structure.
main() function sets up the analog-to-digital converter (ADC) ports, output compare units (for generating PWM signals), and sets up our first read from the touchscreen, before jumping into the infinite cycle of writing to/reading from the screen and the serial port. The ISR then handles cycling through the actual control loop.
Two helper functions called
readYprep() set the ports that control the touchscreen to their appropriate values for a read in one direction versus another. Following the touchscreen specifications, one pin must be set to logic high, one to low and one is set as an input, so that its value “floats” and does not affect the reading. The fourth pin is then read by an ADC on the PIC32.
The PID controller is a feedback loop that tries to minimize the error between the input and a desired input. The “proportional” term applies a correction that is linearly related to the error. The “derivative” term is essentially a damping term and serves to slow down the signal when it is moving too quickly. This means that oscillations around the zero-error point caused by the proportional term will be smoothed out over time. The “integral” term simply corrects for steady-state error. We did not need an integral term, since the system was never settled enough to measure a steady-state error for which to correct.
During one control cycle, the ISR first reads the position of a touch, shifts by an offset value we determined to be at the “edge” of our screen’s sensitive area, and then scales to convert to a position in units of 0.1mm. This step allowed us to check that the positions were being read correctly. The error is calculated by subtracting the read position from our pre-set desired position, and is low-pass filtered to make these position reads less jittery. We used an exponential filter to low pass the output, and found that even after heavy filtering, the error did not lag enough to matter, because the ball did not move fast enough to make it inaccurate (Figure 5).
This filtering was done to desensitize the system, given our very coarse servo positioning (discussed in the Results section) and slow update speed. The servo signal was running at 50Hz, but the update in the ISR took place at 2kHz. Because of that, the position data needed to be slowed down so that the servos updated with the most recent accurate data over the last update period.
To calculate the derivative term, we stored five values of the error—the four previous values of the error, and the current error. Of the different ways to calculate the derivative, we opted for subtracting the most recent error from the oldest, multiplying by derivative gain and adding that to the output signal.
After uploading this version of the program, dragging a finger across the screen causes a reaction in the motors, which should not go outside the ranges set. If this is not the case, fixing the safety parameters before putting the ball on the platform is a good idea. Watching your delicate device—or more harrowingly, HEARING your device break itself due to an overzealous servo—is not a required step and should be avoided.
Tuning the parameters takes a while, so once you get to this step go ahead and settle in. We achieved some starting values for each direction independently by attaching a thin railing to the platform, which constrained the ball to a single direction of linear motion. The derivative coefficient and the proportional coefficient, along with a parameter that changes the strength of the low-pass filter on our error calculations, was performed through a serial connection to a PC. After getting the X direction tuned to a reasonable level, we tuned Y, and then combined them by removing the railing constraints.
Our video demonstrating the device in action is show below. With our best tuning on our best run, we were able to balance the ball for about 44 seconds. In about 24 seconds, each servo performed around 46 direction changes, matching the observed orbit around the setpoint. Visually, it was balancing better than a human could if constrained to a pivot point.
During those runs where stability was not ideal, a few issues could account for the lack of steadiness:
• Minor looseness in the joints could couple the X and Y directions of motion, throwing off the algorithm.
• The servos map to rotations, and don’t linearly map to the angle of the platform, especially at high angles.
• The Y-dimension of the board was about 2/3 as large as the X-dimension, and therefore had a harder time stabilizing the ball.
• The servos would only react to a change in PWM on time of around 0.06ms to 0.08ms. Since servos like ours have unpredictable behavior outside the range of about 1ms to 2.5ms of on time, this means we effectively had about 25 or so positions over 180 degrees. This was further clamped to about 10 distinct positions with which the PID algorithm could work. Buying precise servos that can react to smaller changes in PWM signal would make this platform much more effective.
This project was fun to make, impressed our peers, and taught us a lot. It has an exciting amount of movement, involves interesting dynamics, and has great potential for improvement. While the PID control setup was adequate for getting the results we expected, the dynamics of a ball on a plate has been explored in more detail by similar groups of students employing more complex control algorithms .
 Adafruit. “Resistive Touchscreen Overlay – 7″ diag. 165mm x 105mm – 4 Wire.”https://www.adafruit.com/product/1676
 Microchip PIC32MX1XX/2XX Family datasheet.
 HantouchUSA. “How it works: 4-Wire Analog-Resistive Touch Screens.”
 Land, Bruce. Cornell University ECE4760 Development Boards: PIC32MX250F128B.
 Land, Bruce. ECE 4760: Designing with Microcontrollers. Cornell University School of Electrical and Computer Engineering.
 Dunkels, Adam. Protothreads. http://dunkels.com/adam/pt
 Andrews, Greg, Chris Colasuonno, and Aaron Herrmann. “Ball on Plate Balancing System”ECSE-4962 Control Systems Design Final Project Report, April 28, 2004, Rensselaer Polytechnic Institute.http://cats-fs.rpi.edu/~wenj/ECSE4962S04/final/team2finalreport.pdf?q
Kaiser, GH and SO Feibel. “ACA: AEP’s Can Do Anything. A Two-Degree-of-Freedom Ball Balancing PID Controller.”
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • OCTOBER 2020 #363 – Get a PDF of the issueSponsor this Article
Gregory Kaiser is a graduate student pursuing a M.Eng. in Electrical and Computer Engineering at Cornell University. Email: email@example.com
Samuel Feibel is a graduate student pursuing a M.Eng. in Mechanical and Aerospace Engineering at Cornell University. Email: firstname.lastname@example.org