Rtthread學習筆記(二十)RT-Thread使用Esp8266,連接遠端服務器IP端口發送數據

一、步驟

將RTThread移植到STM32上,添加esp8266,連接wifi,從而實現stm32與服務器通訊。其中STM32做客戶端,在華爲雲服務器上開的網絡調試助手(具有固定IP端口)做服務器,esp8266的作用是將串口數據透傳到網絡上,是客戶端的一部分。
STM32與esp8266通訊採用串口通訊,應用層協議使用AT指令集,STM32做AT客戶端(AT Client),esp8266做AT 服務器(AT Server),注意區別上面的網絡層的客戶端與服務器。使用esp8266,連接wifi,獲取自身本地IP,進入透傳模式,向遠端服務器發送數據。
在這裏插入圖片描述
這個esp8266在Rtthread上使用真是花了好幾天時間調通(用的是野火指南者開發板自帶了ESP8266,也可以整一個模塊直接連在對應的引腳上)。先發送數據成功,大體上用着,以後有項目再仔細研究。程序在末尾貼出。
參照資料RTThread-ESP8266章節
RTThread-AT章節

使用串口3:
在這裏插入圖片描述

1、配置時鐘

依舊使用RT-Thread Studio創建一個新工程,上來第一件事先配置外部時鐘,替換board.c中的void SystemClock_Config(void)
在這裏插入圖片描述

2、開啓Uart3

在board.h中開啓串口3的宏定義,並設置上引腳
在這裏插入圖片描述

3、添加AT軟件包

在這裏插入圖片描述
進行詳細配置,保存
在這裏插入圖片描述

4、編譯

保存編譯後會出現一個錯誤,這是缺少libc的接口函數,開啓RT-Thread Setting 中的libc
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

5.添加兩個文件app_esp8266.c app_esp8266.h

在這裏插入圖片描述

6.使能esp8266、開啓重啓esp8266

指南者開發板的使能引腳是PB8,上電初始化前需要先進行高電平使能;rst重啓引腳是PB9,低電平復位,開機復位的原因是,因爲在調試過程中我只是調試程序未斷電模塊,回有模塊初始化失敗的情況出現,因此在程序中主動控制一下復位引腳。這倆引腳都是可以根據實際需求更換的。
在這裏插入圖片描述

7.修改打印信息問題

使能重啓後編譯下載,會看到串口打印信息,顯示接收到字符串超出接收範圍(也可能是這塊板載的模塊會這樣),如果自行連接的esp8266沒出現就不需要調整這塊內容。出現接收字符串超出範圍是因爲模塊重啓會發出一長串字符導致的,解決方式有兩種,第一種去掉系統初始化的重啓語句(在esp8266初始化的線程中esp8266_init_thread_entry),第二種加大接收回應的字符串大小。我的是直接註釋掉重啓,加長延時到2000ms。
在這裏插入圖片描述
第一種方法:去掉系統初始化的重啓語句(在esp8266初始化的線程中esp8266_init_thread_entry),稍微加長點延時,因爲我們在程序初始化的時候已經重啓過,這裏去掉重啓語句也沒關旭,但是需要適當加長延時給模塊充裕的重啓時間。
在這裏插入圖片描述
在這裏插入圖片描述
第二種方法:加大接收數據的緩衝組大小

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

8.重新在應用函數中編寫初始化函數

在這裏插入圖片描述
重新初始化無非就是對esp8266重新進行一遍AT指令的設置。
在這裏插入圖片描述
在這裏插入圖片描述

9.通訊測試結果

我這裏是手裏正好有個華爲雲服務器,我直接在雲服務器上開啓了一個網絡調試助手,將服務器的10086端口映射到了內部192.168.0.7的10086端口上(雲服務器安全組-入方向規則),在內部主機開啓了10086的端口,外部設備就可以通過連接服務器的固定IP的10086端口,來向內部主機發送數據了。如果不是雲服務器,恰巧有條件控制到的路由器使用的是固定IP,也可以配置例如華3路由器–網絡連接高級設置-虛擬網絡映射,從而映射到你本地的端口上。不想這麼費事,直接連接設置個局域網內的本體端口,連接上一樣測試數據。
在這裏插入圖片描述
設備:
在這裏插入圖片描述
服務器:
在這裏插入圖片描述

二、代碼

app_esp8266.c

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-05-08            the first version
 */
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include <rtconfig.h>
#include <rtdbg.h>
#include <at_device_esp8266.h>
#include "app_esp8266.h"

