ME135 Final Project

Ball Bouncing Robot
Project Overview
Through this project, we wanted to emulate one of many basketball techniques while challenging ourselves in mechanical design, software programming, and user interface design. We integrated all our previous ball balancing/bouncing along with our real-time sensor sampling and multitasking LabVIEW communication. We also programmed such that the ESP32 communicates via COM port, the motors and the camera.

At the end of the project, we successfully prototyped a bouncing robot with real-time ball position tracking and motor calibration to continue bouncing the robot.
My Contributions
I contributed on the design of the GUI, programming, and component design for our robot assembly.

Graphic User Interface (GUI)
I designed and implemented the LabVIEW front panel to function as an operator console—connection controls (address/port + status LED), start/stop, and feature toggles (balance via servos, vertical motion via steppers). I also built the real-time visualizations and indicators (platform height scatterplot/waveform, ball XY tracking, bounce count, and displacement/trajectory error metrics) so we could diagnose performance live and tune the system quickly.

Mechanical Design
I contributed to the mechanical integration of the dribbling robot by translating system requirements into physical interfaces: mounting/packaging for the vertical platform actuation (stepper + belt/pulley travel) and the balance actuation (servos), plus sensor placement to support closed-loop operation. I also helped define and enforce mechanical constraints in the design (e.g., travel limits to prevent platform buckling or overrun) so the software could safely regulate motion based on real-time height feedback.

Programming
I developed the ESP32 application architecture around FreeRTOS, including a high-priority real-time timer task for ultrasonic sampling (~9 ms) running in parallel with a lower-priority TCP server task that streams data to the GUI, with GPIO toggling for oscilloscope-based timing verification. I implemented the data-path from sensors/vision into control—UART parsing/command handling (e.g., gating acquisition on “Acquisition started”), plus the PID struct/setpoint/update flow that converts ball position error into PWM commands for the servo-based balancing loop.

Graphic User Interface (GUI)

Figure 1 and 2. Default GUI and Running GUI

Figure 3. Full Communication State Machine and Front Event Panel Structure

The communication state machine manages the ESP32–LabVIEW link by initializing dedicated Send/Receive queues, validating incoming packet strings, and then stepping through states that handle connection, data transfer, and error pathways (e.g., failed parses or dropped messages) in a controlled, repeatable sequence. In parallel, the front panel event structure is the GUI’s dispatcher: it listens for user interactions and timed “clock” events, and it executes routine indicator/health actions (such as toggling an LED) to both drive the interface logic and confirm the communication loop remains active.

Multi-Tasking (Programming)

Figure 4 and 5. Main Code and Oscilloscope Capture to indicate Multi-Tasking and Real-Time

The left image is a screenshot of the ESP32 main application code (e.g., app_main) where the real-time ultrasonic sampling is implemented as a high-priority timer task (running on a ~9 ms period) alongside a lower-priority tcp_server_task that packages and streams sensor data to LabVIEW, illustrating the software structure used to achieve multitasking. The right image is an oscilloscope photo capturing two GPIO “debug” traces—one toggled by the longer tcp_server_task (GPIO 27) and one toggled by the periodic trigger_sensor timer task (GPIO 12)—so the timing and concurrency are verified physically: the constant-period real-time pulses appear in parallel with the longer communication task activity.

PID Implementation

These two images capture the closed-loop PID control path implemented on the ESP32: the top screenshot shows the runtime task reading ball position data over UART (uart_read_bytes), parsing/extracting posx and posy, then conditionally running the controller only when the measurements are valid (within bounds). It computes two control efforts via PID_Update (one for X, one for Y), maps those outputs into PWM compare values, and writes them directly to the ESP-IDF MCPWM comparators to drive the servo balancing outputs; if the ball is not detected (e.g., posx == 0 && posy == 0), it falls back to a safe/default command. The bottom screenshot shows the underlying PID module (pid.c), where PID_Init sets gains and initializes state, and PID_Update performs the standard discrete PID computation (error, Δt, integral accumulation, derivative term) and returns a control output used by the top-level task.

ME135 Final Project Video