基于STM32的智能仓储环境监测的Proteus仿真
文章目录
- 一、智能仓储环境监测
- 1.题目要求
- 2.思路
- 3.电路仿真
- 3.1 未仿真时
- 3.2 开始仿真,显示屏显示Init后,正常显示温度湿度光照烟雾数值
- 3.3 切换温度阈值界面,用阈值加减设置温度min和温度max阈值
- 3.4 调整温度数值,触发风扇/加热
- 3.5 切换湿度阈值界面,调整湿度数值,模拟通风打开
- 3.6 切换光照阈值界面,调整光照传感器数值,声光报警
- 3.7 远程终端设置阈值和查询温度湿度光照烟雾数值
- 4.仿真程序
- 4.1 程序说明
- 4.2 主程序
- 4.3 OLED显示函数
- 4.4 串口接收函数
- 二、总结
一、智能仓储环境监测
1.题目要求
1、检测温度、湿度、光照、烟雾浓度
2、设置光照、烟雾浓度阈值,超过阈值进行声光报警
3、设置温度阈值,低于阈值加热,高于阈值开风扇
4、设置湿度阈值,超过阈值通风
5、oled显示温度、湿度、光照、烟雾浓度的数值
6、手机端可以设置温度、湿度、光照、烟雾浓度的阈值、显示温度、湿度、光照、烟雾浓度的数值

2.思路
由上面的功能需求和实物照片,我们可知需要一个单片机STM32F103C8T6,温湿度传感器DHT11,光照传感器BH1750,
烟雾传感器MQ-2,显示屏OLED,有源蜂鸣器报警,风扇,加热棒,舵机,WiFi模块ESP8266以及三个按键。
都是一些常见的模块,简单过一遍。
单片机STM32F103C8T6:

温湿度传感器DHT11:

光照传感器BH1750:

烟雾传感器MQ-2(proteus仿真没有,用滑动变阻器代替模拟)

显示屏OLED:

有源蜂鸣器报警(最近不知道软件怎么了,蜂鸣器用不了,所以我都选择在旁边加个指示灯来看效果)

风扇,加热棒(proteus仿真没有,用一个红色LED点亮表示开启加热)

舵机:

WiFi模块ESP8266(proteus仿真没有,用虚拟终端连接到串口调试助手代替)

三个按键:

3.电路仿真
3.1 未仿真时

3.2 开始仿真,显示屏显示Init后,正常显示温度湿度光照烟雾数值
1.一开始显示屏显示Init(表示正在初始化)

2.正常显示温度湿度光照烟雾数值

3.3 切换温度阈值界面,用阈值加减设置温度min和温度max阈值

3.4 调整温度数值,触发风扇/加热
1.当前温度数值为31°C,高于温度max阈值,打开风扇

2.当前温度数值为20°C,低于温度min阈值,打开加热

3.5 切换湿度阈值界面,调整湿度数值,模拟通风打开
默认关闭的时候,舵机角度为-90°

打开的时候舵机角度调整为+90°

3.6 切换光照阈值界面,调整光照传感器数值,声光报警
烟雾阈值同理不演示。
注:蜂鸣器可能不响,所以用指示灯代替。

3.7 远程终端设置阈值和查询温度湿度光照烟雾数值

4.仿真程序
4.1 程序说明
主控芯片:STM32F103C8
HICK:64MHZ
Systick: 1ms
烟雾传感器:ADC(PA0)
光照传感器:LDR(PA2)
DHT11温湿度传感器:DATA(PA4)
模拟WIFI模块(Uart1):9600(PA9:tx1,PA10:rx1)
声光报警:BUZZER(PA15)
按键:
KEY1(PB2)
KEY2(PB3)
KEY3(PB4)
模拟通风:PWM(PB6)
风扇:RELAY1(PB7)
加热:RELAY2(PB8)
OLED显示屏:SCL(PB14),SDA(PB15)

