Wifi Shield 2.0: How to reconnect to AP

Ok, I did some further trying on my own.

For my first original question “How can I retrieve the information “still connected to AP” while being up and ready as a webserver?”, I still haven’t found an answer.

But at least I solved my second, alternative question “How can I make the Wifi Shield 2.0 automatically reconnect again once the AP is available again (after the circuit breaker for the room with the AP is in place again, for instance)?

So finding a solution for the first question is not as urgent any more :mrgreen:



Anyway, here is the solution to make the wifi shield reconnect if the access point has been unavailable for some time.

It basically comes down to inserting
</s>wifly.sendCommand("set wlan join 1\r");<e>

If you have a look at the full code below, you will notice that my code still has the “delay” handling of executing commands (a delay of 100ms after each command) which is poor software design. It is a legacy from the example code that comes with the module.

You will notice that the delays around
</s>wifly.sendCommand("set wlan linkmon 30\r");<e>
have 500ms instead. It took me some time to find out that there appears to be a timing problem. Either I increase the delays, or I move linkmon up in the order of called commands (had it above set wlan hide first, and it worked with 100ms delay as well).

All very unsatisfying.



Anyway, here is the code that finally works for me.

It is similar to example 5 of http://wiki.seeedstudio.com/Wifi_Shield_V2.0/. But it has the ability to reconnect to the AP if the wifi connection failed temporarily.

[code]#include <SoftwareSerial.h>
#include “WiFly.h”

#define stringSSID “Best$Place” // space characters in the SSID must be substituted by $ in this string
#define stringKEY “thisisnotmyrealpassword” // maximum of 22 characters allowed
#define AUTH WIFLY_AUTH_WPA2_PSK // the security level of the access point (constants are defined in WiFly.h)

int flag = 0;

// Pins’ connection
// Arduino WiFly
// 2 <----> TX
// 3 <----> RX

SoftwareSerial wiflyUart(2, 3); // create a WiFi shield serial object
WiFly wifly(&wiflyUart); // pass the wifi sheld serial object to the WiFly class
char ip[16];

void connectToWifi()
{
Serial.println(“Connecting to Wifi…”);

wifly.reset(); // reset the shield
delay(1000);

//set parameters to make wifi shield safer against outside attacks.
wifly.sendCommand("set ip tcp-mode 0x10\r"); // disable remote configuration via TCP connections
delay(100);
wifly.sendCommand("set wlan hide 1\r"); //when the module shows the wlan settings, the passphrase is shown as ******
delay(100);

//set parameters for HTTP server
wifly.sendCommand("set ip local 80\r"); // set the local port to 80 which is standard for HTTP servers
delay(100);
wifly.sendCommand("set comm remote 0\r"); // do not send a default string when a connection opens
delay(100);
wifly.sendCommand("set comm open *OPEN*\r"); // set the string that the wifi shield will output when a connection is opened
delay(100);

//set parameters so the module automatically connects to the access point and attempts to reconnect after loss of connection
wifly.sendCommand("set wlan auth WIFLY_AUTH_WPA2_PSK\r"); //set authentication mode to WPA2 with personal key
delay(100);
wifly.sendCommand("set wlan passphrase ssid " stringSSID "\r"); //set the SSID
delay(100);
wifly.sendCommand("set wlan passphrase " stringKEY "\r"); //set the passphrase (WPA/WPA2 personal key)
delay(500); //longer delay needed, otherwise linkmon causes failure of connection; no documentation found on this topic; just trial and error :-(
wifly.sendCommand("set wlan linkmon 30\r"); //set the link monitor to 30 attempts of reconnecting when detecting the loss of connection to the access point
delay(500); //longer delay needed, otherwise linkmon causes failure of connection; no documentation found on this topic; just trial and error :-(
wifly.sendCommand("set wlan join 1\r"); //set the mode (value 1) so the module will auto-connect and re-connect to the access point
delay(100);


Serial.println("Join " stringSSID );
if (wifly.join(stringSSID, stringKEY, AUTH)) 
{
    Serial.println("OK");
} 
else 
{
    Serial.println("Failed");
}

delay(5000);

wifly.sendCommand("get ip\r");

wiflyUart.setTimeout(500);
if(!wiflyUart.find("IP="))
{
    Serial.println("can not get ip");
    while(1);;
}else
{
    Serial.print("IP:");
}

char c;
int index = 0;
while (wifly.receive((uint8_t *)&c, 1, 300) > 0) 
{ // print the response from the get ip command
    if(c == ':')
    {
        ip[index] = 0;
        break;
    }
    ip[index++] = c;
    Serial.print((char)c);

}
Serial.println();
while (wifly.receive((uint8_t *)&c, 1, 300) > 0);;
Serial.println("Web server ready");

}

