Ball-balancing Platform

Using a combination of mechanics, electronics, and programming, BALANCEBOT is capable of autonomously centering a ball on its platform.

Quick project summary:

Step 1: Integrating hardware components

Step 2: Programming hardware drivers

Step 3: Programming user interface and data collection

Step 4: Analyzing system dynamics and controls

Step 5: Programming control loops

Technical skills employed:

Programming: MicroPython, Object-oriented programming, finite state machine design, hardware driver class development

Communication protocols: UART, I2C, SPI, USB

Hardware: STM32NUCLEO-L476RG microcontroller, BNO-055 9DOF IMU, resistive touch panel, E4T optical encoder

System controls: State-space linearization of dynamic model, PI-controller implementation

Analysis: Hand calculations & system modeling, numerical simulation using MATLAB & simulink

Detailed project documentation can be found here: https://milesyoung.bitbucket.io/

Source code for this project can be found here: https://github.com/mileseayoung/Mechatronics_Coursework

As a mechanical engineering undergraduate at Cal Poly, San Luis Obispo, I analyzed, integrated, and programmed this ball-balancing platform as the culminating project for my mechatronics concentration. This was one of the most comprehensive and valuable learning experiences I had at Cal Poly.

I started this project at the beginning of the coronavirus pandemic lockdown, which meant I was in the first class to attempt it. As an upside, this meant the mechanical engineering department had to find a replacement for the outdated programming techniques and old hardware we would have used had we been allowed on campus. Instead, I got the opportunity to learn object-oriented programming in Python using up-to-date microcontrollers, sensors, and motors through an at-home project.

As with most coursework early in the lockdown, my professor had just a few weeks to plan this project. This meant I had limited guidance and had to figure things out for myself, but it also gave me a lot of freedom to experiment and be creative.

To get started, I was given a package with some disassembled components and asked to source the rest myself. Then I built the working platform over the span of two courses, programming each component individually before integrating them into a complete system.

I needed to learn how to integrate electronic and mechanical hardware into a working system to build a functioning platform. I started by experimenting with each of sensor and actuator individually to understand their different characteristics. To learn how motors and encoders are used together, for instance, I studied the theory behind DC motors and created my own circuit to control its speed and direction, and then learned how to read and interpret the raw data from magnetic encoders placed on the motor’s output shaft so that I could accurately measure the angular position, velocity, and acceleration of the motor.

At the same time, I also dove into learning to use the different components and functions of my microcontroller, including the processor, GPIO, analog to digital conversion, internal clocks, and interrupts. I also practiced using different communication protocols like SPI, I2C, and Serial to pass data and commands between my sensors and actuators, microcontroller, and computer.

While learning how to use all of this hardware, I spent a lot of time debugging different parts of the system. I learned from some frustrating experiences how to methodically trace and pinpoint the locations of errors in both the physical circuitry and my programming.

I also put a ton of effort into learning how to program effectively for microcontrollers using Python. This included learning object-oriented coding methodology, along with best practices regarding version control, code documentation, and repository maintenance.

I employed object-oriented programming in a few key ways. I wrote driver classes for each of the main hardware components — the motors, encoders, touch panel, and IMU — along with user-interface scripts to pass commands and data directly between the microcontroller and my computer. Each of these driver classes had a set of functions designed to cooperatively share data while controlling their respective components. I also developed finite state machine classes that cooperatively shared processing resources while running on regular intervals.

Even though the project parameters didn’t allow me to change out any of my hardware, I spent a lot of extra time making sure my programming was as modular, scaleable, and cooperative as possible. I wanted to practice creating code for a real-world design application, in which the flexibility to rearrange or substitute hardware is essential.

After learning how to use the hardware and program the controls for my balancing platform, the last major component of this project was to analyze the dynamics of the platform so that I could implement a closed-loop controller to balance the ball autonomously.

To do this, I first modeled and analyzed the dynamics of the platform by hand. This included defining a list of reasonable assumptions, creating kinetic and free-body diagrams, and deriving a complete set of equations to describe the dynamic motion of the platform.

My hand calculations produced a matrix equation that represented my system’s motion. Unfortunately, this was a coupled, second-order, nonlinear dynamic model. To simulate my system, I had to convert it into an uncoupled, first-order, linear model using a state-space linearization method. Using this simplified model, I created numerical simulations in MATLAB and Simulink to experiment with system responses in both open- and closed-loop configurations ahead of final assembly. Finally, based on these simulations, I determined theoretical gain values for my closed-loop PI controller.

After completing the electronics, programming, and dynamic analysis, I assembled the balancing platform and programmed the closed-loop controller.

Unfortunately, one of my components ended up being unusable. Over the course of the project, I observed issues with the I2C communications between my IMU and microcontroller. I pinpointed the breakout board’s internal pull-up resistors as the culprit and added supplemental 4.5Kohm pull-up resistors, but I still couldn’t get reliable communications. Finally, as the project deadline approached, I removed the IMU from my final assembly because the IMU measurements weren’t needed to create a closed-feedback loop.

However, after programming and extensively tuning my closed-loop controller, I could only infrequently get my platform to balance the ball for more than a few seconds. I determined this was due to the lack of responsiveness of the motors, as well as the limited sensitivity of the resistive touch panel. After tuning, I could at least observe the approximate behavior that I wanted from my closed-loop control, so I’m confident I could have achieved better performance with a slightly more responsive set of motors and a more sensitive touch panel.

Despite a lower level of performance than I wanted in my final system, I still learned a ton about mechatronics design - especially just how much of an impact hardware specifications can have on system performance and how important it is to design in a way that allows for hardware substitutions.

Previous
Previous

Wearable Balancing Aid

Next
Next

Zephyr Kite Steering