I did not know too much about embedded solutions for Wifi when I started this a couple of weeks ago, but I’ve learned alot since then and want to share. I’m not sure I want to pursue using this module because it is not everything I thought it would be. Basically there are Wifi modules that have a serial to Wifi interface or are a native network interface. Near as I can tell, this has no native network interface and only supports one socket at a time.
Here is a link to a great article on factors you need to consider when putting Wifi into your embedded solution:
[url]http://www.eetimes.com/design/embedded/4026972/Sorting-through-the-embedded-WiFi-confusion-item-1?pageNumber=0[/url]
I am now looking at the Microchip SPI based complete Wifi embedded solution, and the price is less than $30.
[url]http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2884[/url]
High res photos and block diagrams:
[url]http://www.flickr.com/photos/microchiptechnology/sets/72157619304830592/[/url]
The only problem is that I can’t find the command set yet. They make programming easy from the PIC platform, but I want to use NETMF!!! ;D I guess I’m going to write my own.
Here is where I left off with the code for those interested (I don’t think I will pursue this any further):
using System;
using Microsoft.SPOT;
using System.IO.Ports;
using System.Text;
using System.Threading;
namespace WiflyTest
{
/// <summary>
/// Class used to drive Wifly RN-131C Wifi module via the COM1 serial port on FEZ
/// Connect the FEZ "COM1 OUT" to Wifly "Rx" and Fez "COM1 IN" to Wifly "Tx".
/// Notes (verbatim from manual at: http://www.sparkfun.com/datasheets/Wireless/WiFi/WiFlyGSX-um2.pdf:
/// Connect a common ground when using the external TX, RX inputs.
/// Factory default is hardware flow control disabled; CTS and RTS are not required
/// </summary>
public class Wifly
{
/// <summary>
/// used to communicate over the serial port to Wifly
/// </summary>
private static SerialPort uart;
/// <summary>
/// Constructor
/// </summary>
public Wifly()
{
// Use our COM1 as the serial port at 9600 baud (factory default on Wifly)
uart = new SerialPort("COM1", 9600);
// Open a connection to the COM port
uart.Open();
uart.ErrorReceived += ErrorReceived;
uart.DataReceived += DataReceived;
}
private void ListenToWifly()
{
while (true)
{
// As long as there is data to read, print it to the debug port
if (uart.BytesToRead > 0)
{
Debug.Print("\n" + DateTime.Now.ToString() + ": Response from Wifly: " + ReadResponse());
}
Thread.Sleep(100);
}
}
private bool WaitForResponse(string expected)
{
string expectedWithCRLF = expected;
expectedWithCRLF += "\r\n";
int retry = 0;
const int RETRY_COUNT = 10;
while (retry < RETRY_COUNT)
{
// As long as there is data to read, print it to the debug port
if (uart.BytesToRead > 0)
{
string response = ReadResponse();
Debug.Print("\n" + DateTime.Now.ToString() + ": Response from Wifly: " + response);
// If we found the expected string somewhere in the response...
// Is this the right thing to do?
if ((response.IndexOf(expected) >= 0) || (response.IndexOf(expectedWithCRLF) >= 0))
break;
}
Thread.Sleep(100);
retry++;
}
if (retry >= RETRY_COUNT)
{
return false;
//throw new Exception("Did not get the expected response from Wifly...");
}
else
{
return true;
}
}
private void ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
}
private void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
}
/// <summary>
/// Instructs Wifly to enter the command mode
/// </summary>
public void EnterCommandMode()
{
// From the manual at: http://www.sparkfun.com/datasheets/Wireless/WiFi/WiFlyGSX-um2.pdf
// Upon power up, the device will be in data mode. To enter command mode, exactly the three characters $$$
// must be sent. The device will respond with CMD.
SendCommand("");
SendCommand("exit");
Thread.Sleep(150);
RepeatCommandAwaitResponse("$$$", "CMD");
}
public void ResetToManualJoin()
{
// Turn off WiFi auto-joining
RepeatCommandAwaitResponse("set wlan join 0", "AOK");
RepeatCommandAwaitResponse("save", "Storing in config");
// "reboot" to a known state
RepeatCommandAwaitResponse("reboot", "*Reboot*");
Thread.Sleep(2000);
WaitForResponse("*READY*");
}
private void RepeatCommandAwaitResponse(string command, string expectedResponse)
{
do
{
SendCommand(command);
Thread.Sleep(100);
}
while (!WaitForResponse(expectedResponse));
}
/// <summary>
/// Writes a command to the Wifly module
/// </summary>
/// <param name="data"></param>
private void SendCommand(string data)
{
// All commands except the $$$ need a carriage return
if (data != "$$$")
data += "\r";
byte[] tx_data = Encoding.UTF8.GetBytes(data);
int len = tx_data.Length;
int offset = 0;
int ret = 0;
while (len > 0)
{
ret = uart.Write(tx_data, offset, len);
len -= ret;
offset += ret;
}
}
private void SendCharacter(char c)
{
char[] c1 = new char[1];
c1[0] = c;
string s = new string(c1);
byte[] tx_data = Encoding.UTF8.GetBytes(s);
int bytesSent = uart.Write(tx_data, 0, tx_data.Length);
Thread.Sleep(100);
if (bytesSent != tx_data.Length)
throw new Exception("Problems transferring data to Wifly. Wifly didn't report same number of bytes sent.");
}
/// <summary>
/// Reads data from the Wifly module
/// </summary>
/// <returns></returns>
private string ReadResponse()
{
string response = string.Empty;
int numBytesToRead = uart.BytesToRead;
if (numBytesToRead > 0)
{
byte[] rx_data = new byte[numBytesToRead];
int offset = 0;
int ret = 0;
int len = rx_data.Length;
while (len > 0)
{
ret = uart.Read(rx_data, 0, rx_data.Length);
len -= ret;
offset += ret;
}
char[] rawResponse = Encoding.UTF8.GetChars(rx_data);
response = new string(rawResponse);
}
return response;
}
public string[] GetEverything()
{
// We are expecting to be in command mode here
SendCommand("get everything\r\n");
Thread.Sleep(1200);
string s = ReadResponse();
return null;
}
public string[] DiscoverNetworks()
{
// We are expecting to be in command mode here
SendCommand("scan\r");
Thread.Sleep(3500);
string s = ReadResponse();
// Parse the response into networks
string[] rawNetworks = s.Split('\r');
string[] networks = new string[rawNetworks.Length - 6];
for (int i = 0; i < networks.Length; i++)
{
networks[i] = rawNetworks[i + 5];
}
Debug.Print(s);
return networks;
}
public bool JoinNetwork(string ssid)
{
SendCommand("join " + ssid + "\r");
Thread.Sleep(100);
string s = ReadResponse();
if (s.IndexOf("Associated!") >= 0)
return true;
else
return false;
}
public string WebRequest(string url)
{
SendCommand("open " + url + " 80");
Thread.Sleep(100);
Debug.Print(ReadResponse());
return null;
}
}
}