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测试工具软件

ESP8266--学习笔记(三)AP和UDP通信_第1张图片

手机APP也可以做到ESP8266--学习笔记(三)AP和UDP通信_第2张图片

你可能感兴趣的:(C,ESP8266)