Welcome to MSPM0G3519 Development Board repository
2. Vehicle-mounted Balance Ball Motion Control System
MSPM0G3519 Competition Car Tutorial - Ball Control + Eight-Channel Line Tracking Comprehensive
MSPM0G3519 Competition Car Tutorial - Ball Control + Eight-Channel Line Tracking Comprehensive1. Hardware Platform2. Software Environment3. Structure Description3.1 Component List and Material Preparation3.2 Physical Appearance3.3 Assembly Instructions4. Brief Principles4.1 Wiring Pins4.2 Physical Wiring Diagram4.3 Control Principle5. Project File Structure6. Core Parameter Configuration6.1 Servo Ball Control PID (app_k230.c)6.2 Line Tracking PID (app_irtracking.c)6.3 Task Line Tracking Speeds (questions.c)6.4 Task Timeout Settings (questions.c)7. Task Description7.1 State Machine Structure (questions.h)7.2 Task Detailed Description8. Key Code Analysis8.1 K230 Ball Control — K230_Servo_Control() (app_k230.c)8.2 Line Tracking — LineWalking() (app_irtracking.c)8.3 Line Tracking + Ball Control Combined — LineWalking_WithBall() (app_irtracking.c)8.4 Task 2 Ball Reciprocation (questions.c)9. Operation Flow
1. Hardware Platform
| Component | Model/Description |
|---|---|
| Main Control | MSPM0G3519 Development Board |
| Camera | K230 AI Vision Module (YOLOv8 Ball Detection) |
| Line Tracking | Eight-Channel Red Tracking Module (I2C 0x12) |
| Display | OLED 128×32 (I2C) |
| Servo | 9G Servo (Ball Tilt Control) |
| Motor | Two-Wheel L-Type 520 Encoder Motors (Serial Driver Board) |
| Button | Expansion Board K1 Single Button Control |
2. Software Environment
IDE: Keil MDK V5 (ARM Compiler V6.7)
SDK: TI MSPM0 SDK 2.02.00.05
3. Structure Description
3.1 Component List and Material Preparation
Chassis Part: Black metal etched baseplate, drive motors, wheels. The chassis has reserved screw holes and wire routing holes.
Robotic Arm Structure: Blue/black metal servo bracket, metal connecting rods, metal L-type/linear connectors, servo, metal flange.
Horizontal Ruler Slide: Transparent acrylic shell, handwritten digital ruler and zero reference line, internal transmission guide/screw rod.
Top Vision Bracket: Brushed metal long strip (aluminum alloy/stainless steel), transparent acrylic L-bracket, K230 module.
Hardware Accessories: M2/M3 combination screws, nuts, washers, black cable ties, heat shrink tubing.
Note: In addition to the v2 chassis kit accessories, 9g servo, K230 and tracking module can be purchased from our store. Other connecting rods, rulers, water pipes, and those connecting hardware accessories need to be obtained by yourself.
3.2 Physical Appearance







