STM32F4+esp8266 WiFi模块采集温湿度数据对接PC端

项目需要在stm32上开发MQTT,同时MQTT协议基于TCP/IP协议,因此先在探索者开发板上调通基于TCP的WiFi通信,同时采集温湿度数据,上传至PC端的网络调试助手服务端,为后面开发MQTT做准备。

1、准备工作

1.1.STM32F4开发板

image

1.2.DHT11温湿度传感器

DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度20-90%RH, 温度0~50℃。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。

image

1.3.esp8266 WiFi模块

esp8266模块采用串口与MCU进行通信,内置TCP/IP协议栈,能够实现串口与WiFi之间的转换,模块支持串口转WiFi STA、串口转AP和WiFi STA+WiFiAP的模式,从而快速构建串口-WiFi数据传输方案。

image

2. esp8266模块使用

2.1 esp8266模块使用介绍

esp8266模块使用方便,开发过程中可使用AT指令对模块进行操作,及可使用stm32的串口发送相关AT指令控制模块。模块作为TCP连接客户端时使用的AT指令如下所示:

AT:测试模块是否工作正常

AT+RST:复位模块状态

设置客户端模式

AT+CWMODE=1:客服端 Station

AT+CWMODE=2:用户端 AP

AT+CWMODE=3:双端Station+AP

AT+CWJAP="wifi名","密码":连接指定WiFi

TCP连接:AT+CIPSTART="TCP","目标IP",目标端口号 如:AT+CIPSTART="TCP","192.168.1.1",8080

开启传透模式:AT+CIPMODE=1 关闭穿透模式:AT+CIPMODE=0

开启透传后,使用AT+CIPSEND开启数据发送

TCP发送数据到服务器全流程如下:

1.  AT 检测模块是否工作正常
2.  AT+CIPMODE=0 关闭透传
3.  AT+CWMODE=1 客服端STA模式
4.  AT+CWJAP="wifi","password"
5.  AT+CIPSTART="TCP","目标ip地址",目标端口
6.  AT+CIPMODE=0 开启透传
发送数据有两种方法
一  1.   AT+CIPSEND (开启传输数据)
    2.  >  (这个符号代表等待输入,回车发送,在程序里用\r\n转义发送)
    3.  +++  (发送+++代表退出发送,串口助手里需要关闭发送新行才能关闭发送,程序里用+++\r\n关闭)
二  1.  AT+CIPSEND=num (指定发送数据长度,由于指定长度,达到长度后会自动发送,并退出发送)
    2.  >  (这个符号代表等待输入,回车发送,在程序里用\r\n转义发送)

2.2 STM32操作esp8266模块

在实际使用中,STM32通过串口发送相关的AT指令给模块进行相应的操作。芯片上电后,首先进行串口3的初始化,初始化中波特率设置为115200,同时配置一个100ms的定时器中断,用于判断数据接收的连续性。这里也编写了相应的串口3中断服务函数,用于接收WiFi模块收到的数据。串口3中断服务函数如下:

//通过判断接收连续2个字符之间的时间差不大于100ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过100ms,则认为不是1次连续数据.也就是超过100ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
u16 USART3_RX_STA=0;     
void USART3_IRQHandler(void)
{
    u8 res;     
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据
    {    
 
    res =USART_ReceiveData(USART3);     
    if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
    { 
        if(USART3_RX_STA<USART3_MAX_RECV_LEN)       //还可以接收数据
        {
            TIM_SetCounter(TIM7,0);//计数器清空                       
            if(USART3_RX_STA==0)        
                TIM_Cmd(TIM7, ENABLE);  //使能定时器7 
            USART3_RX_BUF[USART3_RX_STA++]=res;     //记录接收到的值    
        }else 
        {
            USART3_RX_STA|=1<<15;                   //强制标记接收完成
        } 
    }   
 }                                       
} 

串口3初始化完成后,通过发送AT指令进行WiFi模块的初始化,这里编写了esp8266_init()函数对模块进行了相关的配置,代码如下:

