XBee

From Wiring

Jump to: navigation, search

By Jaime Patarroyo

xBee modules are radio frequency (RF) transceivers: they're modules capable of sending and receiving data wirelessly between them using an standard communication protocol called ZigBee. The advantage of xBee's is that you don't need to understand the communication protocol to take advantage of there capabilities, you just branch the module to the RX TX pins in the Wiring board and you're ready to go.

Contents

Simple Example

For this simple communication example we're using the same setup and code for two Wiring's, each time you press the button on one Wiring, the board LED (48 for Wiring 1.0 boards, pin 15 for Wiring S) at the other board must light.

Setup Diagram

The Wiring board has two serial communication ports, I prefer branching the xBee to the second (RX1 and TX1) so I can still use the usb connection to the computer. If you want use the RX0 TX0 you'll have to disconnect the xBee each time you want to upload a program to the Wiring.

Remember that the xBee module pin's are closer than the standard, so you'll need a Breakout Board like the one offered by Sparkfun (Breakout Board for XBee Module) to accomplish the next diagram.

XBeeSimple.jpg

Code

/**
 * Simple xBee comunication example
 * by Jaime Patarroyo
 *
 * communicates two Wiring boards using xBee's modules,
 * pressing the button attached  to one Wiring, will 
 * light the board LED (48 for Wiring 1.0 boards, pin 
 * 15 for Wiring S) on the other board.
 */

// digital pin to attach the switch
int switchPin = 8;

// variable to store the data received
int data;

void setup()
{
  // Starts serial communication
  Serial1.begin(9600);
  // set pin as output
  pinMode(WLED, OUTPUT);

}

void loop()
{
  // if the switch is pressed
  if (digitalRead(switchPin) == HIGH)
  {
    // send the character 'a' though the xBee
    Serial1.print('a');
  }
  
  // if data available
  if (Serial1.available())
  {
    // read data
    data = Serial1.read();
    
    // if data received is 'a'
    if (data == 'a')
    {
      // turn ON the board LED
      digitalWrite(WLED, HIGH);
    }
    else
    {
      // if not turn if OFF
      digitalWrite(WLED, LOW);
    }
  }
  
  // wait 100ms
  delay(100);
}


Multiple readings (xBee series 1)

I've done this example using xBee series 1, I haven't worked with xBee series 2 but according to my understanding, they work different, for more information about all the types of xBee's I recommend the Sparkun's XBee Buying Guide.

Setup Diagram

In this example you would be able to read data from a maximum of five clients that should be wired as shown (you can branch the sensor you want) if you want to connect more than five you'll have to change the code (probably just copy paste some parts)

XBeeMultipleReadings.jpg

Code

Server code:

/**
 * xBee (series 1) multiple readings (server)
 * by Jaime Patarroyo
 * 
 * communicates six Wiring boards using xBee's modules,
 * one wiring work's as server and the other five as
 * clients. Sensors are attached to clients and are
 * constantly sending readings. Server selects which
 * client to listen from and saves values in variables. 
 */

// time measure variable
unsigned long previousTime = 0;

// incoming String
String inputString = "";

// address of module that's being heard
int destination = 11;

// sensors readings
int sensor01 = 0;
int sensor02 = 0;
int sensor03 = 0;
int sensor04 = 0;
int sensor05 = 0;

void setup()
{
  // begin seril comunication
  // Serial1 is for hearing the xBee (RX1 and TX1 on the
  // Wiring board)
  Serial1.begin(9600);
  // Serial is for sending readings through USB cable
  // to computer (RX and TX on the Wiring board)
  Serial.begin(9600);

  // mark initial time
  previousTime = millis();

  // change the module that's being heard
  changeDestination(destination);
}

