基于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仿真。
感谢你的观看!