当前位置: 首页 > news >正文

STM32传感器模块编程实践(十四)DIY语音+满溢检测智能垃圾桶模型

文章目录

    • 一.概要
    • 二.实验模型原理
      • 1.硬件连接原理框图
      • 2.控制原理
    • 三.实验模型控制流程
    • 四.智能感应垃圾桶模型程序
    • 五.实验效果视频
    • 六.小结

一.概要

随着科技的飞速发展和环保意识的日益增强,智能垃圾桶成为了城市生活的新宠,智能垃圾桶人们无需接触垃圾桶的任何部位即可投放垃圾,防止交叉感染,环保卫生,外形雅观。

在这里插入图片描述

本文就做一个智能感应垃圾桶套件模型,采用STM32F103C8T6单片机+舵机+超声波模块+红外模块+语音,实现有物体靠近,垃圾桶自动开启,没有物体靠近,一定时间后自动合上,并实现语音播报以及满溢检测。
在这里插入图片描述

二.实验模型原理

1.硬件连接原理框图

在这里插入图片描述

模型主要分为五部分:主芯片单元,测距感应单元,执行动作单元,语音播报单元,满溢检测单元。
在这里插入图片描述

图中主控芯片为STM32F103C8T6单片机,测距传感器为超声波模块,执行传感器为SG90舵机,语音播报单元为MP3语音播放模块,满溢检测单元为红外激光测距检测。

信号线连接:HC-SR04超声波模块信号脚ECHO脚接到单片机的PA0脚,TRIG脚接到单片机的PA1脚。SG90(180度)舵机的信号脚橙色线接到单片机的PA6脚。MP3语音播放模块接单片机的串口PA9,PA10引脚。红外激光测距模块接单片机的模拟IIC通讯引脚PB12,PB13以及PB7引脚。

2.控制原理

超声波模块根据声音的反射原理,对前方的障碍物进行测距。如果没有障碍物,或者障碍物距离>=5CM,单片机驱动舵机转到0度,如果检测到障碍物距离小于5CM,单片机驱动舵机旋转到180度,打开垃圾桶盖子。

超声波测距原理:

在这里插入图片描述

以上时序图表明单片机只需要提供一个10uS以上脉冲触发信号给模块的TRIG引脚,超声波模块内部将发出8个40kHz周期电平并检测回波。模块一旦检测到有回波信号则输出回响信号到模块ECHO引脚。回响信号的脉冲宽度与所测的距离成正比。单片机通过采集收到的输出回响信号的宽度时间就可以计算得到距离。

距离公式:距离=回响高电平时间*声速(340M/S)/2

舵机控制原理:
SG90舵机,首先,控制引脚是三根线,分别是GND(棕色)、VCC(红色)、PWM(黄色),控制方式也是一样的PWM时序,具体的方法如下:

(1)采用PWM控制的方式来进行舵机的旋转
(2)舵机的控制需要MCU产生一个20ms周期的脉冲信号,以0.5ms到2.5ms的高电平来控制舵机的角度。
(3)高电平时间跟舵机旋转的角度对应关系:
0.5ms-------------0度;对应函数中占空比为2.5%
1.0ms------------45度;对应函数中占空比为5.0%
1.5ms------------90度;对应函数中占空比为7.5%
2.0ms-----------135度;对应函数中占空比为10.0%
2.5ms-----------180度;对应函数中占空比为12.5%

语音播报原理:

MP3语音播放模块采用MP3主控芯片,支持MP3、WAV格式双解码,模拟U盘下载。模块内置FLASH存储芯片。支持 UART 异步串口控制:支持播放、暂停、上下曲、音量加减、选曲播放、插播等。我们预先通过USB口存储3段MP3语音播报到语音模块,通过STM32单片机控制语音模块进行指定语音播放。
通讯协议采用标准串口,3.3V TTL 电平,波特率9600,播放协议如下:
在这里插入图片描述

满溢检测原理:

通过红外激光模块装在垃圾桶顶部区域,单片机通过IIC总线与红外模块进行通讯,读取检测到的距离值,红外激光模块通过光线的反射原理,用来测量障碍物的距离,如果障碍物的距离比较小,说明垃圾桶满了。
在这里插入图片描述

三.实验模型控制流程

1.单片机先通过PA0脚驱动超声波模块,模块返回ECHO信号进行测距,超声波模块根据声音的反射原理,对前方的障碍物进行测距。如果没有障碍物,或者障碍物距离>=10CM,单片机不驱动舵机进行动作。

