Arduino‎ > ‎Brewing Arduino‎ > ‎

WiFly : Xbee with WiFi using Arduino serial interface

posted Feb 19, 2012, 9:29 PM by Haris Hashim   [ updated Feb 20, 2012, 5:57 AM ]








Introduction

Ever wanted to add WiFi functionality into your project? Looking for flexible solution that can connect to existing WiFi network be it adhoc or infrastructure mode, using WEP, WPA or WPA2 security?

This WiFi module from Roving Network, with the added advantage of XBee form factor, is a good fit to above needs. Easily configured to securely connect to existing WiFi network. Once configured, it will remember the WiFi connection parameters and will connect to the configured WiFi network automatically.

Worthwhile mention is the module built in RTC. Together with its WiFi capability to connect to internet and synchronize with network time server. Thus complementing Arduino missing real time clock functionlaity. Imagine being able to create a data logger that keeps time as well as synchronize accurately recorded log to the cloud!

It works with existing XBee accessory including XBee USB Adapter, XBee Shield and various DFRobot shield that come with XBee support. An inexpensive WiFi addition to those who already invest in XBee hardwares!

 

Configuration

*Notes: This step are for specific hardware bought from H&T online shop. Applying bellow step on different set of hardware are not advisable and may cause damage or bricking the device. Please be careful! 

As in the last XBee article, we are going to configure the module using XBee USB Adapter. However, instead of X-CTU. The software to be used is called Tera Term. The configuration step is more to the tune of sending raw command instead of using GUI as in the case of XBee. However, it is easy and a very informative process.

Requirement

  • XBee USB Adapter
  • WiFly WiFi module in XBee form factor

*Important: Be careful not to insert WiFly module in reverse in to the XBee USB Adapter. Doing so might damage the module.

Steps

  1. Connect XBee USB adapter to your development machine using USB cable and plugged in the Wi Fly module.
  2. It is a good idea to double check the detected comport number in Device Manager. Otherwise, Tera Term is good enough to display list of connected comports.
  3. Open up Tera Term. File >> New Connection or press ALT-N. Choose Serial and the right port to connect to. Press OK to proceed.
    Tera Term connect to ...
  4. Observed that upon power up, red and yellow LED of the Wi Fly module is blinking. Observed also that the just opened serial terminal is reporting unable to connect to the network. This is because Wi Fi network connection parameter is not configured yet. To do this configuration, we need to be in command mode.
    Tera Term unable to connect
  5. Simply type "$$$" character in the terminal window to enter command mode. No need to press ENTER.
  6. Take note that that command mode can be used to set parameters as well as query a lot of information. Just for kicks, Try get wlan and get ip to see the parameters that we are going to change shortly.
  7. To set WiFi connection using WPA2  issue the following command. Take note that for WPA2, only AES encryption setting is supported on the router.
    • set wlan auth 4
    • set wlan ssid <SSID to connect>
    • set wlan phrase <security key/password>
    • set wlan join 1
    • set wlan channel 0
    • set ip dhcp 1
      WiFi connection configuration
  8. Execute command to save above configuration. Otherwise, the setting will be gone upon power lost. After that reboot.
    • save
    • reboot
      Save &amp; Reboot
  9. The module will than restart and establish WiFi connection with the WiFi router. Note the IP address as we will need it in the next steps.
  10. Development machine must be connected to the same WiFi router to test. Open up windows shell and ping ip address from previous step to verify.
    Ping in command prompt
  11. To demonstrate that the module is now connected to WiFi network, telnet to the IP address. Either using windows shell or Tera Term. When telnet is  successfully   connected, *HELLO* will be displayed. Whatever typed in the telnet terminal will show in serial terminal window used during above configuration steps. We are done with configuration!
    Telnet Test

To The Codes!

As usual, here is a very simple test code for Arduino. The codes it self  is based on SerialCallResponse sample code (Arduino IDE >> File >> Examples >> Communication >> SerialCallResponse). 

