c2knaps
c2knaps

Reputation: 1837

Not getting a response from wait_read_frame()

I can't get the python-xbee library to receive a response from my remote router. They're connected. The local Xbee is a Coordinator API, the remote is a Router AT.

It doesn't seem to be a connection issue because I can use XCTU to send and receive remote packets without a problem. I'm using Series 2 Xbees.

I added a class to help parse the serial responses. It prints out fine for local 'at' commands, but all 'remote_at' commands hang, with no response printed. I can issue a remote_at command (without waiting for a response) and it is processed correctly by the remote XBee. Issuing the remote command hangs at wait_read_frame(). I've tried waiting a few minutes, but it's just stuck.

I'm trying to query the D1 input pin and get its status back (high \x05, low \x04 or off \x00)

Here's the code I've been using to debug. What am I doing wrong?

from xbee import XBee
import time
from serial import Serial

PORT = '/dev/ttyAMA0'
myRouter = 'a big long hex string...'

def message_received(data):
  print data

class TappedSerial(Serial):
  def __init__(self, *args, **kwargs):
    super(TappedSerial, self).__init__(*args, **kwargs)

  def read(self, *args, **kwargs):
    data = super(Serial, self).read(*args, **kwargs)
    print ("read: ", repr(data))
    return data

  def write(self, data, **kwargs):
    print("wrote: ", repr(data))
    return super(Serial, self).write(data, **kwargs)

def main():

  tapped_ser = TappedSerial(port=PORT, baudrate=9600)
  xbee = XBee(tapped_ser) #, callback=message_received)

  try:

    xbee.remote_at(dest_addr_long=myRouter, command='D1', options='\x00')
    response = xbee.wait_read_frame()
    print(response)

  except KeyboardInterrupt:
    pass

  finally:
    tapped_ser.close()
    print("exiting program")

if __name__ == '__main__':
  main()

Upvotes: 1

Views: 1808

Answers (2)

Robert Diamond
Robert Diamond

Reputation: 1165

Two things I noticed setting up the library:

  1. In the version I checked out, in base.py line 74, the code to start the background thread if the callback was set is commented out. Since you got read requests, I don't think that's your issue, but keeping in in case anyone else gets here with a similar problem. You can call xbee.start() manually to make the thread run.

  2. I found that enabling python logging was a bit more useful than the tappedSerial in this case - I enabled logging by adding the following at the top:

    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    logger.addHandler(ch)
    

This revealed that I was adding 4 bytes to my ND responses because I had NO set to 3 instead of 0. I'll send a pull request that appends the DD value to parameters if it's defined, as determined by the length being off by 4.

Upvotes: 1

c2knaps
c2knaps

Reputation: 1837

Answer: You need to include a frame_id with the packet. From John Foster's XBee Cookbook:

Byte: frame id. This is an arbitrary value chosen by the host. The value will be returned in the response packet, except that a value of 0 will suppress the response packet.

Adding a frame_id to the packet gets a response back. Any arbitrary character (other than 0) works.

   try:
    xbee.remote_at(dest_addr_long=myRouter, command='D1', frame_id='A')
    response = xbee.wait_read_frame()
    print(response)

  except KeyboardInterrupt:
    pass

Upvotes: 0

Related Questions