/*使能esp8266 */
void Set_Esp8266_En(void)
{
    rt_pin_mode(GET_PIN(B, 8), PIN_MODE_OUTPUT);
    rt_pin_write(GET_PIN(B, 8), 1);
    rt_kprintf("esp8266_Enable,PB8=1\r\n");
}
INIT_PREV_EXPORT(Set_Esp8266_En);
/*重啓esp8266 */
void Reset_Esp8266(void)
{
    rt_pin_mode(GET_PIN(B, 9), PIN_MODE_OUTPUT);
    rt_pin_write(GET_PIN(B, 9), 0);
    rt_thread_mdelay(200);
    rt_pin_write(GET_PIN(B, 9), 1);
    rt_kprintf("Reset_Esp8266\r\n");
}
INIT_PREV_EXPORT(Reset_Esp8266);

/*esp8266結構體回調函數 */
void CallBack(char *Cmd,float Cycle)
{
}

/*初始化esp8266命令結構體,回調函數暫時沒用到 */
typEsp8266_t typEsp8266CmdTable[]=
{
    {"AT+CWMODE=1",                                 CallBack},          //1:工作在客戶端模式
    {"AT+CWJAP=\"QIANTAI\",\"12345678#\"",          CallBack},          //2: 連接無線
    {"AT+CIFSR",                                    CallBack},          //3: 獲取自身的IP及Mac地址
    {"AT+CIPMUX=0",                                 CallBack},          //4:關閉多連接
    {"AT+CIPSTART=\"TCP\",\"121.36.63.46\",10086",  CallBack},          //5:連接服務器IP端口
    {"AT+CIPMODE=1",                                CallBack},          //6:透傳模式
    {"AT+CIPSEND",                                  CallBack}           //7:啓動透傳,之後esp8266進入透傳狀態,發送的數據將轉發向服務器,不再識別AT指令
};

/*重新配置esp8266 */
int esp8266_init_Reconfiguring(void)
{
    at_response_t resp = RT_NULL;
    const char *line_buffer = RT_NULL;

    /* 創建響應結構體,設置最大支持響應數據長度爲 512 字節,響應數據行數無限制,超時時間爲8 秒 */
    resp = at_create_resp(512, 0, rt_tick_from_millisecond(8000));
    if (!resp)
    {
        LOG_E("No memory for response structure!");
        return -RT_ENOMEM;
    }
    /* 發送 AT 命令並接收 AT Server 響應數據,數據及信息存放在 resp 結構體中並打印出來 */
    for(int i=0;i<array_sizeof(typEsp8266CmdTable);i++)
    {
        if (at_exec_cmd(resp, typEsp8266CmdTable[i].CmdString) != RT_EOK)               //發送AT指令
        {
            LOG_E("%s指令沒收到esp8266的迴應",typEsp8266CmdTable[i].CmdString);
        }
        else
        {
            for(rt_size_t line_num = 1; line_num <= resp->line_counts; line_num++)      //將回應的數據打印出來
                {
                    if((line_buffer = at_resp_get_line(resp, line_num)) != RT_NULL)
                    {
                        LOG_D("%s line%d Response buf: %s",typEsp8266CmdTable[i].CmdString,line_num, line_buffer);
                    }
                    else
                    {
                        LOG_E("Parse line buffer error!");
                    }
                }
        }
    }
    rt_thread_mdelay(20);
    at_exec_cmd( resp, "由開發板發來的第一次測試數據1");
    at_exec_cmd( resp, "由開發板發來的第二次測試數據2");

    /* 命令發送成功 */
    LOG_D("AT Client send commands to AT Server success!");

    /* 刪除響應結構體 */
    at_delete_resp(resp);

    return RT_EOK;
}

app_esp8266.h

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-05-08            the first version
 */
#ifndef APPLICATIONS_APP_ESP8266_H_
#define APPLICATIONS_APP_ESP8266_H_

#define array_sizeof(a) (sizeof(a) / sizeof(a[0]))
/* 服務函數結構體*/
typedef struct typ_Esp8266_handler
{
  char  *CmdString; //命令字符串
  void  (*CmdOperate)(char *Cmd,float Cycle);//命令執行的功能操作
} typEsp8266_t;

extern int esp8266_init_Reconfiguring(void);

#endif /* APPLICATIONS_APP_ESP8266_H_ */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章