3.3 Assembly Instructions
Step 1: Install Mobile Chassis and Motors
Fix the two drive motors (with wheels) on both sides of the black metal baseplate respectively. Ensure the wheels face the same direction and have full contact with the ground.
Install the main control board MSPM0G3519, using screws to fix it at the reserved position on the chassis. Note that the main control board should avoid the wheel and motor rotation space.
Step 2: Build Horizontal Ruler and Translation Slide
Reference Figure 5: Assemble the transparent acrylic shell and embed the scaled paper board inside. This structure is fixed at the front of the chassis.
Note that the guide or screw rod inside the slide needs to remain horizontal, which is the key reference for subsequent robotic arm coordinate calibration.
Step 3: Assemble Robotic Arm Joints
Reference Figures 3, 7: Insert the green servo into the black metal bracket and lock it with matching screws.
Install the servo arm and connect the blue/black metal connecting rods.
Reference Figure 7 to build the end effector (connector/claw part). In the image, this part uses more transparent acrylic and hot glue/resin for reinforcement. In actual assembly, it is recommended to use 3D printed parts or metal parts instead to ensure sufficient structural strength.
Fix the servo base at the rear of the chassis (refer to the layout position in Figure 7).
Step 4: Install Vertical Metal Bracket
Reference Figures 1, 4, 6: Take the brushed metal long strip and vertically install it into the fixed slot at the center or front side of the chassis.
When using screws to fix, ensure the metal strip is perpendicular to the chassis plane and does not wobble. The nuts in Figure 6 are locked through from the back.
Step 5: Install Top Vision Sensor
Reference Figure 35: Install the K230 module with the back facing outward. Use transparent acrylic L-bracket and M3 screws to fix the module at the top of the vertical metal bracket.
Note to adjust the sensor orientation to ensure it can see the track and ruler ahead.
4. Brief Principles
4.1 Wiring Pins
Four-Channel Motor Driver Board:
| Motor Driver Board | MSPM0G3519 |
|---|---|
| RX2 | PB6 |
| TX2 | PB7 |
| GND | GND |
| 5V | 5V |
Motor Wiring:
| Motor | Driver Board |
|---|---|
| M2 | M- |
| V | 3V3 |
| A | H1B |
| B | H1A |
| G | GND |
| M1 | M+ |
Eight-Channel Line Tracking Module:
| Line Tracking Module | MSPM0G3519 |
|---|---|
| 5V | 5V |
| SCL | PA15 |
| SDA | PA16 |
| GND | GND |
OLED:
| OLED | MSPM0G3519 |
|---|---|
| VCC | 5V |
| GND | GND |
| SDA | PA28 |
| SCL | PA31 |
K230 Camera:
| K230 | MSPM0G3519 |
|---|---|
| 5V | 5V |
| GND | GND |
| TXD | PA3 |
| RXD | PA2 |
4.2 Physical Wiring Diagram
.png)
4.3 Control Principle
Car Line Tracking Control Process:
.png)
Eight-channel infrared sensor reads black line position -> Calculate deviation value
PID controller calculates turn correction -> Control motor differential steering
K230 camera detects ball position -> Servo PID controls rod angle
Timer timeout or waypoint detection -> Stop/switch state
PID Control Parameter Description:
| PID Parameter | Function | Adjustment Direction |
|---|---|---|
| P (Proportional) | Determines response speed, large output when deviation is large | Too large: Oscillating serpentine; Too small: Weak turning |
| I (Integral) | Eliminates steady-state deviation, cumulative error correction | Too large: Overshoot; Too small: Cannot return from one side |
| D (Derivative) | Suppresses oscillation, early deceleration | Too large: Jitter; Too small: Cannot brake |
5. Project File Structure
Competition_PJ/├── main.c # Main program: peripheral initialization, main loop, state machine distribution├── APP/│ ├── app_k230.c/h # K230 serial protocol + PID servo ball control (core)│ ├── app_pid.c/h # PID controller (positional + incremental)│ ├── app_kalman.c/h # One-dimensional Kalman filter│ └── app_servo.c/h # Servo PWM drive├── BSP/│ ├── Eight_Tracking/│ │ └── app_irtracking.c/h # Eight-channel line tracking + tracking PID + combined tasks (tracking+ball control)│ ├── Motor/│ │ ├── app_motor.c/h # Car motion control (Motion_Car_Control)│ │ └── app_motor_usart.c/h# Motor driver board serial protocol│ ├── OLED/│ │ ├── oled.c/h # OLED driver + display function OLED_time()│ │ └── oledfont.h # Font data│ ├── Key/│ │ └── key.c/h # Button driver + mode selection state machine│ ├── Questions/│ │ └── questions.c/h # Competition task state machine (Task 1~5)│ ├── Task/│ │ └── task.c/h # Timer task scheduler (Scheduler_Run)│ ├── Timer/│ │ └── timer.c/h # 1ms system clock Get_Time()│ └── usart.c/h # Serial initialization (UART0 debug, UART1 motor, UART3 K230)└── ti_msp_dl_config.c/h # TI driver library configuration (SysConfig generated)
6. Core Parameter Configuration
6.1 Servo Ball Control PID (app_k230.c)
x
// Proportional coefficient: response force, large = aggressive push// Integral coefficient: eliminate steady-state offset// Derivative coefficient: main damping, suppress oscillation
// K230 image center X pixel// Left boundary pixel// Right boundary pixel// Camera field of view width (cm)// Water pipe half length (cm), full length 25cm
// Deadband (px), error <3px no action// Single frame CC change limit, prevent servo sudden turn// Kalman process noise (large = fast response)// Kalman measurement noise (large = smooth)Bidirectional px_per_cm compensation (camera not perfectly centered):
xxxxxxxxxxTarget >= 0 (right side): px_per_cm = (599-360)/12.5 = 19.12Target < 0 (left side): px_per_cm = (360-99)/12.5 = 20.88
PID Tuning Guide:
| Phenomenon | Adjust What | Direction | Description |
|---|---|---|---|
| Ball wobbles back and forth near center | ↑ KD | Increase damping | Larger KD brakes earlier |
| Ball stops before reaching target | ↑ KP | Increase push | Larger KP pushes farther |
| Ball overshoots target far | ↓ KP | Decrease push | |
| Ball stays to one side after stabilizing | ↑ KI | Strengthen integral | Larger integral returns to center faster |
| Servo jitters when ball is still | ↑ DEADBAND | Loosen deadband |
6.2 Line Tracking PID (app_irtracking.c)
xxxxxxxxxx// Line tracking P: larger = stronger correction// Line tracking I: eliminate steady-state deviation// Line tracking D: suppress oscillation// Line tracking default speed (mm/s)Line Tracking Tuning Guide:
| Phenomenon | Adjust What | Direction |
|---|---|---|
| Not turning enough / pressing line | ↑ KP | Increase |
| Serpentine movement | ↑ KD or ↓ KP | Damping/reduce push |
| Always deviating to one side | ↑ KI | Strengthen integral |
Inertia Compensation (for combined tracking+ball control tasks):
xxxxxxxxxx// Forward inertia compensation (cm), larger = ball pushes more forward// Turn inertia compensation (cm)// Start compensation (cm), car accelerates ball lags// Stop compensation (cm), car stops ball overshoots// Start slow acceleration time (ms), larger = gentler start6.3 Task Line Tracking Speeds (questions.c)
xxxxxxxxxx// Task 1 pure tracking speed// Task 3 A->B+ball control speed// Task 4 one lap+ball control speed// Task 5 specified position speed// Start slow acceleration time6.4 Task Timeout Settings (questions.c)
xxxxxxxxxx// Task 1 pure tracking 20s timeout// Task 2 ball reciprocation 5s timeout// Task 3 A->B+ball stabilization 8s timeout// Task 4 one lap+ball stabilization 30s timeout// Task 5 specified position 30s timeout7. Task Description
7.1 State Machine Structure (questions.h)
Main State:
| Macro | Value | Task Description |
|---|---|---|
| STOP_STATE | 0 | Stop |
| TASK_LINE_LAP | 1 | Task 1: Pure tracking one lap back to A, ≤20s |
| TASK_BALL_CTRL | 2 | Task 2: Ball O→+5→0→-5 (stop), <5s |
| TASK_AB_STAB | 3 | Task 3: A→B + ball stabilized at O, ≤8s |
| TASK_LAP_STAB | 4 | Task 4: One lap back to A + ball stabilized at O, ≤30s |
| TASK_LAP_POS | 5 | Task 5: One lap back to A + ball at specified position, ≤30s |
Sub State:
| Macro | Value | Description |
|---|---|---|
| SUB_IDLE | 0 | Idle |
| SUB_INIT | 1 | Initialize (set speed, start timing) |
| SUB_RUNNING | 2 | Running |
| SUB_DONE | 3 | Done (stop car but keep ball control, timeout also enters this state) |
7.2 Task Detailed Description
Task 1 (Pure Tracking):
Line tracking only, no ball control
Speed: TASK1_SPEED = 316 mm/s
Passes 4 waypoints (A/B/C/D) then stops at A
Timeout 20s auto stop
Task 2 (Ball Control):
Car stays still, servo control only
Process: O → +5cm (stable) → 0cm (stable) → -5cm (stable)
Each stage waits for ball to approach target (≤0.5cm) for 30 consecutive frames before switching
Timeout 5s
After task completion, ball continues to hold at -5cm position
Task 3 (A→B + Ball Control):
Line tracking + servo ball control simultaneously
Speed: TASK3_SPEED = 130 mm/s
Depart from A point, pass 1 waypoint to reach B
Ball stabilized at center O during driving
Timeout 8s stop, ball control continues after stop
Task 4 (One Lap + Ball Control):
Line tracking + servo ball control simultaneously
Speed: TASK4_SPEED = 222 mm/s
Clockwise one lap, pass 4 waypoints back to A
Ball stabilized at center O during driving
Timeout 30s stop, ball control continues after stop
Task 5 (Specified Position + Ball Control):
Same as Task 4, but ball target position can be specified (Target_Position)
Speed: TASK5_SPEED = 222 mm/s
Timeout 30s stop, ball control continues after stop
8. Key Code Analysis
8.1 K230 Ball Control — K230_Servo_Control() (app_k230.c)
xxxxxxxxxxvoid K230_Servo_Control(float target_cm){ // Parse K230 serial frame (UART3 interrupt auto receives data) int r; do { r = parse_one(g_buf, g_wr); } while (r > 0); if (!g_valid) return;
// Coordinate conversion cm -> pixels (bidirectional px/cm compensation) float px_per_cm; if (target_cm >= 0.0f) px_per_cm = (K230_MAX - K230_CENTER) / PIPE_HALF_CM; // Right side else px_per_cm = (K230_CENTER - K230_MIN) / PIPE_HALF_CM; // Left side float target_px = K230_CENTER + target_cm * px_per_cm;
// Deadband + positional PID + rate limit + PWM output float error = target_px - Kalman_Filter(&kf_x, g_x); if (error > -DEADBAND_PX && error < DEADBAND_PX) return; float cc = PID_To_CC_Pos(&g_pid, x_flt); // ... rate limit + CC limit ... DL_TimerA_setCaptureCompareValue(PWM_Servo_INST, (uint16_t)cc, DL_TIMER_CC_0_INDEX);}PID Formula (positional, app_pid.c): u = Kp*e + Ki*Integral(e) + Kd*(e - e_last)
8.2 Line Tracking — LineWalking() (app_irtracking.c)
xxxxxxxxxxvoid LineWalking(void){ static int8_t err = 0; static u8 x1~x8; deal_IRdata(&x1,...,&x8); // I2C read eight-channel infrared
if (x4 == 0 || x5 == 0) err = 0; // Center black line, go straight else if (x3 == 0) err = -1; // Left deviation, turn right else if (x6 == 0) err = 1; // Right deviation, turn left // ... more sensor combinations ...
pid_output_IRR = (int)(PID_IR_Calc(err)); Motion_Car_Control(g_line_speed, 0, pid_output_IRR);}8.3 Line Tracking + Ball Control Combined — LineWalking_WithBall() (app_irtracking.c)
xxxxxxxxxxvoid LineWalking_WithBall(float ball_target_cm){ // Inertia compensation: forward + turn float compensated = ball_target_cm; compensated -= BALL_INERTIA_FWD; if (pid_output_IRR > 0) compensated -= BALL_INERTIA_TURN * pid_output_IRR / 5000.0f;
// Start slow acceleration: speed gradually increases from 0 over RAMP_TIME_MS milliseconds uint32_t et = Get_Time() - start_time; if (et < RAMP_TIME_MS) { float ramp = (float)et / RAMP_TIME_MS; g_line_speed = (int)(g_line_speed * ramp); }
LineWalking(); // Line tracking K230_Receive_Process(); // Receive K230 K230_Servo_Control(compensated); // Ball control}8.4 Task 2 Ball Reciprocation (questions.c)
xxxxxxxxxx// Three phases: +5cm(1.8s) -> 0cm(1.8s) -> -5cm(1.8s) -> DONE(hold -5)case SUB_RUNNING: { static int phase = 0; static uint32_t t0 = 0; if ( t0 == 0) t0 = Get_Time();
float target_cm; if (phase == 0) target_cm = +5.0f; else if (phase == 1) target_cm = 0.0f; else target_cm = -5.0f;
K230_Receive_Process(); K230_Servo_Control(target_cm);
if (Get_Time() - t0 >= 1800) { // Each phase 1.8 seconds t0 = Get_Time(); if (phase == 0) phase = 1; else if (phase == 1) phase = 2; else { phase = 0; Sub_State = SUB_DONE; } } break;}case SUB_DONE: K230_Receive_Process(); K230_Servo_Control(-5.0f); // Keep ball at -5cm position break;9. Operation Flow
After wiring, power on, OLED displays "K230 Init..." waiting 4 seconds
Enter mode selection interface, OLED displays "Mode:1"
Long press K1 to switch modes (1~5)
Short press K1 to confirm entering current mode
Car starts executing task, OLED displays task name + timer
Short press K1 during task: pause; Long press K1: exit to mode selection
After task completion/timeout, car stops but ball control continues (ball stays at target position)
Long press K1 to exit to mode selection