Go Down

Topic: WiFlyHQ: A new library for the WiFly RN-XV (Read 31662 times) previous topic - next topic

dhunt

After working on a few WiFly projects with the WiFly RN-XV, and not having much success using and extending the libraries that are available, I decided to write my own.  I think its fairly easy to understand and extend as needed.  Version 0.1 is available here:  https://github.com/harlequin-tech/WiFlyHQ.

I'll continue to add additional features with the goal of providing full access to all of the WiFly module's capabilities, starting with adhoc network support.

Code: [Select]

Example code to setup and use the hardware serial interface:

Serial.begin(9600);
wifly.begin(&Serial);

Example code to setup and use a software serial interface:

#include <SoftwareSerial.h>
SoftwareSerial wifiSerial(8,9);

wifiSerial.begin(9600);
wifly.begin(&wifiSerial);

Example code to join a WiFi network:

wifly.setSSID("mySSID");
wifly.setPassphrase("myWPApassword");
wifly.enableDHCP();
wifly.join();

Example code to send a UDP packet:

wifly.setIpProtocol(WIFLY_PROTOCOL_UDP);
wifly.sendto("Hello, world", "192.168.1.100", 2042);

Example code to open a TCP connection and send some data, and close the connection:

wifly.open("192.168.1.100",8042);
wifly.println("Hello, world!");
wifly.close();

Exmaple code to receive UDP or TCP data (assumes software serial interface):

if (wifly.available() > 0) {
    Serial.write(wifly.read());
}

iball

Thank you!  Even though I get errors trying to pull down an XML page with weather data on it (I need to debug that a little more to find out EXACTLY what's going on with the request, may require more RN-XV settings configuration), it works great for pinging servers, routers, and the like for my ping logger and will enable me to move off my Arduino Ethernet and onto one of my FIOs and shrink the hardware device footprint.

Thanks again, and once I find out what the issue is with pulling down that XML data from an RSS feed I'll let you know.

dhunt

Great. If you run into any bugs, or are missing key functions, you could open an issue on the github page and I'll work on a fix.

iball

#3
Apr 11, 2012, 06:54 pm Last Edit: Apr 11, 2012, 08:53 pm by iball Reason: 1

Great. If you run into any bugs, or are missing key functions, you could open an issue on the github page and I'll work on a fix.


Just posted the issue I'm seeing to Github.

EDIT:  And I resolved it and closed that issue-not-really-an-issue.

This library is by far the easiest to use out of all the ones I've been using so far.  WiFlyHQ has allowed me to combine a ping logger and internet weather display easily and with a lower amount of flash and RAM - less than 18k to ping 3 devices every 30 seconds and pull down internet weather every 2 minutes.
It's also more stable in that it doesn't just "lock up" like WiFlySerial.h and WiFly.h would do after pulling down weather about 7 times.  It just keeps going and going...

dhunt

Awesome, good to hear.

I've aimed for a small RAM footprint, and once the library is feature-complete I'll look at ways to reduce the flash size.

iball

#5
Apr 12, 2012, 03:18 pm Last Edit: Apr 12, 2012, 03:41 pm by iball Reason: 1

Awesome, good to hear.

I've aimed for a small RAM footprint, and once the library is feature-complete I'll look at ways to reduce the flash size.


Doesn't seem to want to work on a Mega 2560.  Put issue on the github with more details.

RESOLVED:  Cannot use SoftwareSerial.h on Mega 2560 with this.  Duh.  Replacing "wiflyserial" with a Mega serial pair you've wired the Xbee RN-XV breakout to works just fine.

sbright33

I look forward to using it next month!  Hopefully it will be well tested by many users by then...     :)
If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

sbright33

Is it working reliably?  How many testers/users so far?
If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

sbright33

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

dhunt


Is it working reliably?  How many testers/users so far?

Seems to be quite stable, three or four people have been using it.  I have no problems with stability for UDP packets.

I don't think there are any issues preventing you from trying it out.  Let me know how it goes.

dhunt


Will you be adding FTP functions soon?


That should be quite easy to add. Feel like giving it a go and contributing it to the library?  I'm planning to add support for adhoc networks next.

dhunt

I've release version 0.3 of the library https://github.com/harlequin-tech/WiFlyHQ.

This adds support for creating Ad Hoc wifi networks:
Code: [Select]

#include <WiFlyHQ.h>
#include <SoftwareSerial.h>
SoftwareSerial wifiSerial(8,9);

WiFly wifly;

