stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)

这篇具有很好参考价值的文章主要介绍了stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

元件清单:

stm32f103c8t6、mq2 检测烟雾浓度(模拟量输出)、mq7 检测一氧化碳浓度、mq135 检测空气质量、OLED屏幕(四引脚仅支持iic协议通信)、dht11检测温湿度(数字量输出)、风扇模块、无源蜂鸣器、两引脚按键、WH-NB73-B5、ttl-usb


接线图:

mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件


mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件


 0:实现了dht11的温湿度以及mq2烟雾浓度的采集并通过OLED显示屏显示

mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件

/*
湿度整数 湿度小数 温度整数  温度小数  校验位 
00000000 00000000 00000000  00000000  00000000

1  看原理图确认GPIO引脚
2、 输出模式, 输出起始信号  :输出低电平18~30ms, 20ms	
3、 IO口配置浮空输入模式,准检测响应信号
		传感器把数据总线( SDA)拉低 83μs,
		再接高 87μs 以响应主机的起始信号。		
4、 40 个位的数据,高位先发;
		一位一位的收,数据0: 54us低电平 + 23~27高电平 
					 数据1: 54us低电平 + 68~74高电平
		注意高位先发的(每个字节)
5、校验数据
	前4个字节,求和,把和值的末八位和校验位对比
	相同数据正确、否则数据异常
*/
//程序未写零下
char tmp = 0,hum = 0;
void DHT_GPIO_Config(u8 flag)
{		
	GPIO_InitTypeDef GPIO_Config; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启端口时钟
	GPIO_Config.GPIO_Pin = GPIO_Pin_8; 
	if(flag==OUTPUT)
		GPIO_Config.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	else
		GPIO_Config.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Config.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_Config);
}

u8 DHT_GetData(void)
{
	u8 i = 0;
	u8 count = 0;
	u8 data[5]={0};
	//输出模式, 输出起始信号  :输出低电平18~30ms, 20ms	
	DHT_GPIO_Config(OUTPUT);
	DHT_High;
	DHT_Low;
	Delay_ms(20);
	//DHT_High;
	DHT_GPIO_Config(INPUT);

	/*IO口配置浮空输入模式,准检测响应信号
		传感器把数据总线( SDA)拉低 83μs,
		再接高 87μs 以响应主机的起始信号。
	*/
	
	while(DHT_CHECK==1)
	{
		delay_1us();
		count++;
		if(count>100)
			return 1;
	}
	count=0;
	while(DHT_CHECK==0)
	{
		delay_1us();
		count++;
		if(count>100)
			return 2;
	}	
	for(i=0;i<40;i++)
	{
		count=0;
		while(DHT_CHECK==1)
		{
			delay_1us();
			count++;
			if(count>100)
				return 3;	
		}
		
		count=0;
		while(DHT_CHECK==0)
		{
			delay_1us();
			count++;
			if(count>100)
				return 4;	
		}
		Delay_us(30);
		if(DHT_CHECK==1)
		{
			data[i/8] |= (1<<(7-i%8)); //置1
		}else
		{
			data[i/8] &=~ (1<<(7-i%8));//清零
		}	
	}
	
	/*校验数据
	前4个字节,求和,把和值的末八位和校验位对比
	相同数据正确、否则数据异常*/
	
	if((data[0]+data[1]+data[2]+data[3])==data[4])
	{
		tmp=data[2];
		hum=data[0];	
		return 0;
	}
	else
	{
		return 5;
	}	
}


1:在上边的基础上利用DMA实现多通道的数据采集(设置阀值,驱动风扇转动,并可手动按键改变阀值,并在屏幕显示变化;通过NB模块上传数据至有人云)