void setup()
{
//set up pins
pinMode(11,OUTPUT);
digitalWrite(11,LOW);
pinMode(12,OUTPUT);
digitalWrite(12,LOW);
pinMode(13,OUTPUT);
digitalWrite(13,LOW);

wiflyUart.begin(9600); // start wifi shield uart port
Serial.begin(9600); // start the arduino serial port
Serial.println("--------- WIFLY Webserver --------");

// wait for initilization of wifly
delay(1000);

Serial.println("Initializing web connection...");
connectToWifi();
Serial.println("Finished initializing web connection.");

Serial.println("Setup finished, starting loop...");

}

void loop()
{
if (wifly.available()) // the wifi shield has data available
{
if(wiflyUart.find(“OPEN”)) // see if the data available is from an open connection by looking for the OPEN string
{
Serial.println(“New Browser Request!”);
delay(1000); // delay enough time for the browser to complete sending its HTTP request string

        if(wiflyUart.find("pin=")) // look for the string "pin=" in the http request, if it's there then we want to control the LED
        {
            Serial.println("LED Control");
            // the user wants to toggle the LEDs
            int pinNumber = (wiflyUart.read()-48); // get first number i.e. if the pin 13 then the 1st number is 1
            int secondNumber = (wiflyUart.read()-48);
            if(secondNumber>=0 && secondNumber<=9)
            {
                pinNumber*=10;
                pinNumber +=secondNumber; // get second number, i.e. if the pin number is 13 then the 2nd number is 3, then add to the first number
            }
            digitalWrite(pinNumber, !digitalRead(pinNumber)); // toggle pin
            
            // Build pinstate string. The Arduino replies to the browser with this string.
            String pinState = "Pin ";
            pinState+=pinNumber;
            pinState+=" is ";
            if(digitalRead(pinNumber)) // check if the pin is ON or OFF
            {
                pinState+="ON"; // the pin is on
            }
            else
            {
                pinState+="OFF";  // the pin is off
            }
            // build HTTP header Content-Length string.
            String contentLength="Content-Length: ";
            contentLength+=pinState.length(); // the value of the length is the lenght of the string the Arduino is replying to the browser with.
            // send HTTP header
            wiflyUart.println("HTTP/1.1 200 OK");
            wiflyUart.println("Content-Type: text/html; charset=UTF-8");
            wiflyUart.println(contentLength); // length of HTML code
            wiflyUart.println("Connection: close");
            wiflyUart.println();
            // send response
            wiflyUart.print(pinState);
        }
        else
        {
            // send HTTP header
            wiflyUart.println("HTTP/1.1 200 OK");
            wiflyUart.println("Content-Type: text/html; charset=UTF-8");
            wiflyUart.println("Content-Length: 540"); // length of HTML code
            wiflyUart.println("Connection: close");
            wiflyUart.println();

            // send webpage's HTML code
            wiflyUart.print("<html>");
            wiflyUart.print("<head>");
            wiflyUart.print("<title>WiFi Shield Webpage</title>");
            wiflyUart.print("</head>");
            wiflyUart.print("<body>");
            wiflyUart.print("<h1>LED Toggle Webpage</h1>");
            // In the <button> tags, the ID attribute is the value sent to the arduino via the "pin" GET parameter
            wiflyUart.print("<button id=\"11\" class=\"led\">Toggle Pin 11</button> "); // button for pin 11
            wiflyUart.print("<button id=\"12\" class=\"led\">Toggle Pin 12</button> "); // button for pin 12
            wiflyUart.print("<button id=\"13\" class=\"led\">Toggle Pin 13</button> "); // button for pin 13
            wiflyUart.print("<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>");
            wiflyUart.print("<script type=\"text/javascript\">");
            wiflyUart.print("$(document).ready(function(){");
            wiflyUart.print("$(\".led\").click(function(){");
            wiflyUart.print("var p = $(this).attr('id');"); // get id value (i.e. pin13, pin12, or pin11)
            // send HTTP GET request to the IP address with the parameter "pin" and value "p", then execute the function
            // IMPORTANT: dont' forget to replace the IP address and port with YOUR shield's IP address and port
            wiflyUart.print("$.get(\"http://");
            wiflyUart.print(ip);
            wiflyUart.print(":80/a\", {pin:p},function(data){alert(data)});");// execute get request. Upon return execute the "function" (display an alert with the "data" send back to the browser.
            wiflyUart.print("});");
            wiflyUart.print("});");
            wiflyUart.print("</script>");
            wiflyUart.print("</body>");
            wiflyUart.print("</html>");
        }
        Serial.println("Data sent to browser");
    }
}

}[/code]

Hope this helps some of the other newbies. Pros probably don’t need this info since they would have known right away. :smiley: