Arduino & Xbee Wifi

Hello every one,

Has any one had any experience with the Xbee wifi module and arduino programming? I’ve been trying to follow this tutorial

https://learn.sparkfun.com/tutorials/in … -xbee-wifi. But I can’t get it to work at all.

I’ve tried setting up my router for WEP and for WPA2_AES. But I can not figure out what is going wrong.

I’ve tried setitng up the xbee to connect to the network via X-CTU and I can do that. It registeres and the LED’s correspond as specified. So I know that the Xbee is connecting to the network.

I’ve taken my Tx & Rx from my xbee and fed them into the arduino Rx → Rx & Tx-> Tx. I’ve tried crossing them over to, no luck. I’m wondering if the segment of code below is causing issues at all, as the description is vauge for me to read.

// Your WiFi network's SSID (name):
String WIFI_SSID = "WIFI_NAME_HERE";
// Your WiFi network's encryption setting
// Set the "encrypt" variable to one of these four characters:
// OPEN = 0, WPA_TKIP = 1, WPA2_AES = 2, WEP = 3
enum encryption{NO_SECURITY, WPA_TKIP, WPA2_AES, WEP};
encryption WIFI_EE = WPA2_AES;
// Your WiFi network's passphrase (if necessary). If your network
// is open, make this a blank string (passphrase = "";)
String WIFI_PSK = "WIFI_PASSWORD_HERE";

below is what I have done,

// Your WiFi network's SSID (name):
String WIFI_SSID = "Wirelessnetwork";
// Your WiFi network's encryption setting
// Set the "encrypt" variable to one of these four characters:
// OPEN = 0, WPA_TKIP = 1, WPA2_AES = 2, WEP = 3
enum encryption{WEP = 3};
encryption WIFI_EE = WEP;
// Your WiFi network's passphrase (if necessary). If your network
// is open, make this a blank string (passphrase = "";)
String WIFI_PSK = "letme";

I can’t quite determine what the note about setting the encrypt variable to means.

Has any one run through this tutorial? Has any one successfully connected an xbee wifi to an arduino for that matter?

Thanks for the help,

No experience with this product.

But choice of encryption type is the same as in most consumer WiFi routers/APs.

You need to find out what your wireless router is set to. The XBee should be the same.

Has any one successfully connected an xbee wifi to an arduino for that matter?

You didn’t specify your complete setup, does your Arduino have a WiFi module on it? What is it that your trying to do in detail? A pic of a drawing showing how everything is connected would be helpful. Or even a pic of your hardware. The Sparkfun tutorial gives you all the info you need so there is obviously something wrong with your setup and/or you skipped a few steps…

Another thing you can do is to lose the encryption all together.

Has any one successfully connected an xbee wifi to an arduino for that matter?

Yes, I have connected it. Tx->Rx and Rx->Tx. Make sure you’re using 3.3v. Once I configured it to a host and port in xtcu and saved the settings, I yanked out all the rest of that code that tries to do the same using AT commands from the arduino. This works well for me since I am only ever talking to one server to send along sensor data.

I’ve actually ran into some larger issues so I’m abandoning the xbee wifi at this time. Thank you for the replies though.

Hello, @johntreacy, I have the similar issue, once i upload the code, it says testing connection but nothing happens after… i have managed to connect the xbee to my wifi with X-CTU but soon as i but it on the arduino wifi proto shield, there is no connection.

any suggestions?

here is my code:

