Showing posts with label XBee. Show all posts
Showing posts with label XBee. Show all posts

Monday, January 7, 2013

One more XBee tools-related bug

This time in (unofficial, unsupported etc) API Frame Maker tool from Digi.

This is, by the way, a very handy tool when it gets to understanding +XBee API operation. In seconds you can tailor a packet for all your needs and send it using X-CTU software (which feature-wise is exhostive, but usability-wise is a pain). Well, this API Frame Maker tools saves a lot of time.

But the bug took me a few hours of debugging (as usual, yes). It incorrectly calculates length for at least one API frame id - '0x90 Receive Packet'.

So be warned!

Sunday, January 6, 2013

The 0x97 bug is fixed in python-xbee!

I raised the issue described in Make a note: how an XBee replies to 'IS' command post on the package author's development group here. Paul replied, that the issue has been fixed for a while in the latest source code.

If you face the same issue (get 0x97 packet insted of 0x92 and the package fails to parse samples), here's what Paul advises:

As it happens, this bug has already been reported and fixed; a much more recent codebase which includes this fix is available at our Google Code source control: http://code.google.com/p/python-xbee/source/browse/. If you click the 'Download zip' link, in the approximate middle of the navigation bar, you will get the very latest version of the code.
I have not gotten around to updating the python-xbee distribution and documentation in quite some time; I apologize for this. 
Thanks again for this great package, Paul!

Saturday, December 29, 2012

Make a note: how an XBee replies to 'IS' command

This may save you a couple of days of debugging. Read on and make a note so when you don't understand why 'IS' command doesn't return packet you expect, you remember this post.

OK, when you configure an XBee to send samples periodically, it will send you 0x92 API frame once in a while. So you would expect to get the same frame in either sampling mode - 'periodic', 'on change', and 'querie'. But the thing is that in 'querie' case a remote XBee replies not with 0x92, but with 0x97 with sample data used as a parameter.

This is not stated anywhere in manual, I had to read it many times and finally debug step by step with python and Excel (yes, I use that great programming tool for modelling and visualisation).

I think +XBee Digi guys shell revisit their manuals and explicitly explain this.

Again, I am using python-xbee and I filed a bug. Here's my workaround about this (not a great one, I'm sure, but it works). You should find base.py in python-xbee lib and change the following:

def _split_response(self, data):
....
...
 # If the data field has no length specified, store any
            #  leftover bytes and quit
            else:
                field_data = data[index:]
                
                # Were there any remaining bytes?
                if field_data:
                    # If so, store them
                    info[field['name']] = field_data
                    try:
                        if info['command'] == 'IS':
                            packet['parse_as_io_samples'] = 'parameter'
                    except:
                        pass
                    index += len(field_data)
                break


Friday, December 28, 2012

My first attempt to build a home monitoring/control system

I've been playing with XBees for a while now and about two weeks ago I hit the wall - transparent UART mode has stopped being enough for my hobby. Sensors, devices to control, clocks to sync all aroung house. I had to move on - API mode, explicit addressing, frames parsing...

I, however, also spent some time recently studying some courses (mostly programming) on edx.org (this eats a lot of my time by the way). So I couldn't just get away with simple functional programming approach. I created many classes, I subclassed subclasses and have a pretty sofisticated class structure now in about 10 different python modules. Trying to get through all of this makes my head ake. However if you just look from a 'Main' program stand point, the whole thing is relatively easy and natural. Here how a blinking led example looks like:

def main():

    ## Create a coordinator. This is an XBee, connected to PC via comport
    ## 'COM4' is a comport to where XBee is connected
    ## 57600 is the comport speed
    ## "\x00\x13\xA2\x00\x40\x78\xFD\x76" is 64-bit address of the coordinator module
    ## 'coord' is a human-readable name
    coordinator = XBee24ZBCoordinator('COM4', 57600,
        "\x00\x13\xA2\x00\x40\x78\xFD\x76", 'coord')


    ##print "Hi, I'm Coordinator, my is hw #", coordinator.get_hwuid(),
    ##print 'and name is', coordinator.getName()

    ## Create a remote module. This is an XBee, hanging out somewhere in my house
    ## "\x00\x13\xA2\x00\x40\x78\xFD\x76" is 64-bit address of the module
    ## 'spalnya' is a human-readable name
    remote = XBee24ZBRemote('\x00\x13\xA2\x00\x40\x79\xB2\x71', 'spalnya')


    ##print "Hi, I'm a remote, my is hw #", remote.get_hwuid(),
    ##print 'and name is', remote.getName(), 'and address is', remote.getLongAddress()

    ## Now we are building the network topology
    ## We tell remote to connect to coordinator
    ## This tells remote where to send information and this
    ## also registers this remote with coordinator
    remote.connectToCoordinator(coordinator)

    ## Create a led
    led = LED()
    ## Connect led to remote, tell to which pin and in which mode
    ## remote.getPin('DO4') <- this is a pin on remote with name 'DO4'
    ## 'DO' is pin operation mode. Can be DO (digital out), DI (digital in),
    ## 'ADC' - analog input
    led.connectTo(remote.getPin('DO4'), 'DO')

    ## Tell led to turn on. Notice, after network topology is set (remote
    ## is connected to coordinator and the led is connected to a specific
    ## pin of the remote, we do not have to care about connections any more
    ## we just tell our led to switch on
    led.on()

    ## Digital input sensor (sempling LOW/HIGH level on an XBee pin)
    ## 'test' is a human readable name
    io = DI('test')

    ## connect this sensor to an XBee pin
    io.connectTo(remote.getPin('DI3'), 'DI')
    
    while True:
        ## Read pin
        io.read()
        try:
            ## switch on led
            led.on()
            sleep(2)
            ## switch off led
            led.off()
            sleep(2)
        except KeyboardInterrupt:
            break

    ## Halt XBee and close comport
    coordinator.halt()