void esp8266_init(void)
{
    u8 *p;
    p=mymalloc(SRAMIN,100); //申请100字节的内存
  atk_8266_quit_trans();
    POINT_COLOR=RED;//设置字体为红色 
    LCD_ShowString(30,50,200,16,16,"Wifi Connecting...");   
  while(atk_8266_send_cmd("AT","OK",20));   //检查WiFi模块是否在线
    {
        atk_8266_quit_trans();                       //退出透传
        atk_8266_send_cmd("AT+CIPMODE=0","OK",200);  //关闭透传模式       
    }
    while(atk_8266_send_cmd("ATE0","OK",20));//关闭回显
    atk_8266_send_cmd("AT+CWMODE=3","OK",50);  //设置为STA模式
    atk_8266_send_cmd("AT+RST","OK",40);
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
    atk_8266_send_cmd("AT+CWAUTOCONN=0","OK",50);
    sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",wifiap_ssid,wifiap_password);
    atk_8266_send_cmd(p,"OK",800);   //连接AP
    delay_ms(3000);
    delay_ms(2000);
    atk_8266_send_cmd("AT+CIPMUX=0","OK",20);
    sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",(u8*)ip,(u8*)portnum); 
    while(atk_8266_send_cmd(p,"OK",200)){}   //连接服务端
    Connect_Flag=1;
    atk_8266_send_cmd("AT+CIPMODE=1","OK",200);   //开启透传
    myfree(SRAMIN,p); //释放内存
}

其中,服务器用了PC端的网络调试助手进行模拟,WiFi模块与PC同时连接同一个WiFi热点,在PC上开启网络调试助手作为服务器,IP地址为局域网内分配给PC的I地址,端口号自己定义,如下图所示:


image.png

esp8266模块配置完成后,当需要通过WiFi发送数据时,调用串口3发送函数即可向服务器发送数据。串口3发送数据可以使用库函数USART_SendData(USART_TypeDef* USARTx, uint16_t Data),这里使用该库函数重新封装了一个串口发送函数,可以进行固定长度的数据帧发送。

 /************串口3的发送函数************/
//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)  
{  
    u16 i,j;
    va_list ap;
    va_start(ap,fmt);
    vsprintf((char*)USART3_TX_BUF,fmt,ap);
    va_end(ap);
    i=strlen((const char*)USART3_TX_BUF);//此次发送数据的长度
    for(j=0;j<i;j++)//循环发送数据
    {
      while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);  //等待上次传输完成 
        USART_SendData(USART3,(uint8_t)USART3_TX_BUF[j]);    //发送数据到串口3 
    }
    
}

3.DHT11温湿度模块

3.1 模块介绍

DHT11与单片机之间能采用简单的单总线进行通信,仅仅需要一个I/O口。传感器内部湿度和温度数据40Bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。


DHT11管脚图

从DHT11读取的温湿度数据组成如下所示:


温湿度数据结构

3.2 STM32操作DHT11

检测DHT11是否正常

//等待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读取温湿度并校验

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
    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])
        {
            *humi=buf[0];
            *temp=buf[2];
        }
    }else return 1;
    return 0;       
}

4.运行结果

配置好DHT11和esp8266模块后,在主函数while(1)中循环计时,定时读取温湿度数据并通过WiFi上传至PC端。

    while(1)
    {               
        if(t%10==0)//每100ms读取一次
        {                                     
            DHT11_Read_Data(&temperature,&humidity);        //读取温湿度值                        
            LCD_ShowNum(30+40,150,temperature,2,16);        //显示温度             
            LCD_ShowNum(30+40,170,humidity,2,16);           //显示湿度
            atk_8266_quit_trans();
            atk_8266_send_cmd("AT+CIPSEND","OK",20);         //开始透传 
            sprintf((char*)p,"温度为:%d℃,湿度为:%d %\r\n",temperature,humidity);
            u3_printf("%s",p);
            
        }                  
        delay_ms(100);
        t++;
    }

这里同时用到了LCD显示屏在开发板上显示温湿度的数据,作为辅助功能,本文就不展开讲LCD的配置与使用了。
开发板上读取温湿度的结果图如下


image.png

在PC端网络调试助手上也定时接收到了温湿度数据。


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容