引言
本项目设计了一个基于STM32的图形识别智能跟踪小车,能够通过摄像头识别特定图形或标志,并自动跟随这些图形进行移动。系统结合了摄像头模块和图像处理算法,实现了对前方物体的识别与跟踪。同时,小车具备避障功能,并通过电机驱动模块实现灵活的运动控制。此设计适用于智能机器人、自动导航以及教学实验等场景。
环境准备
1. 硬件设备
- STM32F103C8T6 开发板(或其他 STM32 系列)
- OV7670 摄像头模块(用于采集图像)
- L298N 电机驱动模块(用于控制电机)
- 直流电机和车轮(用于机器人运动)
- 超声波传感器(如 HC-SR04,用于避障)
- OLED 显示屏(用于显示状态)
- 面包板和杜邦线
- USB-TTL 串口调试工具
2. 软件工具
- STM32CubeMX:用于初始化 STM32 外设。
- Keil uVision 或 STM32CubeIDE:用于编写和下载代码。
- OpenCV 或其他图像处理库(在PC端用于图像调试)。
- ST-Link 驱动程序:用于下载程序到 STM32。
项目实现
1. 硬件连接
- 摄像头模块连接:将 OV7670 摄像头的 SDA、SCL、数据引脚连接到 STM32 的 DCMI 接口或 GPIO 引脚,用于捕获图像信号。
- 电机驱动连接:将 L298N 电机驱动模块的输入引脚连接到 STM32 的 GPIO(如 PA3、PA4、PA5、PA6),用于控制电机的前进、后退、左转和右转。
- 超声波传感器连接:将 HC-SR04 的 Trig 和 Echo 引脚连接到 STM32 的 GPIO(如 PA0 和 PA1),用于测距和避障。
- OLED 显示屏连接:将 OLED 的 SDA 和 SCL 引脚连接到 STM32 的 I2C 接口(如 PB6 和 PB7),用于显示当前小车状态。
- 电源管理:将电池接入电机驱动模块,并为 STM32 和摄像头模块提供稳定的电源。
2. STM32CubeMX 配置
- 打开 STM32CubeMX,选择你的开发板型号。
- 配置系统时钟为 HSI,确保系统稳定运行。
- 配置 GPIO 引脚用于电机控制和超声波传感器。
- 配置 I2C 用于与 OLED 显示屏通信。
- 配置 DCMI 接口或 GPIO 用于摄像头模块数据传输。
- 配置 TIM1 生成 PWM 信号,用于控制电机速度。
- 生成代码,选择 Keil 或 STM32CubeIDE 作为工具链。
3. 编写主程序
在生成的项目基础上,编写图像采集、识别处理、跟踪算法、电机控制和避障的代码。以下是图形识别智能跟踪小车的基本代码示例:
#include "stm32f1xx_hal.h"
#include "camera.h"
#include "motor.h"
#include "ultrasonic.h"
#include "oled.h"
// 定义避障阈值和运动速度
#define OBSTACLE_DISTANCE 15 // 当距离小于15cm时避障
#define PWM_SPEED 80 // 电机默认速度
// 函数声明
void System_Init(void);
void Detect_Obstacle(void);
void Capture_Image(void);
void Process_Image(void);
void Follow_Object(void);
void Control_Motor(uint8_t left_speed, uint8_t right_speed, int8_t left_dir, int8_t right_dir);
void Display_Status(const char *status);
// 全局变量
uint32_t distance = 0;
uint8_t object_detected = 0; // 图形识别标志
void System_Init(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_TIM1_Init();
MX_DCMI_Init();
OLED_Init();
Ultrasonic_Init();
Motor_Init();
Camera_Init();
OLED_ShowString(0, 0, "Tracking Car Ready");
}
// 检测障碍物并进行避障
void Detect_Obstacle(void)
{
distance = Ultrasonic_Measure();
if (distance < OBSTACLE_DISTANCE)
{
Control_Motor(0, 0, 0, 0); // 停止电机
Display_Status("Obstacle Detected");
HAL_Delay(1000); // 等待1秒钟
Control_Motor(PWM_SPEED, PWM_SPEED, -1, -1); // 后退
HAL_Delay(500); // 后退0.5秒
Control_Motor(0, 0, 0, 0); // 停止
}
}
// 捕获图像
void Capture_Image(void)
{
Camera_Capture(); // 使用 OV7670 模块捕获一帧图像
Display_Status("Image Captured");
}
// 处理图像以检测特定对象
void Process_Image(void)
{
object_detected = Camera_ProcessImage(); // 使用图像处理算法检测特定图形
if (object_detected)
{
Display_Status("Object Detected");
}
else
{
Display_Status("No Object");
}
}
// 跟随检测到的目标
void Follow_Object(void)
{
if (object_detected)
{
// 假设检测到的物体在视野左侧,控制小车向左转
Control_Motor(PWM_SPEED, PWM_SPEED, 1, -1); // 左转
Display_Status("Following Object");
}
else
{
Control_Motor(0, 0, 0, 0); // 停止
Display_Status("Searching Object");
}
}
// 控制电机
void Control_Motor(uint8_t left_speed, uint8_t right_speed, int8_t left_dir, int8_t right_dir)
{
Motor_SetSpeed(left_speed, right_speed);
Motor_SetDirection(left_dir, right_dir);
}
// 显示状态
void Display_Status(const char *status)
{
OLED_Clear();
OLED_ShowString(0, 0, status);
}
int main(void)
{
System_Init();
while (1)
{
Detect_Obstacle(); // 避障
Capture_Image(); // 捕获图像
Process_Image(); // 处理图像
Follow_Object(); // 跟随检测到的物体
HAL_Delay(100); // 每0.1秒更新一次状态
}
}
4. 各模块代码
摄像头模块图像捕获与处理
通过 OV7670 摄像头模块采集图像,并将图像数据用于图形识别处理:
#include "camera.h"
// 初始化摄像头
void Camera_Init(void)
{
// 配置摄像头的初始化参数,设置图像分辨率、帧率等
}
// 捕获图像
void Camera_Capture(void)
{
// 调用摄像头采集一帧图像,存储到缓冲区
}
// 处理图像并检测目标
uint8_t Camera_ProcessImage(void)
{
// 使用简单的图像处理算法(如颜色检测、形状检测等)识别特定物体
// 如果检测到特定目标,返回 1;否则返回 0
return 1; // 假设检测到了目标
}
电机控制
通过 L298N 驱动模块控制小车的前进、后退、左转和右转:
#include "motor.h"
#include "tim.h"
// 初始化电机
void Motor_Init(void)
{
// 初始化电机的 GPIO 引脚和 PWM 通道
}
// 设置电机速度
void Motor_SetSpeed(uint8_t left_speed, uint8_t right_speed)
{
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, left_speed); // 左电机 PWM
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, right_speed); // 右电机 PWM
}
// 设置电机方向,1 表示前进,-1 表示后退,0 表示停止
void Motor_SetDirection(int8_t left_dir, int8_t right_dir)
{
if (left_dir == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
}
else if (left_dir == -1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
}
if (right_dir == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);
}
else if (right_dir == -1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);
}
}
超声波传感器避障
使用 HC-SR04 超声波传感器进行障碍物检测,并根据距离数据执行避障操作:
#include "ultrasonic.h"
// 初始化超声波传感器
void Ultrasonic_Init(void)
{
// 配置超声波传感器的 GPIO 引脚
}
// 测量距离
uint32_t Ultrasonic_Measure(void)
{
uint32_t distance = 0;
uint32_t local_time = 0;
// 发送 Trig 脉冲
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(10); // 10 微秒脉冲
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
// 等待 Echo 的高电平并计算时间
while (!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)); // 等待 Echo 引脚变高
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)) // 计算 Echo 高电平的时间
{
local_time++;
HAL_Delay(1); // 延时 1 微秒,注意:需要根据实际时钟调整
}
// 计算距离 (声音速度 34000 cm/s)
distance = (local_time * 0.034) / 2; // 除以 2 是因为声音往返
return distance;
}
OLED 显示
用于显示当前状态,如小车是否检测到障碍物或正在跟踪目标:
#include "oled.h"
// 初始化 OLED 显示屏
void OLED_Init(void)
{
// OLED 初始化代码
}
// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, const char *str)
{
// 在 OLED 上显示字符串
}
// 清屏
void OLED_Clear(void)
{
// 清除 OLED 显示内容
}
⬇帮大家整理了单片机的资料
包括stm32的项目合集【源码+开发文档】
点击下方蓝字即可领取,感谢支持!⬇
点击领取更多嵌入式详细资料
问题讨论,stm32的资料领取可以私信!
系统工作原理
-
图像捕获与处理:通过 OV7670 摄像头模块实时采集图像,将图像数据传输至 STM32,使用简单的图像处理算法(如颜色检测或形状识别)来识别特定的图形或目标。小车根据识别结果进行自动跟踪。
-
障碍物检测:使用超声波传感器实时检测前方障碍物,当障碍物距离小于设定阈值时,小车会自动停止并后退,避免碰撞。
-
电机控制:通过 L298N 电机驱动模块,小车能够实现前进、后退、左转、右转等操作,配合图像识别实现自动跟踪和避障。
-
状态显示:OLED 显示屏实时显示小车的状态信息,如是否检测到目标、是否遇到障碍物等,便于调试和实时监控小车的工作状态。
常见问题与解决方法
1. 图像识别不准确
- 问题原因:摄像头分辨率低,或图像处理算法不够准确。
- 解决方法:可以提高图像分辨率,或者优化图像处理算法,如增加边缘检测或形状匹配的准确性。
2. 电机运行不平稳
- 问题原因:PWM 信号不稳定或电机驱动模块供电不足。
- 解决方法:调整 PWM 信号的频率和占空比,确保电机驱动模块的供电电压稳定。
3. 超声波传感器避障不灵敏
- 问题原因:传感器安装角度不合适或环境中存在干扰。
- 解决方法:调整超声波传感器的安装角度,确保其正对目标,并适当增加避障的阈值。
扩展功能
-
远程控制与数据上传:可以添加 Wi-Fi 模块或蓝牙模块,实现小车的远程控制和实时数据上传,使用户可以通过手机或电脑实时查看小车的运行状态。
-
复杂图形识别:通过扩展图像处理算法,可以识别更加复杂的图形或标志,如二维码或车牌号码,适用于更复杂的场景。
-
自动导航与路径规划:加入 GPS 模块和路径规划算法,使小车能够根据地图信息自动规划路径,实现更复杂的导航功能。
结论
通过本项目,我们成功设计了一个基于 STM32 的图形识别智能跟踪小车,能够通过摄像头识别目标图形并自动跟随。系统集成了图像处理、避障、智能控制等功能,广泛应用于智能机器人、自动驾驶实验以及教育和竞赛项目。该项目具备较强的可扩展性,可以通过增加远程控制和路径规划等功能,实现更多智能化应用。