Проблемы с подключением к точке доступа WiFi101

В настоящее время у меня есть две платы Arduino Zero (с использованием микроконтроллера SAMD21), каждая с подключенным модулем Wi-Fi ATWINC1500. Я установил одно из этих устройств как точку доступа Wi-Fi с работающим на ней сервером, в то время как другое устройство является клиентом, который пытается подключиться к точке доступа, а затем отправить некоторые данные на сервер.

Насколько я могу судить, точка доступа и сервер на первом блоке созданы правильно. Я могу использовать telnet на отдельном устройстве Android для подключения к точке доступа и отправки данных на сервер. К сожалению, когда я пытаюсь подключиться к точке доступа/серверу с помощью другой платы Arduino, это никогда не удается.

Вот код, который я использую на первой плате для создания точки доступа и сервера:

WiFiServer server(23);
WiFiClient client;

void LaunchAccessPoint ()
{
    uint8_t begin_ap_status = WiFi.beginAP(access_point_name);    
    if (begin_ap_status == WL_AP_LISTENING)
    {
        server.begin();
    }
}

void HandleClientConnection ()
{
    String result;
    client = server.available();
    if (client && client.connected() && client.available())
    {
        while (client.available())
        {
            result += (char) client.read();
        }

        client.stop();
    }
    
    SerialUSB.println(result);
}

void setup()
{
    /* ... some code in this function has been cut for clarity ... */
    LaunchAccessPoint();
}

void loop()
{
    /* ... some code in this function has been cut for clarity ... */
    HandleClientConnection();
}

Между тем, вот код клиента, который пытается подключиться к точке доступа / серверу:

bool ConnectToWifi ()
{
    uint8_t wifi_connection_result = 0;
    wifi_connection_result = WiFi.begin(wifi_ssid);
    return (wifi_connection_result == WL_CONNECTED) 
}

void PublishData (const char *json_string)
{
    WiFiClient client = WiFiClient();
    int client_connect_success = client.connect(IPAddress(192, 168, 1, 1), 23);
    if (client_connect_success)
    {
        int client_bytes_written = client.println(json_string);
        client.stop();
    }
}

void setup ()
{
    /* some code cut for clarity */
    ConnectToWifi();
}

void loop()
{
    /* some code cut for clarity */
    PublishData(some_string);
}

Как я уже говорил, если я попытаюсь использовать telnet на компьютере или телефоне, он сможет успешно подключиться к серверу и отправить данные. Но когда я пытаюсь использовать свою плату Arduino в качестве клиента, сокет закрывается сервером, как будто он активно отказывается от соединения.

EDIT: На стороне сервера строка client = server.available(); никогда не возвращает объект client, если сервер ATWINC является AP, а клиент-другим ATWINC.

Есть какие-нибудь предложения? Есть ли что-то, что я упускаю или делаю неправильно? Спасибо!

[править]

После некоторого тестирования кажется, что сервер работает, если он также не действует как точка доступа. Это прискорбно, потому что мне нужно, чтобы он действовал как точка доступа и сервер.

Если у кого-то есть опыт общения двух atwinc1500 друг с другом, где один является одновременно точкой доступа и сервером, а другой-клиентом, любая помощь будет оценена по достоинству!

[править/править код]

, 👍1

Обсуждение

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен в chat](https://chat.stackexchange.com/rooms/133375/discussion-on-question-by-david-problems-connecting-to-wifi101-access-point)., @Juraj


1 ответ


Лучший ответ:

1

Ошибка, по-видимому, заключается в том, что сервер должен быть запущен после того, как Wi-Fi перешел в состояние WL_AP_CONNECTED. Я не уверен, почему это так, но, по-видимому, сокеты недействительны (или становятся недействительными), когда точка доступа Wi-Fi не находится в этом состоянии (или перемещена из этого состояния).

Итак, в принципе, я написал пару небольших функций для обработки состояния сервера, а затем включил их в свой основной цикл следующим образом:

bool is_server_launched = false;

void LaunchServer_IfDeviceConnected ()
{
    if (!is_server_launched)
    {
        uint8_t wifi_status = WiFi.status();
        if (wifi_status == WL_AP_CONNECTED)
        {
            server.begin();
            is_server_launched = true;
        }
    }
}

void StopServer_IfDeviceDisconnected ()
{
    if (is_server_launched)
    {
        uint8_t wifi_status = WiFi.status();
        if (wifi_status != WL_AP_CONNECTED)
        {
            is_server_launched = false;
        }
    }
}

void loop()
{
    LaunchServer_IfDeviceConnected();
    StopServer_IfDeviceDisconnected();
    HandleClientConnection();
}

Я знаю, что мог бы написать эти функции по-другому, чтобы они были в одной функции, но я сделаю это в другой раз.

Суть этого ответа вытекает из прочтения следующей дискуссии на форумах Arduino: https://forum.arduino.cc/t/mkr1000-server-in-ap-mode-socket-connection-problem/465719

В этой теме у ОП была такая же проблема, как и у меня. Один из ответивших дал следующий ответ:

Как только соединение AP потеряно, серверный сокет больше не действителен.

Затем этот человек предложил добавить следующий код в скетч операции:

if (status == WL_AP_CONNECTED) {
  Serial.println("Device connected to AP");
  server.begin(); // <- НОВАЯ СТРОКА
} else {

После реализации этой идеи в моем коде (как я показал выше) она начала работать должным образом.

EDIT: После того, как я еще немного покопался, я также нашел эту связанную проблему, размещенную в репозитории WiFi101 Github:

https://github.com/arduino-libraries/WiFi101/issues/46

,

Сандип Мистри ("человек") работал в то время на Arduino и поддерживал библиотеку WiFi101, @Juraj