void loop()
{
  // if available serial data, receive readings
  if (Serial1.available()) {
    readSensor();
  }

  // change the module that's being heard every 2 seconds
  if ((millis() - previousTime) >= 2000) {
    if (destination == 11)
      destination = 12;
    else if (destination == 12)
      destination = 13;
    else if (destination == 13)
      destination = 14;
    else if (destination == 14)
      destination = 15;
    else {
      destination = 11;
    }

    changeDestination(destination);
    previousTime = millis();
  }
  
  // prints readings in the serial port
  Serial.print("sen 1: ");
  Serial.print(sensor01, DEC);
  Serial.print(" sen 2: ");
  Serial.print(sensor02, DEC);
  Serial.print(" sen 3: ");
  Serial.print(sensor03, DEC);
  Serial.print(" sen 4: ");
  Serial.print(sensor04, DEC);
  Serial.print(" sen 5: ");
  Serial.println(sensor05, DEC);
}

void readSensor() {
  // save serial reading in internal variable
  char inByte = Serial1.read();

  if (isDigit(inByte)) {
    inputString = inputString + inByte;
  }

  // save each sensor reading in a different variable
  if (inByte == '\n') {
    int reading = inputString.toInt();

    if (destination == 11)
      sensor01 = reading;
    else if (destination == 12)
      sensor02 = reading;
    else if (destination == 13)
      sensor03 = reading;
    else if (destination == 14)
      sensor04 = reading;
    else
      sensor05 = reading;

    inputString = "";
  }
}

void changeDestination(int dest) {
  // print "+++" in the serial mode to put the xBee in
  // configuration mode
  Serial1.print("+++");
  char thisByte = 0;
  
  // wait for the character 'K' in the 'OK' response of
  // the xBee module  
  while(thisByte != 'K') {
    if(Serial1.available()) {
      thisByte = Serial1.read();
    }
  }

  // change address depending on destination
  if (dest == 11) {
    Serial1.print("ATDH0, DL11\r");
    Serial1.print("ATMY01\r");
    Serial1.print("ATCN\r");
  } 
  else if (dest == 12) {
    Serial1.print("ATDH0, DL12\r");
    Serial1.print("ATMY02\r");
    Serial1.print("ATCN\r");
  }
  else if (dest == 13) {
    Serial1.print("ATDH0, DL13\r");
    Serial1.print("ATMY03\r");
    Serial1.print("ATCN\r");
  }
  else if (dest == 14) {
    Serial1.print("ATDH0, DL14\r");
    Serial1.print("ATMY04\r");
    Serial1.print("ATCN\r");
  } 
  else {
    Serial1.print("ATDH0, DL15\r");
    Serial1.print("ATMY05\r");
    Serial1.print("ATCN\r");
  }
}

Client Code:

Remember to change the address in the code for each Wiring (search in the code comments for the exact location).

/**
 * xBee (series 1) multiple readings (client)
 * by Jaime Patarroyo
 * 
 * communicates six Wiring boards using xBee's modules,
 * one wiring work's as server and the other five as
 * clients. Sensors are attached to clients and are
 * constantly sending readings. Server selects which
 * client to listen from and saves values in variables. 
 */

// analog pin to attach the sensor
const int sensorPin = A7;

// variable to store the data received
int sensorValue = 0;

void setup()
{
  // starts serial communication
  Serial.begin(9600);
  Serial1.begin(9600);
  
  // changes the addtress of the xBee
  changeAddress();
}

void loop()
{
  // read data
  sensorValue = analogRead(sensorPin);
  sensorValue = sensorValue/4;

  // send data through xBee
  Serial1.println(sensorValue, DEC);
  Serial.println(sensorValue, DEC);

  delay(50);
}

void changeAddress() {
  // print "+++" in the serial mode to put the xBee in
  // configuration mode
  Serial.print("+++");
  char thisByte = 0;
  
  // wait for the character 'K' in the 'OK' response of
  // the xBee module  
  while(thisByte != 'K') {
    if(Serial.available()) {
      thisByte = Serial.read();
    }
  }

  // assign address:
  // change ATMY11 to ATMY12, ATMY13, ATMY14 or ATMY15
  // depending on the Wiring/sensor.
  Serial.print("ATMY11\r");
  Serial.print("ATCN\r");
}
Personal tools