//mq2 mq7 mq135的采集
void ADC1_Config(void)
{
	GPIO_InitTypeDef GPIO_Struct = {0};
	ADC_InitTypeDef ADC_Struct = {0};
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		
	GPIO_Struct.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_Struct.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Struct);
		
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
		
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC时钟 72/6<14
	ADC_Struct.ADC_Mode = ADC_Mode_Independent; //独立工作模式
	ADC_Struct.ADC_ContinuousConvMode = ENABLE;//连续模式
	ADC_Struct.ADC_ScanConvMode = ENABLE; //多通道模式
	ADC_Struct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件触发启动
	ADC_Struct.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
	ADC_Struct.ADC_NbrOfChannel = 3;//规定了顺序进行规则转换的 ADC 通道的数目
	ADC_Init(ADC1,&ADC_Struct);

	//设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间
	//MQ2
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
	//MQ7
	ADC_RegularChannelConfig(ADC1,ADC_Channel_6,2,ADC_SampleTime_239Cycles5);
	//MQ135
	ADC_RegularChannelConfig(ADC1,ADC_Channel_7,3,ADC_SampleTime_239Cycles5);
		
	ADC_DMACmd(ADC1,ENABLE);
	DMA_Config();	
	ADC_Cmd(ADC1,ENABLE); 
	
	//校准:减小误差
	ADC_ResetCalibration(ADC1);//重置寄存器
	while(ADC_GetResetCalibrationStatus(ADC1)==SET)//等待重置完成
	{}
	ADC_StartCalibration(ADC1);//启动校准,用校准寄存器 校准 ADC1
	while(ADC_GetCalibrationStatus(ADC1)==SET)//等待校准完成
	{}			
	ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启动转换	 使能或者失能指定的 ADC 的软件转换启动功能 					
}

u16 DMA_buf[3]={0};
void DMA_Config(void)
{
	DMA_InitTypeDef DMA_Struct={0};
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //开启DMA时钟

	DMA_Struct.DMA_PeripheralBaseAddr =(u32) &ADC1->DR; //定义DMA外设基地址
	DMA_Struct.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据传输的来源
	DMA_Struct.DMA_BufferSize = 3; //地址递增两次(单位为字宽)
	DMA_Struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
	DMA_Struct.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
	DMA_Struct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
	DMA_Struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
	DMA_Struct.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式
	DMA_Struct.DMA_Priority = DMA_Priority_High;//优先级
	DMA_Struct.DMA_M2M = DMA_M2M_Disable;//DMA通道没有设置为内存到内存传输
	DMA_Struct.DMA_MemoryBaseAddr = (u32)&DMA_buf[0]; //内存基地址
	
	DMA_Init(DMA1_Channel1,&DMA_Struct);
	DMA_Cmd(DMA1_Channel1,ENABLE);
}

//不采用DMA的多通道采集方法
//u16 ADC_Result(u8 ADC_Channel_x)
//{
//	u16 ADC_val = ADC_GetConversionValue(ADC1); //返回最近一次 ADCx 规则组的转换结果
//	ADC_RegularChannelConfig(ADC1,ADC_Channel_x,1,ADC_SampleTime_239Cycles5);
//	ADC_SoftwareStartConvCmd(ADC1,ENABLE); //启动转换	 使能或者失能指定的 ADC 的软件转换启动功能 	
//	while((ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC))==RESET);
//	
//	//float ADC_Cha = (ADC_val*3.3/4096);
//	//printf("ADC_val == %d\r\n",ADC_val);
//	return ADC_val;
//}

2:将按键连接PB引脚,通过外部终端配置实现部分功能

mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件

3、在进行有人云端链接之前,需要先再云端添加设备模板、创建设备。有人透传云

mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件

在通信过程中,由底层开发板采集数据,并将数据封装成MODBUS-RTU格式,通过串口发送给NB模块,然后NB模块将数据上传到云端(创建模板时选择了MODBUS-RTU格式),NB模块是直连有人云的,在这里,我们访问云端,并将数据写入到云端的寄存器中。 

在云端设置完成后,NB模块主动发送数据、或重新上电之后即可上线。因为在测试阶段已经保证了设备是正常工作的,在这里我们直接尝试上传数据了。

在上传数据时,有人云平台支持MODBUS-RTU协议,我们只需要将采集的数据进行封装,然后将数据通过串口发送给NB模块。数据上传成功后,可以在设备概况、监控大屏或者云组态当中查看数据内容、上传时间、异常信息、设备上下线等。

通信格式: 设备号 功能码 起始地址 寄存器数量 数据长度 数据块(寄存器) 校验(CRC)

