Hola muy buenas a todos.
Actualmente estoy trabajando con dos módulos XBee S2 y los he configurado uno como Coordinador modo API (Arduino MEGA 2560), y otro como Router modo AT (Arduino UNO). Con ellos trato de realizar una comunicación vía Arduino usando la librería que hay de XBee (Andrewrapp), para enviar y recibir datos. El código es simple, sólo quiero enviar desde el Coordinador una letra, en este caso la 'a', al Router. Pero aquí mi problema: cuando estan ambas tarjetas ya programadas, el Coordinador (emisor) empieza a mandar información, pero el Router (receptor) no recibe nada. Por el contrario, si programo el Router como emisor y el Coordinador como receptor, éste último sí recibe datos. Pero datos aleatorios, es decir, yo quiero recibir un frame que, para la letra 'a' sería el siguiente:
7E 00 0D 90 00 13 A2 00 40 A1 F2 46 5D E1 01 61 01
Y no consigo que me legue justamente este frame.
Otro dato es que, teniendo el Router como emisor y mandando información (la letra 'a') desde XCTU al Coordinador, éste si muestra por el puerto serie de Arduino el frame correcto.
Los códigos de emisor y receptor son los siguientes:
TRANSMISOR
#include <XBee.h>
XBee xbee = XBee();
uint8_t payload[] = {'a'}; //Enviamos una 'a' {'H','o','l','a',0,0};
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x40afc964); //MAC Coordinador MEGA 40afc964, MAC Router UNO 40a1f246
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();
int spwd = 512; //Valor mitad de la salida PWM enviado al receptor
int statusLed = 9;
int errorLed = 7;
void flashLed(int pin, int times, int wait) {
for (int i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(wait);
digitalWrite(pin, LOW);
if (i + 1 < times) {
delay(wait);
}
}
}
void setup() {
pinMode(statusLed, OUTPUT);
pinMode(errorLed, OUTPUT);
Serial.begin(9600);
xbee.setSerial(Serial);
}
void loop() {
payload[0] = spwd >> 8 & 0xff;
// payload[5] = spwd & 0xff;
xbee.send(zbTx);
// flash TX indicator
flashLed(statusLed, 1, 100);
// after sending a tx request, we expect a status response
// wait up to half second for the status response
if (xbee.readPacket(500)) {
// got a response!
// should be a znet tx status
if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
xbee.getResponse().getZBTxStatusResponse(txStatus);
// get the delivery status, the fifth byte
if (txStatus.getDeliveryStatus() == SUCCESS) {
// success. time to celebrate
flashLed(statusLed, 5, 50);
} else {
// the remote XBee did not receive our packet. is it powered on?
flashLed(errorLed, 3, 500);
}
}
} else if (xbee.getResponse().isError()) {
Serial.print("Error reading packet. Error code: ");
Serial.println(xbee.getResponse().getErrorCode());
} else {
// local XBee did not provide a timely TX Status Response -- should not happen
flashLed(errorLed, 2, 50);
}
delay(2000);
}
RECEPTOR
#include <XBee.h>
/*
This example is for Series 2 XBee
Receives a ZB RX packet and sets a PWM value based on packet data.
Error led is flashed if an unexpected packet is received
*/
XBee xbee = XBee();
XBeeResponse response=XBeeResponse();
ZBRxResponse zbRx = ZBRxResponse();
ModemStatusResponse msr = ModemStatusResponse();
int statusLed = 9;
int errorLed = 7;
int dataLed = 9;
int rout;
void flashLed(int pin, int times, int wait) {
for (int i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(wait);
digitalWrite(pin, LOW);
if (i + 1 < times) {
delay(wait);
}
}
}
void setup () {
pinMode(statusLed, OUTPUT);
pinMode(errorLed, OUTPUT);
pinMode(dataLed, OUTPUT);
Serial.begin(9600);
xbee.setSerial(Serial);
flashLed(statusLed, 3, 50);
}
void loop () {
// 1. Leemos cualquier dato disponible
xbee.readPacket();
// 2. Asegurarnos de que se recibe el paquete
if (xbee.getResponse().isAvailable()) {
if (xbee.getResponse().getApiId() == ZB_RX_RESPONSE) {
xbee.getResponse().getZBRxResponse(zbRx);
Serial.println("Tenemos una Recepción!");
if (zbRx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
// the sender got an ACK
flashLed(statusLed, 10, 10);
Serial.println("paquete acknowledged");
} else {
// we got it (obviously) but sender didn't get an ACK
flashLed(errorLed, 2, 20);
Serial.println("paquete acknowledged");
}
// set dataLed PWM to value of the first byte in the data
analogWrite(dataLed, zbRx.getData(5));
Serial.print("checksum is ");
Serial.println(zbRx.getChecksum(), HEX);
Serial.print("Longitud Paquete RX ");
Serial.println(zbRx.getPacketLength(), DEC);
for (int i = 0; i < zbRx.getDataLength(); i++) {
Serial.print("payload [");
Serial.print(i, DEC);
Serial.print("] is ");
Serial.println(zbRx.getData()[i], HEX);
}
for (int i = 0; i < xbee.getResponse().getFrameDataLength(); i++) {
if(i==7 && xbee.getResponse().getFrameData()[i]==0x46){
//Serial.println("Paquete de router 1");
rout=1;
}
Serial.print("frame data [");
Serial.print(i, DEC);
Serial.print("] is ");
Serial.println(xbee.getResponse().getFrameData()[i], HEX);
}
if(rout==1){
Serial.println("Paquete de router 1");
}
} else if (xbee.getResponse().getApiId() == MODEM_STATUS_RESPONSE) {
xbee.getResponse().getModemStatusResponse(msr);
// the local XBee sends this response on certain events, like association/dissociation
if (msr.getStatus() == ASSOCIATED) {
// yay this is great. flash led
flashLed(statusLed, 10, 10);
} else if (msr.getStatus() == DISASSOCIATED) {
// this is awful.. flash led to show our discontent
flashLed(errorLed, 10, 10);
} else {
// another status
flashLed(statusLed, 5, 10);
}
} else {
// not something we were expecting
flashLed(errorLed, 1, 25);
}
}else if (xbee.getResponse().isError()) {
Serial.print("error code:");
Serial.println(xbee.getResponse().getErrorCode());
flashLed(errorLed, 3, 50);
}
}
Está programado para la última opción que he comentado, cuando el Router es emisor.
Pero mi deseo sería que el Coordinador fuera el emisor y el Router respondiera, ambos desde arduino.
¿Es problema que uno trabaje en modo API y otro en modo AT, o no tiene nada que ver? Cabe decir que desde XCTU he establecido que el Router se comunique con el Coordinador.
Gracias y perdón si no me he explicado bien, es un poco engorroso de hacer desde un teclado.