/*****************************************************************
Phant_XBee_WiFi.ino
Post data to SparkFun's data stream server system (phant) using
an XBee WiFi and XBee Shield.
Jim Lindblom @ SparkFun Electronics
Original Creation Date: May 20, 2014
https://learn.sparkfun.com/tutorials/online-datalogging-with-an-xbee-wifi

This sketch uses an XBee WiFi and an XBee Shield to get on
the internet and POST analogRead values to SparkFun's data
logging streams (http://data.sparkfun.com).

Hardware Hookup:
  The Arduino shield makes all of the connections you'll need
  between Arduino and XBee WiFi. If you have the shield make
  sure the SWITCH IS IN THE "DLINE" POSITION.

  I've also got four separate analog sensors (methane, co,
  temperature, and photocell) connected to pins A0-A3. Feel
  free to switch that up. You can post analog data, digital 
  data, strings, whatever you wish to the Phant server.

Requires the lovely Phant library:
  https://github.com/sparkfun/phant-arduino

Development environment specifics:
    IDE: Arduino 1.0.5
    Hardware Platform: SparkFun RedBoard
    XBee Shield & XBee WiFi (w/ trace antenna)

This code is beerware; if you see me (or any other SparkFun 
employee) at the local, and you've found our code helpful, please 
buy us a round!

Distributed as-is; no warranty is given.
*****************************************************************/
// SoftwareSerial is used to communicate with the XBee
#include <SoftwareSerial.h>
// The Phant library makes creating POSTs super-easy
#include <Phant.h>

// Time in ms, where we stop waiting for serial data to come in
// 2s is usually pretty good. Don't go under 1000ms (entering
// command mode takes about 1s).
#define COMMAND_TIMEOUT 2000 // ms

////////////////////////
// WiFi Network Stuff //
////////////////////////
// Your WiFi network's SSID (name):
String WIFI_SSID = "saqib";
// Your WiFi network's encryption setting
// Set the "encrypt" variable to one of these four characters:
// OPEN = 0, WPA_TKIP = 1, WPA2_AES = 2, WEP = 3
enum encryption{WPA2_AES};
encryption WIFI_EE = WPA2_AES;
// Your WiFi network's passphrase (if necessary). If your network
// is open, make this a blank string (passphrase = "";)
String WIFI_PSK = "saqibwifipassword";

/////////////////
// Phant Stuff //
/////////////////
// destIP will go into the XBee's configuration setting, so
// it'll automatically connect to the correct server.
String destIP = "54.86.132.254"; // data.sparkfun.com's IP address
// Initialize the phant object:
// Phant phant(server, publicKey, privateKey);
Phant phant("data.sparkfun.com", "o85jyKNrXEIK32Gw4byN", "yzo87X59jEU2DZbEV5N8");
// Phant field string defintions. Make sure these match the
// fields you've defined in your data stream:
const String AirTempField = "AirTemp";
const String CamErrField = "CamErr";
const String CrankErrField = "CrankErr";
const String FuelConField = "FuelCon";
const String FuelPressField = "FuelPress";
const String GearField = "Gear";
const String KPHField = "KPH";
const String LambdaField = "Lambda";
const String MAPKpaField = "MAPKpa";
const String OilPressField = "OilPress";
const String OilTempField = "OilTemp";
const String RPMField = "RPM";
const String TPSField = "TPS";
const String VoltsField = "Volts";
const String WaterTempField = "WaterTemp";


////////////////
// XBee Stuff //
////////////////
const byte XB_RX = 2; // XBee's RX (Din) pin
const byte XB_TX = 3; // XBee's TX (Dout) pin
// We'll use "xB" from here-on to send and receive data to it:
SoftwareSerial xB(XB_RX, XB_TX); 
const int XBEE_BAUD = 9600; // Your XBee's baud (9600 is default)

//set the baud rate up to match the one on the can bus



/////////////////////////////
// Input Pin Stuff //
/////////////////////////////
int a;
int b;
int c;
int d;
int e;
int f;
int g;
int h;
int i;
int j;
int k;
int l;
int m;
int n;
int o;
//think about adding the CAN bus variables here



/////////////////////////
// Update Rate Control //
/////////////////////////
// Phant limits you to 10 seconds between posts. Use this variable
// to limit the update rate (in milliseconds):
const unsigned long UPDATE_RATE = 10000; // 10000ms = 10 seconds
unsigned long lastUpdate = 0; // Keep track of last update time

