基于STM32的智能数据采集系统

基于STM32的智能数据采集系统

介绍

由STM32C8T6作为主控芯片,控制温湿度传感器与光照强度传感器来检测温湿度值和光照强度值,取得的数据经过处理后可在0.96寸OLED显示屏上实时显示,还可根据预设值实现蜂鸣器报警和led指示灯报警的功能。

一、效果图

整体图片
在这里插入图片描述
嘉立创打的板子
输入图片说明
立创画的pcb
输入图片说明
实验的效果
在这里插入图片描述

二、整体设计内容

该设计是基于STM32的智能数据采集系统,通过主控芯片STM32C8T6接收传感器采集到光照强度和温湿度数据。

具体工作流程为:当智能数据采集系统上电运行之后,系统首先运行初始化代码,检测各个模块如ESP8266、蜂鸣器、温湿度传感器、光照强度传感器和OLED等与主控板是否连接正常,通过对各个硬件模块的初始化来分别判断各部分功能是否正常。在初始化完成之后,可以通过蜂鸣器进行提示,这时就可以进行正常的工作,OLED就可以正常显示采集到的温度、湿度和光照强度值

其整体设计框如图所示
在这里插入图片描述

三、各个模块设计

3.1 光强度检测模块

使用的模块是BH1750,使用的是I2C协议
留出来5个API,分别是BH1750s上电、BH1750s断电、BH1750复位、BH1750初始化、获取光照强度
对于这一块详细版本,在另外一文

//BH1750s上电
void BH1750_Power_ON(void)
{
	BH1750_Byte_Write(POWER_ON);
}

//BH1750s断电
void BH1750_Power_OFF(void)
{
	BH1750_Byte_Write(POWER_OFF);
}

//BH1750复位	仅在上电时有效
void BH1750_RESET(void)
{
	BH1750_Byte_Write(MODULE_RESET);
}

//BH1750初始化
void BH1750_Init(void)
{
	I2C_BH1750_GPIOConfig();		/* 配置GPIO */
	
	BH1750_Power_ON();	//BH1750s上电
	//BH1750_RESET();			//BH1750复位
	BH1750_Byte_Write(Measure_Mode);
	//SysTick_Delay_ms(120);
}

//获取光照强度
float LIght_Intensity(void)
{
	return (float)(BH1750_Read_Measure()/1.1f*Resolurtion);
}

3.2 温湿度检测模块

使用的模块是DHT11
留出来5个API,分别是DHT11初始化、获取温湿度、DHT11检测、DHT11复位、
对于这一块详细版本,在另外一文

//复位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的存在
//返回1:不存在
//返回0:存在    	 
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的回应
} 
3.3控制模块
/******************************************************************
 * 文件:main.c
 * 功能:主函数入口,实现各类函数的初始化,设置判断的阈值执行对应功能
*******************************************************************/
u8 alarmFlag = 0;//是否报警的标志
u8 alarm_is_free = 10;//报警器是否被手动操作,如果被手动操作即设置为0



u8 humidityH;	  //湿度整数部分
u8 humidityL;	  //湿度小数部分
u8 temperatureH;   //温度整数部分
u8 temperatureL;   //温度小数部分
extern char oledBuf[20];
float Light = 0; //光照度
u8 Led_Status = 0;