During configuration step, we have seen how the WiFly module can be accessed using telnet over WiFi network. We are just going to extend this functionality by having Arduino monitor input sent through telnet session for ON or OFF command set. In a way, it is a demonstration of turning LED over telnet!

Being base on XBee means that communication between Arduino and the WiFly module is serial. I.e. whatever written to Arduino RX pin will be received by the module TX pin and vice versa for the module TX pin and Arduino RX pin. 

The beauty of using shield is that hardware is abstracted. Just plugged in WiFly module on top of a shield with XBee connector and stack the shield on top of an Arduino micro controller board. No need to worry about what RX pin connected what else TX pin :D. It is good to know that the code will just work! Perhaps one day we will delve deeper into this hardware complexity. Definitely that day is not today.

Here is the hardware requirement, or at least what used for this particular coding activity.

Requirement

  • An Arduino micro-controller board. Uno R3 will do nicely.
  • DFRobot IO Expansion Shield just to use something that is lying around and available to me. DFRobot XBee Shield would do it. In fact,  nowadays  DFRobot have a lot of shield with XBee support. Any of this shield will do!
  • WiFly WiFi module in XBee form factor.

Assembly


This is the tricky part. Generally, Arduino board can not be programmed while any XBee module is connected to it. Since the board is sharing serial communication with USB as well as the module. There are ways to work around this, but simplest is to disconnect the wiFly module before uploading the code. The assembly order should be as bellow:
  • Connect Arduino board to your development machine (PC or notebook) using USB cable.
  • Write the codes, compile and upload it to the board.
  • Mount WiFly module on top of the shield and stack the shield on top of Arduino. If needed, power down Arduino board before stacking the shield. Just being careful to avoid accidental shorting whenever board is powered up.
  • If there is need to reprogram the Arduino board, unplug the shield or the WiFly module before reprogramming.


The Code


In summary, the code waits for certain ASCII character which will then turn on or off built in LED on pin 13. DFRobot IO Expansion shield does duplicate the built in LED pin. Otherwise, it will be hard to see the LED on or off status.


Take note of the cmd global variable, basically it keeps track a line of command.



The setup part of the code simply do the necessary to initialize serial communication and set digital pin 13 as output for turning the built in LED on and off. 

The establishContact() function is sort of the place where communication hand shake should happen.


String cmd = "";

void setup()

{

      Serial.begin(9600);

      pinMode(13, OUTPUT);

      establishContact(); 

}



Here we see that establish contact actually is not doing anything much. Remember that this code is running on Arduino, i.e. the Atmega micro controller chip. The mcu simply send ASCII character A through the serial connection until there is a reply from the other side.
The other side, in this case is our WiFly module. Which is relaying the character over WiFi network connection.

void establishContact() {

      while (Serial.available() <= 0) {

            Serial.print('A', BYTE); // send a capital A

            delay(300);

      }

}



The main loop just happen again and again as long as the hardware is running.

So it repetitively wait for a byte of data available to read from the WiFly module serial connection.
When there is such data, it is appended to the cmd global variable, which is a string object. A byte of data is just another way of saying a character. So you can imagine cmd string is being built a character at a time.

As the cmd string is being built, it is being checked whether it is a command or not.



void loop()

{

      if (Serial.available() > 0) {

            // get incoming byte:

            char inByte = Serial.read();

            cmd = cmd + inByte;

            checkCommand();

      }

}




How it is being check is also a simple matter of
  • whether it is a line ended by carriage return and line feed character (CR = \r and LF = \n).
  • whether it is a valid command. Which in this case ON command (turn on LED) and OFF command (turn off LED).
Depending on the command, LED connected to digital pin 13 is going to be turned on or off.


This function simply process commands as it is detected and only once. After that it simply clear the cmd string. So that the global variable will start fresh the next time. To be filled up by another series of character that will build the next command.



void checkCommand(){

      if(cmd.endsWith("\r\n")){

            if (cmd == "ON\r\n"){

                  digitalWrite(13, HIGH);

            }else if (cmd == "OFF\r\n"){

                  digitalWrite(13, LOW);

            }

            cmd="";

      }

}



Comments