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

参考: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
}

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

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用ESP8266和OLED 1306显示屏制作网络时钟是一个很有趣的项目。下面是一些步骤来帮助你实现它: 1. 硬件准备: - ESP8266开发板:你可以选择NodeMCU或者Wemos D1 mini等。 - OLED 1306显示屏:确保你有一个兼容I2C接口的OLED 1306显示屏。 - 杜邦线:用于连接ESP8266和OLED显示屏。 2. 软件准备: - Arduino IDE:确保你已经安装了Arduino IDE,并正确设置了ESP8266开发板的支持。 - Adafruit SSD1306库:在Arduino IDE中安装Adafruit SSD1306库,用于控制OLED显示屏。 3. 连接: - 连接ESP8266和OLED显示屏。将ESP8266的SDA引脚连接到OLED显示屏的SDA引脚,将ESP8266的SCL引脚连接到OLED显示屏的SCL引脚。 4. 编程: - 打开Arduino IDE,创建一个新的Arduino项目。 - 导入Adafruit SSD1306库:在Arduino IDE中选择“工具”->“库管理器”,搜索并安装“Adafruit SSD1306”库。 - 编写代码:使用以下代码作为起点,你可以自定义它来满足你的需求。 ```cpp #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 0 // OLED显示屏复位引脚 Adafruit_SSD1306 display(OLED_RESET); void setup() { // 初始化OLED显示屏 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // 传入OLED地址 display.clearDisplay(); display.setTextColor(WHITE); } void loop() { display.clearDisplay(); // 获取当前时间 int hours = hour(); int minutes = minute(); int seconds = second(); // 在OLED上显示时间 display.setTextSize(2); display.setCursor(0, 0); display.print(hours); display.print(":"); if (minutes < 10) display.print("0"); display.print(minutes); display.print(":"); if (seconds < 10) display.print("0"); display.println(seconds); display.display(); delay(1000); // 更新时间间隔 } ``` 5. 上传代码: - 连接ESP8266到电脑,并确保选择了正确的开发板和端口。 - 编译并上传代码到ESP8266开发板。 这样,你的ESP8266和OLED 1306显示屏网络时钟就完成了。它会通过无线网络连接获取当前时间,并在OLED显示屏上实时显示。你还可以根据需要进行更多的定制和功能扩展。祝你成功!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值