///////////
// Setup //
///////////
// In setup() we configure our INPUT PINS, start the XBee and
// SERIAL ports, and CONNECT TO THE WIFI NETWORK.
void setup()
{
  // Set up sensor pins:
//  a=0;
//  b=0;
//  c=0;
//  d=0;
//  e=0;
//  f=0;
//  g=0;
//  h=0;
//  i=0;
//  j=0;
//  k=0;
//  l=0;
//  m=0;
//  n=0;
//  o=0;


  // Set up serial ports:
  Serial.begin(9600);
  // Make sure the XBEE BAUD RATE matches its pre-set value
  // (defaults to 9600).
  xB.begin(XBEE_BAUD);

  // Set up WiFi network
  Serial.println("Testing network");
  // connectWiFi will attempt to connect to the given SSID, using
  // encryption mode "encrypt", and the passphrase string given.
  connectWiFi(WIFI_SSID, WIFI_EE, WIFI_PSK);
  // Once connected, print out our IP address for a sanity check:
  Serial.println("Connected!");
  Serial.print("IP Address: "); printIP(); Serial.println(); 

  // setupHTTP() will set up the destination address, port, and
  // make sure we're in TCP mode:
  setupHTTP(destIP);

  // Once everything's set up, send a data stream to make sure
  // everything check's out:
  Serial.print("Sending update...");
  if (sendData())
    Serial.println("SUCCESS!");
  else
    Serial.println("Failed :(");
}

//////////
// Loop //
//////////
// loop() constantly checks to see if enough time has lapsed
// (controlled by UPDATE_RATE) to allow a new stream of data
// to be posted.
// Otherwise, to kill time, it'll print out the sensor values
// over the serial port.
void loop()
{
  // If current time is UPDATE_RATE milliseconds greater than
  // the last update rate, send new data.
  if (millis() > (lastUpdate + UPDATE_RATE))
  {
    Serial.print("Sending update...");
    if (sendData())
      Serial.println("SUCCESS!");
    else
      Serial.println("Failed :(");
    lastUpdate = millis();
  }
  // In the meanwhile, we'll print data to the serial monitor,
  // just to let the world know our Arduino is still operational:
  readSensors(); // Get updated values from sensors
  Serial.print(millis()); // Timestamp
  Serial.print(": ");
  Serial.print(a);
  Serial.print('\t');
  Serial.print(b);
  Serial.print('\t');
  Serial.print(c);
  Serial.print('\t');
  Serial.print(d);
  Serial.print('\t');
  Serial.print(e);
  Serial.print('\t');
  Serial.print(f);
  Serial.print('\t');
  Serial.print(g);
  Serial.print('\t');
  Serial.print(h);
  Serial.print('\t');
  Serial.print(i);
  Serial.print('\t');
  Serial.print(j);
  Serial.print('\t');
  Serial.print(k);
  Serial.print('\t');
  Serial.print(l);
  Serial.print('\t');
  Serial.print(m);
  Serial.print('\t');
  Serial.print(n);
  Serial.print('\t');
  Serial.println(o);
  delay(1000);

//add the messgae bytes here to display on the serial monitor
}

////////////////
// sendData() //
////////////////
// sendData() makes use of the PHANT LIBRARY to send data to the
// data.sparkfun.com server. We'll use phant.add() to add specific
// parameter and their values to the param list. Then use
// phant.post() to send that data up to the server.
int sendData()
{
  xB.flush(); // Flush data so we get fresh stuff in
  // IMPORTANT PHANT STUFF!!!
  // First we need to add fields and values to send as parameters
  // Since we just need to read values from the analog pins, this
  // can be automized with a for loop:
  //readSensors(); // Get updated values from sensors.
  //phant.add(tempField, tempVal);
  //follow this as shown

  
  phant.add(AirTempField, a); 
  phant.add(CamErrField, b);
  phant.add(CrankErrField, c);
  phant.add(FuelConField, d);
  phant.add(FuelPressField, e);
  phant.add(GearField, f);
  phant.add(KPHField, g);
  phant.add(LambdaField, h);
  phant.add(MAPKpaField, i); 
  phant.add(OilPressField, j); 
  phant.add(OilTempField, k);
  phant.add(RPMField, l);
  phant.add(TPSField, m);
  phant.add(VoltsField, n);
  phant.add(WaterTempField, o); 
  
  // After our PHANT.ADD's we need to PHANT.POST(). The post needs
  // to be sent out the XBee. A simple "print" of that post will
  // take care of it.
  xB.print(phant.post());

  // Check the response to make sure we receive a "200 OK". If 
  // we were good little programmers we'd check the content of
  // the OK response. If we were good little programmers...
  char response[12];
  if (waitForAvailable(12) > 0)
  {
    for (int i=0; i<12; i++)
    {
      response[i] = xB.read();
    }
    if (memcmp(response, "HTTP/1.1 200", 12) == 0)
      return 1;
    else
    {
      Serial.println(response);
      return 0; // Non-200 response
    }
  }
  else // Otherwise timeout, no response from server
    return -1;
}

