Проблемы с подключением к точке доступа 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 друг с другом, где один является одновременно точкой доступа и сервером, а другой-клиентом, любая помощь будет оценена по достоинству!
[править/править код]
@David, 👍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
- WebSocketsServer.h: No such file or directory
- Как разрешить междоменные запросы на ESP8266 WebServer
- Почему мы используем client.flush() в коде, когда мы подключаем Esp8266 к Интернету или серверу?
- Управление реле 5В с помощью Wemos D1 R1
- Автоматическая веб-страница ESP32 AP
- TCP-клиент readStringUntil только при наличии данных
- Как установить RTC в ES32 с помощью NTP-сервера?
- Создать один сервер в режиме точки доступа, а другой - в режиме станции.
Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен в chat](https://chat.stackexchange.com/rooms/133375/discussion-on-question-by-david-problems-connecting-to-wifi101-access-point)., @Juraj