Sunday, September 1, 2013

Raspberry Pi and XBee

The continuation of this post is here <link>.

So, since I have the little Pi working with the internet, how about getting an XBee hooked to it and start receiving data from my home network?  Well, it isn't hard to hook an XBee up to a Pi; the little device uses 3.3 volts and has an output pin, so I hooked one up.  Four wires later, I had the XBee attached, powered and ready to go.  Of course, the serial port (the only one on the Pi) is already used for a console, but there's (again) a thousand web sites out there that show how to change the init files to allow the serial port to be used directly, so I used one of the examples and freed the serial port for use.

A quick aside here.  In looking around the web, I haven't found a single instance where someone successfully hooked a Pi up to an XBee and did something real with it.  This didn't bode well for me, I want this thing to monitor a network of a dozen XBees and keep the devices they're attached to under control, not print pretty messages on the screen.  It actually looks like a lot of people buy the Pi because it's cool and don't do much besides bring up a little web server on it.

But, the first thing is to see how I can read data from the XBee on the Raspberry Pi.  So, prowling around I found an XBee library for Python and it seems to support everything I need as well as some things I might want to use someday.  I installed it on the Pi and wrote a little test program to see what happens:

The Python Script
#!/usr/bin/python
import serial
from xbee import ZigBee

serial_port = serial.Serial('/dev/ttyAMA0', 9600)

zb = ZigBee(serial_port)

while True:
    try:
        data = zb.wait_read_frame() #Get data for later use
        #print data # for debugging only
        print data['rf_data']

    except KeyboardInterrupt:
        break

serial_port.close()

This actually wasn't as simple as it looks.  This tiny little piece of code took almost all day to get to work and gave me a lot of trouble.  Sure, it looks easy, but that's after failing over and over again.  Most of my problems came from not having a clear example to work from and a horrible dearth of documentation.  As usual, libraries provided by community efforts have minimal documentation, but this was an example of even less than that.  There was also problems with not having any description of the proper XBee settings.  For example, the author wrote that the XBee had to be in API mode, so following the Andrew Rapp library example, I set it to API mode 2.  I got nothing.  That led me to look at the code for the library and it turns out this library uses API mode 1 by default.  Switching to API mode 1 allowed me to actually see data.  And, there were a number of problems like that.

Another one that drove me nuts for an hour or so was that he (the author) sees the XBees as either Series 1 which uses different packets or Series 2 which is ZigBee based (mostly), but requires you to use special classes for each of them  So, if you import like this:

from xbee import XBee

I won't work at all using a series 2 XBee running the various ZigBee software.  It will work with the older software.  That's why the example above has:

from xbee import ZigBee

The author didn't understand that the series 2 devices can run multiple styles and versions of the protocols.

So, I can read XBee packets and pick the data out of them to do something with, but now along comes another problem.  All he supplies is a blocking read.  That's about useless for any project that needs to be able to catch packets and do something else at the same time.  He does have an asyncronous read in the code, but it uses threads to set aside a process that handles the XBee interaction, but since threads can't share data, it would require interprocess communication or queues to pass the data around.

Something like that takes all the usefullness out of an incredibly simple device like the XBee.  If you have to have multiple processes, queues, locks, and such to read a message, no one is going to bother.

I'm still looking at it, but this particular path doesn't show much promise so far.

