Advanced Users can post their questions and comments here for the not so Newbie crowd.

Moderator: eriksl

User avatar
By quackmore
#81658 put together some code
Code: Select allstruct fast_scan
{
    char ssid_len;
    char *ch_list;
    char ch_count;
    int ch_idx;
    void (*callback)(void *);
    void *param;
    sint8 best_rssi;
    char best_channel;
    char best_bssid[6];
};

static struct scan_config qs_cfg;
static struct fast_scan qs_vars;

static void ICACHE_FLASH_ATTR fast_scan_check_results(void *arg, STATUS status)
{
    if (status == OK)
    {
        struct bss_info *scan_list = (struct bss_info *)arg;
        while (scan_list)
        {
            // check for ssid
            if (0 == os_strncmp((char *)qs_cfg.ssid, (char *)scan_list->ssid, qs_vars.ssid_len))
            {
                if (scan_list->rssi > qs_vars.best_rssi)
                {
                    // update bssid, channel and rssi
                    qs_vars.best_rssi = scan_list->rssi;
                    qs_vars.best_channel = scan_list->channel;
                    os_memcpy(qs_vars.best_bssid, scan_list->bssid, 6);
                }
            }
            scan_list = scan_list->next.stqe_next;
        }
    }
    // move to next channel
    qs_vars.ch_idx++;
    if (qs_vars.ch_idx < qs_vars.ch_count)
    {
        qs_cfg.channel = qs_vars.ch_list[qs_vars.ch_idx];
        wifi_station_scan(&qs_cfg, (scan_done_cb_t)fast_scan_check_results);
    }
    else
    {
        // that's all, scan completed
        if (qs_vars.callback)
            qs_vars.callback(qs_vars.param);
    }
}

void ICACHE_FLASH_ATTR fast_scan_for_best_ap(char *ssid, char *ch_list, char ch_count, void (*callback)(void *), void *param)
{
    // init results
    qs_vars.best_rssi = -128;
    qs_vars.best_channel = 0;
    os_memset(qs_vars.best_bssid, 0, 6);

    // init algo vars
    qs_vars.ssid_len = os_strlen(ssid);
    qs_vars.ch_list = ch_list;
    qs_vars.ch_count = ch_count;
    qs_vars.callback = callback;
    qs_vars.param = param;

    qs_cfg.ssid = (uint8 *)ssid;
    qs_cfg.show_hidden = 0;
    qs_cfg.scan_type = WIFI_SCAN_TYPE_ACTIVE;
    qs_cfg.scan_time.active.min = 0;
    qs_cfg.scan_time.active.max = 30;

    // move to the first channel
    qs_vars.ch_idx = 0;
    if (qs_vars.ch_idx < qs_vars.ch_count)
    {
        qs_cfg.channel = qs_vars.ch_list[qs_vars.ch_idx];
        wifi_station_scan(&qs_cfg, (scan_done_cb_t)fast_scan_check_results);
    }
    else
    {
        // that's all, scan completed
        if (qs_vars.callback)
            qs_vars.callback(qs_vars.param);
    }
}


and did some more test

apparently on wifi_station_connect a channel scan is always performed (I always get the scandone message on the serial debug) but if you set the channel (wifi_set_channel) probably (hard to verify) that channel is checked first

anyway

using the code above and scanning channels 1, 6 and 11 I managed to connect to the AP in less than 1 second (measuring from before the scan to the GOT_IP event)
with my setup a regular connect (that I still prefer) takes around 4 seconds
User avatar
By eriksl
#81671 This may be well-known maybe not, who knows; after a succesful connect, the bssid and channel are stored in RTC memory (by the SDK code itself). After a normal reset (I guess a timed reset from RTC power-down and wakeup also counts), this bssid and channel are tried first. In my experience the client connects to the ap within one second. It's the DHCP that takes long, too long to my taste.
User avatar
By davydnorris
#81767 I suspected DHCP was what was taking a lot of time - so what may speed things up a lot would be to get the IP info and DHCP lease time and cache that so that IP configuration after deep sleep is super fast. Looking at the functions, I can't see any access to DHCP lease time - looks like another case of rolling our own :-(

I had a look at DNS address caching for SNTP servers, which is the other expensive call and unfortunately most of the SNTP servers in the public domain have a very short TTL, so that's not viable for me but it may be for others who run their own time server.

That's also the case for the public cloud platforms I use, which have a bit longer TTL but still not long enough for me to be able to cache details between sleeps.
User avatar
By eriksl
#81787 How about measuring it? You can get a signal (callback) when association has completed and when ip address is assigned. I'd like to see for both when they take after start (when internal timer = 0), I guess it shouldn't be that difficult to store the timestamps somewhere or log them?