char PUB_BUF[256];//上传数据的buf
const char *devSubTopic[] = {"/mysmarthome/sub"};
const char devPubTopic[] = "/mysmarthome/pub";
u8 ESP8266_INIT_OK = 0;//esp8266初始化完成标志


 int main(void)
 {	
	unsigned short timeCount = 0;	//发送间隔变量
	unsigned char *dataPtr = NULL;
	
	delay_init();	    	 //延时函数初始化	 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	LED_Init();		  	//初始化与LED连接的硬件接口
	KEY_Init();          	//初始化与按键连接的硬件接口
	EXTIX_Init();		//外部中断初始化
	BEEP_Init();
	DHT11_Init();
    BH1750_Init();
	Usart1_Init(115200);//debug串口
	Usart2_Init(115200);//stm32-8266通讯串口
	 
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示
    OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
	OLED_Clear();
	
	UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
	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);
			UsartPrintf(USART_DEBUG,"\r\n");
			UsartPrintf(USART_DEBUG,"温度:%d.%d  湿度:%d.%d ",humidityH,humidityL,temperatureH,temperatureL);
			/********** 光照度传感器获取数据**************/
			if (!i2c_CheckDevice(BH1750_Addr))
			{
				Light = LIght_Intensity();
				UsartPrintf(USART_DEBUG,"光照度:%.1f lx\r\n", Light);
				UsartPrintf(USART_DEBUG,"\r\n");
			}
			
			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++;
			//UsartPrintf(USART_DEBUG,"alarm_is_free = %d\r\n", alarm_is_free);
			//UsartPrintf(USART_DEBUG,"alarmFlag = %d\r\n", alarmFlag);
		}
		if(++timeCount >= 200)	// 5000ms / 25 = 200 发送间隔5000ms
		{
			Led_Status = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);//读取LED0的状态
			UsartPrintf(USART_DEBUG,"=========================================\r\n");
			UsartPrintf(USART_DEBUG,"发布数据\r\n");
			UsartPrintf(USART_DEBUG, "OneNet_Publish\r\n");
			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);
			UsartPrintf(USART_DEBUG,"=========================================\r\n");
			timeCount = 0;
			ESP8266_Clear();
		}
		
		dataPtr = ESP8266_GetIPD(3);
		if(dataPtr != NULL)
			OneNet_RevPro(dataPtr);
		delay_ms(10);
	}
}

版权声明:本文为CSDN博主「杨德兴」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Leroi64/article/details/121453173

基于STM32的智能数据采集系统

介绍

由STM32C8T6作为主控芯片,控制温湿度传感器与光照强度传感器来检测温湿度值和光照强度值,取得的数据经过处理后可在0.96寸OLED显示屏上实时显示,还可根据预设值实现蜂鸣器报警和led指示灯报警的功能。

一、效果图

整体图片
在这里插入图片描述
嘉立创打的板子
输入图片说明
立创画的pcb
输入图片说明
实验的效果
在这里插入图片描述

二、整体设计内容

该设计是基于STM32的智能数据采集系统,通过主控芯片STM32C8T6接收传感器采集到光照强度和温湿度数据。

具体工作流程为:当智能数据采集系统上电运行之后,系统首先运行初始化代码,检测各个模块如ESP8266、蜂鸣器、温湿度传感器、光照强度传感器和OLED等与主控板是否连接正常,通过对各个硬件模块的初始化来分别判断各部分功能是否正常。在初始化完成之后,可以通过蜂鸣器进行提示,这时就可以进行正常的工作,OLED就可以正常显示采集到的温度、湿度和光照强度值

其整体设计框如图所示
在这里插入图片描述

三、各个模块设计

3.1 光强度检测模块

使用的模块是BH1750,使用的是I2C协议
留出来5个API,分别是BH1750s上电、BH1750s断电、BH1750复位、BH1750初始化、获取光照强度
对于这一块详细版本,在另外一文

//BH1750s上电
void BH1750_Power_ON(void)
{
	BH1750_Byte_Write(POWER_ON);
}

//BH1750s断电
void BH1750_Power_OFF(void)
{
	BH1750_Byte_Write(POWER_OFF);
}

//BH1750复位	仅在上电时有效
void BH1750_RESET(void)
{
	BH1750_Byte_Write(MODULE_RESET);
}

//BH1750初始化
void BH1750_Init(void)
{
	I2C_BH1750_GPIOConfig();		/* 配置GPIO */
	
	BH1750_Power_ON();	//BH1750s上电
	//BH1750_RESET();			//BH1750复位
	BH1750_Byte_Write(Measure_Mode);
	//SysTick_Delay_ms(120);
}

//获取光照强度
float LIght_Intensity(void)
{
	return (float)(BH1750_Read_Measure()/1.1f*Resolurtion);
}

