基于STM32的智能声音追随小车设计
引言
本项目设计了一个基于STM32的智能声音追随小车,可以通过多个麦克风模块检测声音的方向,并控制小车自动朝向声音源移动。该系统利用声源定位算法结合麦克风阵列实现声音追踪,通过STM32的PWM控制驱动小车的电机,适用于竞赛项目或智能机器人研究。
环境准备
1. 硬件设备
- STM32F103C8T6 开发板(或其他 STM32 系列)
- 4 个驻极体麦克风模块(用于检测声音来源方向)
- L298N 电机驱动模块
- 直流电机和车轮(用于驱动小车)
- PWM 控制器(用于调节电机速度)
- 面包板和杜邦线
- USB-TTL 串口调试工具
2. 软件工具
- STM32CubeMX:用于初始化 STM32 外设。
- Keil uVision 或 STM32CubeIDE:用于编写和下载代码。
- ST-Link 驱动程序:用于下载程序到 STM32。
项目实现
1. 硬件连接
- 麦克风阵列连接:将4个麦克风模块分别放置在小车的四个方向(前、后、左、右),并将其输出引脚分别连接到 STM32 的 ADC 输入引脚(如 PA0、PA1、PA2、PA3),用于检测声音强度。
- 电机驱动连接:将 L298N 电机驱动模块的输入引脚连接到 STM32 的 GPIO(如 PA8、PA9、PA10、PA11),用于控制电机的前进、后退、左转和右转。
- PWM 控制连接:将 PWM 输出引脚连接到 L298N 的使能引脚,用于调节电机速度。
- 电源管理:为小车的电机和麦克风模块提供适当的电源(如9V电池),确保稳定的电源供应。
2. STM32CubeMX 配置
- 打开 STM32CubeMX,选择你的开发板型号。
- 配置系统时钟为 HSI,以确保系统稳定。
- 配置 ADC 引脚用于读取麦克风模块的信号。
- 配置 GPIO 引脚用于控制电机方向。
- 配置 TIM1 生成 PWM 信号,用于调节电机速度。
- 生成代码,选择 Keil 或 STM32CubeIDE 作为工具链。
3. 编写主程序
在生成的项目基础上,编写声音方向检测、声源定位算法、电机控制以及小车移动逻辑的代码。以下是智能声音追随小车的基本代码示例:
#include "stm32f1xx_hal.h"
#include "adc.h"
#include "tim.h"
// 定义麦克风阈值和敏感度
#define SOUND_THRESHOLD 1000
#define SENSITIVITY 200
// 电机控制引脚
#define MOTOR_LEFT_FORWARD_PIN GPIO_PIN_8
#define MOTOR_LEFT_BACKWARD_PIN GPIO_PIN_9
#define MOTOR_RIGHT_FORWARD_PIN GPIO_PIN_10
#define MOTOR_RIGHT_BACKWARD_PIN GPIO_PIN_11
#define MOTOR_PORT GPIOA
// 函数声明
void System_Init(void);
void Motor_Control(uint8_t left_speed, uint8_t right_speed, int8_t left_dir, int8_t right_dir);
uint16_t Read_Microphone(uint8_t channel);
void Detect_Sound_Direction(void);
void Move_To_Sound(uint8_t direction);
// 全局变量
uint16_t mic_front, mic_back, mic_left, mic_right;
void System_Init(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM1_Init();
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 启动PWM通道1
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); // 启动PWM通道2
}
// 读取麦克风信号
uint16_t Read_Microphone(uint8_t channel)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
uint16_t value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return value;
}
// 控制电机,speed范围0-100,dir为1表示前进,-1表示后退
void Motor_Control(uint8_t left_speed, uint8_t right_speed, int8_t left_dir, int8_t right_dir)
{
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, left_speed); // 设置左电机PWM占空比
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, right_speed); // 设置右电机PWM占空比
if (left_dir == 1)
{
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_LEFT_FORWARD_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_LEFT_BACKWARD_PIN, GPIO_PIN_RESET);
}
else if (left_dir == -1)
{
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_LEFT_FORWARD_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_LEFT_BACKWARD_PIN, GPIO_PIN_SET);
}
if (right_dir == 1)
{
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_RIGHT_FORWARD_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_RIGHT_BACKWARD_PIN, GPIO_PIN_RESET);
}
else if (right_dir == -1)
{
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_RIGHT_FORWARD_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_PORT, MOTOR_RIGHT_BACKWARD_PIN, GPIO_PIN_SET);
}
}
// 声音方向检测和小车运动逻辑
void Detect_Sound_Direction(void)
{
// 读取前、后、左、右麦克风的声音强度
mic_front = Read_Microphone(0);
mic_back = Read_Microphone(1);
mic_left = Read_Microphone(2);
mic_right = Read_Microphone(3);
// 判断声音来源方向
if (mic_front > SOUND_THRESHOLD &&
mic_front > mic_back + SENSITIVITY &&
mic_front > mic_left + SENSITIVITY &&
mic_front > mic_right + SENSITIVITY)
{
Move_To_Sound(0); // 向前移动
}
else if (mic_back > SOUND_THRESHOLD &&
mic_back > mic_front + SENSITIVITY &&
mic_back > mic_left + SENSITIVITY &&
mic_back > mic_right + SENSITIVITY)
{
Move_To_Sound(1); // 向后移动
}
else if (mic_left > SOUND_THRESHOLD &&
mic_left > mic_front + SENSITIVITY &&
mic_left > mic_back + SENSITIVITY &&
mic_left > mic_right + SENSITIVITY)
{
Move_To_Sound(2); // 向左移动
}
else if (mic_right > SOUND_THRESHOLD &&
mic_right > mic_front + SENSITIVITY &&
mic_right > mic_back + SENSITIVITY &&
mic_right > mic_left + SENSITIVITY)
{
Move_To_Sound(3); // 向右移动
}
else
{
Motor_Control(0, 0, 0, 0); // 停止
}
}
// 根据声音方向控制小车运动
void Move_To_Sound(uint8_t direction)
{
switch (direction)
{
case 0: // 向前
Motor_Control(80, 80, 1, 1);
break;
case 1: // 向后
Motor_Control(80, 80, -1, -1);
break;
case 2: // 向左
Motor_Control(60, 80, -1, 1);
break;
case 3: // 向右
Motor_Control(80, 60, 1, -1);
break;
}
}
int main(void)
{
System_Init();
while (1)
{
Detect_Sound_Direction(); // 检测声音方向并移动小车
HAL_Delay(100); // 每0.1秒更新一次检测
}
}
⬇帮大家整理了单片机的资料
包括stm32的项目合集【源码+开发文档】
点击下方蓝字即可领取,感谢支持!⬇
问题讨论,stm32的资料领取可以私信!
4. 麦克风阵列信号处理
麦克风模块通过 ADC 读取声音强度,每个麦克风的数据经过简单的比较来判断声音的强度差异,从而确定声音源的方向。
5. 电机控制
使用 PWM 信号调节电机速度,结合 L298N 电机驱动模块控制电机的正反转,实现小车的前进、后退、左转和右转。PWM 的占空比决定了电机的转速,从而控制小车的行进速度。
6. 系统工作原理
- 声音方向检测:通过麦克风模块读取不同方向的声音强度,并通过对比各个麦克风的信号,确定声音源的大致方向。
- 电机控制与运动:根据检测到的声音方向,驱动电机控制小车朝向声音源移动。如果声音来自正前方,则小车直行;如果来自侧面,则小车左右转动;如果声音来自后方,则小车后退。
- 自动跟踪:系统不断监测声音来源,并持续调整小车方向,使其朝向声音源行进,模拟了声音追随功能。
常见问题与解决方法
1. 声音定位不准
- 问题原因:麦克风灵敏度差异或安装不对称。
- 解决方法:调整麦克风模块的灵敏度,并确保它们对称分布在小车四周。可以通过增大声音检测的阈值来减少环境噪声的影响。
2. 小车运动不稳定
- 问题原因:PWM 信号频率不合适,导致电机转速不稳定。
- 解决方法:调整 PWM 信号的频率,确保电机能够稳定响应 PWM 信号,避免出现过快或过慢的问题。
3. 小车无法转向
- 问题原因:L298N 电机驱动模块连接错误,或控制信号出错。
- 解决方法:检查电机驱动模块与 STM32 的连接,确保所有控制信号正确连接,并检查电机驱动的逻辑。
结论
通过本项目,我们成功设计了一个基于 STM32 的智能声音追随小车,实现了对声音方向的自动追踪和响应。该系统通过麦克风阵列感知环境中的声音变化,结合电机驱动实现小车朝向声音源的自动移动。项目可以用于智能机器人研究、竞赛项目以及声音定位技术的学习和开发,是对嵌入式系统开发的一个很好的实践案例。
原文地址:https://blog.csdn.net/2401_84204806/article/details/142832917
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!