#include "nbiot.h"
/*
	buf[0]  :温度
	buf[1]	:湿度
	buf[2]	:光照强度
	buf[3]  :烟雾浓度
*/
void NB_Send_IOT1(uint16_t buf[4])
{
	char sendbuf[256]={0};
	char sendbuf1[256]={0};
	uint8_t tmpbuf[64]={0};
	uint16_t CRC_Tmp;
	tmpbuf[0]=0x01;//从机地址
	tmpbuf[1]=0x46;//操作码
	tmpbuf[2]=0x00;
	tmpbuf[3]=0x00;//寄存器起始地址  
	tmpbuf[4]=0x00;
	tmpbuf[5]=0x04;//寄存器数量
	tmpbuf[6]=0x08;//字节数 = 寄存器数量 * 2
	tmpbuf[7]=(buf[0]>>8);
	tmpbuf[8]=(buf[0]&0xFF);//高位清零
	tmpbuf[9]=(buf[1]>>8);
	tmpbuf[10]=(buf[1]&0xFF);
	tmpbuf[11]=(buf[2]>>8);
	tmpbuf[12]=(buf[2]&0xFF);
	tmpbuf[13]=(buf[3]>>8);
	tmpbuf[14]=(buf[3]&0xFF);
	CRC_Tmp=CRC_16_Tab(tmpbuf,15);
	tmpbuf[15]=(CRC_Tmp>>8);
	tmpbuf[16]=(CRC_Tmp&0xFF);
    
//把16进制数据转换为字符串,放入sendbuf
	SIM7020_Hex_to_Str((char *)tmpbuf,17,sendbuf,256);
    
//拼接字符串,拼接成上述格式
//设备号 功能码 起始地址 寄存器数量 数据长度 数据块(寄存器) 校验(CRC)
	strcpy((char *)tmpbuf,"AT+NMGS=17,");
	
	strcat(sendbuf1,(char *)tmpbuf);
	strcat(sendbuf1,sendbuf);
	strcat(sendbuf1,"\r\n");
	NB_SendString((char *)sendbuf1);
	//Send_String_NBlot((uint8_t *)sendbuf1);
	printf("发送内容= %s\r\n",sendbuf1);
}
/***************************************************************************/
//转化数据,转成16进制字符串
/*
char *data 	 	:数据来源
int data_len	    :数据长度
char *out 		:存储地址
int out_len		:存储地址长度
*/
void SIM7020_Hex_to_Str(char *data, int data_len, char *out, int out_len)
{
	char temp[2];
	int  i;
	
	memset(out,0,out_len);              //清空缓冲区
	for(i=0;i<data_len;i++)
	{            //for循环
		sprintf(temp,"%02X",data[i]);   //转化数据,转成16进制字符串
		strcat(out,temp);               //追加到out缓冲区              
	} 	
}






mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件

 上传后:可以发现,数据已经改变mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件

 也可以在“监控大屏”中左侧选择设备、右侧查看实时数据,点击变量可以下发数据,或控制指令,完成数据指令下发。mq2传感器oled屏幕显示,mcu,stm32,嵌入式硬件

在数据或指令下发时,云端下发指令也是MODBUS-RTU格式,以03功能码为例:云端下发读保持寄存器指令(03功能码),通过 UDP链接传输到我们的NB模块,然后NB模块将相应的指令转到我们的设备串口,在开发板上我们可以检测串口的接收,在串口接收数据完成后,将所接收的数据,按照MODBUS协议进行解析,如果下发的为03码,则参照03功能码的响应方式对云端进行数据响应。如果是其他功能码,则根据需求进行解析。

程序资料已经上传到资源可以下载。

stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)-智能家居文档类资源-CSDN下载

如果这篇博客对你有帮助,给博主一个免费的点赞或者评论收藏以示鼓励呀~感谢!😘😘😘

 有任何问题可以评论区留言~🤞🤞🤞文章来源地址https://www.toymoban.com/news/detail-787090.html