34 comments:

  1. It is true the Raspberry Pi draws a lot more power than the Arduino, but it can do so much more.

    For power, check out the Motorola Micro-USB charger, around $5 on Amazon. I use a USB keyboard and an LCD monitor from Goodwill to get mine configured as a headless server. From there I do everything through an secure shell connection.

    I have several of these Pis between home and work, used for network monitoring, environmental control and web severs. One, makes a great Xbee to Ethernet gateway using ideas from your blog. I just love them.

    Have fun with yours.

    Chris

    ReplyDelete
    Replies
    1. Thanks. You're right, these little things are really, really powerful for a 35 dollar computer. The paradigm is wonderful, a Linux machine that can set on a bookshelf and do incredible things.

      I've actually made significant progress on the XBee interaction; it will be posted soon. I've also made some progress on a power supply that I think can power all the stuff I want to run off the board (thinking about wireless so I can move it around the house).

      Delete
  2. Have you considered the XRF as an alternative? It fits the same socket

    ReplyDelete
  3. Yes I did. They're nice little devices, but they don't do networking on their own. The big selling point for me is that an XBee network just works. If one of them is too far away, put a device in the middle to relay the data. It keeps me from having to buy high power devices to get reasonable coverage.

    No matter what the advertising hype is, the low power versions have a two wall transmit distance. The high power ones do pretty well for a lot more money.

    ReplyDelete
  4. Did you get your python-xbee info from Jeff Skinner? http://jeffskinnerbox.wordpress.com/2012/12/22/selecting-xbee-radios-and-supporting-softwaretools/
    I'm working on moving my networks from Arduino to RPi as well and it seems a little more daunting like everything out there assumes that you already know what you are doing.
    thanks cheers!

    ReplyDelete
    Replies
    1. I remember looking at Skinner's blog and several others as I was first working with the XBee, but I basically wound up doing it on my own using the Digi documentation. There is so much mis-information out there that doing it from the docs was easiest.

      If you have a specific question on getting started with the XBee, drop a note here somewhere, and I'll try to help you. Once you get started, it turns into fun again.
      The thing about my code up on this site is that I'm actually running it. It may have a few changes to add things or fix bugs, but what I post is what I actually run (warts and all). Once I got my first received message from an XBee on the Pi, I was off and running.

      Delete
  5. My first and main question is where did you import your xbbe-python library from? could you paste a link. I just don't want to have to download a bunch of different libraries and comb through them to see if they even work or have enough functionality. Also how did you set up your network so that all of the nodes send data at relatively the same time? I'm sleeping mine and sending data every hour but what I'm not sure of is how to get all of them to send the data at pretty much the same time. I'm thinking that I need to set the SM to 5 on the end devices in xctu and then send out the ST SN and SP as a broadcast so that every node receives the instructions at the same time and are all timed together. How well do xbees keep time? could I set up a network that would take a reading at say 4am everyday and not drift to much from that or would I have to send out commands to re-time the nodes every so often? Sorry to ask for more than I've given. I hope to test out most of this over the next two weekends but I have a mid-term paper that is due on Monday so I have to dedicate some time to that. Cheers!

    ReplyDelete
  6. I used pip to install xbee and got version 2.1.0 the command was: sudo pip install xbee Then you can use pip to tell you where it wound up. Once you get it installed, you can just import it and start using it.

    I have an arduino hooked to most of my XBees. There is one standalone thermometer and three standalone battery monitors. The standalone devices are just set up to transmit roughly once a minute and they do it whenever they want to, there's no coordination. The ones with XBees receive a time sync packet from a clock I made that has a GPS chip in it. It sends the time about every 15 seconds as a broadcast that each device picks up and sets their internal clock to.

    I use the arduino time and timeAlarm libraries to keep track of time and schedule events. Things like automatically turning on motors and things are basically alarms that fire at a preset time. I don't have any real time clocks because I didn't want to worry about batteries.

    Doing it this way, I have semi-autonomous devices that report back to a monitor and I used the monitor to either override or control the devices. If there's a power failure, each device takes care of its own init and startup. Some of the devices wait until a time signal comes in to really go to work, other can start without it.

    Details are under each device.

    ReplyDelete
  7. Why not just connect ur XBee via one of the USB...much like you do to configure it on your PC?

    ReplyDelete
    Replies
    1. Heh, you didn't follow the link at the top of the post did you? But, the reasons for not hooking it up with USB at first are: I didn't have a USB adapter handy. I wanted to see how it would work direct. Other folk reading this might not have a USB adapter. I wanted to use as little hardware as possible. I didn't think of it until later. Etc.

      I have it hooked up to the USB port now. Actually, I have two of them hooked to the USB ports handling different networks for different purposes. Check around the blog, it's all there.

      Delete
  8. Dizzy, I have the XBee attached to mine by way of USB. I am using the internal GPIO header for a RazBerry Z-Wave board. Dave's done a wondeful job of forging ahead with an idea and sharing the outcome.

    ReplyDelete
  9. Hi, I use my raspberry pi with xbee to collect weather data from my davis vantage vue also with xbee connected. I installed weewx. It works excellent!

    ReplyDelete
  10. Hi,

    Unable to receive data in XBee coordinator radio connected to raspberry pi from Xbee router radio connected to PC.

    1. Xbee coordinator radio configurations are as below.
    [Connected to Raspberry pi- RPi 3.3 volt to XBee 3.3 volt pin,Ground to XBee ground, Rx to Xbee Tx(Data Out),Tx to XBee Rx (Data In)]

    Product family: XB24-ZB
    Function set: ZigBee coordinator API
    Firmware version: 21A7
    Port: COM7 - 9600/8/N/1/N- API 1

    Written and not default values
    PAN ID: 2001
    DH: 13A200
    DL: 40D85671 (my router id)

    rest all values are default

    2. Xbee router configurations are as below
    [Connected using XBEE exploere USB to PC and using next Gen X-CTU]

    Product family: XB24-ZB
    Function set: ZigBee Router AT
    Firmware version: 22A7
    Port: COM17 - 9600/8/N/1/N- AT

    Written and not default values
    PAN ID: 2001

    rest all values are default (DH & Dl are 0)

    3. Running below python script on Raspberry pi to get the data sent by router

    #######
    import pprint
    import serial
    import xbee

    SERIAL_PORT = '/dev/ttyAMA0'
    BAUD_RATE = 9600
    ser_port = serial.Serial(SERIAL_PORT, BAUD_RATE)
    xbee1 = xbee.zigbee.ZigBee(ser_port)

    while True:
    try:
    data_samples = xbee1.wait_read_frame()
    pprint.pprint(data_samples)
    except KeyboardInterrupt:
    break
    ser_port.close()
    #########

    Pleas help me to make it work...

    ReplyDelete
    Replies
    1. To double check that the two XBees connected the new XCTU has a feature to show the connections. If you're using that version, just click on the tab to the far right and let it map the devices. That's the first step to making sure the two XBees actually see each other.

      Delete
    2. Thanks Dave for your reply...

      I have scanned the network from my coordinator radio(AP mode) but couldn't see the router(AT mode) on same network.

      Delete
    3. You have to get them connected first before you can send anything. Take a look at the scan channels, pan id and addressing, those are your most likely problem areas. The other possibility are the encryption settings.

      Delete
  11. print data('rf_data')

    I think the above should be:
    print data['rf_data']

    otherwise I get a "TypeError: 'dict' object is not callable error which I found reference to at the following:

    http://stackoverflow.com/questions/6634708/typeerror-dict-object-is-not-callable

    This has been a great help!! Thanks for the write-up!

    ReplyDelete
    Replies
    1. This is one of those 'font' things. The statement has square brackets in it when I look at it, you must be seeing parenthesis in yours. You're right, with parens, it would give an error because it would try to call something that wasn't callable.

      Delete
  12. Hi,

    I am able to send and receive messages when i connect xbee radios(series 2) to PC but when i connect them to raspberry pi i am not able to receive any message.

    Router is in AT mode (22A7) and Coordinator is also in AT mode(20A7).
    Coordinator connected to PC(Next gen X-CTU) and router connected to raspberry pi.

    Below is python script to receive messages.

    import serial
    import pprint
    from xbee import ZigBee

    serial_port = serial.Serial('/dev/ttyAMA0', 9600)

    zb = ZigBee(serial_port)

    while True:
    try:
    data = zb.wait_read_frame() #Get data for later use
    #print data # for debugging only
    pprint.pprint(data)
    print data['rf_data']

    except KeyboardInterrupt:
    break

    ReplyDelete
    Replies
    1. I don't see anything wrong with your code, but did you make sure the XBees are talking by looking at the network connections in XCTU? Sometimes, when you unplug the coordinator, you have to reestablish the network since the XBee might start up on a new channel.

      Also, try to just read the serial port on the pi using cat with input redirected to the serial port to see if it opens and can receive data. You'll get gibberish since the baud rate is probably wrong, but it will tell you if it sees something.

      Delete
  13. hi,
    i want to send moisture sensors value from zigbee to raspberry pi,first of all for writing the commands needed for zigbee from where I should install python libraries and secondly can u give me some code to send moisture sensor vallues from zigbee to raspberry pi

    ReplyDelete
    Replies
    1. The python libraries have installation instructions with them, just take a look. There's code all over this site that will help you send the data, but I've never actually worked with moisture sensors.

      Delete
  14. hi,
    can i connect zigbee directly to raspberry pi (zigbee 3.3 to rasp 3.3, zigbee tx to rasp rx, zigbee rx to rasp tx) or whather they should be connected by any means?

    ReplyDelete
    Replies
    1. Yes you can. I did that at first using the console port on the PI. I went to a USB dongle type of connection when I decided to have two XBees hooked to the same PI.

      Delete
  15. hi,
    Presently I am working to interface XBee with Rpi..We achieved in communicating between two laptops by using Xbee but when we tried to communicate between laptop and RPi..there was an error : the Xbee receiving the data but unable to know what it is...
    can you help me in this case ?

    ReplyDelete
    Replies
    1. I can try, but you'll have to tell me more.

      Delete
  16. Hi,
    I want to know which Function Set this Xbee python library uses - ZIGBEE TH Reg or 802.15.4?

    ReplyDelete
  17. Hello I am trying to realize a multihub network between several XBee S2c radios interfaced with Arduino Uno R3. Specifically each arduino with the xbee acts as a node in the network, arduino 1 collects data from digital sensors sends it to arduino 2. Arduino 2 then sends its data plus the data gotten from arduino 1 to arduino 3 which then forwards the data from 1 2 and three to the coordinator connected to a PI. Please helps with how to implement this and how to configure the XBee radios. Thanks

    ReplyDelete
    Replies
    1. I don't think you can actually do this because it's contrary to the way a mesh network works. The XBee will set up a mesh network automatically and find the shortest route from origin to the destination. It even allows for devices that are asleep or dead; that's really the point of the network, get the data from one point to another.

      The only way I can think of to do it is to specify the address of each message and handle the movement of data yourself.

      Delete
  18. Thanks for the clarification, so if the XBee handles the mesh network automatically, do i have to just set all the radios to the same PAN ID and allow the radios do the rest?

    ReplyDelete
    Replies
    1. Exactly, on my network the coordinator XBee is running in a clock I made that syncs all the house's actions to GPS satellite time. This little machine doesn't do anything else. All my XBee messages are addressed to a Pi that handles the data. The rest of the XBees are scattered around the garage, barn, pool, etc. I let the XBee mesh network handled the actual message routing on its own. So, the temperature sensor out on the fence wakes up from being asleep for a couple of minutes, sends a message to the Pi which is routed by the closest XBee to it forward. I don't have to do anything to have this happen, the XBee does all that for me.

      Delete