1. 程式人生 > >ESP8266--學習筆記(三)AP和UDP通訊

ESP8266--學習筆記(三)AP和UDP通訊

 ESP8266可以配置三種模式:

  • station模式 : 0x01
  • soft-AP模式 : 0x02
  • soft-AP兼station模式 : 0x03

1、station模式
 station模式可以連線其他的路由器,不能被其他的裝置連線。

2、soft-AP模式
 AccessPoint即網路接入點,可以看成是路由器模式,即可以讓其他的WiFi裝置連線本模組,但是模組自己就不能連線其他的路由器。

3、station+soft-AP模式
 可以看成是station和soft-AP的混合模式,即模組本身自己可以連線其他的路由器也可以被其他的裝置連線。這個模式是主要的使用模式,因為可以實現真正的路由器功能。

一、soft-AP的配置
配置流程

  • 將ESP8266配置成“station+soft-AP模式”
  • 使用wifi_softap_get_config獲取當前ap配置
  • 更改配置引數ssid和password分別為“ESP8266”和“123456789”
  • 使用wifi_softap_set_config設定ap引數
void user_init(){
    struct softap_config config;//首先定義一個soft_config的結構體
    uint8 opmode;

    uart_init(115200,115200);
    wifi_set_opmode(0x03
);//設定為AP模式 opmode = wifi_get_opmode_default(); os_printf("\r\n當前的工作模式:%d\r\n",opmode); wifi_softap_get_config(&config);//這個函式的引數是soft_config的結構體,記得取地址 os_memcpy(config.ssid,"ESP8266",strlen("ESP8266"));//往結構體裡面初始化配置,呼叫os_memcpy函式 os_memcpy(config.password,"123456789",strlen("123456789"
)); config.ssid_len = strlen("ESP8266"); wifi_softap_set_config(&config);//完成AP模式的引數配置,記得取地址 }

然後開啟手機,就可以在WiFi搜尋裡面看到“ESP8266”了!
二、UDP通訊

配置流程

  • 設定遠端IP地址為“255.255.255.255”
  • 設定遠端埠為:1112
  • 設定本地埠為:2525
  • 註冊接收回調函式
  • 註冊傳送回撥函式
  • 建立UDP通訊
  • 獲取station的MAC地址
  • 傳送資料
  • 傳送成功後使用定時器繼續傳送

一、在前面的連線WiFi程式碼基礎上進行修改Wifi_conned函式,完成基本的UDP通訊配置

void ICACHE_FLASH_ATTR Wifi_conned(void *arg){
    static uint8 count=0;
    uint8 status;
    os_timer_disarm(&connect_timer);
    count++;
    status=wifi_station_get_connect_status();
    if(status==STATION_GOT_IP){
        os_printf("Wifi connect success!");//連線WiFi成功

        wifi_set_broadcast_if(STATIONAP_MODE);//設定UDP廣播的傳送介面station+soft-AP模式傳送
        user_udp_espconn.type=ESPCONN_UDP;
        user_udp_espconn.proto.udp=(esp_udp*)os_zalloc(sizeof(esp_udp));
        user_udp_espconn.proto.udp->local_port=2525;//本地埠
        user_udp_espconn.proto.udp->remote_port=1112;//遠端埠

        const char udp_remote_ip[4]={255,255,255,255};//用於存放遠端IP地址
        os_memcpy(&user_udp_espconn.proto.udp->remote_ip,udp_remote_ip,4);

        espconn_regist_recvcb(&user_udp_espconn,user_udp_recv_cb);//接收回調函式
        espconn_regist_sentcb(&user_udp_espconn,user_udp_sent_cb);//傳送回撥函式
        espconn_create(&user_udp_espconn);//建立UDP連線
        user_udp_send(); //傳送出去
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,NULL);
}

二、配置傳送和接收回調函式

void ICACHE_FLASH_ATTR user_udp_sent_cb(void *arg){//傳送回撥函式
    os_printf("\r\nUDP傳送成功!\r\n");
    os_timer_disarm(&test_timer);//定個時傳送
    os_timer_setfn(&test_timer,user_udp_send,NULL);
    os_timer_arm(&test_timer,1000,NULL);//定1秒鐘傳送一次
}

void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg,
        char *pdata,
        unsigned short len){//接收回調函式
    os_printf("UDP已經接收資料:%s",pdata);//UDP接收到的資料打印出來
}

三、註冊UDP通訊函式,實際上我只是將本機的MAC地址進行UDP廣播

void ICACHE_FLASH_ATTR user_udp_send(void){//UDP傳送函式
    char yladdr[6];
    char DeviceBuffer[40]={0};//將獲取的MAC地址格式化輸出到一個buffer裡面
    wifi_get_macaddr(STATION_IF,yladdr);//查詢MAC地址
    os_sprintf(DeviceBuffer,"裝置地址為"MACSTR"!!!\r\n",MAC2STR(yladdr));//格式化MAC地址
    espconn_sent(&user_udp_espconn,DeviceBuffer,os_strlen(DeviceBuffer));
}

四、所有程式碼

