Recibir y analizar el Transmit Status de Xbee

Hola amigos

Parte del funcionamiento del sistema que estoy haciendo, es que sabe que los datos que envío a través de los frames ya establecidos por el modo API fueron recibidos exitosamente por el Xbee en la PC o por otro lado que no fueron recibidos .
Es por eso que confío en el diagrama de estado de transmisión que Xbee ya proporciona y que puedo ver en el XCTU.

Les voy a mostrar el ejemplo con el envío de un frame desde la PC y la recepción del Transmit Status, es solo para ilustrar, porque en realidad el envío viene del sensor y la recepción del Transmit Status es para el sensor. . Bueno, empecemos. En la siguiente imagen podemos ver un frame que se envió y un frame que se recibió, el frame que se recibió es el Transmit Status, este frame, como te dije al principio, indica si el frame fue recibido o si no fue recibió.

Podemos observar la composición HEX de la trama en bytes.

Estado de transmisión (API 1)

7E 00 07 8B 01 FF FE 00 00 00 76

Delimitador de inicio: 7E
Longitud: 00 07 (7)
Tipo de trama: 8B (estado de transmisión)
ID de cuadro: 01 (1)
Dest. De 16 bits dirección: FF FE
Tx. número de reintentos: 00 (0)
Estado de entrega: 00 (correcto)
Estado de descubrimiento: 00 (sin gastos generales de descubrimiento)
Suma de comprobación: 76

Ahora desconecto la energía del Arduino, simulando que el Xbee se quedó sin energía y vuelvo a enviar la trama para ver el resultado del Estado de transmisión.

Estado de transmisión (API 1)

7E 00 07 8B 01 FF FE 02 25 02 4D

Delimitador de inicio: 7E
Longitud: 00 07 (7)
Tipo de trama: 8B (estado de transmisión)
ID de cuadro: 01 (1)
Dest. De 16 bits dirección: FF FE
Tx. número de reintentos: 02 (2)
Estado de entrega: 25 (Ruta no encontrada)
Estado de descubrimiento: 02 (descubrimiento de ruta)
Suma de comprobación: 4D

Ya podemos ver las diferencias entre una parcela que indica una entrega de paquete exitosa y una entrega fallida.

Lo que hice fue tomar un ejemplo de TX de la biblioteca de Andrewrapp y copiarlo en mi código, que debería funcionar. Pero no funciona y no sé por qué.

También pensé que, dado que ya sabía cómo se compone el estado de transmisión, podría simplemente agregarlo al código y compararlo con un marco entrante y poder decidir si es el mismo o si es diferente.

A continuación se muestra el código con el que estoy trabajando. Verás muchos comentarios, ya que estoy agregando otras etapas como el Datalogger, que funcionará una vez que logre desarrollar este problema que tengo. Mi idea es guardar el marco de datos en caso de que no se entregue el mensaje, esto para mantener un registro de las medidas, y enviarlas de regreso al inicio del código intentando enviarlas nuevamente. También puedo escuchar observaciones en esta parte.

Finalmente, también verá comentada la etapa ADC, ya que también agregaré dentro del marco donde voy a enviar la hora y fecha, un valor de voltaje, tomado de un sensor.

//Librerias
#include <XBee.h>
#include <SafeString.h>
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <SoftwareSerial.h>
//#include <SPI.h> 
//#include <SD.h>

//DataLogeer
//const int chipSelect = 4;

//Xbee
SoftwareSerial xbeee(2, 3); //(Rx, TX)

XBee xbee = XBee();
ZBTxStatusResponse txStatus = ZBTxStatusResponse();

//ADC
//ADC--> const int ADC = A0;
//float voltPanel;
//TRAMAS
byte packet1[] = {0x7E, 0x00, 0x21}; //Byte delimitador y Longitud de trama // variar por el voltaje
byte packet2[] = {0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x41, 0x4E, 0xF1, 0x24, 0xFF, 0xFE, 0x00, 0x00,}; //Id de trama, tipo de trama, direccion de 64bits, opciones y numero de brincos.
// 00:11:46 05/01/2021 == 19 chars
byte fullPacket[3 + 14 + 19 + 1];// (Delimitador + longitud )+ (tipo + direccion)+ voltage + fecha + checksum = 37
                                //  [3 + 14 + 4 + 19 + 1]
char buffer [25]; // 19 la fecha  +1  '\0', 25 bytes de tamaño // cambiar porque hay voltaje
#define DEBUG SafeString::Output

//Setup
void setup() {
  Serial.begin(9600);
  delay(100);
  xbeee.begin(9600);
  xbee.setSerial(Serial);
  delay(100);
 // if (!SD.begin(4)) {
   // Serial.println("initialization failed!");
    //while (1);
  //}
  //Serial.println("initialization done.");
  delay(2000);
  Serial.println();
  Serial.println("MACHOTE DEL CODIGO PRINCIPAL");
  Serial.println("-------------------");

  SafeString::setOutput(Serial);
  }

