基于STM32单片机的声音压力红外检测OneNET云平台防盗设计
- 0、毕业设计选题原则说明(重点)
- 1、项目简介
- 1.1 系统功能
- 1.2 演示视频
- 2、部分电路设计
- 2.1 STM32单片机核心板电路设计
- 2.2 HX711压力重力检测电路设计
- 2.3 ESP8266 WIFI无线通信电路设计
- 2.4、声音检测电路设计
- 3、单片机代码展示
- 3.1 系统初始化
- 3.2 系统运行函数
- 3.3 HX711重力传感器初始化
- 3.4、HX711获取称重数据
0、毕业设计选题原则说明(重点)
- 选题之前,同学们要弄明白一件事情,做毕业设计是干什么用的!
- 这里我告诉大家,毕业设计对于你来说,不是让你去搞研究,掌握运用所学知识的,也不是让你去比谁做的毕业设计多么牛逼,多么厉害。
- 说白点,它的作用就是一个,让你顺利毕业,能够拿到学位证,毕业证而已!!!
- 当你明白这一点后,作毕业设计的要求就是在满足老师的要求后,越简单越好,这样不但容易去做,而且你自己也容易去理解,掌握,同样也能花最少的钱!!!
- 满足老师的要求,这个没办法,毕竟他是决定你是否能通过答辩的人。
- 每年都有很多同学找到我的时候,后悔当初为什么要把功能写的那么复杂,后悔没有提前找我咨询一下!所以在这里提醒同学们,提交开题报告之前一定要多想想,不要自己随便写一堆提交上去!!
1、项目简介
- 系统构成:本设计由STM32单片机电路+声音检测电路+HX711压力检测电路+蜂鸣器报警电路+ 红外检测电路+wifi电路+电源电路组成。
1.1 系统功能
- 功能介绍:
- 1、系统实时监测声音、压力、红外信号。
- 2、系统检测到声音、压力变化、有人时候会触发蜂鸣器报警
- 3、系统会将报警信息上传OneNET物联网云平台。
1.2 演示视频
2、部分电路设计
2.1 STM32单片机核心板电路设计
- 基于 ARM Cortex-M3内核的STM32F1系列单片机属于主流STM32单片机,其中增强型STM32F103子系列单片机的CPU 主频高达72MHz,片内Flash容量高达1MB,芯片引脚数量多达144个,有 QFN、LQFP、CSP、BGA 等多种芯片封装形式,并具有多种片内外设、USB接口和CAN 接口。根据STM32F103单片机片内Flash容量的不同,ST 公司将其分为小容量(16-32KB)、中等容量(64-128KB)、大容量(256KB-1MB)3种。
- 电源电路:为单片机提供稳定的工作电压,通常采用3.3V电源供电。电源电路的设计要保证单片机在不同工作条件下都能获得稳定的电压输出,以确保单片机的正常工作。
- 晶振电路:提供单片机工作所需的时钟信号。晶振电路通过晶振和电容组成,为单片机提供稳定的工作脉冲,确保单片机的定时和同步需求。
- 复位电路:实现单片机的复位功能,类似于电脑的重启。复位电路通过电容和电阻的配合,实现单片机在上电启动时的自动复位,以及通过手动按键实现复位功能,保证单片机在程序跑飞或异常情况下能够重新开始执行程序。
STM32单片机是一种功能强大、易于使用、灵活且可靠的32位微控制器,基于ARM Cortex™-M内核。其主要功能特点包括:
- 高性能和低功耗:STM32系列单片机提供多种内核选择,如Cortex-M0、Cortex-M3、Cortex-M4等,满足不同应用场景对性能的需求,同时保持低功耗特性。
- 多种通信和外设接口:STM32单片机具备广泛的通信和外设接口,如I2C、SPI、USART、USB等,便于开发者实现各种复杂功能。
- 易于开发和调试:STM32单片机提供了丰富的软件和硬件工具,如HAL库、CubeMX等,帮助开发者快速创建和调试嵌入式系统。
- 高集成度和设计灵活性:STM32系列单片机全系列产品共用大部分引脚、软件和外设,优异的兼容性为开发人员带来最大的设计灵活性
单片机最小系统原理图如下图所示:
- 实物图:
2.2 HX711压力重力检测电路设计
- HX711是一款专为高精度电子秤而设计的24 位A/D 转换器芯片。与同类型其它芯片相比,该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本,提高了整机的性能和可靠性。
将采集到的AD电压值准换为重力值
- 假设重力为 A Kg,(x<5Kg),测量出来的 AD 值为 y 传感器输出,发送给 AD 模块儿的电压为 A Kg * 4.3mV / 5Kg = 0.86A mV 经过 128 倍增益后为 128 * 0.86A = 110.08AmV 转换为 24bit 数字信号为 110.08A mV * 224 / 4.3V = 429496.7296A 所以 y = 429496.7296A 因此得出 A = y / 429496.7296 。
- 所以得出程序中计算公式 Weight_Shiwu = (unsigned long)((float)Weight_Shiwu/429.5);
- 特别注意: 因为不同的传感器斜率特性曲线不是完全一样,因此,每一个传感器需要矫正这里的 429.5 这个除数,才能达到精度很高。
- #define GapValue 430
- 当发现测试出来的重量偏大时,增加该数值。 如果测试出来的重量偏小时,减小改数值。该值可以为小数,例如 429.5 等。
具体电路原理图如下图所示:
实物图:
2.3 ESP8266 WIFI无线通信电路设计
- ESP8266-01s是由安信可科技开发的Wi-Fi模块,其核心处理器是ESP8266,这款处理器在较小的尺寸封装中集成了业界领先的Tensilica L106 超低功耗 32 位微型 MCU,支持 80 MHz 和 160 MHz 的主频,并带有 16 位精简模式。ESP8266-01s 支持RTOS,集成Wi-Fi MAC/BB/RF/PA/LNA,支持标准的IEEE802.11 b/g/n协议和完整的TCP/IP协议栈。这使得用户可以为现有设备添加联网功能,或者构建独立的网络控制器。
- ESP8266-01s 以其高性能和低成本的特性,为Wi-Fi功能的嵌入提供了无限可能,特别适用于物联网和智能家居等应用场景
其具体电路原理图如下图所示:
实物图如下:
2.4、声音检测电路设计
- 声音传感器是一种能够将声音信号转换为电信号的设备,通常由一个或多个麦克风组成。 声音传感器的工作原理基于压电效应,当声波撞击传感器表面时,传感器内部的压电材料产生微小的电荷变化,这种变化可以被测量并转换为数字信号。此外,声音传感器还需要前置放大器来增强电荷变化信号,并过滤掉其他类型的干扰信号。声音传感器的作用非常广泛,包括但不限于安防监控、医疗诊断、语音识别、音乐制作等领域。
- 声音传感器的基本工作原理可以概括为:声波使传感器内部的驻极体薄膜振动,导致电容的变化,进而产生与之对应变化的微小电压。这一电压随后被转换成0-5V的电压,经过A/D转换被数据采集器接收,并传送给计算机进行处理。声音传感器内置一个对声音敏感的电容式驻极体话筒,这种话筒能够将感受到的声音大小转换成相应的模拟信号输出,被广泛应用于录音机、声控照明灯等场景中。
其具体电路原理图如下图所示:
实物图:
3、单片机代码展示
3.1 系统初始化
void DeviceInit(void) {
Usart2_Init(115200); //串口2,驱动ESP8266用
Usart1_Init(115200); //串口1 系统打印调试信息
Beep_Init(); //蜂鸣器初始化
DIInit(); //声音检测模块 红外识别模块初始化
HX711Init(); //压力检测模块初始化
GetMaoPi(); //称毛皮重量
delay_ms(1000);
delay_ms(1000);
GetMaoPi(); //重新获取毛皮重量
ConnectionOneNet(); //连接OneNET云平台
//清除数据
memset(&sample_data, 0, sizeof(SampleData));
}
3.2 系统运行函数
void DeviceRun(void) {
sample_data.weight = GetWeight();
sample_data.hongwai = DI_1_IN;
sample_data.shengyin = DI_2_IN;
//检测到压力 或 声音 或 人
if(sample_data.weight > 1000 || sample_data.hongwai == 0 || sample_data.shengyin == 0)
{
sample_data.baojing = 1;
BUZZER_ON //打开蜂鸣器
}
else
{
sample_data.baojing = 0;
BUZZER_OFF //关闭蜂鸣器
}
//向OneNET发送数据
OneNetSend();
}
3.3 HX711重力传感器初始化
void HX711Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PF端口时钟
//HX711_SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
//HX711_DOUT
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_9); //初始化设置为0
}
3.4、HX711获取称重数据
/* 传感器结构体参数初始化 */
static void hx711_struct_config(void)
{
hx711.gain = GAIN_128; /* 当前增益 128 */
hx711.isTare = true; /* 默认第一次称重为皮重 */
hx711.k = 0.004757f; /* 传感器转换系数 */
hx711.b = 0.f; /* 传感器误差校正/补偿值 */
hx711.tare = 0.f; /* 保存皮重数据 */
hx711.actual = 0.f; /* 保存净重数据 */
}
/* 读取传感器返回的ADC数据值(数字量) 假定为一阶线性关系 y=kx+b */
static unsigned long hx711_readCount(void)
{
unsigned long count = 0; /* 需要读取25-27个0/1数据 */
unsigned char timeOut_cnt = 0; /* 检测超时计数值 */
HX711_SCK(0);
/* 添加超时检测 防止一直未识别到传感器导致程序卡死在这里 */
while(HX711_DOUT_STATE) { /* 等待DOUT从高电平到低电平跳变 */
timeOut_cnt ++;
delay_ms(1);
if(timeOut_cnt > 100) return 0;
}
/* 读取24位的ADC数字量数据 */
for(unsigned char i=0; i<24; i++) {
HX711_SCK(1);
delay_us(1);
HX711_SCK(0);
count |= (HX711_DOUT_STATE) << (24-i); /* 上升沿读取数据 */
delay_us(1);
}
/* 用于设置输出增益和输出通道 */
for(unsigned char j=0; j<hx711.gain; j++) {
HX711_SCK(1);
delay_us(1);
HX711_SCK(0);
delay_us(1);
}
return (count ^ 0x800000);
}
/* ----------------------------- 接口函数 ---------------------- */
/* 传感器 初始化 */
void hx711_init(void)
{
hx711_gpio_config();
hx711_struct_config();
}
/* 传感器断电 */
void hx711_power_off(void)
{
HX711_SCK(0);
delay_us(1);
HX711_SCK(1);
delay_us(100);
}
/* 传感器上电 */
void hx711_reset(void)
{
if(HX711_SCK_STATE == 1) {
HX711_SCK(0);
}
}
/* 设置传感器转换系数 */
void hx711_set_convert_ratio(float ratio)
{
hx711.k = ratio;
}
/* 设置传感器误差校正/补偿值 */
void hx711_set_offset_value(float offset)
{
hx711.b = offset;
}
/* 设置传感器增益 */
void hx711_set_gain(ENUM_HX711_GAIN_TYPEDEF gain)
{
hx711.gain = gain;
}
/* 获取传感器皮重数据 */
float hx711_get_tare_weight(void)
{
hx711.isTare = true; /* 获取皮重的时候 将该标志位置位 */
if(hx711.isTare == true) {
hx711.isTare = false;
hx711.tare = (float)hx711_readCount() * hx711.k + hx711.b; /* 此时获取到的重量为皮重 */
}
return (hx711.tare);
}
/* 获取传感器实际重量 */
float hx711_get_actual_weight(void)
{
float weight = 0.f;
if(hx711.isTare == false) { /* 当该标志位复位 代表此时应计算净重 */
weight = (float)hx711_readCount() * hx711.k + hx711.b;
hx711.actual = weight - hx711.tare;
}
return (hx711.actual);
}