#include "osapi.h"
#include "ets_sys.h"
#include "driver/uart.h"
#include "user_interface.h"
#include "espconn.h"
#include "mem.h"

struct espconn user_udp_espconn;

ETSTimer connect_timer;
ETSTimer test_timer;

void ICACHE_FLASH_ATTR user_udp_send(void){//UDP傳送函式
    char yladdr[6];
    char DeviceBuffer[40]={0};//將獲取的MAC地址格式化輸出到一個buffer裡面
    wifi_get_macaddr(STATION_IF,yladdr);//查詢MAC地址
    os_sprintf(DeviceBuffer,"裝置地址為"MACSTR"!!!\r\n",MAC2STR(yladdr));//格式化MAC地址
    espconn_sent(&user_udp_espconn,DeviceBuffer,os_strlen(DeviceBuffer));
}

void ICACHE_FLASH_ATTR user_udp_sent_cb(void *arg){//傳送回撥函式
    os_printf("\r\nUDP傳送成功!\r\n");
    os_timer_disarm(&test_timer);//定個時傳送
    os_timer_setfn(&test_timer,user_udp_send,NULL);
    os_timer_arm(&test_timer,1000,NULL);//定1秒鐘傳送一次
}

void ICACHE_FLASH_ATTR user_udp_recv_cb(void *arg,
        char *pdata,
        unsigned short len){//接收回調函式
    os_printf("UDP已經接收資料:%s",pdata);//UDP接收到的資料打印出來
}

void ICACHE_FLASH_ATTR Wifi_conned(void *arg){
    static uint8 count=0;
    uint8 status;
    os_timer_disarm(&connect_timer);
    count++;
    status=wifi_station_get_connect_status();
    if(status==STATION_GOT_IP){
        os_printf("Wifi connect success!");//連線WiFi成功

        wifi_set_broadcast_if(STATIONAP_MODE);//設定UDP廣播的傳送介面station+soft-AP模式傳送
        user_udp_espconn.type=ESPCONN_UDP;
        user_udp_espconn.proto.udp=(esp_udp*)os_zalloc(sizeof(esp_udp));
        user_udp_espconn.proto.udp->local_port=2525;
        user_udp_espconn.proto.udp->remote_port=1112;

        const char udp_remote_ip[4]={255,255,255,255};//用於存放遠端IP地址
        os_memcpy(&user_udp_espconn.proto.udp->remote_ip,udp_remote_ip,4);

        espconn_regist_recvcb(&user_udp_espconn,user_udp_recv_cb);//接收回調函式
        espconn_regist_sentcb(&user_udp_espconn,user_udp_sent_cb);//傳送回撥函式
        espconn_create(&user_udp_espconn);//建立UDP連線
        user_udp_send(); //傳送出去
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,NULL);
}

void ICACHE_FLASH_ATTR scan_done(void *arg,STATUS status){

     uint8 ssid[33];
      char temp[128];
      struct station_config stationConf;
      if (status == OK)
       {
         struct bss_info *bss_link = (struct bss_info *)arg;
         bss_link = bss_link->next.stqe_next;//ignore first

         while (bss_link != NULL)
         {
           os_memset(ssid, 0, 33);
           if (os_strlen(bss_link->ssid) <= 32)
           {
             os_memcpy(ssid, bss_link->ssid, os_strlen(bss_link->ssid));
           }
           else
           {
             os_memcpy(ssid, bss_link->ssid, 32);
           }
           os_sprintf(temp,"+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",
                      bss_link->authmode, ssid, bss_link->rssi,
                      MAC2STR(bss_link->bssid),bss_link->channel);
           os_printf("%s",temp);
           bss_link = bss_link->next.stqe_next;
         }
        os_memcpy(&stationConf.ssid, "MERCURY_2784", 32);
        os_memcpy(&stationConf.password, "123456789", 64);
        wifi_station_set_config_current(&stationConf);
        wifi_station_connect();
        os_timer_setfn(&connect_timer,Wifi_conned,NULL);
        os_timer_arm(&connect_timer,2000,NULL);
       }
       else
       {
     //     os_sprintf(temp,"err, scan status %d\r\n", status);
     //     uart0_sendStr(temp);
        os_printf("%s","Error");
       }
}
void to_scan(void)  { wifi_station_scan(NULL,scan_done); }

void user_init(){
    struct softap_config config;
    uint8 opmode;
    uart_init(115200,115200);
    wifi_set_opmode(0x03);//設定為AP模式
    opmode = wifi_get_opmode_default();
    os_printf("\r\n當前的工作模式:%d\r\n",opmode);

    wifi_softap_get_config(&config);
    os_memcpy(config.ssid,"ESP8266",strlen("ESP8266"));
    os_memcpy(config.password,"123456789",strlen("123456789"));
    config.ssid_len = strlen("ESP8266");
    wifi_softap_set_config(&config);

    system_init_done_cb(to_scan);//掃描WiFi需要系統初始化完成之後
}

void user_rf_pre_init(){

}

效果:

  • 必須成功地連上有用的WIFi
  • 配置好TCP/UDP測試工具軟體

這裡寫圖片描述

手機APP也可以做到這裡寫圖片描述