3.2 温湿度检测模块

使用的模块是DHT11
留出来5个API,分别是DHT11初始化、获取温湿度、DHT11检测、DHT11复位、
对于这一块详细版本,在另外一文

//复位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的存在
//返回1:不存在
//返回0:存在    	 
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的回应
} 
3.3控制模块
/******************************************************************
 * 文件:main.c
 * 功能:主函数入口,实现各类函数的初始化,设置判断的阈值执行对应功能
*******************************************************************/
u8 alarmFlag = 0;//是否报警的标志
u8 alarm_is_free = 10;//报警器是否被手动操作,如果被手动操作即设置为0



u8 humidityH;	  //湿度整数部分
u8 humidityL;	  //湿度小数部分
u8 temperatureH;   //温度整数部分
u8 temperatureL;   //温度小数部分
extern char oledBuf[20];
float Light = 0; //光照度
u8 Led_Status = 0;

char PUB_BUF[256];//上传数据的buf
const char *devSubTopic[] = {"/mysmarthome/sub"};
const char devPubTopic[] = "/mysmarthome/pub";
u8 ESP8266_INIT_OK = 0;//esp8266初始化完成标志


 int main(void)
 {	
	unsigned short timeCount = 0;	//发送间隔变量
	unsigned char *dataPtr = NULL;
	
	delay_init();	    	 //延时函数初始化	 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	LED_Init();		  	//初始化与LED连接的硬件接口
	KEY_Init();          	//初始化与按键连接的硬件接口
	EXTIX_Init();		//外部中断初始化
	BEEP_Init();
	DHT11_Init();
    BH1750_Init();
	Usart1_Init(115200);//debug串口
	Usart2_Init(115200);//stm32-8266通讯串口
	 
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示
    OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
	OLED_Clear();
	
	UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
	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);
			UsartPrintf(USART_DEBUG,"\r\n");
			UsartPrintf(USART_DEBUG,"温度:%d.%d  湿度:%d.%d ",humidityH,humidityL,temperatureH,temperatureL);
			/********** 光照度传感器获取数据**************/
			if (!i2c_CheckDevice(BH1750_Addr))
			{
				Light = LIght_Intensity();
				UsartPrintf(USART_DEBUG,"光照度:%.1f lx\r\n", Light);
				UsartPrintf(USART_DEBUG,"\r\n");
			}
			
			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++;
			//UsartPrintf(USART_DEBUG,"alarm_is_free = %d\r\n", alarm_is_free);
			//UsartPrintf(USART_DEBUG,"alarmFlag = %d\r\n", alarmFlag);
		}
		if(++timeCount >= 200)	// 5000ms / 25 = 200 发送间隔5000ms
		{
			Led_Status = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);//读取LED0的状态
			UsartPrintf(USART_DEBUG,"=========================================\r\n");
			UsartPrintf(USART_DEBUG,"发布数据\r\n");
			UsartPrintf(USART_DEBUG, "OneNet_Publish\r\n");
			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);
			UsartPrintf(USART_DEBUG,"=========================================\r\n");
			timeCount = 0;
			ESP8266_Clear();
		}
		
		dataPtr = ESP8266_GetIPD(3);
		if(dataPtr != NULL)
			OneNet_RevPro(dataPtr);
		delay_ms(10);
	}
}

版权声明:本文为CSDN博主「杨德兴」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Leroi64/article/details/121453173

杨德兴

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

串口不定长接收

一、保留接收区和开启接收的语句    uint8_t buffer[5];HAL_UART_Transmit_IT(&huart1,buffer,3); 二、写入开启空闲中断的语句    __HAL_UART_ENABLE_IT(&huart

基于STM32单片机的电子密码锁设计

一.硬件方案 本设计采用STM32F103C8T6单片机作为主控芯片,结合外围的矩阵按键输入、LCD1602液晶显示、报警、开锁等电路模块实现开锁、上锁、报警、密码更改等功能,设计了一款可以多次修改密码并且具有报警