May I ask why after I uncomment the following line
- data = getSimulatedData(); // uncomment this to use random data for testing
- import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.log4j.PropertyConfigurator;
import com.rapplogic.xbee.api.PacketListener;
import com.rapplogic.xbee.api.XBee;
import com.rapplogic.xbee.api.XBeeResponse;
import com.rapplogic.xbee.api.wpan.RxResponseIoSample;
/*
* Draws a set of thermometers for incoming XBee Sensor data
* by Rob Faludi http://faludi.com
*/
// used for communication via xbee api
import processing.serial.*;
// xbee api libraries available at http://code.google.com/p/xbee-api/
// Download the zip file, extract it, and copy the xbee-api jar file
// and the log4j.jar file (located in the lib folder) inside a "code"
// folder under this Processing sketch's folder (save this sketch, then
// click the Sketch menu and choose Show Sketch Folder).
import com.rapplogic.xbee.api.ApiId;
import com.rapplogic.xbee.api.PacketListener;
import com.rapplogic.xbee.api.XBee;
import com.rapplogic.xbee.api.XBeeResponse;
import com.rapplogic.xbee.api.zigbee.ZNetRxIoSampleResponse;
String version = "1.01";
// *** REPLACE WITH THE SERIAL PORT (COM PORT) FOR YOUR LOCAL XBEE ***
String mySerialPort = "COM13";
// create and initialize a new xbee object
XBee xbee = new XBee();
// make an array list of thermometer objects for display
ArrayList thermometers = new ArrayList();
// create a font for display
PFont font;
void setup() {
size(800, 600); // screen size
smooth(); // anti-aliasing for graphic display
// You'll need to generate a font before you can run this sketch.
// Click the Tools menu and choose Create Font. Click Sans Serif,
// choose a size of 10, and click OK.
font = loadFont("SansSerif-10.vlw");
textFont(font); // use the font for text
// The log4j.properties file is required by the xbee api library, and
// needs to be in your data folder. You can find this file in the xbee
// api library you downloaded earlier
//PropertyConfigurator.configure(dataPath("")+"log4j.properties");
println(dataPath(""));
PropertyConfigurator.configure("D:\\processing2.0.1\\faludi\\sketch_130801a\\data\\log4j.properties");
// Print a list in case the selected one doesn't work out
println("Available serial ports:");
println(Serial.list());
try {
// opens your serial port defined above, at 9600 baud
xbee.open(mySerialPort, 9600);
}
catch (XBeeException e) {
println("** Error opening XBee port: " + e + " **");
println("Is your XBee plugged in to your computer?");
println("Did you set your COM port in the code near line 20?");
}
}
// draw loop executes continuously
void draw() {
background(224); // draw a light gray background
SensorData data = new SensorData(); // create a data object
data = getData(); // put data into the data object
data = getSimulatedData(); // uncomment this to use random data for testing
// check that actual data came in:
if (data.value >=0 && data.address != null) {
// check to see if a thermometer object already exists for this sensor
int i;
boolean foundIt = false;
for (i=0; i <thermometers.size(); i++) {
if ( ((Thermometer) thermometers.get(i)).address.equals(data.address) ) {
foundIt = true;
break;
}
}
// process the data value into a Celsius temperature reading for
// LM335 with a 1/3 voltage divider
// (value as a ratio of 1023 times max ADC voltage times
// 3 (voltage divider value) divided by 10mV per degree
// minus zero Celsius in Kelvin)
float temperatureCelsius = (data.value/1023.0*1.2*3.0*100)-273.15;
println(" temp: " + round(temperatureCelsius) + "°C");
// update the thermometer if it exists, otherwise create a new one
if (foundIt) {
((Thermometer) thermometers.get(i)).temp = temperatureCelsius;
}
else if (thermometers.size() < 10) {
thermometers.add(new Thermometer(data.address,35,450,
(thermometers.size()) * 75 + 40, 20));
((Thermometer) thermometers.get(i)).temp = temperatureCelsius;
}
// draw the thermometers on the screen
for (int j =0; j<thermometers.size(); j++) {
((Thermometer) thermometers.get(j)).render();
}
}
} // end of draw loop
// defines the data object
class SensorData {
int value;
String address;
}
// defines the thermometer objects
class Thermometer {
int sizeX, sizeY, posX, posY;
int maxTemp = 40; // max of scale in degrees Celsius
int minTemp = -10; // min of scale in degrees Celsius
float temp; // stores the temperature locally
String address; // stores the address locally
Thermometer(String _address, int _sizeX, int _sizeY,
int _posX, int _posY) { // initialize thermometer object
address = _address;
sizeX = _sizeX;
sizeY = _sizeY;
posX = _posX;
posY = _posY;
}
void render() { // draw thermometer on screen
noStroke(); // remove shape edges
ellipseMode(CENTER); // center bulb
float bulbSize = sizeX + (sizeX * 0.5); // determine bulb size
int stemSize = 30; // stem augments fixed red bulb
// to help separate it from moving mercury
// limit display to range
float displayTemp = round( temp);
if (temp > maxTemp) {
displayTemp = maxTemp + 1;
}
if ((int)temp < minTemp) {
displayTemp = minTemp;
}
// size for variable red area:
float mercury = ( 1 - ( (displayTemp-minTemp) / (maxTemp-minTemp) ));
// draw edges of objects in black
fill(0);
rect(posX-3,posY-3,sizeX+5,sizeY+5);
ellipse(posX+sizeX/2,posY+sizeY+stemSize, bulbSize+4,bulbSize+4);
rect(posX-3, posY+sizeY, sizeX+5,stemSize+5);
// draw gray mercury background
fill(64);
rect(posX,posY,sizeX,sizeY);
// draw red areas
fill(255,16,16);
// draw mercury area:
rect(posX,posY+(sizeY * mercury),
sizeX, sizeY-(sizeY * mercury));
// draw stem area:
rect(posX, posY+sizeY, sizeX,stemSize);
// draw red bulb:
ellipse(posX+sizeX/2,posY+sizeY + stemSize, bulbSize,bulbSize);
// show text
textAlign(LEFT);
fill(0);
textSize(10);
// show sensor address:
text(address, posX-10, posY + sizeY + bulbSize + stemSize + 4, 65, 40);
// show maximum temperature:
text(maxTemp + "°C", posX+sizeX + 5, posY);
// show minimum temperature:
text(minTemp + "°C", posX+sizeX + 5, posY + sizeY);
// show temperature:
text(round(temp) + " °C", posX+2 ,posY+(sizeY * mercury+ 14));
}
}
// used only if getSimulatedData is uncommented in draw loop
//
SensorData getSimulatedData() {
SensorData data = new SensorData();
int value = int(random(750,890));
String address = "00:13:A2:00:12:34:AB:C" + str( round(random(0,9)) );
data.value = value;
data.address = address;
delay(200);
return data;
}
// queries the XBee for incoming I/O data frames
// and parses them into a data object
SensorData getData() {
SensorData data = new SensorData();
int value = -1; // returns an impossible value if there's an error
String address = ""; // returns a null value if there's an error
try {
// we wait here until a packet is received.
XBeeResponse response = xbee.getResponse();
// uncomment next line for additional debugging information
//println("Received response " + response.toString());
// check that this frame is a valid I/O sample, then parse it as such
if (response.getApiId() == ApiId.ZNET_IO_SAMPLE_RESPONSE
&& !response.isError()) {
ZNetRxIoSampleResponse ioSample =
(ZNetRxIoSampleResponse)(XBeeResponse) response;
// get the sender's 64-bit address
int[] addressArray = ioSample.getRemoteAddress64().getAddress();
// parse the address int array into a formatted string
String[] hexAddress = new String[addressArray.length];
for (int i=0; i<addressArray.length;i++) {
// format each address byte with leading zeros:
hexAddress[i] = String.format("%02x", addressArray[i]);
}
// join the array together with colons for readability:
String senderAddress = join(hexAddress, ":");
print("Sender address: " + senderAddress);
data.address = senderAddress;
// get the value of the first input pin
value = ioSample.getAnalog0();
print(" analog value: " + value );
data.value = value;
}
else if (!response.isError()) {
println("Got error in data frame");
}
else {
println("Got non-i/o data frame");
}
}
catch (XBeeException e) {
println("Error receiving response: " + e);
}
return data; // sends the data back to the calling function
}
I really appreciate any help.
1