Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Robust communication between Python and Xbee?

  1. Question Robust communication between Python and Xbee?

    I am using Xbee API library for Python to process the data received by the Xbee module. I am wondering how to construct the robust protocol for sending and receiving data. What I would like to build is

    1. send the data request message to power monitoring uint (Xbee in remote).
    2. Receive the transmitted power monitoring data and process it in Python.

    If the aforementioned process works in just one time, it would be great, but sometimes it does not work. Thus, I would like to code autonomous acknowledging procedure into this communication. That is

    1. send the data request message to power monitoring uint (Xbee in remote).
    2. If the dat is not received, go back to 1.
    3. If the data is received ok.

    Here are my code, but it does not work all the time. Would you please look at how can I improve the code further to make it this ? The code is as follows:

    Code:
    
    
    Code:
    def listeningAndClusterData(targetWT):
        
        #targetWT-->this will be used to construct the target address
        targetAddress = struct.pack('b',0x00)+struct.pack('b',targetWT)
        Data = struct.pack('h',0x0000) #prefix for requesting information
        xbee.tx(dest_addr=targetAddress, data=Data)
        ser.flush()
        time.sleep(0.01)
        response = xbee.wait_read_frame(100)
        #wait for data packet from Xbee, if packet is not recieved within 100ms, return 1
    
    
        watingData = 1;
        while watingData:
            try:
                
                if response != 1: # if the data is received
                    sa = hex(response['source_addr'])
                    rf = hex(response['rf_data'])
                    datalength=len(rf)
                    agentId = int(sa[2:4],24)
                    # if datalength is compatible with two floats
                    if datalength==16: 
                        voltage=struct.unpack('f',response['rf_data'][0:4])[0]
                        current=struct.unpack('f',response['rf_data'][4:8])[0]
                        power=voltage*current
                        watingData = 0 # I received the average data and escape the loop
                        ser.flush()
                    else: #data is received but the format is not correct
                        ser.flush()
    
    
                if watingData != 0: #if the data is not received--> keep sending the request message 
                    xbee.tx(dest_addr=targetAddress, data=Data)
                    print("data is requested again")
                    time.sleep(0.01)
                    ser.flush()
                    response = xbee.wait_read_frame(100)
              
            except KeyboardInterrupt:
                break
    
    
        return  voltage, current, power
    Last edited by ddugi79; 02-10-2015 at 12:59 AM.

  2. #2

    Re: Robust communication between Python and Xbee?

    There are two options:

    1) Define a RPC protocol, kind of like you try to do here, where one side must ask the other side for some data, and that data may later come back. This is more like a telephone conversation.

    2) Decide that the other side generally wants to hear, and send the latest data in fire-and-forget mode at a regular interval. The other side may or may not be there; if it is, it may get the data, and can decode and act on it. This is more like a radio broadcast.

    To best implement 2) you probably want to turn off acknowledge/retransmit for the Xbee, and instead rely on sending "often enough" that a few packets will get through even when there's lots of interference.


    Regarding "the code doesn't work all the time," what is the exact symptom of "it doesn't work"?
    What things have you tried to investigate to debug the problem?

  3. Re: Robust communication between Python and Xbee?

    Thank you very much for your comments.

    First, I would like to implement approach (1). The central node will send the data request message to each of 6 Xbee modules sequentially. Only when the central node received the data from one remote node, it will ask the data to another node.

    When I tested this code, it works only a certain duration. For example, when I try to collect data for every minute from 6 modules, it only works 30 times (30minutes) and then stuck somewhere. In this situation, python keep printing out

    "data is requested again"
    "data is requested again"
    "data is requested again"
    "data is requested again"
    "data is requested again"
    "data is requested again"
    "data is requested again"
    "data is requested again"
    ....

    Let me explain little bit about the code for the other side. The remote module just send the monitoring data when ever the request message is arrived.

    Thank you.

  4. #4
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,317
    Images
    27
    Rep Power
    283

    Re: Robust communication between Python and Xbee?

    Doubt it is the cause, but if 'ser' is used within the 'xbee' object, it would probably be best to ensure that the 'ser.flush()' is always before the 'time.sleep(0.01)' so that you actually know the xbee has at least started sending the message to the nodes before pausing and switching over to receive with timeout (failing to flush and pause for TX could significantly shorten useful RX timeout length).
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    [git][mech][hack]
    gives free advice only on public threads

  5. Re: Robust communication between Python and Xbee?

    Thank you for your reply. I am little bit confused with the role of ser.flush(). Is this command used to actually transmit the data? I thought this command is only for deleting the data in the buffer. Do I also have to clear the buffer after I transmit the data as follows?

    1. for sending
    xbee.tx()
    ser.flush()
    time.sleep(0.01)

    2. for receiving
    response = xbee.wait_read_frame(100)
    ser.flush()
    time.sleep(0.01)

  6. #6
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,317
    Images
    27
    Rep Power
    283

    Re: Robust communication between Python and Xbee?

    flush() is what forces the data in the outgoing buffer to actually be sent out to its destination regardless of any other buffer timeout/overflow conditions triggering the buffer contents to be pushed to their destination. A problem I have run into many times, and almost always forget the about until I try running the program, is printing to stdout or files using streams in C++ without remembering to flush(). Print something about upcoming computations, do lots of computations, print results, start over with new conditions; without adding a flush() somewhere in that loop, the print buffer will fill with data to be printed that will never actually be printed out until the program finishes because pushing that data out of the buffer is lower priority than continuing on with computations (may be one of the optimizations made by compiler). pySerial likely handles things a bit nicer than printing to files in C++ programs using standard libraries and default optimizations (like a shorter timeout to flush its buffer), but doubt it can hurt to add a flush() after a TX operation. If my thinking that flush() only affects the outgoing buffers is correct, then it should not really do much of anything for RX operation.

    edit: according to pySerial documentation, flush() forces a write out of the data in the buffer, flushInput() discards everything in the input buffer, and flushOutput() aborts the current output and discards everything in the output buffer. From serialposix.py -> flush() calls drainOutput(), which calls termios drain and (probably) waits until all data has been sent before returning.
    Last edited by tician; 02-10-2015 at 11:18 PM. Reason: checked pyserial docs
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    [git][mech][hack]
    gives free advice only on public threads

  7. #7

    Re: Robust communication between Python and Xbee?

    and then stuck somewhere
    Where does it get stuck?
    Is your protocol robust to lost bytes?
    How does it implement re-synchronization?
    Have you tried the code in some kind of simulator, where you replace the serial port with a dummy object that performs as you expect the real serial port to perform?

  8. Re: Robust communication between Python and Xbee?

    Quote Originally Posted by tician View Post
    flush() is what forces the data in the outgoing buffer to actually be sent out to its destination regardless of any other buffer timeout/overflow conditions triggering the buffer contents to be pushed to their destination. A problem I have run into many times, and almost always forget the about until I try running the program, is printing to stdout or files using streams in C++ without remembering to flush(). Print something about upcoming computations, do lots of computations, print results, start over with new conditions; without adding a flush() somewhere in that loop, the print buffer will fill with data to be printed that will never actually be printed out until the program finishes because pushing that data out of the buffer is lower priority than continuing on with computations (may be one of the optimizations made by compiler). pySerial likely handles things a bit nicer than printing to files in C++ programs using standard libraries and default optimizations (like a shorter timeout to flush its buffer), but doubt it can hurt to add a flush() after a TX operation. If my thinking that flush() only affects the outgoing buffers is correct, then it should not really do much of anything for RX operation.

    edit: according to pySerial documentation, flush() forces a write out of the data in the buffer, flushInput() discards everything in the input buffer, and flushOutput() aborts the current output and discards everything in the output buffer. From serialposix.py -> flush() calls drainOutput(), which calls termios drain and (probably) waits until all data has been sent before returning.
    Thank you very much for your insightful comments. Due to my ignorance, I don't understand you comment "doubt it can hurt to add a flush() after a TX operation".

    Instead of using flush(), which is related with actual writing procedure, would it be better to use flushInput() and flushOutput()? The reasons I would like to use these commands is to clear the buffer so that the new message that will be sent and will be received are corrupted with the remaining bytes in the buffer. So, how do you think about this approach?


    1. for sending
    xbee.tx()
    ser.flushOutput() #once I sent the message, clear output buffer
    time.sleep(0.01)

    2. for receiving
    response = xbee.wait_read_frame(100)
    ser.flushInput() # once I read the response, clear the input buffer
    time.sleep(0.01)

    However, don't we have to give a some time for Xbee to complete sending and receiving tasks before flushing out the buffer?

  9. Re: Robust communication between Python and Xbee?

    Quote Originally Posted by jwatte View Post
    Where does it get stuck?
    Is your protocol robust to lost bytes?
    How does it implement re-synchronization?
    Have you tried the code in some kind of simulator, where you replace the serial port with a dummy object that performs as you expect the real serial port to perform?
    Thank you very much for your comments. Actually most words you mentions are not quite familiar to me. They must be more advanced topics I don't understand at this point.

    1. The algorithm stuck because it does not receive the data sent from another Xbee although it repeatedly sends out the data request message to another Xbee.

    2. Since I am using Xbee API library module in Python, I did not implement the protocol for dealing with lost bytes and re-synchronization. When I received data, I check if the message contains the right header, defined by me like 0x1234, to determine whether or not the received packet is relevant or not. For possibility of missing bytes, I clear the buffer whenever I receive the message and send the message.

  10. #10
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,317
    Images
    27
    Rep Power
    283

    Re: Robust communication between Python and Xbee?

    Quote Originally Posted by ddugi79 View Post
    Thank you very much for your insightful comments. Due to my ignorance, I don't understand you comment "doubt it can hurt to add a flush() after a TX operation".

    Instead of using flush(), which is related with actual writing procedure, would it be better to use flushInput() and flushOutput()? The reasons I would like to use these commands is to clear the buffer so that the new message that will be sent and will be received are corrupted with the remaining bytes in the buffer. So, how do you think about this approach?


    1. for sending
    xbee.tx()
    ser.flushOutput() #once I sent the message, clear output buffer
    time.sleep(0.01)

    2. for receiving
    response = xbee.wait_read_frame(100)
    ser.flushInput() # once I read the response, clear the input buffer
    time.sleep(0.01)

    However, don't we have to give a some time for Xbee to complete sending and receiving tasks before flushing out the buffer?
    Use flush() after xbee.tx() to ensure that the data written by the python xbee object to the PC's serial object buffer is actually sent over the wire to the USB device connecting the Xbee to the PC. If you are not doing anything else with the serial object, there is never going to be a corrupted TX packet so no need to flushOutput(). If you use flushOutput() instead of flush() after xbee.tx(), then you will corrupt the message if any of it has already begun to be sent out of the buffer to the USB/Xbee or completely discard the message before it can be sent over USB.

    If the python xbee library/object is at all intelligent, then it will automatically discard anything in the RX buffer that is not part of a valid packet/message, so there would be no need to flushInput().
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    [git][mech][hack]
    gives free advice only on public threads

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Robust, affordable gun design
    By jwatte in forum Mech Warfare
    Replies: 40
    Last Post: 08-10-2013, 08:49 PM
  2. Python
    By Fobian in forum Software and Programming
    Replies: 6
    Last Post: 09-08-2012, 11:20 AM
  3. Question(s) Arduino- xbee -xbee-arduino - stepper motors
    By Icemonkey in forum Arbotix, Microcontrollers, Arduino
    Replies: 7
    Last Post: 06-04-2012, 01:35 PM
  4. iRobot python GUI communication
    By ash in forum ROS - Robot Operating System
    Replies: 1
    Last Post: 06-07-2011, 01:18 PM
  5. Question(s) Robust Autonomous Robot Localization Using Interval Analysis
    By aadhavan in forum Robotics General Discussion
    Replies: 17
    Last Post: 12-15-2009, 09:57 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •