ESP8266 使用笔记(六) 扫描网络和连接网络

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/P_xiaojia/article/details/82559268

参考:https://blog.csdn.net/qq_28877125/article/details/62319191
使用WiFi进行联网操作
这里写图片描述
整体调用的架构
这里写图片描述
1.获取wifi当前的工作模式
wifi的工作模式:
第一种:STA模式
任何一种无线网卡都可以运行在此模式下,这种模式也可以称为默认模式。在此模式下,无线网卡发送连接与认证消息给热点,热点接收到后完成认证后,发回成功认证消息,此网卡接入无线网络。这种模式下,wifi工作于从模式
第二种:AccessPoint模式
在一个无线网络环境中,无线热点是作为一个主设备,工作于主模式(Master mode)。通过管理控制可控制的STA,从而组成无线网络,也有相应的安全控制策略。由AP形成的网络,由AP的MAC地址唯一识别。热点完成创建后,会由热点创建一个被别的设备可识别的名称,称为SSID。在Linux下,要使用AP模式,必须使系统支持hostapd。
这里写图片描述
代码:
//获取wifi的工作模式
opmode = wifi_get_opmode();
os_printf(“\r\n 当前模式为:%d\r\n”,opmode);
现象:
这里写图片描述

2.设置wifi的工作模式
这里写图片描述
这里写图片描述
代码
//设置wifi的工作模式
opmode_error = wifi_set_opmode (0x03);
if(false == opmode_error)
{
os_printf(“set error\r\n”);
}

3.扫描所有附近所有的AP
这里写图片描述
这里写图片描述
这里写图片描述
system_init_done_cb(to_scan);//等到系统完成初始化就扫描

void to_scan(void)
{
wifi_station_scan(NULL,scan_done);
}

参考AT固件源码实现
void ICACHE_FLASH_ATTR
scan_done(void *arg,STATUS status)
{

  char ssid[33] = "MEIZU";
  char  password[64] = "21103690";
  char temp[128];

  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;
     }
   }
   else
   {
 //     os_sprintf(temp,"err, scan status %d\r\n", status);
 //     uart0_sendStr(temp);
    os_printf("%s","Error");
   }

}
这里写图片描述

4.连接某一个路由
这里写图片描述
这里写图片描述
这里写图片描述
//扫描完成以后就开始连接WiFi了
os_memcpy(&stationConf.ssid,ssid, 32);//WiFi名字加入到配置中去
os_memcpy(&stationConf.password,password,64);//WiFi密码加入到配置中去
wifi_station_set_config_current(&stationConf);//将设置好的配置加入到配置函数中去
wifi_station_connect();//在非user_init()入口函数中连接WiFi,需要调用这个函数

5.定时扫描
这里写图片描述
这里写图片描述
这里写图片描述
os_timer_setfn(&connect_timer,Wifi_conned,NULL);//调用自己写的WiFi连接函数
os_timer_arm(&connect_timer,2000,1);//设置连接WiFi定时器

其他一些知识
ICACHE_FLASH_ATTR
 添加了这个宏的函数就会存放到ROM里面去,CPU仅在调用的时候才将它们读到cache(缓存)中运行,没有添加这个宏的函数将一开始上电就运行在RAM中;由于模块的空间有限,我们无法将所有的代码都一次性加载到RAM中去运行,因此在大部分函数前添加这个特殊的宏。
 需要注意的是不要在GPIO或UART中断处理函数中调用带有“ICACHE_FLASH_ATTR”宏的函数,否则将引起异常

整个user_main.c的代码

#include "ets_sys.h"
#include "osapi.h"

#include "user_interface.h"

#include "user_devicefind.h"
#include "user_webserver.h"

#if ESP_PLATFORM
#include "user_esp_platform.h"
#endif

uint32 priv_param_start_sec;

/******************************************************************************
 * FunctionName : user_rf_cal_sector_set
 * Description  : SDK just reversed 4 sectors, used for rf init data and paramters.
 *                We add this function to force users to set rf cal sector, since
 *                we don't know which sector is free in user's application.
 *                sector map for last several sectors : ABCCC
 *                A : rf cal
 *                B : rf init data
 *                C : sdk parameters
 * Parameters   : none
 * Returns      : rf cal sector
*******************************************************************************/
os_timer_t  connect_timer;
struct station_config stationConf;

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!");
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,1);
}


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

      char ssid[33] = "MEIZU";
      char  password[64] = "21103690";
      char temp[128];

      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;
         }

               //扫描完成以后就开始连接WiFi了
               os_memcpy(&stationConf.ssid,ssid, 32);//WiFi名字加入到配置中去
               os_memcpy(&stationConf.password,password,64);//WiFi密码加入到配置中去

               wifi_station_set_config_current(&stationConf);//将设置好的配置加入到配置函数中去

               wifi_station_connect();//在非user_init()入口函数中连接WiFi,需要调用这个函数

               os_timer_setfn(&connect_timer,Wifi_conned,NULL);//调用自己写的WiFi连接函数
               os_timer_arm(&connect_timer,2000,1);//设置连接WiFi定时器

       }
       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);
}

