随着物流行业的迅速发展,仓库管理在确保供应链高效运作方面变得越来越重要。为了保障仓库内物品和设施的安全,设计一个高效且智能的仓库环境监测系统显得尤为迫切。本文的毕业设计目标是开发一个基于STM32的仓库环境监测系统,实现对仓库内温度、湿度、空气质量等环境参数的实时监测,并通过WiFi模块将数据上传至APP,同时在APP上控制仓库设备。
系统架构设计
本系统分为四个主要部分:传感器节点、数据传输模块、数据存储与处理模块和用户界面模块。
- 传感器节点:负责采集仓库内的环境数据,包括温度、湿度、光照和气体传感器等,这些传感器通过无线通信将数据传送到数据传输模块。
- 数据传输模块:接收传感器节点传来的数据,并利用WiFi技术传输到数据存储与处理模块。
- 数据存储与处理模块:负责接收、存储和处理传感器传来的数据。利用云服务器进行数据存储和分析,实时监控仓库环境数据,并提供报警和预警功能。
- 用户界面模块:通过专用APP,仓库管理员可以实时查看环境数据和报警信息,并进行管理。
硬件设计
本设计是基于STM32仓库环境检测设计,主要实现的功能是对仓库的环境进行检测,通过气体传感器模块、温湿度模块传感器、光敏电阻传感器模块、可燃液化传感器模块对中药材仓库进行检测,检测出的实时数据上传到STM32最小系统,通过STM32最小系统对上传的数据进行分析和运算,通过编程和算法得出检测的实时数据与设定好的数值进行对比,最后通过有源矩阵液晶显示器显示仓库的环境正常与否。
硬件部分包括STM32F103C8T6单片机、DHT11温湿度传感器、火焰传感器、ESP8266WiFi模块和继电器等。STM32F103C8T6作为主控芯片,负责系统控制和数据处理;DHT11用于监测温湿度;火焰传感器检测明火;ESP8266负责无线数据传输;继电器控制通风风扇和抽水泵等设备。
软件设计
软件部分涵盖STM32的编程和APP开发。STM32的编程实现环境数据采集、处理及通过WiFi模块的数据发送。APP开发则侧重于数据接收、展示和远程控制。在开发过程中,需确保系统的稳定性和实时性,保证数据的准确可靠。
功能实现与测试
完成硬件和软件设计后,需要对系统进行集成测试和功能验证。测试内容包括传感器数据采集的准确性、数据传输的稳定性和APP功能的实现。通过反复测试和优化,确保系统满足设计要求并稳定运行。
总结与展望
本设计通过开发一个基于STM32的仓库环境监测系统,实现了对仓库环境参数的实时监测和远程控制,具有高稳定性、实时性和良好的扩展性,为仓库管理提供了强有力的支持。未来,可以进一步优化系统性能,提升数据传输速度和准确性,并增加更多传感器以监测额外的环境参数,以满足不同用户的需求。
该系统的基本代码涉及多方面,如STM32的初始化、传感器读取、数据处理和通信接口实现等。由于代码量较大,这里提供一个简化框架和部分核心代码段,用户可根据需求和硬件配置进行补充和完善。
部分代码
#include "stm32f10x.h" // Device header
#include "sys.h"
#include "Delay.h"
#include "OLED.h"
#include "dht11.h"
#include "sgp30.h" // Device header
#include "i2delay.h"
#include "AD.h" // Device header
#include "USART.h"
#include "esp.h"
#include "LED.h"
#include "PWM.h"
#include "fmq.h"
#include "exit.h"
#include "Timer.h"
#include <stdio.h>
#include <string.h>
u32 sgp30_dat;
u32 CO2Data;//CO2Ũ¶È
int Light=401;//¹âÕÕÇ¿¶È
int CO2=401;//CO2Ũ¶È
int Temperature=20;//ζÈ
int Shidu=20;//¿ÕÆøÊª¶È
uint8_t Switch='0';
uint8_t Switch1='0';
extern char RECS[200];
u8 T=20,S=20;
void Init(void)
{
uint8_t Judge=0;
delay_init();
OLED_Init();
OLED_ShowString(1,1,"Linking...");
MyUSART_Init(); //³õʼ»¯´®¿Ú
do
{
Judge = esp_Init();
OLED_ShowString(1,1,"error code:");
OLED_ShowNum(2,1,Judge,1);
}while(Judge); //Á¬½Ó°¢ÀïÔÆÖ±µ½³É¹¦
LED_Init();
DHT11_Init();
SGP30_Init();
AD_Init();
PWM_Init();
fmq_Init();
Key_Init();
}
int main(void)
{
Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_ms(100);
OLED_Clear();
exit_init();
while(1)
{
OLED_ShowString(1, 9, "gz");
OLED_ShowString(1, 1, "CO2");
OLED_ShowString(2, 1, "wendu");
OLED_ShowString(2, 10, "shidu");
Delay_ms(100);
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();//¶ÁÈ¡SGP30µÄÖµ
CO2Data = (sgp30_dat & 0xffff0000) >> 16;//È¡³öCO2Ũ¶ÈÖµ
// CO2Data++;
CO2=(int)CO2Data;
Delay_ms(100);
DHT11_Read_Data(&T, &S); //¶ÁÈ¡ÎÂʪ¶ÈÖµ
Temperature=(int)T;
Temperature++;
Shidu=(int)S;
// Shidu++;
Delay_ms(1);
Light=AD_GetValue();//¶ÁÈ¡¹âÕÕÇ¿¶ÈÖµ
// trshidu=4000;//¶ÁÈ¡ÍÁÈÀʪ¶ÈÖµ
// trshidu++;
Delay_ms(1);
OLED_ShowNum(1,12,(int)Light,4);
Delay_ms(1);
OLED_ShowNum(1,5,CO2Data,3);
Delay_ms(1);
OLED_ShowNum(2,7,Temperature,2);
Delay_ms(1);
OLED_ShowNum(2,15,Shidu,2);
Delay_ms(1);
// Esp_PUB();
Delay_ms(1000);
if(Esp_PUB() == 1)
{
OLED_ShowString(4,3,"publish failed");
Delay_ms(100);
// OLED_Clear();
}
Delay_ms(1000);
// CommandAnalyse();
OLED_ShowChar(4,1,Switch);
OLED_ShowChar(4,3,Switch1);
if(Switch=='0')//ÔÆ¿ØÖÆ
{
PWM_SetCompare2(0/ 180 * 2000 + 500);
}
if(Switch=='1')//ÔÆ¿ØÖÆ
{
PWM_SetCompare2(90/ 180 * 2000 + 500);
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //?PB1????????,???0,?????1??
{
Switch1='1';
LED1_ON();
}
else
{
Switch1='0';
}
if(Temperature>30)
{
fmq_start();
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_8);
}
}
}
联网部分代码
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <string.h>
#include "Delay.h"
#include "i2delay.h"
extern int Light;//光照强度
extern int CO2;//CO2浓度
extern int Temperature;//温度
extern int Shidu;//空气湿度
extern uint8_t Switch;
extern uint8_t Switch1;
extern char RECS[250];
const char* WIFI ="hyjh";//WIFI名称
const char* WIFIASSWORD="87654321";//WIFI密码
const char* ClintID="a18Jel5OjFz.V001|securemode=2\\,signmethod=hmacsha256\\,timestamp=1732186445460|";
const char* username="V001&a18Jel5OjFz";
const char* passwd="75a8af533ec5ddce83797a68183b9d37401b68c6ee2adfee7644db48e69f58bb";
const char* Url="a1KorDempMv.iot-as-mqtt.cn-shanghai.aliyuncs.com";
const char* pubtopic="/sys/a18Jel5OjFz/V001/thing/event/property/post";
const char* subtopic="/sys/a18Jel5OjFz/V001/thing/event/property/post_reply";
const char* func1="LEDSwitch";
const char* func2="ForcedAlarmSwitch";
const char* func3="co2";
const char* func4="ADC1";
const char* func5="Humidity";
const char* func6="temperature";
int fputc(int ch,FILE *f ) //printf重定向
{
USART_SendData(USART1,(uint8_t)ch);
while(USART_GetFlagStatus (USART1,USART_FLAG_TC) == RESET);
return ch;
}
char esp_Init(void)
{
memset(RECS,0,sizeof(RECS));
printf("AT+RST\r\n"); //重启
Delay_ms(2000);
memset(RECS,0,sizeof(RECS));
printf("ATE0\r\n"); //关闭回显
Delay_ms(10);
if(strcmp(RECS,"OK"))
return 1;
printf("AT+CWMODE=1\r\n"); //Station模式
Delay_ms(1000);
if(strcmp(RECS,"OK"))
return 2;
memset(RECS,0,sizeof(RECS));
printf("AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI,WIFIASSWORD); //连接热点
Delay_ms(1000);
if(strcmp(RECS,"OK"))
return 3;
memset(RECS,0,sizeof(RECS));
printf("AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",ClintID,username,passwd);//用户信息配置
Delay_ms(10);
if(strcmp(RECS,"OK"))
return 4;
memset(RECS,0,sizeof(RECS));
printf("AT+MQTTCONN=0,\"%s\",1883,1\r\n",Url); //连接服务器
Delay_ms(1000);
if(strcmp(RECS,"OK"))
return 5;
printf("AT+MQTTSUB=0,\"%s\",1\r\n",subtopic); //订阅消息
Delay_ms(1000);
if(strcmp(RECS,"OK"))
return 5;
memset(RECS,0,sizeof(RECS));
return 0;
}
//功能:esp发送消息
//参数:无
//返回值:0:发送成功;1:发送失败
char Esp_PUB(void)
{
memset(RECS,0,sizeof(RECS));
printf("AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"thing.event.property.post\\\"\\,\\\"params\\\":{\\\"%s\\\":%c\\,\\\"%s\\\":%c\\,\\\"%s\\\":%d\\,\\\"%s\\\":%d\\,\\\"%s\\\":%d\\,\\\"%s\\\":%d}}\",0,0\r\n",pubtopic,func1,Switch,func2,Switch1,func3,CO2,func4,Light,func5,Shidu,func6,Temperature);
// printf("AT+MQTTPUB=0,\"%s\",\"{\\\"method\\\":\\\"thing.event.property.post\\\"\\,\\\"params\\\":{\\\"%s\\\":%d\\,\\\"%s\\\":%d\\,\\\"%s\\\":%d\\,\\\"%s\\\":%d\\}}
// while(RECS[0]);//等待ESP返回数据
Delay_ms(1000);//延时等待数据接收完成
if(strcmp(RECS,"ERROR")==0)
return 1;
return 0;
}
void CommandAnalyse(void)
{
if(strncmp(RECS,"+MQTTSUBRECV:",13)==0)//at+MQTTSUBRECV:0
{
unsigned char i=0;
while(RECS[i++] != '\0')
{
if(strncmp((RECS+i),func1,9)==0)
{
while(RECS[i++] != ':');
Switch=RECS[i];
}
if(strncmp((RECS+i),func2,17)==0)
{
while(RECS[i++] != ':');
Switch1=RECS[i];
}
}
}
}