课程设计or练手小项目,基于STM32的环境数据采集系统(附送源码+PCB+原理图)

系列文章目录



前言

今天给大家分享的是环境数据采集系统,是一个很简单的小项目,用来入门学习STM32的知识,或者是用来练手做一些小项目什么的,都特别地合适,下面是它的功能要求:

若需获取资料,直接拉到文末的链接点击获取

【任务要求】: 
1.	采集温湿度,光照强度
2.	可实现温度,湿度,光照强度异常报警(报警方式用蜂鸣器)
3.	可手动解除报警
4.	可在远程端查看采集到的数据,远程端可选用电脑端或手机端,传输方式不限,但需做到无线传输

在这里插入图片描述

一、整体方案设计

1、总体框图的设计:

(1)硬件部分,用单片机实现环境数据的采集。明确系统各个模块的功能,选择相关的器件,对应满足相关的功能设计,然后绘制系统的整体电路图。

(2)用ESP8266模块实现单片机数据的输出,通过mqtt服务器实现与用户的APP联接。

(3)软件部分,设计App,实现环境数据的展示,并且设置控制蜂鸣器的开关。主要通过模块化进行设计,优点在于调试的时候具有针对性,可以一边调试一边观察结果进行修改,最后实现系统的整体功能。

程序框图如图所示:
在这里插入图片描述

二、电路图&PCB设计

这套环境数据采集系统主要包括了STM32F103C8T6、 DHT11温湿度传感器、 BH1750光照传感器、OLED显示屏、BEEP有源蜂鸣器,WiFI模块。

1.电路图设计

在做电路原理图设计,采用了排母的方式来制板,这样可以避免直焊时出现的错误,可以提高PCB板的利用率。

stm32核心板插座电路图:
在这里插入图片描述

温湿度传感器电路:
在这里插入图片描述

光照传感器电路:
在这里插入图片描述

2.PCB设计

在设计PCB电路时,关键在于保持布局的简洁和清晰,确保元件之间的间距合理,便于后续的焊接和检查工作。线路应尽可能直线布局,减少不必要的弯曲和长度,以降低电阻和信号传输延迟。同时,要为电路中的每个元件提供明确的电源和地线连接,并注意将模拟和数字信号分开,以减少潜在的干扰。最后,利用立创EDA的设计规则检查功能,确保设计的准确性,并保证设计满足基本的生产要求,从而制作出既简单又可靠的PCB。

以下为PCB设计的顶层图
在这里插入图片描述

三、示例代码

1,主函数

以下这段STM32的代码的作用主要是:通过集成温湿度传感器DHT11和光照度传感器BH1750,实时收集环境数据,并通过OLED显示屏和串口输出进行本地显示和调试。

利用ESP8266 Wi-Fi模块收集数据,设备能够将收集到的温湿度、光照度以及LED状态等信息上传至云平台,实现数据的远程存储和分析。

此外,设备还包含报警逻辑,当环境参数超出预设阈值时,会自动触发报警。代码中还实现了对报警器的手动控制逻辑,允许用户干预报警状态。

通过订阅云平台的主题,设备能够接收来自云端的指令,实现远程控制。整体而言,代码展示了一个完整的物联网设备开发流程,从传感器数据采集、本地处理、云端上传到远程指令接收的作用。

 int main(void)
 {	
	if(!ESP8266_INIT_OK){
		OLED_Clear();
		sprintf(oledBuf,"Waiting For");
		OLED_ShowString(16,0,(u8*)oledBuf,16);//8*16 “ABC”
		sprintf(oledBuf,"WiFi");
		OLED_ShowString(48,18,(u8*)oledBuf,16);//8*16 “ABC”
		sprintf(oledBuf,"Connection");
		OLED_ShowString(24,36,(u8*)oledBuf,16);//8*16 “ABC”
		OLED_Refresh();
	}
	ESP8266_Init();					//初始化ESP8266
	OLED_Clear();
	sprintf(oledBuf,"Waiting For");
	OLED_ShowString(16,0,(u8*)oledBuf,16);//8*16 “ABC”
	sprintf(oledBuf,"MQTT Server");
	OLED_ShowString(16,18,(u8*)oledBuf,16);//8*16 “ABC”
	sprintf(oledBuf,"Connection");
	OLED_ShowString(24,36,(u8*)oledBuf,16);//8*16 “ABC”
	OLED_Refresh();	
	while(OneNet_DevLink()){//接入OneNET
		delay_ms(500);
	}		
	
	OLED_Clear();	
	
	TIM2_Int_Init(4999,7199);
	TIM3_Int_Init(2499,7199);
	
	BEEP = 0;//鸣叫提示接入成功
	delay_ms(250);
	BEEP = 1;
	
	OneNet_Subscribe(devSubTopic, 1);
	
	while(1)
	{
		if(timeCount % 40 == 0)//1000ms / 25 = 40 一秒执行一次
		{
			/********** 温湿度传感器获取数据**************/
			DHT11_Read_Data(&humidityH,&humidityL,&temperatureH,&temperatureL);
			
			/********** 光照度传感器获取数据**************/
			if (!i2c_CheckDevice(BH1750_Addr))
			{
				Light = LIght_Intensity();
			}
			
			/********** 读取LED0的状态 **************/
			Led_Status = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);
			
			/********** 报警逻辑 **************/
			if(alarm_is_free == 10)//报警器控制权是否空闲 alarm_is_free == 10 初始值为10
			{
				if((humidityH < 80) && (temperatureH < 30) && (Light < 1000))alarmFlag = 0;
				else alarmFlag = 1;
			}
			if(alarm_is_free < 10)alarm_is_free++;
			/********** 输出调试信息 **************/
			DEBUG_LOG(" | 湿度:%d.%d C | 温度:%d.%d %% | 光照度:%.1f lx | 指示灯:%s | 报警器:%s | ",humidityH,humidityL,temperatureH,temperatureL,Light,Led_Status?"关闭":"【启动】",alarmFlag?"【启动】":"停止");
		}
		if(++timeCount >= 200)	// 5000ms / 25 = 200 发送间隔5000ms
		{
			Led_Status = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);//读取LED0的状态
			DEBUG_LOG("==================================================================================");
			DEBUG_LOG("发布数据 ----- OneNet_Publish");
			sprintf(PUB_BUF,"{\"Hum\":%d.%d,\"Temp\":%d.%d,\"Light\":%.1f,\"Led\":%d,\"Beep\":%d}",
				humidityH,humidityL,temperatureH,temperatureL,Light,Led_Status?0:1,alarmFlag);
			OneNet_Publish(devPubTopic, PUB_BUF);
			DEBUG_LOG("==================================================================================");
			timeCount = 0;
			ESP8266_Clear();
		}
		
		dataPtr = ESP8266_GetIPD(3);
		if(dataPtr != NULL)
			OneNet_RevPro(dataPtr);
		delay_ms(10);
	}
}