uint32 ICACHE_FLASH_ATTR
user_rf_cal_sector_set(void)
{
    enum flash_size_map size_map = system_get_flash_size_map();
    uint32 rf_cal_sec = 0;

    switch (size_map) {
        case FLASH_SIZE_4M_MAP_256_256:
            rf_cal_sec = 128 - 5;
            priv_param_start_sec = 0x3C;
            break;

        case FLASH_SIZE_8M_MAP_512_512:
            rf_cal_sec = 256 - 5;
            priv_param_start_sec = 0x7C;
            break;

        case FLASH_SIZE_16M_MAP_512_512:
            rf_cal_sec = 512 - 5;
            priv_param_start_sec = 0x7C;
            break;
        case FLASH_SIZE_16M_MAP_1024_1024:
            rf_cal_sec = 512 - 5;
            priv_param_start_sec = 0xFC;
            break;

        case FLASH_SIZE_32M_MAP_512_512:
            rf_cal_sec = 1024 - 5;
            priv_param_start_sec = 0x7C;
            break;
        case FLASH_SIZE_32M_MAP_1024_1024:
            rf_cal_sec = 1024 - 5;
            priv_param_start_sec = 0xFC;
            break;

        case FLASH_SIZE_64M_MAP_1024_1024:
            rf_cal_sec = 2048 - 5;
            priv_param_start_sec = 0xFC;
            break;
        case FLASH_SIZE_128M_MAP_1024_1024:
            rf_cal_sec = 4096 - 5;
            priv_param_start_sec = 0xFC;
            break;
        default:
            rf_cal_sec = 0;
            priv_param_start_sec = 0;
            break;
    }

    return rf_cal_sec;
}

void ICACHE_FLASH_ATTR
user_rf_pre_init(void)
{
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
    uint8 opmode;
    uint8 opmode_error;

    uart_init(115200,115200);
//  uart0_sendStr("\r\nhello world\r\n");

    //获取wifi的工作模式
    opmode = wifi_get_opmode();
    os_printf("\r\n 当前模式为:%d\r\n",opmode);

    //设置wifi的工作模式
    opmode_error = wifi_set_opmode  (0x03);
    if(false == opmode_error)
    {
        os_printf("set error\r\n");
    }

    //获取wifi的工作模式
//  opmode = wifi_get_opmode();
//   os_printf("\r\n 当前模式为:%d\r\n",opmode);

    //获取AP信息
    system_init_done_cb(to_scan);//等到系统完成初始化就扫描

//  os_printf("hello  i am liangjia\r\n");
//   os_printf("SDK version:%s\n", system_get_sdk_version());
//  os_printf("hello  i am liangjia\r\n");
#if ESP_PLATFORM
    /*Initialization of the peripheral drivers*/
    /*For light demo , it is user_light_init();*/
    /* Also check whether assigned ip addr by the router.If so, connect to ESP-server  */
    user_esp_platform_init();
#endif
    /*Establish a udp socket to receive local device detect info.*/
    /*Listen to the port 1025, as well as udp broadcast.
    /*If receive a string of device_find_request, it rely its IP address and MAC.*/
    user_devicefind_init();

    /*Establish a TCP server for http(with JSON) POST or GET command to communicate with the device.*/
    /*You can find the command in "2B-SDK-Espressif IoT Demo.pdf" to see the details.*/
    /*the JSON command for curl is like:*/
    /*3 Channel mode: curl -X POST -H "Content-Type:application/json" -d "{\"period\":1000,\"rgb\":{\"red\":16000,\"green\":16000,\"blue\":16000}}" http://192.168.4.1/config?command=light      */
    /*5 Channel mode: curl -X POST -H "Content-Type:application/json" -d "{\"period\":1000,\"rgb\":{\"red\":16000,\"green\":16000,\"blue\":16000,\"cwhite\":3000,\"wwhite\",3000}}" http://192.168.4.1/config?command=light      */
#ifdef SERVER_SSL_ENABLE
    user_webserver_init(SERVER_SSL_PORT);
#else
    user_webserver_init(SERVER_PORT);
#endif
}

实验现象:
用手机开一个热点先
这里写图片描述
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页