This is a tank car control system based on STM32, implementing motion control, sensor data processing, and communication functionalities.
This project implements a comprehensive tank car control system with the following features:
- Motor PWM control for movement
- Encoder data reading for speed feedback
- MPU6050 sensor data processing with filtering and correction
- PID control for precise motion control
- UART communication for command input and data output
- Angle calculation and control for precise turning
- Straight line driving with automatic correction
The system uses the following hardware components:
- STM32F103C8T6 microcontroller
- L298N motor driver module
- MPU6050 6-axis sensor module
- Encoder modules for wheel speed detection
- UART interface for communication
The software is organized into modular components:
- Hardware abstraction layer (HAL) for peripheral control
- Sensor data processing modules (MPU6050 related)
- Control algorithms (PID, angle control)
- Communication handling (UART)
- Main application logic
Controls the L298N motor driver to control the left and right motors of the tank car, supporting forward, reverse and stop operations.
The motor control module provides functions to set PWM values for both left and right motors:
Motor_Left_SetPWM(int out): Controls the left motor with specified PWM value. Positive values for forward rotation, negative values for reverse rotation, and zero for stopping.Motor_Right_SetPWM(int out): Controls the right motor with specified PWM value. Positive values for forward rotation, negative values for reverse rotation, and zero for stopping.
The module uses TIM3 to generate PWM signals for motor control, with channels 1 and 2 controlling the left motor's IN1 and IN2 pins, and channels 3 and 4 controlling the right motor's IN3 and IN4 pins.
Reads encoder data to obtain wheel speed information for feedback control.
The encoder module interfaces with two encoder sensors through TIM2 and TIM4 to measure wheel rotation:
Encoder_Init(void): Initializes the encoder timers (TIM2 and TIM4) in encoder modeEncoder_Reset(void): Resets the encoder counters to zeroGet_Encoder_Data(void): Reads current encoder values and calculates speed with direction information
The module maintains global variables for encoder counts and speeds:
encoder1_count,encoder2_count: Raw encoder count valuesencoder1_speed,encoder2_speed: Encoder speeds with direction information
Interfaces with the MPU6050 sensor to read raw accelerometer and gyroscope data, using non-blocking DMA transfers.
The MPU6050 driver implements a state machine for non-blocking data reading:
MPU6050_Init(void): Initializes the MPU6050 sensor with proper configurationMPU6050_Read_Accel_IT(void): Initiates non-blocking accelerometer data reading via DMAMPU6050_Read_Gyro_IT(void): Initiates non-blocking gyroscope data reading via DMAMPU6050_Process_Data(void): Processes the raw data received from the sensorMPU6050_StateMachine(void): Manages the sensor data reading state machine
The module uses a state machine with the following states:
MPU6050_STATE_IDLE: Waiting for data read triggerMPU6050_STATE_READ_ACCEL: Reading accelerometer dataMPU6050_STATE_READ_GYRO: Reading gyroscope dataMPU6050_STATE_DATA_READY: Data processing complete
Data is read using DMA transfers triggered by TIM1 interrupts, ensuring non-blocking operation.
Applies Kalman filtering to MPU6050 raw data to reduce noise and improve accuracy.
The filter module implements Kalman filters for all six axes of the MPU6050 sensor:
KalmanFilter_Init(KalmanFilter_t *filter, float Q, float R, float P, float initial_value): Initializes a Kalman filter with specified parametersKalmanFilter_Update(KalmanFilter_t *filter, float measurement): Updates the filter with a new measurementMPU6050_Filter_Init(void): Initializes all six Kalman filters for the MPU6050 axesMPU6050_Filter_Data(void): Applies filtering to the raw MPU6050 data
The module uses separate Kalman filter instances for each axis:
- Accelerometer: accel_x_filter, accel_y_filter, accel_z_filter
- Gyroscope: gyro_x_filter, gyro_y_filter, gyro_z_filter
Filter parameters are tuned specifically for the MPU6050 sensor characteristics to provide optimal noise reduction.
Corrects filtered MPU6050 data using offset values to compensate for sensor deviations.
The correction module applies offset corrections to compensate for sensor biases:
MPU6050_Correction_Init(void): Initializes correction offsets based on sensor calibration dataMPU6050_Correct_Data(void): Applies offset corrections and zero-threshold processing to filtered data
The module uses predefined offset values based on calibration measurements:
- Accelerometer offsets: ax_offset, ay_offset, az_offset (typically 0 for accelerometer)
- Gyroscope offsets: gx_offset, gy_offset, gz_offset (based on stationary measurements)
After applying offsets, values below threshold are set to zero to eliminate small residual errors.
Calculates rotation angle based on corrected gyroscope data through integration.
The angle calculation module integrates gyroscope data to determine rotation angle:
MPU6050_Angle_Init(void): Initializes angle calculation variablesMPU6050_Update_Angle(void): Updates the rotation angle based on gyroscope data
Key features:
- Uses Z-axis gyroscope data for rotation angle calculation
- Integrates angular velocity over time (10ms sampling period)
- Applies correction coefficient to compensate for systematic errors
- Maintains continuous angle tracking without reset during operation
The module maintains:
mpu6050_angle_data.angle: Current rotation angle in degreesmpu6050_angle_corrected: Corrected angle value for control applications
Implements PID control algorithm for precise motion control.
The PID controller module provides a complete implementation of the proportional-integral-derivative algorithm:
PID_Init(...): Initializes PID parameters including gains, limits, and targetsPID_SetTarget(PID_HandleTypeDef *pid, float target): Sets the target value for the controllerPID_SetParams(...): Updates PID gains (Kp, Ki, Kd)PID_Compute(PID_HandleTypeDef *pid, float actual): Computes the control output based on actual value
Features:
- Configurable proportional, integral, and derivative gains
- Output and integral term limiting to prevent saturation
- Error tracking for derivative calculation
- Flexible parameter adjustment during operation
The module is used for both motor speed control and angle control applications.
Implements straight line driving functionality with automatic deviation correction.
The straight line driving module maintains robot trajectory through angle-based correction:
Set_Straight_Line_Speed(int16_t speed): Sets the target speed for straight line drivingEnhance_Small_Angle_Correction(float angle): Enhances correction for small angle deviationsLine_Correction(void): Applies trajectory correction based on angle sensor data
Key features:
- Dead zone handling to ignore small angle deviations
- Enhanced correction for small angles to improve accuracy
- Integral control for accumulating small angle corrections
- Proportional control for immediate deviation correction
- Output limiting to prevent overcorrection
The module adjusts left and right motor speeds based on the robot's angular deviation from the intended path.
Handles UART communication, including data sending and receiving.
The UART communication module provides formatted output and command input capabilities:
uart_init(void): Initializes UART reception with DMAuart_printf(const char *format, ...): Sends formatted text output via UARTcheck_response(const char *expected): Checks received data for specific stringsHAL_UARTEx_RxEventCallback(...): Handles UART reception completion events
Features:
- DMA-based non-blocking reception
- Formatted output using vsnprintf
- Automatic reception restart after data reception
- Error handling with UART reinitialization
- 100ms timeout for transmission to prevent blocking
The module maintains:
rx_data[256]: Reception buffer for incoming datarex_flag: Flag indicating new data receptionstr1[256]: Copy of received data for processing
Implements angle control functionality for precise turning operations.
The angle control module provides precise rotation control using PID:
AngleControl_Init(void): Initializes angle control PID parametersAngleControl_SetTarget(float angle): Sets target rotation angleAngleControl_Task(void): Executes angle control algorithm (called periodically)AngleControl_ProcessUARTData(void): Processes incoming UART commands for angle controlCar_SetMode(CarMode_e mode): Sets car operation mode (STOP, RUN, ROTATE)
Key features:
- PID-based rotation control with tunable parameters
- Dead zone handling for precise stopping
- Smooth stopping algorithm to prevent overshoot
- Minimum output control to ensure motor activation
- State machine for rotation sequence management
The module implements three operation modes:
- CAR_MODE_STOP: Complete stop with motors off
- CAR_MODE_RUN: Straight line driving with PID speed control
- CAR_MODE_ROTATE: Precise angle rotation control
Main program entry point that initializes all modules and implements the main control loop.
The main module orchestrates all system components:
- System and peripheral initialization
- Sensor initialization and calibration
- Control module setup
- Main loop with non-blocking multitasking
- TIM1 interrupt handler for periodic tasks
Key features:
- 10ms timer interrupt for deterministic task scheduling
- Non-blocking multitasking through task state management
- Proper initialization sequence for all modules
- Error handling and system recovery mechanisms
- Debug output for system status monitoring
The system implements two state machines:
- Car operation mode state machine (STOP, RUN, ROTATE)
- Angle control state machine (IDLE, ROTATING, STOPPING, PAUSING)
The car operation mode state machine controls the overall behavior:
- STOP: Motors are off, no motion control
- RUN: Straight line driving with speed control
- ROTATE: Precise angle rotation with position control
The angle control state machine manages rotation sequences:
- IDLE: Waiting for rotation command
- ROTATING: Active rotation toward target angle
- STOPPING: Smooth stopping after reaching target
- PAUSING: Temporary pause during rotation (if implemented)
- TIM1: Used for non-blocking multitasking (10ms interval)
- TIM2: Used for left wheel encoder input
- TIM3: Used for motor PWM output
- TIM4: Used for right wheel encoder input
TIM1 generates a 10ms interrupt that serves as the system's time base for non-blocking multitasking. All periodic tasks are scheduled relative to this timer.
TIM2 and TIM4 are configured as encoder interfaces to count wheel rotations and determine direction.
TIM3 generates PWM signals for motor speed control with four channels for the two motors.
run: Start the car in straight line driving modestop: Stop the car- Numeric values: Set turning angle (e.g.,
90for 90-degree turn)
The system accepts commands through UART interface:
- Text commands ("run", "stop") for mode control
- Numeric values (including negative) for angle specification
- Automatic command parsing and validation
- STM32CubeIDE
- STM32F103C8T6 microcontroller
- HAL library
- Open the project in STM32CubeIDE
- Build the project
- Connect the development board
- Flash the firmware
- The system uses a 10ms timer interrupt for non-blocking multitasking
- MPU6050 data processing is performed in the main loop
- PID control is enabled only in specific modes
- Angle accumulation is maintained for continuous angle tracking
- If the car does not respond to commands, check UART connection
- If angle control is inaccurate, recalibrate MPU6050 offsets
- If motor does not work, check L298N connections