// readSensors() will simply update a handful of global variables
// It updates tempVal, lightVal, coVal, and methaneVal
void readSensors()
{
  a = a + 1;
  b = b + 2;
  c = c + 3;
  d = d + 4;
  e = e + 5;
  f = f + 6;
  g = g + 7;
  h = h + 8;
  i = i + 9;
  j = j + 10;
  k = k + 11;
  l = l + 12;
  m = m + 13;
  n = n + 14;
  o = o + 15;
  
}

///////////////////////////
// XBee WiFi Setup Stuff //
///////////////////////////
// setupHTTP() sets three important parameters on the XBee:
// 1. Destination IP -- This is the IP address of the server
//    we want to send data to.
// 2. Destination Port -- We'll be sending data over port 80.
//    The standard HTTP port a server listens to.
// 3. IP protocol -- We'll be using TCP (instead of default UDP).
void setupHTTP(String address)
{
  // Enter command mode, wait till we get there.
  while (!commandMode(1))
    ;

  // Set IP (1 - TCP)
  command("ATIP1", 2); // RESP: OK
  // Set DL (destination IP address)
  command("ATDL" + address, 2); // RESP: OK
  // Set DE (0x50 - port 80)
  command("ATDE50", 2); // RESP: OK

  commandMode(0); // Exit command mode when done
}

///////////////
// printIP() //
///////////////
// Simple function that enters command mode, reads the IP and
// prints it to a serial terminal. Then exits command mode.
void printIP()
{
  // Wait till we get into command Mode.
  while (!commandMode(1))
    ;
  // Get rid of any data that may have already been in the
  // serial receive buffer:
  xB.flush();
  // Send the ATMY command. Should at least respond with
  // "0.0.0.0\r" (7 characters):
  command("ATMY", 7);
  // While there are characters to be read, read them and throw
  // them out to the serial monitor.
  while (xB.available() > 0)
  {
    Serial.write(xB.read());
  }
  // Exit command mode:
  commandMode(0);
}

