1

I currently have two Arduino Zero boards (using the SAMD21 microcontroller), each with an ATWINC1500 wifi module attached. I have established one of these units as a wifi access point with a server running on it, while the other unit is a client that attempts to connect to the access point and then send some data to the server.

As far as I can tell, the access point and the server on the first unit are created correctly. I am able to use telnet on a separate Android device to connect to the access point and send data to the server. Unfortunately, when I attempt to connect to the AP/server using the other Arduino board, it is never successful.

Here is the code I am using on the first board to create the access point and server:

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();
}

Meanwhile, here is the code for the client that attempts to connect to the AP/server:

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);
}

As I said before, if I try using telnet on a computer or phone, it is able to successfully connect to the server and send data. But when I attempt to use my Arduino board to act as the client, the socket gets closed by the server, as if it's actively refusing the connection.

EDIT: On the server side, the line client = server.available(); never returns a client object if server ATWINC is AP and client is the other ATWINC.

Any suggestions? Is there something I am missing or doing wrong? Thanks!

[edit]

After doing some testing, it seems as though the server works if it is not also acting as an access point. This is unfortunate, because I need it to act as the access point and a server.

If anyone has experience getting two ATWINC1500s to talk to each other, where one is both an AP and a server, and the other is a client, any help would be appreciated!

[/edit]

1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Juraj
    Jan 20 at 13:55
1

The bug seems to be that the server must be started after the wifi has moved into the WL_AP_CONNECTED state. I am not sure why this is, but apparently sockets are invalid (or become invalidated) when the wifi access point is not in this state (or moved out of this state).

So basically, I wrote a couple small functions to handle the state of the server, and then incorporated them in my main loop like so:

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();
}

I know I could have written those functions differently to be in one single function, but I'll do that at another time.

The core of this answer comes from reading the following discussion on the Arduino forums: https://forum.arduino.cc/t/mkr1000-server-in-ap-mode-socket-connection-problem/465719

In that thread, the OP had a similar issue as me. One of the people responding gave the following reply:

Once the AP connection is lost, the server socket is no longer valid.

That person then suggested adding the following code to the OP's sketch:

if (status == WL_AP_CONNECTED) {
  Serial.println("Device connected to AP");
  server.begin(); // <- NEW LINE
} else {

After implementing that idea in my code (as I displayed above), it began to work properly.

EDIT: After doing some more digging, I also found this related issue posted in the WiFi101 Github repository:

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

New contributor
David is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • Sandeep Mistry ("the person") worked at that time for Arduino and maintained the WiFi101 library
    – Juraj
    Jan 20 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.