void loop() {
  //while xbee.read();{ //Generar un loop que pregunte Se ha recibido un mensaje de la PC? 
    //SI-->proceder if myserial.read();
    //Verificar si hay Tramas en memoria
    //File dataFile = SD.open("MedicionesVoltPanel.txt");
    //SI--> enviar tramas una por una.
    //if (dataFile) {
      //read from the file until there's nothing else in it:
      //while (dataFile.available()) {
      //xbeee.write(dataFile.read());} //Enviar lo que va leyendo 
    //close the file:
    //dataFile.close();
    
    //Comprobar que hay SUCCESS en el Transmit STATUS
    //if (xbee1.readPacket(500)) {
    // got a response!
    // should be a znet tx status              
    //if (xbee1.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
      //xbee1.getResponse().getZBTxStatusResponse(txStatus);
      // get the delivery status, the fifth byte
      //if (txStatus.getDeliveryStatus() == SUCCESS) {
        // success.  time to celebrate
        //Serial.println("SUCCESS"));
      //} else {
        // the remote XBee did not receive our packet. is it powered on?
        //Serial.println("FAIL"));
      //}
    //}
  //} else if (xbee1.getResponse().isError()) {
    //Serial.println("ERROR"));
  //} else {
    // local XBee did not provide a timely TX Status Response -- should not happen
   //Serial.println("ERROR"));
  //}
       //SI-->Borrar datos de memoria
       //SD.remove(dataFile);
    //else
       //No-->Continuar con la lectura del nuevo dato
    //} else {   
    //No-->Continuar con la lectura del nuevo dato
    //} 

  tmElements_t tm;
  if (RTC.read(tm)) {
    sprintf(buffer, ",%02d:%02d:%02d,%02d/%02d/%04d", tm.Hour , tm.Minute, tm.Second, tm.Day, tm.Month, tmYearToCalendar(tm.Year));
    Serial.println(buffer); // con este print compruebo que la fecha y hora

    //Extraer Voltaje de ADC
    //Convertir voltaje a Valor REAL
    //voltPanel= ((float(analogRead(ADC))*5.0/1023)*3+25, 2);  //Aqui multiplico por 5 y divido por 1023, 
    //para tener el voltaje que lee el ADC y multiplo por 3 y umo 25, para dar el voltaje real.
    //convertir voltPanel a HEX 
    //Ingresar este valor a los datos, parte de la horayfecha (xx.xx,00:11:46,05/01/2021)
    
    //Actualizar length y las tramas de arriba.
    //{0x7E, 0x00, 0x27}; //0x27 19 caracteres de fecha + 4bytes del flotante + espacio
    
    // build fullpacket
    size_t idx = 0;
    memmove(fullPacket + idx, packet1, sizeof(packet1));
    idx += sizeof(packet1);
    memmove(fullPacket + idx, packet2, sizeof(packet2));
    idx += sizeof(packet2);
    if ((idx + 19 + 1) > sizeof(fullPacket)) {
      // Si el tamaño es incorrecto
      Serial.println(F("fullPacket size wrong"));
    }
    
    memmove(fullPacket + idx, buffer, 19);
    idx += 19;
    // dejar un byte para el cheksum
    if ((idx + 1) != sizeof(fullPacket)) {
      // fullPacket size wrong
      Serial.println(F("fullPacket size wrong"));
    }

    int chksum = 0;
    for (size_t i = 3; i < idx; i++) { // comienza despues del tamaño dela trama
      chksum += fullPacket[i]; // comienza a sumar 
    }
    chksum = (0xff & chksum);
    chksum = (0xff) & (0xff - chksum);
    fullPacket[idx] = chksum;
    idx++; // El tamao total de la trama
    if (idx != sizeof(fullPacket)) {
      Serial.println(F("fullPacket size error"));
    }

    // Imprime el paquete
    size_t printSize = idx * 3; // ..<space>
    cSF(sfPacket, printSize);
    for (size_t i = 0; i < idx; i++) {
      //sfPacket += "0x";
      if (fullPacket[i] < 16) {
        sfPacket += '0'; 
      }
      sfPacket.print(fullPacket[i], HEX); 
      sfPacket.print(' ');
    }
    Serial.println(sfPacket);

    xbeee.write (fullPacket , idx);   
    delay(500);

    //Comprobar que hay SUCCESS en el Transmit STATUS
    if (xbee.readPacket(5000)){
      Serial.println("StatusRecibida");
      if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) { //Comprobar que el mensaje fue enviado, Programar un analisis de la Trama API Transmit Status 
        xbee.getResponse().getZBTxStatusResponse(txStatus);
     
      // get the delivery status, the fifth byte
        if (txStatus.getDeliveryStatus() == SUCCESS) {
          Serial.println("SUCCESS");
        } else {
        // the remote XBee did not receive our packet. is it powered on?
          Serial.println("FAIL");
         }
       }
    }else if (xbee.getResponse().isError()) {
      Serial.println("Error reading packet.");
    }else {
         // local XBee did not provide a timely TX Status Response -- should not happen
      Serial.println("local XBee did not provide a timely TX Status Response");
      }  
      //No-->Ir al Datalogger 
      //File dataFile = SD.open("MedicionesVoltPanel.txt", FILE_WRITE);// open the file.
         //Activar el Datalogger Guardar la Trama que se intento enviar
         //if (dataFile) {
         //dataFile.println(fullPacket);
         //Cerrar Datalogger
         //dataFile.close(); }      
  }
}
  
   
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}