Here’s a simple program that uses Rob Faludi and Dan Shiffman’s XBee library for processing to read three analog sensors from a remote XBee radio and graph it. For this application, you need two XBee series 1 radios. One is attached to the serial port of the computer, and the other is remote, broadcasting three analog values.
The settings for the radios are as follows:
Base station radio:
- Personal Area Network (PAN) ID: AAAA
- Source address: ATMY 0
- Baud rate 115200 bits per second: ATBD 7
Remote radio:
- Personal Area Network (PAN) ID: AAAA
- Source address: ATMY 1
- Destination address: ATDL 0
- Analog inputs activated:
-
- ATD0 2
- ATD1 2
- ATD2 2
- Sample rate 80 milliseconds: ATIR 50
- 1 sample per transmission: ATIT 1
- Baud rate 115200 bits per second: ATBD 7
And here’s the code:
/*
XBee sensor data graphing sketch
This sketch takes data in from an XBee radio and graphs the analog
input values. It's for XBee series 1 radios
Based on code from Rob Faludi and Daniel Shiffman
http://www.faludi.com
http://www.shiffman.net
created 2 Feb 2008
by Tom Igoe
*/
//import the xbee and serial libraries:
import xbee.*;
import processing.serial.*;
// Your Serial Port
Serial port;
// Your XBee Reader object
XBeeReader xbee;
// set up a font for displaying text:
PFont myFont;
int fontSize = 12;
// set up Xbee parameters:
int rssi = 0; // received signal strength
int address = 0; // sender's address
int[] analog = new int[6]; // values from the analog I/O pins
int[] previousValue = new int[6]; // previous values from the pins
int numSensors = 3; // number of sensors you actually plan to graph
int xpos = 0; // graph x position
int oldYPos = 0; // graph y position
int yPos = 0; // previous y position
int hitThreshold = 250; // peak value to check hits against
int hits = 0; // hit count
int lastHitValue = 0; // value of last hit
boolean newData = false; //whether or not you got a new reading
void setup() {
size(400, 300); // window size
frameRate(60); // frame rate
smooth(); // clean the jagged edges
// create a font with the third font available to the system:
myFont = createFont(PFont.list()[2], fontSize);
textFont(myFont);
// you might need a list of the serial ports to find yours:
println("Available serial ports:");
println(Serial.list());
// open the first serial port. Change this to match
// your serial port number in the list:
port = new Serial(this, Serial.list()[0], 115200);
// initialize the xbee object:
xbee = new XBeeReader(this,port);
xbee.startXBee();
// black screen:
background(0);
}
public void draw() {
// only draw when you have a new reading:
if (newData == true) {
// iterate over the number of sensors:
for (int thisSensor = 0; thisSensor < numSensors; thisSensor++) {
// if you have new data and it's valid (>0), graph it:
if (analog[thisSensor] > -1) {
// map the sensor values to the screen size for graphing:
yPos = int(map(analog[thisSensor], 0, 1023, 0, height));
oldYPos = int(map(previousValue[thisSensor], 0, 1023, 0, height));
// if we get a big change, increment the hit counter:
if (abs(yPos - oldYPos) >= hitThreshold) {
hits++;
// note the magnitude of the hit:
lastHitValue = abs(yPos - oldYPos);
}
}
// draw the graph axis:
stroke(255);
int xAxis = height/2;
line(0, xAxis, width, xAxis);
// use a different the graphing color for each axis:
switch (thisSensor) {
case 0:
stroke(255,0,0);
break;
case 1:
stroke(0,255,0);
break;
case 2:
stroke(0,0,255);
break;
}
// draw the graph line from last value to current:
line(xpos, oldYPos, xpos+1,yPos);
newData = false;
// write the text at the top
noStroke();
fill(0);
rect(0, 0, 300, 100);
fill(255);
text("From: " + hex(address), 10, 20);
text ("RSSI: " + rssi + " dBm", 10, 40);
text("X: " + analog[0] + " Y: " + analog[1] + " Z: " + analog[2], 10, 60);
text("Last hit value: " + lastHitValue, 10, 80);
}
// if you're at the right of the screen,
// clear and go back to the left:
if (xpos >= width) {
xpos = 0;
background(0);
}
else {
xpos++;
}
}
}
/*
This function works just like a "serialEvent()" and is
called for you when data is available to be read from your XBee radio.
*/
public void xBeeEvent(XBeeReader xbee) {
// Grab a frame of data
XBeeDataFrame data = xbee.getXBeeReading();
// This version of the library only works with IOPackets
// For ZNet radios, you would say XBeeDataFrame.ZNET_IOPACKET
if (data.getApiID() == XBeeDataFrame.SERIES1_IOPACKET) {
// Get the transmitter address
address = data.getAddress16();
// Get the RSSI reading in dBM
rssi = data.getRSSI();
// save previous state of analog values:
arraycopy(analog, previousValue);
// get the current values
// (-1 indicates channel is not configured):
analog = data.getAnalog();
// trip the new data flag so the draw() loop will graph:
newData = true;
}
else {
// it's not I/O data:
println("Not I/O data: " + data.getApiID());
}
}