DEV Community

Hedy
Hedy

Posted on

Using STM32 to make a tracking car

Creating a tracking car using an STM32 microcontroller involves integrating sensors, motors, and control algorithms to enable the car to follow a line or avoid obstacles. Below is a step-by-step guide to building a tracking car with STM32:

Image description

1. Define the Project Requirements

Type of Tracking:

Line-following: Use IR sensors to detect a line on the ground.

Obstacle avoidance: Use ultrasonic or IR sensors to detect and avoid obstacles.

Motor Control: Use DC motors with an H-bridge or motor driver.

Power Supply: Ensure the STM32, sensors, and motors are properly powered (e.g., using batteries).

Communication: Optional, for remote control or data logging (e.g., UART, Bluetooth, Wi-Fi).

2. Gather Components

STM32 Microcontroller: e.g., STM32F4 or STM32F1 series.

Motor Driver: e.g., L298N, TB6612FNG, or DRV8833.

DC Motors: Two or four motors for movement.

Wheels: Matching wheels for the motors.

Sensors:

Line-following: IR sensors (e.g., TCRT5000).

Obstacle avoidance: Ultrasonic sensors (e.g., HC-SR04) or IR distance sensors.

Chassis: A frame to hold all components.

Power Supply: Batteries (e.g., 9V or LiPo) and voltage regulators (e.g., 5V or 3.3V for STM32).

Optional: Bluetooth module (e.g., HC-05) for remote control.

3. Design the Hardware

a. Motor Control

  • Connect the motors to the motor driver.
  • Connect the motor driver to the STM32 GPIO pins for PWM control.
  • Example connections for L298N:

  • IN1, IN2, IN3, IN4 โ†’ STM32 GPIO pins.

  • ENA, ENB โ†’ STM32 PWM pins for speed control.

b. Sensor Integration

Line-following:

  • Place IR sensors at the front of the car.
  • Connect the sensor outputs to STM32 GPIO pins.

Obstacle avoidance:

  • Place ultrasonic sensors at the front and sides.
  • Connect the trigger and echo pins to STM32 GPIO pins.

c. Power Supply

  • Use a voltage regulator to provide 3.3V or 5V to the STM32 and sensors.
  • Connect the motor driver directly to the battery.

4. Write the Firmware

a. Initialize Peripherals

  • Configure GPIO pins for sensors and motor control.
  • Set up PWM for motor speed control.
  • Initialize ADC (if using analog sensors).

Example:

c

void GPIO_Init(void) {
    // Configure motor control pins
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
Enter fullscreen mode Exit fullscreen mode

b. Read Sensor Data

Line-following:

Read the IR sensor outputs to detect the line.

Example:


c

uint8_t Read_IR_Sensors(void) {
    uint8_t left = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
    uint8_t right = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
    return (left << 1) | right;
}
Enter fullscreen mode Exit fullscreen mode

Obstacle avoidance:

Use the ultrasonic sensor to measure distance.

Example:

c

float Read_Ultrasonic_Sensor(void) {
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET); // Trigger
    delay_us(10);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
    while (!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3)); // Wait for echo
    uint32_t start = TIM2->CNT;
    while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3));
    uint32_t end = TIM2->CNT;
    return (end - start) * 0.034 / 2; // Distance in cm
}
Enter fullscreen mode Exit fullscreen mode

c. Implement Control Logic

Line-following:

Use a PID controller or simple logic to adjust motor speeds based on sensor inputs.

Example:

c

void Line_Following(void) {
    uint8_t sensors = Read_IR_Sensors();
    if (sensors == 0b01) { // Turn left
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    } else if (sensors == 0b10) { // Turn right
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
    } else { // Move forward
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
    }
}
Enter fullscreen mode Exit fullscreen mode

Obstacle avoidance:

Adjust the car's direction based on distance measurements.

Example:

c

void Avoid_Obstacle(void) {
    float distance = Read_Ultrasonic_Sensor();
    if (distance < 20) { // Turn left if obstacle is close
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    } else { // Move forward
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
    }
}
Enter fullscreen mode Exit fullscreen mode

d. Main Loop

Continuously read sensor data and adjust motor control.

Example:

c

int main(void) {
    HAL_Init();
    SystemClock_Config();
    GPIO_Init();
    while (1) {
        Line_Following(); // or Avoid_Obstacle();
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Test and Debug

  • Test the car on a line or in an obstacle-filled environment.
  • Adjust the control logic and sensor thresholds for optimal performance.
  • Use a debugger (e.g., STM32CubeIDE) to monitor variables and troubleshoot issues.

6. Optional Enhancements

  • Wireless Control: Add a Bluetooth module for remote control.
  • Data Logging: Use UART or an SD card to log sensor data.
  • Advanced Algorithms: Implement advanced control algorithms like PID for smoother tracking.

Example Code for Line-Following Car

c

#include "stm32f4xx.h"

void GPIO_Init(void) {
    // Configure motor control pins
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // Configure IR sensor pins
    __HAL_RCC_GPIOB_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

uint8_t Read_IR_Sensors(void) {
    uint8_t left = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
    uint8_t right = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
    return (left << 1) | right;
}

void Line_Following(void) {
    uint8_t sensors = Read_IR_Sensors();
    if (sensors == 0b01) { // Turn left
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    } else if (sensors == 0b10) { // Turn right
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
    } else { // Move forward
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    GPIO_Init();
    while (1) {
        Line_Following();
    }
}
Enter fullscreen mode Exit fullscreen mode

By following these steps, you can build a tracking car using an STM32 microcontroller. Customize the design and code based on your specific requirements and components.

Top comments (0)