串口协议
举例如发送*Tmin20,即设置温度低阈值位20度
设置指令:
*TminXX 设置温度低阈值 XX取值为0-99(温度低阈值必须小于温度高阈值)
*TmaxXX 设置温度高阈值 XX取值为0-99(温度高阈值必须大于温度低阈值)
*HumiXX 设置湿度阈值 XX取值为0-99
*ILLuXX 设置光照阈值 XX取值为0-99
*SmogXX 设置烟雾阈值 XX取值为0-99
查询指令:查询温度、湿度、光照、烟雾浓度的数值
*Read
4.2 主程序
/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/*** @brief main function.* @param none* @retval none*/
int main(void)
{UserSystemInit();//用户配置初始化 while (1){ if (stSysTime.flg._100ms + TEN_MILLISECOND < Time_millis()) //10ms{stSysTime.flg._10ms = Time_millis(); Key_Scan();//按键扫描 }if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms{stSysTime.flg._50ms = Time_millis(); ADC_Scan();//光照,土壤湿度检测 DHT11_Collect_data();//DHT11采集温度,湿度 } if(stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms{stSysTime.flg._100ms = Time_millis(); Receive_data_Handel();//数据接收判断 OLED_Handel();//OLED显示 Forewarning_Handel();//预警函数 IWDG_ReloadCounter();//清开门狗 }if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s{stSysTime.flg._1s = Time_millis(); }}
}
4.3 OLED显示函数
/******************************************************************************** 函数名:OLED_Handel* 描述 :OLED显示* 输入 :void* 输出 :void* 调用 :初始化* 备注 :100ms
*******************************************************************************/
void OLED_Handel(void)
{ if(Screen_switching == 1){OLED_Show_Character(1,1,0,16);//温OLED_Show_Character(1,2,1,16);//度 OLED_Show_Character(1,3,2,16);//: OLED_ShowNum(1,7,DHT11_temp_high,2); OLED_Show_Character(1,5,3,16);//° OLED_ShowString(1, 11, "C"); OLED_Show_Character(2,1,4,16);//湿OLED_Show_Character(2,2,5,16);//度 OLED_Show_Character(2,3,2,16);//: OLED_ShowNum(2,7,DHT11_humi,2);OLED_ShowString(2, 9, "%"); OLED_Show_Character(3,1,8,16);//光OLED_Show_Character(3,2,9,16);//照 OLED_Show_Character(3,3,2,16);//: OLED_ShowNum(3,7,ADC2_Value,2);OLED_ShowString(3, 9, "%"); OLED_Show_Character(4,1,6,16);//烟OLED_Show_Character(4,2,7,16);//雾 OLED_Show_Character(4,3,2,16);//: OLED_ShowNum(4,7,ADC1_Value,2);OLED_ShowString(4, 9, "%"); }else if((Screen_switching == 2) || (Screen_switching == 3)){ OLED_Show_Character(1,3,10,16);//设OLED_Show_Character(1,4,11,16);//置 OLED_Show_Character(1,5,0,16);//温OLED_Show_Character(1,6,1,16);//度 OLED_ShowString(2, 3, "min"); OLED_Show_Character(2,4,2,16);//:OLED_ShowNum(2,9,Temp_minThreshold,2); OLED_Show_Character(2,6,3,16);//° OLED_ShowString(2, 13, "C"); OLED_ShowString(3, 3, "max"); OLED_Show_Character(3,4,2,16);//:OLED_ShowNum(3,9,Temp_maxThreshold,2); OLED_Show_Character(3,6,3,16);//° OLED_ShowString(3, 13, "C"); }else if(Screen_switching == 4) {OLED_Show_Character(1,3,10,16);//设OLED_Show_Character(1,4,11,16);//置 OLED_Show_Character(1,5,4,16);//湿OLED_Show_Character(1,6,5,16);//度 OLED_ShowNum(3,7,Humi_Threshold,2);OLED_ShowString(3, 9, "%"); }else if(Screen_switching == 5) {OLED_Show_Character(1,3,10,16);//设OLED_Show_Character(1,4,11,16);//置 OLED_Show_Character(1,5,8,16);//光OLED_Show_Character(1,6,9,16);//照 OLED_ShowNum(3,7,ADC2_Threshold,2);OLED_ShowString(3, 9, "%"); } else if(Screen_switching == 6) {OLED_Show_Character(1,3,10,16);//设OLED_Show_Character(1,4,11,16);//置 OLED_Show_Character(1,5,6,16);//烟OLED_Show_Character(1,6,7,16);//雾 OLED_ShowNum(3,7,ADC1_Threshold,2);OLED_ShowString(3, 9, "%"); }
}
4.4 串口接收函数
/******************************************************************************** 函数名:Send_Cmd1* 描述 :设置温度阈值* 输入 :void* 输出 :void* 调用 :需要时调用* 备注 :举例如发送*Tmin20,即设置温度低阈值位20度*******************************************************************************/
void Send_Cmd1(void)
{uint8_t i = 0;if(uart1_rx_buf[i+3] == 'i'){variable1 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));if((variable1 > 0) && (variable1 < 100)){if(variable1 < Temp_maxThreshold) { Temp_minThreshold = variable1;printf("手机设置的温度低阈值 = %d\r\n",Temp_minThreshold);}else{printf("温度低阈值大于温度高阈值,设置失败"); } } else{printf("手机设置的温度低阈值超出设置范围 \r\n"); } }else if(uart1_rx_buf[i+3] == 'a'){variable2 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));if((variable2 > 0) && (variable2 < 100)){if(variable2 > Temp_minThreshold) { Temp_maxThreshold = variable2;printf("手机设置的温度高阈值 = %d\r\n",Temp_maxThreshold);}else{printf("温度高阈值小于温度低阈值,设置失败"); } } else{printf("手机设置的温度高阈值超出设置范围 \r\n"); } }
}/******************************************************************************** 函数名:Send_Cmd2* 描述 :设置湿度阈值* 输入 :void* 输出 :void* 调用 :需要时调用* 备注 :*******************************************************************************/
void Send_Cmd2(void)
{uint8_t i = 0;variable3 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));if((variable3 > 0) && (variable3 < 100)){Humi_Threshold = variable3;printf("手机设置的湿度阈值 = %d\r\n",Humi_Threshold); } else{printf("手机设置的湿度阈值超出设置范围 \r\n"); }
}/******************************************************************************** 函数名:Send_Cmd3* 描述 :设置光照阈值* 输入 :void* 输出 :void* 调用 :需要时调用* 备注 :*******************************************************************************/
void Send_Cmd3(void)
{uint8_t i = 0;variable4 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));if((variable4 > 0) && (variable4 < 100)){ADC2_Threshold = variable4;printf("手机设置的光照雾阈值 = %d\r\n",ADC2_Threshold); } else{printf("手机设置的光照阈值超出设置范围 \r\n"); }
}/******************************************************************************** 函数名:Send_Cmd4* 描述 :设置烟雾阈值* 输入 :void* 输出 :void* 调用 :需要时调用* 备注 :*******************************************************************************/
void Send_Cmd4(void)
{uint8_t i = 0;variable5 = (AsciiToHex(uart1_rx_buf[i+5])*10+AsciiToHex(uart1_rx_buf[i+6]));if((variable5 > 0) && (variable5 < 100)){ADC1_Threshold = variable5;printf("手机设置的烟雾阈值 = %d\r\n",ADC1_Threshold); } else{printf("手机设置的烟雾阈值超出设置范围 \r\n"); }
}/******************************************************************************** 函数名:Send_Cmd5* 描述 :查询温度、湿度、光照、烟雾浓度的数值* 输入 :void* 输出 :void* 调用 :需要时调用* 备注 :*******************************************************************************/
void Send_Cmd5(void)
{if(ADC_Flag){ printf("温度=%d 湿度=%d 光照= %d 烟雾=%d\r\n",DHT11_temp_high,DHT11_humi,ADC2_Value,ADC1_Value); }
}/******************************************************************************** Function : Receive_data_Handel* Description : 数据接收判断* Input : 无* Return : 无* Call : 100ms* Others :*******************************************************************************/
void Receive_data_Handel(void)
{uint8_t i = 0;if(uart1_rx_finsh){ for(i = 0;i< 20; i++){if(uart1_rx_buf[i] == '*') {switch(uart1_rx_buf[i+1]){case 'T':Send_Cmd1();break;//*TempXX case 'H':Send_Cmd2();break;//*HumiXXcase 'I':Send_Cmd3();break;//*IlluXX case 'S':Send_Cmd4();break;//*SmogXX case 'R':Send_Cmd5();break;//*Read default:break; } }}uart1_rx_finsh = 0; uart1_rx_count = 0;memset(uart1_rx_buf,0,RX_MAX_NUM); }
}
二、总结
今天主要讲了基于STM32的智能仓储环境监测的Proteus仿真。
感谢你的观看!

相关文章:
基于STM32的智能仓储环境监测的Proteus仿真
文章目录 一、智能仓储环境监测1.题目要求2.思路3.电路仿真3.1 未仿真时3.2 开始仿真,显示屏显示Init后,正常显示温度湿度光照烟雾数值3.3 切换温度阈值界面,用阈值加减设置温度min和温度max阈值3.4 调整温度数值,触发风扇/加热3.…...
logback日志控制台打印与写入文件
1.创建logback-spring.xml文件放入resource下 <?xml version"1.0" encoding"UTF-8"?> <configuration><property name"LOG_CONTEXT_NAME" value"log"/><!--定义日志文件的存储地址 勿在 LogBack 的配置中使用…...
成方金融科技后端部分笔试题 - 解析
单选题 1.以下关于JAVA自动类型转换,描述错误的是哪一项?(B) A.byte->short B.char->short C.char->int D.float->double 2.请选择运行以下代码后,系统显示的内容什么?(B) public class Test {static {int x1;}static int x,y;publ…...
WatchAlert - 开源多数据源告警引擎
概述 在现代 IT 环境中,监控和告警是确保系统稳定性和可靠性的关键环节。然而,随着业务规模的扩大和数据源的多样化,传统的单一数据源告警系统已经无法满足复杂的需求。为了解决这一问题,我开发了一个开源的多数据源告警引擎——…...
Linux procps-ng 包详解
简介 procps-ng 包是用于监视和管理 Linux 上的进程和系统性能的实用程序集合。它与 /proc 文件系统交互以检索实时系统信息。procps-ng 中的实用程序包括 ps、top、free、uptime 等命令。 安装 procps-ng 使用包管理工具安装 Debian/Ubuntu sudo apt update sudo apt ins…...
[react] <NavLink>自带激活属性
NavLink v6.28.0 | React Router 点谁谁就带上类名 当然类名也是可以自定义 <NavLinkto{item.link}className{({ isActive }) > (isActive ? 测试 : )}>{item.title}</NavLink> 有什么用?他会监听你的路由,刷新的话也会带上激活效果...
智能语音识别模块与声音传感器模块对比分析:原理、优缺点、性价比与应用领域
随着物联网(IoT)和智能家居的发展,智能设备的控制方式越来越多样化,尤其是语音控制和声音感应控制。智能语音识别模块和声音传感器模块作为两种常见的音频输入设备,它们在不同的应用场景中发挥着重要作用。本文将深入分…...
大模型+安全实践之春天何时到来?
引子:距《在大模型实践旅途中摸了下上帝的脚指头》一文发布近一年,2024年笔者继续全情投入在大模型+安全上,深度参与了一些应用实践,包括安全大模型首次大规模应用在国家级攻防演习、部分项目的POC直到项目落地,也推动了一些场景安全大模型应用从0到3的孵化上市。这一年也…...
贪心算法【Lecode_HOT100】
文章目录 1.买卖股票的最佳时机No.1212.跳跃游戏No.553.跳跃游戏IINo.454.划分字母区间No.763 1.买卖股票的最佳时机No.121 class Solution {public int maxProfit(int[] prices) {if (prices null || prices.length 0) {return 0;}// 初始化买入价格为最大值,最大…...
cmd初使用windows-docker时的一些小小问题
跟着大神文章做的,原文地址为【Docker】掌握 Docker魔法:Windows 11 平台上的完美容器部署终极指南_win11 docker-CSDN博客 1.用户名或密码错误 报错原文:Error response from daemon: Head "https://registry-1.docker.io/v2/library…...
使用qemu搭建armv7嵌入式开发环境
目录 目录 1 概述 2 环境准备 2.1 vexpress系列开发板介绍 2.2 安装工具 2.2.1 安装交叉工具链 2.2.2 安装qemu 2.2.3 安装其他工具 3 启动uboot 3.1 uboot下载与编译 3.1.1 下载 3.1.2 编译 3.2 使用qemu启动uboot 4 启动kernel 4.1 下载和编译kernel 4.1.1 下…...
火山引擎FORCE:智算能力全面升级
火山引擎智算专场 : 有幸参加 2024年 12月18日 在 上海国际博览中心 15:00~17:00的 智算专场。 这里 火山引擎智算专场图片 : 火山引擎智算专场内容 : 火山引擎图片 智算专场:乘云之势,智启未…...
ARM 处理器平台 Ethernet Compliance 测试流程示例
By Toradex秦海 1). 简介 为了保证基于IEEE 802.3 协议设计的以太网设备接口可以互相兼容互联互通,需要进行 Ethernet Compliance 一致性测试,相关的技术原理说明请参考如下文章,本文就不赘述,主要展示基于 NXP i.MX8M Mini ARM…...
基于HAL库的stm32的can收发实验
十六、CAN 1.CAN简介 CAN协议,全称为Controller Area Network(控制器局域网络),是一种广泛应用的串行通信协议,最初由 德国BOSCH公司开发,并已成为国际标准。 低速CAN(ISO11519)通…...
重构(二)
继续"提高代码质量" 接着上文提高代码质量, 需要从这几个特点入手 1、代码重用性。2、可读性。3、可扩展性。4、可靠性。5、高内聚,低耦合。 仅仅就"可读性"去分析一下吧, 毕竟例子实在是太多了 递归的"可读性"不如while循环 递归…...
centos7下制作DockerFile 镜像
文章目录 介绍DockerFile 常用命令示例1.创建Dockerfile文件2.构建Dockerfile镜像3.验证结果 小结 介绍 Dockerfile 是一个文本文件,包含了用于构建 Docker 镜像的所有命令和指令。它定义了镜像的构建过程,包括基础镜像、安装软件、设置环境变量、复制文…...
GFPS扩展技术原理(七)-音频切换消息流
音频切换消息流 Seeker和Provider通过消息流来同步音频切换能力,触发连接做切换,获取或设置音频切换偏好,通知连接状态等等。为此专门定义了音频切换消息流Message Group 为0x07,Message codes如下: MAC of Audio s…...
压缩qcow2镜像带来的性能损失简单分析
本文拟对压缩qcow2镜像所带来的虚拟机性能损失进行简单分析 背景 生产中发现使用压缩镜像启动的虚拟机开机总是会慢一些。 qcow2镜像的压缩方式为:qemu-img convert -p -c -O qcow2 zero_disk.qcow2 compress_disk.qcow2 分析 qemu代码:https://down…...
Kali操作系统简单介绍
Kali是一个集成了各种安全工具的操作系统 安全问题的根源 1.分层思想:网络和软件开发的分层方法 2.安全问题:分层思想导致的片面认识和系统脆弱性 3.人的因素:安全问题的最终根源是人的错误 传统安全建设 1.防护型安全建设:关闭不…...
LabVIEW物联网开发实战:专栏总述
本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合实际案例,展示如何利用LabVIEW和常用模块实现物联网系统的快速开发与原型设计,助你从基础到实战࿰…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