到了这里,关于stm32c8t6+dht11+MQ系列环境检测模块+oled显示屏(基于物联网的家庭环境检测系统设计)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Openmv+STM32F103C8T6视觉巡线小车

    机器视觉巡线处理是参考openmv官方代码 Openmv官网源代码:book. openmv.cc/project/follow-lines.html 根据官网视频及教程将源码注入openmv中。 小车巡的是黑线,所以颜色阈值要更改。 在文件示例中打开helloworld.py。 打开工具/机器视觉/阈值编辑器/缓冲区。 将我们需要寻迹的黑线调至全

    2023年04月09日
    浏览(53)
  • SG90舵机的使用--STM32F103C8T6

    SG90带有一个3P的接头 根据颜色分为 黄线(信号线) 红线(电源线) 棕色 (地线) 舵机的 工作电压 在 4.8V-6V ,接在STM32系统板上驱动不了,所以需要接电源模块单独的5V供电,我使用的是如图所示的电源模块 注: 如果STM32系统板供电和舵机供电不为同一模块,则需要共地,

    2024年02月03日
    浏览(45)
  • [附源码] STM32F103C8T6+外接MCP4725 外部DAC

            STM32F103C8T6最小系统板是大家很常用的一款单片机,它内部有多个ADC模数转换通道,但并 没有DAC数模转换功能 ,当需要进行数字量转换为模拟量时就需要借助外部DAC。             MCP4725是具有非易失性存储器的单通道12位缓冲电压输出DAC。用户可将配置寄存器

    2024年02月04日
    浏览(44)
  • STM32CubeIDE使用示例(STM32CubeMX+STM32CubeIDE+Gcc+JLINK+STM32G030C8T6)

    本文简单记录下STM32CubeIDE的使用方法,整体的环境是STM32CubeMX+STM32CubeIDE+Gcc+JLINK+STM32G030C8T6,实现的简单测试功能是让STM32G030C8T6板子上的LED闪烁,以STM32G030C8T6 PB4 脚做LED 输出闪烁为例,外部8MHZ 晶振,系统主频64MHZ,LED 灯1 秒钟闪烁一次做一个示例程序; 1、我这边已经装好了ST

    2024年02月15日
    浏览(44)
  • JQ8400语音模块-stm32f103c8t6(内含全代码)-亲测有效

    一.模块介绍 1.常见的JQ8400-FL语音模块有两种,一种是带3W功放,有4M的存储空间,可通过USB拷贝声音文件,通过单片机串口控制;另外一种是附有SD卡槽,用SD卡存储文件的文件(MP3格式)进行语音播报,也是通过单片机串口控制 2.我用的是二线串口通信,一线的没试过 3.程序

    2023年04月26日
    浏览(43)
  • 基于STM32F103C8T6单片机的DHT11温湿度传感器与OLED显示屏实时动态数据监测系统设计

    标题: 摘要: 本文提出了一种利用STM32F103C8T6微控制器,结合DHT11数字温湿度传感器和OLED显示屏实现环境温湿度实时、直观显示的方法。该系统通过低功耗且精确的DHT11传感器获取环境温湿度信息,并借助于STM32F103C8T6强大的处理能力和I/O资源进行数据读取、解析以及控制OLE

    2024年01月19日
    浏览(65)
  • STM32---stm32f103c8t6与stm32f103zet6之间的代码移植转换

    目录 一、将c8t6转换为zet6 1、修改启动文件 2、修改芯片 3、将MD修改为HD  4、下载器的修改 5、修改完成,编译成功  二、将zet6转换为c8t6 最终结果如下:   将STM32F103C8改为STM32F103ZE   基本相同,反向即可。    

    2024年02月06日
    浏览(55)
  • 【沧海拾昧】STM32F103C8T6/C6T6的ISP烧录

    #C0105 沧海茫茫千钟粟,且拾吾昧一微尘 ——《沧海拾昧集》@CuPhoenix 【阅前敬告】 沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系 【如有问题必是本集记录有谬,切勿深究】   对于某种STM32F103C8T6/C6T6最小系统板,没有配置J-LINK/ST-LINK烧录口,此时可以

    2024年02月03日
    浏览(68)
  • STM32单片机PWM控制实现电机调速度(小车运动,STM32F103C8T6&TB6612&TT电机)

    作者:公子易平 时间:2023/6/6 前段时间做一个智能小车的相关项目时,发现很少有人能够将STM32的PWM控制讲清楚,故而书此文,希望对后来的学习者有所帮助。 STM32F103C8T6最小系统板 直流TT电机 电机驱动芯片(TB6612) 杜邦线若干 接线情况: TB6612引脚说明: STM32主控芯片与TB6612接

    2024年02月15日
    浏览(45)
  • STM32F103C8T6---定时器1&定时器8输出PWM信号注意事项

    博主今天在驱动定时器1的通道1输出PWM信号的时候,遇到了好多问题,在这里指出,警醒自己的同时希望能给各位带来帮助 首先,第一个错误, 第一:PA8引脚默认模式就是定时器1的通道一,我们在代码里面,直接 将PA8的输出模式改为复用推挽输出,不要去重定向它,也不要

    2024年02月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包