ESP8266: отправка кадра маяка в режиме глубокого сна не работает должным образом

У меня проблема с моим проектом esp8266. Моя цель - использовать esp8266 для передачи кадров маяка каждую секунду, чтобы мое устройство Android или мой ноутбук могли получать их и отображать в списке точек доступа, к которым я могу подключиться. Вот мой код, который я написал:

#include <ESP8266WiFi.h>
extern "C" {
  #include "user_interface.h"
}

void setup() {
  delay(500);
  sendBeacon("ESP8266");
  ESP.deepSleep(10e5);
}

void loop() {
}

void sendBeacon(char* ssid) {
    // Randomize channel //
    byte channel = 1; 
    wifi_set_channel(channel);

    uint8_t packet[128] = { 0x80, 0x00, //Frame Control 
                        0x00, 0x00, //Duration
                /*4*/   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address 
                /*10*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
                /*16*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
                /*22*/  0xc0, 0x6c, //Seq-ctl
                //Frame body starts here
                /*24*/  0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
                /*32*/  0xFF, 0x00, //Beacon interval
                /*34*/  0x01, 0x04, //Capability info
                /* SSID */
                /*36*/  0x00
                };

    int ssidLen = strlen(ssid);
    packet[37] = ssidLen;

    for(int i = 0; i < ssidLen; i++) {
      packet[38+i] = ssid[i];
    }

    uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
                        0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };

    for(int i = 0; i < 12; i++) {
      packet[38 + ssidLen + i] = postSSID[i];
    }

    packet[50 + ssidLen] = channel;

    // get SRC MAC
    unsigned char mac[6];
    WiFi.macAddress(mac);
    packet[10] = packet[16] = mac[0];
    packet[11] = packet[17] = mac[1];
    packet[12] = packet[18] = mac[2];
    packet[13] = packet[19] = mac[3];
    packet[14] = packet[20] = mac[4];
    packet[15] = packet[21] = mac[5];

    int packetSize = 51 + ssidLen;

    wifi_send_pkt_freedom(packet, packetSize, 0);
    delay(1);
}

Я использовал tcpdump для захвата этих кадров, и да, они есть. Но я все еще не мог видеть его в списке точек доступа на своем ноутбуке и устройстве Android. Я увижу это, если перестану использовать режим глубокого сна. Например:

#include <ESP8266WiFi.h>
extern "C" {
  #include "user_interface.h"
}

void setup() {
  delay(500);
//  sendBeacon("ESP8266");
//  ESP.deepSleep(10e5);
}

void loop() {
  sendBeacon("ESP8266");
}

void sendBeacon(char* ssid) {
    // Randomize channel //
    byte channel = 1; 
    wifi_set_channel(channel);

    uint8_t packet[128] = { 0x80, 0x00, //Frame Control 
                        0x00, 0x00, //Duration
                /*4*/   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address 
                /*10*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
                /*16*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
                /*22*/  0xc0, 0x6c, //Seq-ctl
                //Frame body starts here
                /*24*/  0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
                /*32*/  0xFF, 0x00, //Beacon interval
                /*34*/  0x01, 0x04, //Capability info
                /* SSID */
                /*36*/  0x00
                };

    int ssidLen = strlen(ssid);
    packet[37] = ssidLen;

    for(int i = 0; i < ssidLen; i++) {
      packet[38+i] = ssid[i];
    }

    uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
                        0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };

    for(int i = 0; i < 12; i++) {
      packet[38 + ssidLen + i] = postSSID[i];
    }

    packet[50 + ssidLen] = channel;

    // get SRC MAC
    unsigned char mac[6];
    WiFi.macAddress(mac);
    packet[10] = packet[16] = mac[0];
    packet[11] = packet[17] = mac[1];
    packet[12] = packet[18] = mac[2];
    packet[13] = packet[19] = mac[3];
    packet[14] = packet[20] = mac[4];
    packet[15] = packet[21] = mac[5];

    int packetSize = 51 + ssidLen;

    wifi_send_pkt_freedom(packet, packetSize, 0);
    delay(1);
}

Кто-нибудь знает, почему? Пожалуйста, помогите мне получить это, спасибо!


person Hòa Lê Việt    schedule 14.09.2017    source источник


Ответы (1)


Прежде всего, ESP.deepSleep(10e5) переводит процессор в спящий режим на 100 мс, а не на секунду. Правильным будет ESP.deepSleep(10e6). Во-вторых, вы пытаетесь отправить только один пакет каждую секунду или около того, довольно сложно убедиться, что чтение Wi-Fi с устройства точно получит этот пакет и отобразит его в списке SSID. Из моих экспериментов мне приходилось отправлять три пакета каждые 200 мс, чтобы убедиться, что он отображается на моем мобильном телефоне Android и ПК. Вы можете попробовать поиграть с количеством пакетов, которые вы отправляете, и интервалом, чтобы увидеть, что подходит вам лучше всего...

Кроме того, обязательно правильно настройте ESP в функции настройки. Когда я попробовал свой аналогичный код, мне пришлось использовать две инструкции: wifi_set_opmode(STATION_MODE) и wifi_promiscuous_enable(1)

person Hiram    schedule 17.01.2018