¿Puede un XBee en modo API recibir datos a través de una serie?

0

Siguiendo la python-Xbee y un ejemplo , estoy tratando de comunicarme entre 2 XBees

Usando XBee S2C Preparar: Coordinador API = 2, ejecutando el código en python @ Mac Modo Router AT, ejecutando el código python @ Mac

El código de envío de datos a continuación se ejecuta en modo API en el coordinador

#!/usr/bin/python


#this code runs on the xbee coordinator that is set to API mode 2

import serial
from xbee import ZigBee
from xbee.helpers.dispatch import Dispatch
import time

PORT = '/dev/tty.usbserial-A104IC2U'
BAUD_RATE = 9600

UNKNOWN = '\xff\xfe' 
WHERE = '\x00\x13\xA2\x00\x40\xF7\x0A\x50'
dataString='Hello\n'

# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)

zb = ZigBee(ser)

#sends data to xbee address
def sendData(address, datatosend):
    zb.send('tx', dest_addr_long = address, dest_addr = UNKNOWN, data = datatosend)


#test data sending method
while True:
    try:
        sendData(WHERE, dataString)
    except KeyboardInterrupt:
        break


zb.halt()
ser.close()

Y en el enrutador (modo AT) corro debajo del código

#!/usr/bin/python

import serial

#router port
PORT = '/dev/tty.usbserial-A104IAUX'
BAUD_RATE = 9600
ser = serial.Serial(PORT, BAUD_RATE)

#myaddress - its the router
ack='0013A20040F70A50'

while True:
    incoming = ser.readline().strip()
    if incoming != '0013A20040F70A50':
        print '%s' % incoming
        ser.write('%s' % ack)

ser.close()

Esto funciona bien y veo la salida 'Hola' en la terminal python del lado del enrutador en Mac. Ahora también necesito recibir datos en el lado del coordinador. Así que hago esto en el código del coordinador: después de enviarlo, también lee el número de serie e imprime los datos

while True:
    try:
        sendData(WHERE, dataString)
        incoming = ser.readline().strip() #added to receive serial data at coordinator
        print '%s' % incoming
    except KeyboardInterrupt:
        break

Pero tan pronto como agrego esas dos líneas, la comunicación se detiene. ¿Esto se debe a que el coordinador está en modo API y no puede recibir en serie? ¿Y tengo que escribir el código de recepción para el modo API? ¿Alguna sugerencia?

    
pregunta nad

1 respuesta

1

Podría ser porque read() y readline() son métodos de bloqueo, cuando no se establece un tiempo de espera. Inicialice la instancia serial de esta manera:

ser = serial.Serial(PORT, BAUD_RATE, timeout=1)

para un tiempo de espera de 1 segundo. Esto significa que cualquier llamada read() esperará un máximo de 1 segundo antes de regresar con lo que se haya leído hasta ahora. Parece que estás escribiendo '0013A20040F70A50' al coordinador, que no contiene caracteres de nueva línea; ya que su read() está bloqueando, espero que su programa espere hasta que llegue una nueva línea a través del puerto serie (lo que nunca ocurre) antes de regresar. De los documentos de pyserial:

  

Tenga cuidado al usar readline (). Especifique un tiempo de espera al abrir el puerto serie, de lo contrario podría bloquearse para siempre si no se recibe un carácter de nueva línea.

Por lo tanto, debe agregar un tiempo de espera como ya expliqué, o continuar con el modo de bloqueo, pero asegúrese de agregar un nuevo carácter de línea a lo que envíe al coordinador. En el primer caso, corre el riesgo de no leer nada en absoluto, ya que no está ni siquiera comprobando si ha llegado algo, antes de leer. Puedes arreglar esto con:

while not ser.inWaiting():
    pass
incoming = ser.readline()

Esto esperará hasta que entre el primer carácter y luego intente leer una línea, dentro de 1 segundo, es decir, el valor del tiempo de espera. Esto puede ser problemático si su línea completa es tan larga que no llega en un segundo. Puedes probar interCharTimeout en su lugar; Es una de las propiedades de un objeto serial.

ser = serial.Serial(PORT, BAUD_RATE, interCharTimeout=0.5)

Esto debería establecer el tiempo máximo permitido entre los bytes recibidos a 500 ms; si supera esto, se devolverá read() o readline() . Sin embargo, no he intentado esto antes, solo algo que he visto en los documentos.

Por supuesto, puede dejar todo en modo de bloqueo tal como está y simplemente asegurarse de que siempre envíe un carácter de nueva línea con sus paquetes.

    
respondido por el TisteAndii

Lea otras preguntas en las etiquetas