void setup()
{
    Serial.begin(115200);
    Serial.println(F("Starting"));
    wifiSerial.begin(9600);
    wifly.begin(&wifiSerial, &Serial));

    wifly.createAdhocNetwork("wifly", 10);

    Serial.println(F("Network ready"));
}

void loop()
{
    wifly.terminal();
}



Version 0.2 added a Web Server example sketch with chunked encoding support:
Code: [Select]

/*
* WiFlyHQ Example httpserver.ino
*
* This sketch implements a simple Web server that waits for requests
* and serves up a small form asking for a username, then when the
* client posts that form the server sends a greeting page with the
* user's name and an analog reading.
*
* This sketch is released to the public domain.
*
*/

/* Notes:
  * Uses chunked message bodies to work around a problem where
  * the WiFly will not handle the close() of a client initiated
  * TCP connection. It fails to send the FIN to the client.
  * (WiFly RN-XV Firmware version 2.32).
  */

/* Work around a bug with PROGMEM and PSTR where the compiler always
* generates warnings.
*/
#undef PROGMEM
#define PROGMEM __attribute__(( section(".progmem.data") ))
#undef PSTR
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); &__c[0];}))

#include <WiFlyHQ.h>

#include <SoftwareSerial.h>
SoftwareSerial wifiSerial(8,9);

//#include <AltSoftSerial.h>
//AltSoftSerial wifiSerial(8,9);

WiFly wifly;

/* Change these to match your WiFi network */
const char mySSID[] = "myssid";
const char myPassword[] = "my-wpa-password";

void sendIndex();
void sendGreeting(char *name);
void send404();

char buf[80];

void setup()
{
    Serial.begin(115200);
    Serial.println(F("Starting"));
    Serial.print(F("Free memory: "));
    Serial.println(wifly.getFreeMemory(),DEC);

    wifiSerial.begin(19200);
    if (!wifly.begin(&wifiSerial, &Serial)) {
        Serial.println(F("Failed to start wifly"));
wifly.terminal();
    }

    /* Join wifi network if not already associated */
    if (!wifly.isAssociated()) {
/* Setup the WiFly to connect to a wifi network */
Serial.println(F("Joining network"));
wifly.setSSID(mySSID);
wifly.setPassphrase(myPassword);
wifly.enableDHCP();
wifly.save();

if (wifly.join()) {
    Serial.println(F("Joined wifi network"));
} else {
    Serial.println(F("Failed to join wifi network"));
    wifly.terminal();
}
    } else {
        Serial.println(F("Already joined network"));
    }

    wifly.setBroadcastInterval(0); // Turn off UPD broadcast

    //wifly.terminal();

    Serial.print(F("MAC: "));
    Serial.println(wifly.getMAC(buf, sizeof(buf)));
    Serial.print(F("IP: "));
    Serial.println(wifly.getIP(buf, sizeof(buf)));

    wifly.setDeviceID("Wifly-WebServer");

    if (wifly.isConnected()) {
        Serial.println(F("Old connection active. Closing"));
wifly.close();
    }

    wifly.setProtocol(WIFLY_PROTOCOL_TCP);
    if (wifly.getPort() != 80) {
        wifly.setPort(80);
/* local port does not take effect until the WiFly has rebooted (2.32) */
wifly.save();
Serial.println(F("Set port to 80, rebooting to make it work"));
wifly.reboot();
delay(3000);
    }
    Serial.println(F("Ready"));
}

void loop()
{
    if (wifly.available() > 0) {

        /* See if there is a request */
if (wifly.gets(buf, sizeof(buf))) {
    if (strncmp_P(buf, PSTR("GET / "), 6) == 0) {
/* GET request */
Serial.println(F("Got GET request"));
while (wifly.gets(buf, sizeof(buf)) > 0) {
    /* Skip rest of request */
}
sendIndex();
Serial.println(F("Sent index page"));
    } else if (strncmp_P(buf, PSTR("POST"), 4) == 0) {
        /* Form POST */
        char username[16];
        Serial.println(F("Got POST"));

/* Get posted field value */
if (wifly.match(F("user="))) {
    wifly.gets(username, sizeof(username));
    wifly.flushRx(); // discard rest of input
    sendGreeting(username);
    Serial.println(F("Sent greeting page"));
}
    } else {
        /* Unexpected request */
Serial.print(F("Unexpected: "));
Serial.println(buf);
wifly.flushRx(); // discard rest of input
Serial.println(F("Sending 404"));
send404();
    }
}
    }
}

/** Send an index HTML page with an input box for a username */
void sendIndex()
{
    /* Send the header direclty with print */
    wifly.println(F("HTTP/1.1 200 OK"));
    wifly.println(F("Content-Type: text/html"));
    wifly.println(F("Transfer-Encoding: chunked"));
    wifly.println();

    /* Send the body using the chunked protocol so the client knows when
     * the message is finished.
     * Note: we're not simply doing a close() because in version 2.32
     * firmware the close() does not work for client TCP streams.
     */
    wifly.sendChunkln(F("<html>"));
    wifly.sendChunkln(F("<title>WiFly HTTP Server Example</title>"));
    wifly.sendChunkln(F("<h1>"));
    wifly.sendChunkln(F("<p>Hello</p>"));
    wifly.sendChunkln(F("</h1>"));
    wifly.sendChunkln(F("<form name=\"input\" action=\"/\" method=\"post\">"));
    wifly.sendChunkln(F("Username:"));
    wifly.sendChunkln(F("<input type=\"text\" name=\"user\" />"));
    wifly.sendChunkln(F("<input type=\"submit\" value=\"Submit\" />"));
    wifly.sendChunkln(F("</form>"));
    wifly.sendChunkln(F("</html>"));
    wifly.sendChunkln();
}

/** Send an greeting HTML page with the user's name and an analog reading */
void sendGreeting(char *name)
{
    /* Send the header direclty with print */
    wifly.println(F("HTTP/1.1 200 OK"));
    wifly.println(F("Content-Type: text/html"));
    wifly.println(F("Transfer-Encoding: chunked"));
    wifly.println();

    /* Send the body using the chunked protocol so the client knows when
     * the message is finished.
     */
    wifly.sendChunkln(F("<html>"));
    wifly.sendChunkln(F("<title>WiFly HTTP Server Example</title>"));
    /* No newlines on the next parts */
    wifly.sendChunk(F("<h1><p>Hello "));
    wifly.sendChunk(name);
    /* Finish the paragraph and heading */
    wifly.sendChunkln(F("</p></h1>"));

    /* Include a reading from Analog pin 0 */
    snprintf_P(buf, sizeof(buf), PSTR("<p>Analog0=%d</p>"), analogRead(A0));
    wifly.sendChunkln(buf);

    wifly.sendChunkln(F("</html>"));
    wifly.sendChunkln();
}

/** Send a 404 error */
void send404()
{
    wifly.println(F("HTTP/1.1 404 Not Found"));
    wifly.println(F("Content-Type: text/html"));
    wifly.println(F("Transfer-Encoding: chunked"));
    wifly.println();
    wifly.sendChunkln(F("<html><head>"));
    wifly.sendChunkln(F("<title>404 Not Found</title>"));
    wifly.sendChunkln(F("</head><body>"));
    wifly.sendChunkln(F("<h1>Not Found</h1>"));
    wifly.sendChunkln(F("<hr>"));
    wifly.sendChunkln(F("</body></html>"));
    wifly.sendChunkln();
}


sbright33

Nice!  Thanks!  I'm writing some brief code to execute commands and retrieve/parse their results.  I've noticed it works at 460k baud using hardware UART, but only 38,400 reliably using SofwareSerial.  For debugging I use SoftwareSerial to Wifly, pins 0,1 for debug messages, but when the code is reliable you can easily switch 2 wires and 1 define to make it faster with hardware UART.  Do you see the same results?
If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

ndanl

hi, I have the usb weather board from sparkfun and I am trying to get this http://www.sparkfun.com/products/11047 to get it work but after uploading the httpserver example all I get is this:

Code: [Select]

Starting
Free memory: 1337
setPrompt failed
Failed to enter command mode
Failed to start wifly
Terminal ready


what am I doing wrong ?:(

thanks

dhunt


hi, I have the usb weather board from sparkfun and I am trying to get this http://www.sparkfun.com/products/11047 to get it work but after uploading the httpserver example all I get is this:

Code: [Select]

Starting
Free memory: 1337
setPrompt failed
Failed to enter command mode
Failed to start wifly
Terminal ready


what am I doing wrong ?:(

thanks


The XBee hardware interface looks ok, its directly connecting TX and RX to the WiFly at 3.3V.

Those errors indicate that the Library can't talk to the board. Why don't you post the sketch you are using. It might be a simple problem like you're still using software serial when the WiFly is actually connected to the hardware serial interface, or maybe the baud rate doesn't match the rate set in the WiFly module.

Go Up