Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Running a wifi server is mutually exclusive to using it as a client. #12

Closed
kostecky opened this Issue · 11 comments

5 participants

@kostecky

If you load the WifiTwitterClient library that comes with the Arduino you can demonstrate this bug. If you add code to the example sketch that ships with the library (or any other sketch) to fire up a TCP server on the wifi shield, the server will start up and return 1 when server.status() is run UNTIL the client initiates a connection to its target using client.connect(). I believe you should be able to both run a server and use the wifi shield as a client (both independently and simultaneously). Here is the modified code. Dont' forget to add your ssid and password (i've put them in a keys.h file for safety).

Observe all the instances of 'serverO'. That is the code I've added to fire up a server and the resulting status() calls in the loop so you can see what happens to it as the program progresses. A functioning wifi server will always return 1 from my experience.

#include <SPI.h>
#include <WiFi.h>
#include "keys.h"

int keyIndex = 0;            // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS; // status of the wifi connection

// initialize the library instance:
WiFiClient client;
WiFiServer serverO(23);

const unsigned long requestInterval = 30*1000;    // delay between requests; 30 seconds

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(199,59,149,200);    // numeric IP for api.twitter.com
char server[] = "api.twitter.com";     // name address for twitter API

boolean requested;                     // whether you've made a request since connecting
unsigned long lastAttemptTime = 0;     // last time you connected to the server, in milliseconds

String currentLine = "";               // string to hold the text from server
String tweet = "";                     // string to hold the tweet
boolean readingTweet = false;          // if you're currently reading the tweet

void setup() {
  // reserve space for the strings:
  currentLine.reserve(256);
  tweet.reserve(150);
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
    status = WiFi.begin(ssid, pass);  

    // wait 10 seconds for connection:
    delay(10000);
  } 
  // you're connected now, so print out the status:
  printWifiStatus();
  serverO.begin();
  Serial.println("Server status: " + String(serverO.status()));
  connectToServer();
}

void loop()
{
  Serial.println("Server status: " + String(serverO.status()));
  if (client.connected()) {
    if (client.available()) {
      // read incoming bytes:
      char inChar = client.read();

      // add incoming byte to end of line:
      currentLine += inChar; 

      // if you get a newline, clear the line:
      if (inChar == '\n') {
        currentLine = "";
      } 
      // if the current line ends with <text>, it will
      // be followed by the tweet:
      if ( currentLine.endsWith("<text>")) {
        // tweet is beginning. Clear the tweet string:
        readingTweet = true; 
        tweet = "";
        // break out of the loop so this character isn't added to the tweet:
        return;
      }
      // if you're currently reading the bytes of a tweet,
      // add them to the tweet String:
      if (readingTweet) {
        if (inChar != '<') {
          tweet += inChar;
        } 
        else {
          // if you got a "<" character,
          // you've reached the end of the tweet:
          readingTweet = false;
          Serial.println(tweet);   
          // close the connection to the server:
          client.stop(); 
        }
      }
    }   
  }
  else if (millis() - lastAttemptTime > requestInterval) {
    // if you're not connected, and two minutes have passed since
    // your last connection, then attempt to connect again:
    connectToServer();
  }
}

void connectToServer() {
  // attempt to connect, and wait a millisecond:
  Serial.println("connecting to server...");
  if (client.connect(server, 80)) {
    Serial.println("making HTTP request...");
    // make HTTP GET request to twitter:
    client.println("GET /1/statuses/user_timeline.xml?screen_name=arduino HTTP/1.1");
    client.println("Host:api.twitter.com");
    client.println("Connection:close");
    client.println();
  }
  // note the time of this connect attempt:
  lastAttemptTime = millis();
}   


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
@mlafauci mlafauci closed this
@salanki

Has this issue been fixed? Does not seem so in the firmware with 1.0.5.

Also tested the udp_dev branch, same issue still exists for me.

If I try to connect to the Arduino server while it is making an output TCP connection as a client, the TCP server stack seems to get messed up and it won't accept any more connections. I have found no way to recover:

$ telnet 10.0.17.20 9001
Trying 10.0.17.20...

If you start the server, then have noone connecting to it but still do a bunch of unrelated TCP Client stuff in your arduino, the TCP server will stall in the same way.

@salanki

Also, if you would put server.begin() after a client connection has already been made (and closed) the server will never start and you will get connection refused:

$ telnet 10.0.17.20 9000
Trying 10.0.17.20...
telnet: connect to address 10.0.17.20: Connection refused
telnet: Unable to connect to remote host

@oztimuk

Finally got this working in 1.0.5. Make sure to flash BOTH firmwares. To do this I had to modify the install script. It points to "wifi-shield" but the Arduino.app package uses wifishield. Also note that you have to move the .hex and .elf files from /hardware/firmwares/wifishield/binary to /hardware/firmwares/wifishield for the script to work. I can now send my IP address to a sever (as a client) then act as a server and accept incoming requests. All seems to be a lot more stable. Personally, Arduino used to be a lot more about being easy to use and things "just worked". BTW by updating the firmware you can also use WiFi.config() without issue and set a static IP address. I should probably write a tutorial on how I was finally able to do this on a mac...

@salanki

Are you running server.begin() after your client connection?

@oztimuk

I'm running my server.begin() before my client connection - BOTH are the in setup(). The main loop() deals with server requests only. I even have a static IP address. I haven't tested swapping between both server and client mode back and forth. Just an initial send before accepting requests.

@salanki

Ok, that did work for me too (and I am pretty sure I am running the correct 1.0.5 firmware and had to do a lot of trickery just as you describe). If I only do one client connection I am probably fine too, but I need to be able to both intermixed. Try to move your server.begin() after your client connection and see if your server fails to start completely.

@oztimuk

Yep - it fails :( I've tried client.flush() and client.stop() to get it to reset before starting the server but to no avail. I'll try again in the next day or so and let you know.

@salanki

Ok, so at least you are hitting the same bugs at me so we must be on the same firmware, just that you don't mix server/client connections in the way I do and don't hit all the bugs.

@guitarbeard

Why was this issue closed if it still breaks after one switch?

@salanki

Yes, why was it closed?

@guitarbeard

The only way around I found was using the ethernet shield and a small mini router like this guy.
http://www.lucadentella.it/en/2012/12/09/enc28j60-e-arduino-11/?utm_source=rss&utm_medium=rss&utm_campaign=enc28j60-e-arduino-11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.