自学内容网 自学内容网

基于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)!