Note, that we have to define topology first (like connectTo(coordinator)), but than I simply don't care HOW my led is connected to main server - via XBee, WiFi, TCP/IP, UART or else. I don't have to. I just tell the led to shine and it magically goes on. That's what I wanted to get and it seems I'll get that.

What I have now is a working prototype. I wouldn't been able to do even this without this great XBee library: http://code.google.com/p/python-xbee/


Wednesday, September 26, 2012

XBee introduction for Dummies (in a nutshell - XBee's cool!)

XBees with different antennas (Image source:  http://wireless-e.ru )

I've recently started playing with XBee from Digi. As usual with me I started with ruining one of the lent XBee's firmware and spent a week trying to get one back. That was a lot of fun and desperation - but I also learned a lot, found a lot of great materials (most of them on Digi's website, something like this: Designing a Sleeping XBee Sensor) and had a chance to talk to Digi support. All in all, I like this company, what they do and how they do it.

Just a few words about what is an XBee. I used to have an idea that it's just a wireless UART extension and was wondering why it costs so much (I paid for mine $17 a piece at Digikey.com). It turned out the thing is way better. Of course it is a wireles solution and it is able to:

1. Serve as transparent UART bridge (no surprise here)
2. Form different networks with point-to-point, star or mesh topology (this is why I bought them in the first place, but later about this)
This example setup is a combination of Start and Mesh topologies (Image source:  http://xbee.wikispaces.com/ )

3. Communicate to othe XBees on such a network through API commands (that is superior to transparent bridge in a way that it has rich addressing capabilities, allows to execute a remote AT commands, control remote units, ensure data integrity and even flash new firmware remotely)
4. Easily extensible with a led, a resistor and two buttons: led would show a module state, and buttons control network behaviour (wake up, ping remote, leave network) and mudule reset.
5. Has digital IOs - you can control them or sample them remotely (just add power, a transistor, a relay and you've got a wireless switch)
6. Has analog sampling channels - wire a temperature sensor to it and it will send values over network without an external MCU
7. Has got impressive performance. With my flat build out of metal/concrete with walls of 45 cm, it reaches every single corner of my flat. That wifi fails to achieve (although I tend to think this has got something to do with data throughput) and Bluetooth not even trying. I thought I would need to put a few router in between coordinator and end devices to relay the link, but it was not needed. The signal and data perfectly goes through!

So it really looks like a perfect solution for tasks such as home automation. With XBee the design pretty much becomes an integration question. Decide what you need, grab an XBee, add some spice and you're done. I built a wireless sensor that reads my water consumption just in a few evenings.

There's really a lot of information on the net already, but also as I said very useful forums and support community from Digi. If you were thinking about how to pass information from eg sensor to a control hub, go grab a few XBees and start experimenting. I also suggest that you read this unofficial FAQ to dive fast into the topic as well as check out this buying guide from Sparkfun. Also if you are going to buy XBees you will really need something to connect it to a PC with. A very basic thing is an USB-UART converter with just TX/RX signals. You can really get away with this, but it's going to be somewhat painful. You should look (or upgrade the basic variant) for something that provides:

1. Regulated power (3,3V !!!)
2. RX/TX signals (3,3V !!!)
3. Reset signal (for module to automatically reset when uploading firmware) (3,3V !!!)
4. Reset button (so you can manually reset the module)
5. DTR signal (to be able to jump to boot loader) (3,3V !!!)
6. Association LED (so you can say at a glance if XBee is powered, connected or what the error is)
7. Commissioning button (so you can test the link and control XBee a bit)
Such an adapter can be DIY from e.g. USB-UART converter, schematic is super-simple, the trickiest part is the XBee connector that is not regular 2,5 mm connector (0.1"), but 2,0 mm (0,78").

Next time I'll probably tell you how to easily turn a router into an XBee gateway ($110 worth!) :-)

Happy getting rid of wires!

Cheers!