2.单片机一直通过PA0脚驱动超声波模块,模块返回ECHO信号进行测距,如果障碍物距离<10CM,单片机通过PA6引脚输出20ms周期的PWM波。PWM波高电平脉冲时间为2.5ms,这样舵机就会旋转180度,从而带动垃圾桶的盖打开,单片机同时通过串口发送指令给语音模块,发出垃圾桶打开语音,如果障碍物距离一直小于10CM,垃圾桶保持打开状态不变。单片机同时驱动红外激光模块测距,如果距离小于8CM,说明垃圾桶顶部被东西覆盖,垃圾桶已经满了。

3.单片机一直通过PA0脚驱动超声波模块,模块返回ECHO信号进行测距,如果障碍物距离>=10CM,单片机通过PA6引脚输出20ms周期。PWM波高电平脉冲时间为0.5ms,这样舵机就回到0度,从而带动垃圾桶的盖闭合,单片机同时通过串口发送指令给语音模块,发出闭合语音。

四.智能感应垃圾桶模型程序

板子与超声波模块用杜邦线连接:
板子G-----模块GND
板子3.3---模块VCC
板子A0----模块Trig
板子A1----模块Echo板子与SG90舵机(180度舵机)用杜邦线连接:
板子5V----红色线
板子A6----橙色线
板子G-----棕色线板子与红外激光测距模块用杜邦线连接:
板子3.3V----VIN
板子B12----SCL
板子B13----SDA
板子B7------XSHUT
板子G-------GND

USB线需要接小系统板,给STM32板子供5V, 板子与语音模块直接相连。
在这里插入图片描述

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述
配置系统主频
在这里插入图片描述
配置PA0为输出,PA1为输入,PA1管脚选择下拉
在这里插入图片描述

配置定时器2,10us产生中断一次,用来统计后续采集超声波返回的脉冲宽度时间
在这里插入图片描述
在这里插入图片描述

配置PWM输出,定时器3通道1,周期20ms
在这里插入图片描述
配置串口1,9600波特率,PA9为发送,PA10为接收
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

添加代码

添加红外激光代码:
在这里插入图片描述

添加舵机控制与超声波检测以及语音播报代码:
在这里插入图片描述

添加满溢检测代码:
在这里插入图片描述

主要程序:


//超声波测距,通过检测脉冲时间测试距离
uint32_t Distance_Calculate(uint32_t count)//传入时间单位10us
{uint32_t Distance = 0;Distance = (uint32_t)(((float)count *17)/100);//距离单位cm,声速340M/S,时间*速度/2=距离return Distance;
}
//等待us级别
void Delay_us(unsigned long i)
{unsigned long j;for(;i>0;i--){for(j=8;j>0;j--);}
}
//发送播放指令语音指令
void MY1690_Appoint_ID_SendCMD(uint16_t	ID)
{	uint8_t H_ID;uint8_t	L_ID;uint8_t MY1690_Appoint_ID[7]; //播放 //根据协议不使用这条。uint8_t i = 0;H_ID = (ID >>8)&0xff;L_ID = ID&0xff;MY1690_Appoint_ID[i++] = 0x7E;MY1690_Appoint_ID[i++] = 0x05;MY1690_Appoint_ID[i++] = 0x41;MY1690_Appoint_ID[i++] = H_ID;MY1690_Appoint_ID[i++] = L_ID;MY1690_Appoint_ID[i++] = Xor_Valid(&MY1690_Appoint_ID[1],MY1690_Appoint_ID[1]-1);MY1690_Appoint_ID[i++] = 0xEF;MY1690_SendCMD(MY1690_Appoint_ID);
}
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM3_Init();MX_TIM2_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */while(vl53l0x_init(&vl53l0x_dev))//vl53l0x初始化{	 HAL_Delay(500);}if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)//启动定时器2,10us进入中断一次{while(1);}if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出{/* PWM generation Error */while(1);}HAL_Delay(200);//等待200ms//以180度角度伺服为例,那么对应的控制关系是这样的(t为高电平时间)://t=0.5ms(占空比2.5%)---------0°;//t=1.0ms(占空比5%)-----------45°;//t=1.5ms(占空比7.5%)---------90°;//t=2.0ms(占空比10%)---------135°;//t=2.5ms(占空比12.5%)-------180°;Pluse_Time=500;//0.5ms高电平脉冲,用于控制舵机转到0度HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出HAL_Delay(100);//等待100msMX_TIM3_Init();//重新初始化配置PWM波if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出{/* PWM generation Error */while(1);}HAL_Delay(200);//等待200msHAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出	OpenFlag=0;//关闭vl53l0x_general_Init(&vl53l0x_dev,Default_Mode);//默认模式测试/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);//预先拉低Trig引脚HAL_Delay(5);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);//拉高Trig引脚Delay_us(40);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);//拉低Trig引脚Delay_us(20);while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == 0);//如果是低电平,一直等HalTime1= TimeCounter;while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == 1);//如果是高电平,一直等if(TimeCounter>HalTime1){HalTime2 = TimeCounter-HalTime1;if(HalTime2<0x300){Distance = Distance_Calculate(HalTime2);//计算距离}else{Distance=100;}}HAL_Delay(100);DistanceTimeCounter++;if(DistanceTimeCounter>2)//连续监测2次{DistanceTimeCounter=0;}else{if(Distance<=10 && Distance>0){DistanceCounter++;}continue;//没到3次,不动作,防止超声波抖动}if(DistanceCounter>=2 && OpenFlag==0)//距离小于10CM,说明有手挡住{MY1690_Appoint_ID_SendCMD(0001); //指定曲目播放//打开垃圾桶语音DistanceCounter=0;Pluse_Time=2500;HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出MX_TIM3_Init();//重新初始化配置PWM波if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出{while(1);}HAL_Delay(1000);OpenFlag=1;}else if((Distance>=10 || Distance==0) && OpenFlag==1){DistanceCounter=0;Pluse_Time=500;//0.5ms高电平脉冲,用于控制舵机转到0度if(Old_Pluse_Time!=Pluse_Time){MY1690_Appoint_ID_SendCMD(0002); //关闭垃圾桶语音HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//PWM停止输出MX_TIM3_Init();//重新初始化配置PWM波HAL_Delay(100);//等待100msif (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)//PA6脚PWM输出{/* PWM generation Error */while(1);}HAL_Delay(1000);//等待1000msOpenFlag=0;	}			}if(OpenFlag==1)//打开的时候做满检测{vl53l0x_general_Test(&vl53l0x_dev);if(Vl53l0_OK_Flag==1&& vl53l0x_data.RangeMilliMeter<=50)//检测到有效距离,且距离小于5cm,说明满了{Vl53l0_FullFlag++;if(Vl53l0_FullFlag>=3){MY1690_Appoint_ID_SendCMD(0003); //指定曲目播放//满了满了HAL_Delay(1000);//等待1000ms}}else{Vl53l0_FullFlag=0;}}Old_Pluse_Time=Pluse_Time;}/* USER CODE END 3 */
}

