STM32智能家居项目:STM32+ES-01S+DHT11+tlink物联网平台

一,项目简介

        本项目是基于STM32F103C8T6制作,通过DHT11温湿度模块采集温湿度数据上传至Tlink物联网平台适合嵌入式初学者的练手项目。

        所用工具:STM32F103C8T6最小系统板,DHT11温湿度模块,ESP-10S WIFI模块,0.96寸OLED显示屏(I2C),CH340串口模块,面包板,杜邦线。

二,DHT11温湿度模块

        (1)模块介绍

        DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度 复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。DHT11和DS18B20一样采用单总线协议,湿度测量范围5~95%误差±5%,温度测量范围-20~60℃误差±2℃

        (2)引脚说明

引脚说明

Pin 名称 注释
1 VDD 供电3.3~3.5V DC
2 DATA 串行数据,单总线
3 NC 空脚
4 GND 接地,电源负极

        (3)协议说明

        DHT11采用单总线协议与单片机进行通讯,单片机发送一次复位信号后,DHT11发送响应信号,并拉高总线开始传输数据。

        数据格式:8位湿度整数数据+8位湿度小数+8位温度整数数据+8位温度小数数据+8位校验和

一次完整的数据为40位接收到的40位数据为:
        0011 0101(湿度高8位)0000 0000 (湿度低8位)0001 1000(温度高8位 )0000 0100(温度低8位)    0101 0001( 校验位)                                           

        校验位=湿度高位+湿度低位+温度高位+温度低位

        计算方式:
        00110101+00000000+00011000+00000100=01010001(接收数据正确)

        湿度:00110101(数)=35H=53%RH00000000=00H=0.0%RH=>53%RH+0.0%RH=53.0%RH

        温度:00011000(整数)=18H=24℃00000100=04H=0.4℃=>24℃+0.4℃=24.4℃

    单总线协议可以详细看这篇文章  https://blog.csdn.net/weixin_45137708/article/details/127660219?ops_request_misc=%257B%2522request%255Fid%2522%253A%25228bb14ad03357581377930b0eccb3d575%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=8bb14ad03357581377930b0eccb3d575&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-127660219-null-null.142^v100^pc_search_result_base8&utm_term=%E5%8D%95%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE&spm=1018.2226.3001.4187

        (3)DHT11代码部分 

                 引脚接线

DHT11 stm32f103c8t6
GND GND
DATA PA5
VCC 3.3V

         DHT11.c

#include "stm32f10x.h"                  // Device header
#include  "Delay.h"

#define DHT11_Pin  GPIO_Pin_5
#define DHT11_Port GPIOA//使用PA5引脚
#define DHT11_Low GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define DHT11_High GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define Read_Data GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)

float Temp,Humi;//定义温度和湿度
uint8_t Rec_Data[4];//储存温湿度高八位和低八位

void DHT11_STM32_Mode(uint8_t mode)//设置stm32为输入或输出模式 1为输输出 0为输入
{
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin=DHT11_Pin;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	if(mode)
	{
		GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
	}
	else
	{
		GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
	}
	GPIO_Init(DHT11_Port,&GPIO_InitStruct);
}

void DHT11_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIO时钟
	DHT11_STM32_Mode(1);//stm32默认为输出模式
	DHT11_High;//总线拉高
}

void DHT11_Start(void)
{
	DHT11_STM32_Mode(1);//输出模式
	DHT11_Low;
	Delay_ms(20);//拉低总线20ms产生起始信号
	DHT11_High;
	Delay_us(30);//拉高总线20~40us
	DHT11_STM32_Mode(0);//切换为输入模式等待接收数据
}

uint8_t DHT11_RecByte(void)//接收一个字节
{
	uint8_t i,byte;
	for(i=0;i<8;i++)
	{
		while(Read_Data == 0);//等待低电平结束
		Delay_us(30);
		byte<<=1;
		if(Read_Data==1)
		{
			byte|=1;
		}
		while(Read_Data==1);
	}
	return byte;
}

void DHT11_RecData()
{
	uint8_t T_H,T_L,H_H,H_L,Check;
	DHT11_Start();
	DHT11_High;
	if(Read_Data==0)
	{
		while(Read_Data==0);
		while(Read_Data==1);
		H_H=DHT11_RecByte();
	H_L=DHT11_RecByte();
	T_H=DHT11_RecByte();
	T_L=DHT11_RecByte();
	Check=DHT11_RecByte();
		
	DHT11_Low;
		Delay_us(55);
	DHT11_High;
	if(T_H+T_L+H_H+H_L==Check)
	{
		Rec_Data[0]=H_H;
		Rec_Data[1]=H_L;
		Rec_Data[2]=T_H;
		Rec_Data[3]=T_L;
		Temp=T_H+T_L*0.1;
		Humi=H_H+H_L*0.1;
	}
	}
}

        DHT11.h

#ifndef __DHT11_H
#define __DHT11_H


void DHT11_Init(void);
void DHT11_RecData(void);

#endif

     三,ESP-01S模块

        (1)模块介绍

        ESP-01S 是由安信可科技开发的Wi-Fi模块,该模块核心处理器 ESP8266 在较小尺 寸封装中集成了业界领先的 Tensilica L106 超低功耗 32 位微型 MCU,带有 16 位精 简模式,主频支持 80 MHz 和 160 MHz,支持 RTOS,集成 Wi-Fi MAC/ BB/RF/PA/LNA。

引脚功能定义

脚序 名称 功能说明
1 GND 接地
2 IO2 GPIO2/UART1_TXD
3 IO0 GPIO0;下载模式:外部拉低;运行模式:悬空或者外部拉高
4 RXD UART0_RXD/GPIO3
5 TXD UART0_TXD/GPIO1
6 EN 芯片使能端,高电平有效
7 RST 复位
8 VCC 3.3V 供电(VDD)外部供电电源输出电流建议在500mA以上

        (2)AT指令

        ESP-01s模块有两种模式:
        STA模式(TCP Client):连网传输数据,就是连接你家中的路由器,本文章主要使用此模式
        AP模式(TCP Server):用模块作为热点让手机或其他智能设备连接。

        设置ESP-01s主要通过AT指令来实现

基础AT指令

AT指令 说明
AT 测试ESP-01是否连接
AT+GMR 查看固件版本信息
AT+RST 软重启
AT+RESTORE 恢复出厂设置

        将CH340串口模块与ESP-01s连接进行测试

CH340 ESP-01s
5V 3.3v
TXD RXD
RXD TXD
GND GND

串口配置

端口 波特率 校验位 数据位 停止位 HEX
UART0 115200 None 8 1

        打开串口助手输入以下AT命令进行STA模式设置

步骤 示例 说明
第一步

AT

OK

测试AT是否OK
第二步

AT+CWMODE=1

OK

设置为Station模式
第三步

AT+CWJAP_DEF="Name",“Password”

WIFI CONNECTED

WIFI GOT IP

OK

Name为连接WIFI名称,Password为WIFI密码,可以连接手机热点或者路由器

连接到AP

第四步

AT+CIPMUX=0

OK

开启单链接
第五步

AT+CIPSTART="TCP","tcp.tlink.io",8647

CONECT

连接到TCP服务器
第六步

AT+CIPSEND=16

OK

向tlink发送设备序列号连接到设备
> 输入序列号
Recv 16 bytes 串口几收到数据
SEND OK 发送成功
CLOSED TCP连接被关闭

        (3)配置tlink平台

        打开Tlink物联网-工业物联网平台点击右上方登

        进入后点击右侧设备管理

        点击添加设备然后进行配置

        这样就得到了序列号

                 然后点击连接设置进行设置

        (3)串口程序

                ESP-01S与STM32主要通过串口进行数据收发,STM32主要对温湿度采集处理然后发送给ESP-01S然后发送到TCP服务器,所以串口程序只需要写发送部分。

ESP-01S STM32
GND GND
RX PA9
VCC 3.3V

MYusart.c

#include "stm32f10x.h"                  // Device header 
#include <stdio.h>
void MYusart_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//开启USART1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA时钟
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	USART_InitTypeDef USART_InitStruct;
	USART_StructInit(&USART_InitStruct);
	USART_InitStruct.USART_BaudRate=115200;//波特率设置为115200
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件流触发
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//RX接收模式 | TX发送模式
	USART_InitStruct.USART_Parity=USART_Parity_No;//无校验
	USART_InitStruct.USART_StopBits=USART_StopBits_1;//1位停止位
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;//数据长度 8
	USART_Init(USART1,&USART_InitStruct);
	
	USART_Cmd(USART1,ENABLE);//开启串口
}

void MYusart_SendData(uint16_t data)	
{
	USART_SendData(USART1,data);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE )==RESET);
}

int fputc(int ch, FILE *f)
{
	MYusart_SendData(ch);			//将printf的底层重定向到自己的发送字节函数
	return ch;
}

MYusart.h 

#ifndef __MYUART_H__
#define __MYUART_H__
#include <stdio.h>
void MYusart_Init(void);
void MYusart_SendData(uint16_t data);
#endif

        (4)ESP-01S代码部分

        ESP8266.c 

#include "stm32f10x.h"                  // Device header
#include "MYusart.h"
#include "Delay.h"
#include "DHT11.h"

uint8_t Esp8266_State;//显示连接状态 1为正在初始化 2为初始化完成 3为正在发送数据 4为发送数据完成
extern float Humi,Temp;
void Esp8266_Init(void)
{
	Esp8266_State=1;
	MYusart_Init();
	printf("AT+CWMODE=1\r\n");
	Delay_ms(3000);
	printf("AT+CWJAP_DEF=\"WIFI\",\"123456789\"");//连接WIFI,格式为“WIFI名称”,“密码”
	Delay_ms(5000);
	printf("AT+CIFSR\r\n");
	Delay_ms(3000);
	printf("AT+CIPMUX=0\r\n");
	Delay_ms(3000);
	printf("AT+CIPSTART=\"TCP\",\"tcp.tlink.io\",8647\r\n");
	Delay_ms(3000);
	printf("AT+CIPSEND=16\r\n");
	Delay_ms(3000);
	printf("X7E154S8JX2ASVD8\r\n");
	Esp8266_State=2;
}

void Esp8266_SendData(void)
{
	Esp8266_State=3;
	printf("AT+CIPSEND=13\r\n");
	Delay_ms(3000);
	printf("#%.2f,%.2f#\r\n",Temp,Humi);
	Delay_ms(2000);
	Esp8266_State=4;
}

ESP8266.h

#ifndef __ESP8266_H__
#define __ESP8266_H__

void Esp8266_Init(void);
void Esp8266_SendData(void);

#endif

        四,main函数部分

     main.c

#include "stm32f10x.h"  // Device header
#include "Delay.h"
#include "OLED.h"
#include "MYusart.h"
#include "DHT11.h"
#include "esp8266.h"
extern uint8_t Rec_Data[4];
extern uint8_t Esp8266_State;

void Esp8266_Getstate(void);
int main()
{
	
	OLED_Init();	
	Esp8266_Getstate();
	OLED_ShowString(1,1,"Tem:");
	OLED_ShowString(2,1,"Hum:");
	OLED_ShowString(3,1,"Esp8266State:");
	OLED_ShowString(1,7,".");
	OLED_ShowString(1,10,"C");
	OLED_ShowString(2,7,".");
	OLED_ShowString(2,10,"%");
	DHT11_Init();
	Esp8266_Init();
	Esp8266_Getstate();
	while(1)
	{
		DHT11_RecData();
		Esp8266_SendData();
		Esp8266_Getstate();
		OLED_ShowNum(1,5,Rec_Data[2],2);
		OLED_ShowNum(1,8,Rec_Data[3],2);
		OLED_ShowNum(2,5,Rec_Data[0],2);
		OLED_ShowNum(2,8,Rec_Data[1],2);
		Delay_s(1);
	}
}

void Esp8266_Getstate(void)
{
	if(Esp8266_State==1)
	{
		OLED_ShowString(4,1,"       ");
		OLED_ShowString(4,1,"Initing");
	}
	else if(Esp8266_State==2)
	{
		OLED_ShowString(4,1,"       ");
		OLED_ShowString(4,1,"Initok");
	}
	else if(Esp8266_State==3)
	{
		OLED_ShowString(4,1,"        ");
		OLED_ShowString(4,1,"Dataing");
	}
	else if(Esp8266_State==4)
	{
		OLED_ShowString(4,1,"        ");
		OLED_ShowString(4,1,"Dataok");
	}
	else if(Esp8266_State==0)
	{
		OLED_ShowString(4,1,"       ");
		OLED_ShowString(4,1,"None");
	}
}

        最终运行效果

        

作者:北²

物联沃分享整理
物联沃-IOTWORD物联网 » STM32智能家居项目:STM32+ES-01S+DHT11+tlink物联网平台

发表回复