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 | 测试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");
}
}
最终运行效果
作者:北²