6.1 Lab: Ping-ing a Sensor
Adding a computer to our electronics mix makes things much more interesting. We will be using the API mode 2, since we will be using the Python XBee library to talk to the XBee. In this Lab we will cover three different activities to show the possibilities that the combination of Python and XBee offer.
First, we will use remote AT commands to blink an LED connected to a stand-alone computer. Then, we will measure how long it takes from the moment we send a packet until we receive the confirmation. There is last activity in the video, but we won't explain you the details of how to do it. This third part is about sending data to remote XBee using the API mode. The remote XBee is connected to an Arduino that uses the XBee library to receive the data. The Arduino receives the data, which is just a number, and then blinks the LED as many times as indicated by the received packet.
This can be tricky, confusing or complicated. Don't hesitate to ask questions if you are in doubt.
Code to blink an LED using AT remote command:
#! /usr/bin/python
from xbee import XBee
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 9600)
xbee = XBee(ser)
while True:
try:
xbee.send('remote_at',
frame_id='A',
dest_addr_long='\x00\x00\x00\x00\x00\x00\xFF\xFF',
dest_addr='\xFF\xFE',
options='\x02',
command='D1',
parameter='\x05')
time.sleep(1)
xbee.send('remote_at',
frame_id='A',
dest_addr_long='\x00\x00\x00\x00\x00\x00\xFF\xFF',
dest_addr='\xFF\xFE',
options='\x02',
command='D1',
parameter='\x04')
time.sleep(1)
except KeyboardInterrupt:
break
xbee.send('remote_at',
frame_id='A',
dest_addr_long='\x00\x00\x00\x00\x00\x00\xFF\xFF',
dest_addr='\xFF\xFE',
options='\x02',
command='D1',
parameter='\x05')
ser.close()
Example code to send a number 3 to a remote XBee
#! /usr/bin/python
import time
from datetime import datetime
import serial
from xbee import XBee, ZigBee
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port and enable flow control
ser = serial.Serial(PORT, BAUD_RATE, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=1, rtscts=1, dsrdtr=1)
# Create API object
xbee = ZigBee(ser,escaped=True)
DEST_ADDR_LONG = "\x00\x13\xA2\x00\x40\x8B\x44\xFA"
#part to discovery shot 16-bit address
xbee.send("tx",data="\x00\x03",dest_addr_long=DEST_ADDR_LONG,dest_addr="\xff\xfe")
response = xbee.wait_read_frame()
shot_addr = response["dest_addr"]
# Continuously read and print packets
while True:
try:
print "send data"
tstart = datetime.now()
xbee.send("tx",data="\x03",dest_addr_long=DEST_ADDR_LONG,dest_addr=shot_addr)
response = xbee.wait_read_frame()
tend = datetime.now()
print tend - tstart
time.sleep(10)
except KeyboardInterrupt:
break
ser.close()
Code to run in the arduino to blink an LED as many times as indicated by the packet sent from the python program: #include
int ledPin = 13;
XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle
ZBRxResponse rx = ZBRxResponse();
void flashLed(int pin, int times, int wait) {
for (int i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(wait);
digitalWrite(pin, LOW);
if (i + 1 < times) {
delay(wait);
}
}
}
void setup() {
xbee.begin(9600);
pinMode(ledPin, OUTPUT);
flashLed(ledPin, 10, 50); // sets the LED off
}
void loop() {
// 1. This will read any data that is available:
xbee.readPacket();
if (xbee.getResponse().isAvailable()) {
if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
xbee.getResponse().getZBRxResponse(rx);
//flashLed(ledPin, 1, 100); // sets the LED off
flashLed(ledPin, rx.getData(0), 100); // sets the LED off
}
}
}
Activity:
There are so many possibilities at this point. One idea is to send a number to the Arduino using a python program and API mode. Then, use the Arduino XBee library to receive and read that number. And finally, blink the LED as many times as indicated by the number. And this is just an idea. We are sure that you will come up with more interesting projects!