Reconnect to AP on AP power cycle?

Questions specifically regarding the WiShield 1.0 family driver.

Re: Reconnect to AP on AP power cycle?

Postby Chief Robot » Mon Nov 23, 2009 4:37 am

Sounds very useful. I have similar issues.
User avatar
Chief Robot
 
Posts: 36
Joined: Thu May 07, 2009 10:47 am

Re: Reconnect to AP on AP power cycle?

Postby aerodyno » Mon Nov 23, 2009 2:34 pm

So I've been playing with this for a few days and haven't gotten it to work yet.

Here's what I'm doing -- what am I missing? Basically, I initialize the server normally (or with async init, I never have trouble on first start). Then, I check if the connection has dropped every 2 minutes. If it has, I do a 'full reset' and then keep pushing up the server until serverUp is true.

My problem is that when I power-cycle my router, the network connection WiServer.connection_up returns true -- even though the connection has been lost. So I never get to the point of restarting the connection.

-s



Code: Select all
setup() {

Wiserver.init(myPage); // normal init, don't care if this blocks.

}

unsigned long connectonCheckTime = 120000;

loop() {

  if (millis()>=connectionCheckTime) {
    connectionCheckTime+=120000; // check the connection every 2 minutes
    if (!WiServer.connection_up()) {  // if it's down, restart it
      serverUp = WiServer.async_init(wvHome,1);
      Serial.println("fixing");
      Serial.println((int)serverUp);
    }
    else {
      Serial.println("good");
    }
  }

  doStuff(); // make some HTTP requests

if (serverUp) {
     WiServer.server_task();   // Run WiServer
   }
   else {
     serverUp = WiServer.async_init(wvHome,0); // continue to restart server
   }

}
aerodyno
 
Posts: 65
Joined: Tue Aug 04, 2009 8:42 pm

Re: Reconnect to AP on AP power cycle?

Postby John_Ryan » Mon Nov 23, 2009 3:40 pm

Have you debugged WiServer.connection_up() to determine what it returns if the router is on, or off?

I have a vague recollection that its not possible to reinitialize/reconnect WiServer without repowering.

If the Asynclab team are around, perhaps they could comment?
John_Ryan
 
Posts: 155
Joined: Thu Jun 04, 2009 11:24 pm

Re: Reconnect to AP on AP power cycle?

Postby aerodyno » Sat Nov 28, 2009 5:42 pm

Hruska, can you post a complete code sample of what you have working? (sorry to bug you).

Thought: if we can determine, through code, whether the connection has gone down, then at worst we could do a hardware reset of the arduino triggered by software. That's definitely a brute force solution, but something I'm thinking about. Or perhaps I should dig in to g2100.c. ;)

-s
aerodyno
 
Posts: 65
Joined: Tue Aug 04, 2009 8:42 pm

Re: Reconnect to AP on AP power cycle?

Postby GregEigsti » Sat Nov 28, 2009 6:36 pm

then at worst we could do a hardware reset of the arduino triggered by software. That's definitely a brute force solution

I looked up software resets of the AVR and found that it is not trivial - kind of Rube Goldberg like. Search the forums, I think I remember someone posting here a way that they were resetting the WiShield via g1200 calls (or something like that).

I have yet to look at Hruska's solution - mainly because it is at the WiServer level and I'm not currently using WiServer in any of my projects. I did start looking into making uip_connect() truly return an error value - and it will if you are out of resources. However its one of those deals where you don't know if the failure to connect has occured until the next iteration of your UIP_APCALL function. Sigh.

And then I started playing with combining the .pde and .c files and got it working except for when you use the upper case form of the PSOCK_* functions (the "threaded" ones). And then I saw something shiny ;)

Anyway, hope you all had a great Thanksgiving!

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1067
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: Reconnect to AP on AP power cycle?

Postby gsxrex » Sun Nov 29, 2009 8:40 am

The default firmware of the WiFi module is setup to retry the connection if lost. I forget how much testing I did with it previously (whether I pinged it or just waited for the LED to light up).

Anyway, the real issue is that you somehow need to clean the stack state up a bit to "reset" it correctly. Stacks are usually built with an underlying ethernet theme, in that the stack believes that there is always a connection on the other side plugged in. Obviously, wireless doesn't work that way.

I haven't taken a look at hruska's code, but I assume that he is attempting to do this type of cleanup of the stack state. A reset of the entire MCU is also an option. I'm in the middle of a lot of hardware things, so might not have much chance to look at the code and offer advice, but I'll try to do so.
User avatar
gsxrex
 
Posts: 115
Joined: Thu Apr 30, 2009 9:49 am

Re: Reconnect to AP on AP power cycle?

Postby hruska » Mon Nov 30, 2009 8:30 pm

aerodyno wrote:Hruska, can you post a complete code sample of what you have working? (sorry to bug you).

Thought: if we can determine, through code, whether the connection has gone down, then at worst we could do a hardware reset of the arduino triggered by software. That's definitely a brute force solution, but something I'm thinking about. Or perhaps I should dig in to g2100.c. ;)

-s


Here is a quick sketch that monitors the connection and reports whether it us up or down. If it goes down, it re-initializes it. This utilizes the previous changes I documented to the WiServer library.

With my router I see about a 10 second pause between powering it down and the WiServer reporting that there is no connection. WiServer reports that it is back up about 15 seconds after my router is powered on.

One thing to note - I have found that if the async_init runs for more than about a minute with no connection available, the zg_init code won't recover when the wifi connection becomes available. To overcome this I added an audit that "kicks" the init every 45 seconds (the value is in a #define and you can change it to suit your needs) and that seems to make everything happy.

Code: Select all
#include "WiServer.h"

#define WIRELESS_MODE_INFRA   1
#define WIRELESS_MODE_ADHOC   2

//Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = { 10, 1, 1, 125 }; // IP address of WiShield
unsigned char gateway_ip[] = { 10, 1, 1, 1 }; // router or gateway IP address
unsigned char subnet_mask[] = { 255, 255, 255, 0 }; // subnet mask for the local network
const prog_char ssid[] PROGMEM = { "RCH" }; // max 32 bytes


unsigned char security_type = 1; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = { "12345678" }; // max 64 characters
// WEP 128-bit keys (modified to be 64 bit in library g2100.c func zg_write_wep_key()
prog_uchar wep_keys[] PROGMEM = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x00,
      0x00, 0x00, 0x00,
      0x00,
      0x00,
      0x00, // Key 0
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00,
      0x00,
      0x00, // Key 1
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00,
      0x00, // Key 2
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00 }; // Key 3

// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;
//---------------------------------------------------------------------------


unsigned int current_millis_value = 0;
unsigned int previous_millis_value = 0;
unsigned int m = 0;
unsigned int minutes = 0;
unsigned int seconds = 0;
unsigned int hours = 0;
char wireless_stat = 'N';
int server_up = 0;
int retry_seconds = 0;
#define WIFI_RETRY_KICK_TIME 45

void setup() {

   Serial.begin(57600);
   Serial.println("Setup");
   server_up = WiServer.async_init(sendMyPage, 1);
}

void loop() {

   // Run any code you need to run that is not WiServer related 
   update_time();

   // This is the logic to establish / re-establish the wireless connection.
   // setup() begins the process by calling async_init with the reset flag set.
   //
   // During loop() the reset flag is not set and the reset will not
   // be done.
   //
   // Once connection is established, connection_up is checked continuously.  If the
   // connection goes down, the async_init is called again with the reset flag set
   // and the process starts over.
   if (!server_up) {
      server_up = WiServer.async_init(sendMyPage, 0);
   } else {
      if (!WiServer.connection_up()) {
         server_up = WiServer.async_init(sendMyPage, 1);
      } else {
         retry_seconds = 0;
         WiServer.server_task();
      }
   }

}

// This is our page serving function that generates web pages
boolean sendMyPage(char* URL) {

   // Check if the requested URL matches "/" and if so give generic info page

   if (strcmp(URL, "/") == 0) {
      WiServer.print("<html>");
      WiServer.print("You are connected to the WiServer ");
      WiServer.println(seconds);
      WiServer.print("</html>");

      return true;
   }
}

void hours_tick() {

}

void minutes_tick() {
   Serial.println("Minutes tick");
}

// Run this every second.  Inside it could also have static counters to run things on
// other multiples of seconds.
void seconds_tick() {
   char line[60];

   if (WiServer.connection_up()) {
      wireless_stat = 'Y';
   } else {
      wireless_stat = 'N';
      if (retry_seconds++ > WIFI_RETRY_KICK_TIME) {
         // For some reason if the wifi init runs for too long without getting a connection
         // it will not work when a connection becomes available.  This allows the process
         // to start over from scratch after a long timeout intercal.
         Serial.println("Kicking wifi init");
         server_up = WiServer.async_init(sendMyPage, 1);
         retry_seconds = 0;
      }
   }

   sprintf(line, "Secs=%d  Wireless=%c\n", seconds, wireless_stat);
   Serial.print(line);
}

void update_time() {
   static unsigned char last_seconds = 0;
   static unsigned char last_minutes = 0;
   static unsigned char last_hours = 0;

   current_millis_value = millis();
   m += current_millis_value - previous_millis_value;
   seconds += m / 1000;
   minutes += seconds / 60;
   hours += minutes / 60;
   if (seconds > last_seconds) {
      last_seconds = seconds % 60;
      seconds_tick();
   }
   if (minutes > last_minutes) {
      last_minutes = minutes % 60;
      minutes_tick();
   }
   if (hours > last_hours) {
      last_hours = hours % 24;
      hours_tick();
   }
   m = m % 1000;
   seconds = seconds % 60;
   minutes = minutes % 60;
   hours = hours % 24;
   previous_millis_value = current_millis_value;
}
hruska
 
Posts: 13
Joined: Thu Nov 12, 2009 10:53 pm

Re: Reconnect to AP on AP power cycle?

Postby GregEigsti » Mon Nov 30, 2009 10:32 pm

Thanks Hruska!

Greg
Check out the wiki!
uIP Stack Docs
Compatible Access Point List
WiShield user contrib branch - DNS, DHCP, AP Scanning, bug fixes, etc.
SlackLab.org - My geek projects blog.
User avatar
GregEigsti
 
Posts: 1067
Joined: Sun Aug 02, 2009 5:23 pm
Location: Sammamish WA USA (near Seattle)
  • Website

Re: Reconnect to AP on AP power cycle?

Postby aerodyno » Mon Dec 07, 2009 8:49 pm

Hey Thanks Hruska! I haven't tried the code yet as I've been distracted by another project, but I will try it out and get back to you guys.

-s
aerodyno
 
Posts: 65
Joined: Tue Aug 04, 2009 8:42 pm

Re: Reconnect to AP on AP power cycle?

Postby John_Ryan » Sun Dec 20, 2009 11:50 pm

This is really excellent. Has anyone tried it?

I'm anxious to know as I have a connection critical project and I need the unit to reconnect if the signal is dropped. The unit "out of the box" does not - so this could be the solution I'm looking for.

Thanks.
John_Ryan
 
Posts: 155
Joined: Thu Jun 04, 2009 11:24 pm

PreviousNext

Return to WiShield 1.0 Driver

Who is online

Users browsing this forum: No registered users and 1 guest