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()); } }