2,DHT11模块

以下的这段关于DHT11的代码首先通过配置GPIO端口和发送特定的复位信号来初始化传感器,这一过程由DHT11_Init函数完成,并且它还会检查传感器是否正确连接。

紧接着,DHT11_Rst函数负责启动传感器的复位序列,而DHT11_Check函数则监听传感器的响应,确保其正常工作。

在数据读取方面,DHT11_Read_Bit函数精细地从传感器中逐位读取数据,而DHT11_Read_Byte函数则将这些位组合成完整的字节。最关键的是DHT11_Read_Data函数,它不仅读取湿度和温度的详细数据,还包括整数和小数部分,并且在最后通过校验和验证来确保数据的完整性和准确性。

#include "dht11.h"
#include "delay.h"
//复位DHT11
void DHT11_Rst(void)	   
{                 
		DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_DQ_OUT=0; 	//拉低DQ
    delay_ms(20);    	//拉低至少18ms
    DHT11_DQ_OUT=1; 	//DQ=1 
		delay_us(30);     	//主机拉高20~40us
}

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();//SET INPUT	 
    while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}

//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void) 			 
{
 	u8 retry=0;
	while(DHT11_DQ_IN&&retry<100)//等待变为低电平
	{
		retry++;
		delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)//等待变高电平
	{
		retry++;
		delay_us(1);
	}
	delay_us(40);//等待40us
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}

//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)    
{        
    u8 i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *humiH,u8 *humiL,u8 *tempH,u8 *tempL)    
{        
 	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humiH=buf[0];			
			*humiL=buf[1];			
			*tempH=buf[2];
			*tempL=buf[3];	
		}
	}else return 1;
	return 0;	    
}

//初始化DHT11的IO口 DQ 同时检测DHT11的存在	 
u8 DHT11_Init(void)
{	 
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PA端口时钟
	
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //PA0端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);				 //初始化IO口
 	GPIO_SetBits(GPIOA,GPIO_Pin_8);						 //PA0 输出高
			    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
} 

四、应用场景

本设计为环境数据采集系统,而这个系统,适用于多种应用场景,特别是在需要实时监控和调节环境条件的场合。以下是一些具体的应用场景:

  1. 智能家居系统:在智能家居环境中,该系统能够监测室内的温度、湿度和光照强度,自动调节空调、加湿器和照明设备,以保持最舒适的居住环境。

  2. 农业温室控制:在现代农业温室中,系统可以实时监测土壤湿度、空气温度和光照强度,自动控制灌溉系统和遮阳设备,优化作物生长条件。

  3. 工业环境监测:在工业生产过程中,环境数据采集系统可以监测车间内的温度、湿度和光照,确保生产环境符合安全标准,防止因环境因素导致的设备故障或生产事故。

  4. 医院和实验室:在医院的病房和实验室中,精确的环境控制对于病人康复和实验结果至关重要。该系统可以监测和调节环境参数,确保达到所需的卫生和科研标准。

  5. 仓库和档案馆:对于存放敏感物品的仓库和档案馆,环境数据采集系统可以监测温湿度,防止物品因环境变化而损坏,如艺术品、历史文献等。

  6. 学校和幼儿园:在学校和幼儿园,系统可以确保孩子们在适宜的环境中学习和玩耍,通过监测和调节温湿度,预防疾病和不适。

  7. 远程办公环境:对于远程工作的员工,系统可以让他们通过手机或电脑远程监控和调节办公室的环境条件,提高工作效率和舒适度。

通过这些应用场景,环境数据采集系统不仅提高了环境管理的效率和准确性,还为人们提供了更加健康、舒适和安全的生活环境。

五、资料领取

=================================================

资料可以点击链接进行获取免费领取单片机资料
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值