//////////////////////////////
// connectWiFi(id, ee, psk) //
//////////////////////////////
// For all of your connecting-to-WiFi-networks needs, we present
// the connectWiFi() function. Supply it an SSID, encryption
// setting, and passphrase, and it'll try its darndest to connect
// to your network.
int connectWiFi(String id, byte auth, String psk)
{
  const String CMD_SSID = "ATID";
  const String CMD_ENC = "ATEE";
  const String CMD_PSK = "ATPK";
  // Check if we're connected. If so, sweet! We're done.
  // Otherwise, time to configure some settings, and print
  // some status messages:
  int status;
  while ((status = checkConnect(id)) != 0)
  {
    // Print a status message. If `status` isn't 0 (indicating
    // "connected"), then it'll be one of these 
    //  (from XBee WiFI user's manual):
    // 0x01 - WiFi transceiver initialization in progress. 
    // 0x02 - WiFi transceiver initialized, but not yet scanning 
    //        for access point. 
    // 0x13 - Disconnecting from access point. 
    // 0x23 – SSID not configured. 
    // 0x24 - Encryption key invalid (either NULL or invalid 
    //        length for WEP) 
    // 0x27 – SSID was found, but join failed. 0x40- Waiting for 
    //        WPA or WPA2 Authentication 
    // 0x41 – Module joined a network and is waiting for IP 
    //        configuration to complete, which usually means it is
    //        waiting for a DHCP provided address. 
    // 0x42 – Module is joined, IP is configured, and listening 
    //        sockets are being set up. 
    // 0xFF– Module is currently scanning for the configured SSID.
    //
    // We added 0xFE to indicate connected but SSID doesn't match
    // the provided id.
    Serial.print("Waiting to connect: ");
    Serial.println(status, HEX);

    commandMode(1); // Enter command mode

    // Write AH (2 - Infrastructure) -- Locked in
    command("ATAH2", 2);
    // Write CE (2 - STA) -- Locked in
    command("ATCE2", 2);  
    // Write ID (SparkFun) -- Defined as parameter
    command(CMD_SSID + id, 2);
    // Write EE (Encryption Enable) -- Defined as parameter
    command(CMD_ENC + auth, 2);
    // Write PK ("sparkfun6175") -- Defined as parameter
    command(CMD_PSK + psk, 2);
    // Write MA (0 - DHCP) -- Locked in
    command("ATMA0", 2);
    // Write IP (1 - TCP) -- Loced in
    command("ATIP1", 2);

    commandMode(0); // Exit Command Mode CN

    delay(2000);
  }
}

// Check if the XBee is connected to a WiFi network.
// This function will send the ATAI command to the XBee.
// That command will return with either a 0 (meaning connected)
// or various values indicating different levels of no-connect.
byte checkConnect(String id)
{
  char temp[2];
  commandMode(0);
  while (!commandMode(1))
    ;
  command("ATAI", 2);
  temp[0] = hexToInt(xB.read());
  temp[1] = hexToInt(xB.read());
  xB.flush();

  if (temp[0] == 0)
  {
    command("ATID", 1);
    int i=0;
    char c=0;
    String atid;
    while ((c != 0x0D) && xB.available())
    {
      c = xB.read();
      if (c != 0x0D)
        atid += c;
    }
    if (atid == id)
      return 0;
    else
      return 0xFE;
  }
  else
  {
    if (temp[1] == 0x13)
      return temp[0];
    else
      return (temp[0]<<4) | temp[1];
  }
}

/////////////////////////////////////
// Low-level, ugly, XBee Functions //
/////////////////////////////////////
void command(String atcmd, int rsplen)
{
  xB.flush();
  xB.print(atcmd);
  xB.print("\r");
  waitForAvailable(rsplen);
}

int commandMode(boolean enter)
{
  xB.flush();

  if (enter)
  {
    char c;
    xB.print("+++");   // Send CMD mode string
    waitForAvailable(1);
    if (xB.available() > 0)
    {
      c = xB.read();
      if (c == 'O') // That's the letter 'O', assume 'K' is next
        return 1; // IF we see "OK" return success
    }
    return 0; // If no (or incorrect) receive, return fail
  }
  else
  {
    command("ATCN", 2);
    return 1;
  }
}

int waitForAvailable(int qty)
{
  int timeout = COMMAND_TIMEOUT;

  while ((timeout-- > 0) && (xB.available() < qty))
    delay(1);

  return timeout;
}

byte hexToInt(char c)
{
  if (c >= 0x41) // If it's A-F
    return c - 0x37;
  else
    return c - 0x30;
}

saqib: One thing that is wrong in your code is the enum statement (line 55). For this to work, the enum declaration should contain the four values, and in the next line you are choosing one. By leaving the others out, the value assigned shifts - should have been 2 is instead 0. This may help.

What I did however, was to leave a lot of this code out by configuring the xbee-wifi with AT commands in xctu and saving the configuration so that each time the xbee is powered up it knows its all of its wifi parameters AND knows its server IP addr that it is writing to and that its a TCP connection. This works for me because this arduino will always only write to this particular phant server.

Another thing in the code is the check of the result from send_data. It only checks for non-zero. You really want to know if its in fact == 1 for success.