五.实验效果视频

基于STM32单片机带语音播报和满溢检测智能垃圾桶模型

六.小结

融合了舵机,超声波模块,语音播报模块,红外激光测距的控制,对STM32的单片机的定时器PWM功能,定时器功能,IIC通讯,串口通讯有更深的了解。

http://www.dtcms.com/a/333426.html

相关文章:

  • SD-WAN核心特点有哪些,适用哪些场景?
  • Rust 入门 泛型和特征-深入特征 (十五)
  • 【Cuda 编程思想】LinearQaunt-分块量化矩阵乘法计算过程
  • 关系型数据库核心组件:视图、函数与存储引擎详解
  • 分布式锁那些事
  • 机器学习中的PCA降维
  • ubuntu 20.04 搭建多用户远程桌面共享及同时在线使用
  • langGraph--2--langServe+langGraph示例
  • 云原生俱乐部-k8s知识点归纳(3)
  • Spark03-RDD01-简介+常用的Transformation算子
  • Rust 中 Box 的深度解析:作用、原理与最佳实践
  • 图解软件知识库体系
  • MiniSetupGetCdType函数分析之CDTYPE三种零售版oem版vol版
  • MMU 的资料收集
  • 【DDIA】第九章:一致性与共识
  • IDEA插件选择和设置优化指南(中英双版)
  • 永磁同步电机控制 第一篇、认识电机
  • 【原创理论】Stochastic Coupled Dyadic System (SCDS):一个用于两性关系动力学建模的随机耦合系统框架
  • STM32如何定位HardFault错误,一种实用方法
  • 进程和线程 (线程)
  • C#内嵌字符串格式化输出
  • C语言实现类似C#的格式化输出
  • Kubernetes(3)控制器的应用详解
  • 【Linux应用】V4L2的摄像头配置、获取等操作,并进行视频录制
  • 准直太阳光模拟器 | HUD 光照角度和强度的测试应用
  • 论文解读:从工具人到永动机,AI代理(AI Agent、智能体)如何跨越静态到自进化的鸿沟?
  • Effective Java笔记:类层次优于标签类
  • k8s单master部署
  • 用 Enigma Virtual Box 将 Qt 程序打包成单 exe
  • QT|windwos桌面端应用程序开发,当连接多个显示器的时候,如何获取屏幕编号?