Xbee and the ConnectPort

March 27th, 2011 by Lizabeth Arum Leave a reply »

Inspired by Rob Faludi’s book, Building Wireless Sensor Networks, my students and I have recently been working with Series 1 Xbee radios and the ConnectPort. While the book covers XBee Series 2 (ZB) radios, we just had Series 1 radios laying around, so that’s what we used.

After completing a few exercises that demonstrated how to send data from radio to radio, we plugged the ConnectPort in and controlled a light remotely through a web page. For most of the class, this was the first time writing PHP. This exercise was based on Rob’s example in the book and works just like Make magazine’s Matt Richardson’s Networked On Air Light example, except that our light was a bit smaller—we used a pink 3mm LED.

Once we could control the LED through the form, I challenged the students to control the light both locally and remotely. This turned out to be a bit more complicated than we expected. After several hours of debugging and with some much appreciated help from Rob, it turned out that

  • The connectPort couldn’t handle a url request that returned nothing.
  • We needed to do a little handshaking
  • We needed to be able to resend a request if it failed

The Basic PHP Form

The Second PHP Script

The Arduino Code

The First PHP Script

<html>
<head>
<title>LightingState</title>
<meta http-equiv="refresh" content="5";url="lighting_state_form.php" />
<meta name="viewport" content="width=device-width; initial-scale=1.0;" /> <!-- for iphone size -->
</head>
<body>
<div>
<?php
// define a variable for the data file
$myFile = "lightingState.txt";
// open the data file
$fh = fopen($myFile, 'r') or die("can't open file");

// read the current light setting from the data file

$contents = fread($fh, filesize($myFile));

// close the data file
fclose($fh);
if(!isset($_POST['send'])){
//statements
if ($contents==1){
$contents="On";
}else{
$contents="Off";
}
echo "Light was last: ".$contents;
} else {
$value =$_POST['light'];
if ($value==1){
echo "Light is now: On";
}else{
echo "Light is now: Off";
}
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh,$value);
fclose($fh);
}
echo"<form action=".$_SERVER['PHP_SELF']." method='post'>";
echo "<input type='radio' name='light' value='1' /> On<br />";
echo "<input type='radio' name='light' value='0' /> Off<br />";
echo"</label><br />";
echo"<input type='submit' value='Submit' name='send' />";
echo"</form>";
?>
</div>
</body>
</html>

The Second PHP Script

<?php
$value =$_GET['light'];
$myFile = "lightingState.txt";
$fh = fopen($myFile, 'r') or die("can't open file");
$oldValue=fread($fh, filesize($myFile));
fclose($fh);
$fh = fopen($myFile, 'w') or die("can't open file");
if(($value==0 ||$value==1) && ($value!=NULL)){
fwrite($fh,$value);
}else{
fwrite($fh,$oldValue);
}
fclose($fh);
echo "A";
?>

Arduino Code

#include <Tone.h>
#include <Button.h>
/*
* *********ZigBee Internet Gateway Light Example********
* by Rob Faludi http://faludi.com
*/
#define NAME "ZIG Light Example"
#define VERSION "1.00"
#define LED_PIN 13
Button btn=Button(5,PULLDOWN);
int outputLight = 12;
int lightState;
int light;
unsigned long pt;
unsigned long pt2;
boolean lightOn=false;
Tone speaker;
String urlRequest;
boolean received=false;
void setup() {
pinMode(LED_PIN,OUTPUT);
pinMode(outputLight,OUTPUT);
blinkLED(LED_PIN,2,100);
blinkLED(outputLight,2,100);
////////////////////////////////
// faster is better for ZIG, but with Series 1
// this seemed to be the best speed
Serial.begin(57600);
////////////////////////////////
delay(2000);
received=true;
////////////////////////////////
speaker.begin(7);
}
void loop() {
if(btn.uniquePress()){
if(lightOn) {
speaker.play(NOTE_C3,200);
urlRequest="my_url/lighting_state_form2.php?light=0";
speaker.play(NOTE_C3,200);
}else if(!lightOn){
speaker.play(NOTE_C5,200);
urlRequest="my_url/lighting_state_form2.php?light=1";
speaker.play(NOTE_C5,200);
}
received=false;
}
if(!received){
if(millis()-pt2>250){
pt2=millis();
Serial.println(urlRequest);
}
}

if(millis()-pt>1000){
pt=millis();
if(received){
Serial.println("my_url/lightingState.txt");
}
}
////////////////////////////////
// if there's a byte waiting
if (Serial.available() > 0) {
////////////////////////////////
// read the ASCII numeral byte
lightState = Serial.read();
////////////////////////////////
//do a little handshaking
if(lightState=='A'){
//run a timer if false, if it waits too long resend it
received=true;
digitalWrite(13,HIGH);
delay(250);
}else{
digitalWrite(13,LOW);
}
////////////////////////////////
if (lightState == '0' || lightState=='1') {
lightState=lightState-48;
if(lightState==1){
lightOn=true;
light=1;
} else if(lightState==0){
lightOn=false;
light=0;
}
}
}
digitalWrite(outputLight, light);
}

////////////////// UTILITIES //////////////////
// this function blinks the an LED light as many times as requested, at the requested blinking rate
void blinkLED(byte targetPin, int numBlinks, int blinkRate) {
for (int i=0; i<numBlinks; i++) {
digitalWrite(targetPin, HIGH); // sets the LED on
delay(blinkRate); // waits for blinkRate milliseconds
digitalWrite(targetPin, LOW); // sets the LED off
delay(blinkRate);
}
}

Advertisement

Leave a Reply