AT Command Mode. Maximun Payload

Hi,

I’m trying to send a RF data payload of 73 bytes between 2 Zigbee-Pro modules in AT Command Mode.

The two modules are equal configured:

ROUTER AT. Fmw 22A7
ID: 5555
DH: 0
DL: FFFF
BD: 5

And they shows, NP: 54 (this is 84 bytes in decimal). So, it must be read perfectly, but instead of this the data frame is wrapped, and this makes me have errors at reading time of serial buffer.

How can I configure my modules to avoid this behaviour??

Where is the error (receiver or transmitter side)??

Hello Jorge,

The NP value is not the absolute maximum, in the Product manual Section 4 (:

XBee ZB firmware includes a command (ATNP) that returns the maximum number of RF payload bytes that can be
sent in a unicast transmission. Querying the NP command, like most other commands, returns a HEXADECIMAL
value. This number will change based on whether security is enabled or not. If security is enabled (EE command),
the maximum number of RF payload bytes decreases since security requires additional overhead.
After reading the NP value, the following conditions can affect the maximum number of data bytes in a single RF
transmission:
• Broadcast transmissions can support 8 bytes more than unicast transmissions.
• If source routing is used, the 16-bit addresses in the source route are inserted into the RF payload space. For
example, if NP returns 84 bytes, and a source route must traverse 3 intermediate hops (3 16-bit addresses),
the total number of bytes that can be sent in one RF packet is 78.
• Enabling APS encryption (API tx option bit set) will reduce the number of payload bytes by 4.

I’ve tested sending from an AT coordinator to an API router a payload of 84 bytes and it worked perfectly (more than 84 shows two frames in receiver). What do you mean with the data frame is wrapped? Do you mean that you receive two packets instead of one?

1 Like

Hi Spastor,

Thanks!

I’ve read about NP and this is why I’m worry, because I have a NP command of 54 (HEX) [84B (DEC)].

But I can’t know if I receive two packets because when TX sends data, the RC doesn’t show it, and I don’t know why is this happening.

Explanation:

  • To send data, I’m working with x-ctu and ‘Assemble Packet’ option, so I know the data I’m sending (73 bytes, including ’
    ').

  • To receive data, I have an Arduino Mega with a XBee Shield, and a similar code:

#define INI_MSG         0
#define FIN_MSG         4
#define INI_MAC         12
#define FIN_MAC         28
#define INI_IDMSG       29
#define FIN_IDMSG       43
#define INI_ACT         44
#define FIN_ACT         51
#define INI_TACT        52
#define FIN_TACT        61
#define INI_PRACT       62
#define FIN_PRACT       71

unsigned long init_int_time = 0;
unsigned long last_int_time = 0;

String MacAlta = "", MacBaja = "";

int tProbe = 0;
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

int aCt = 0;
int tAct = 0;
int prAct = 0;
int vAct = 0;
int vTAct = 0;
int vPrAct = 0;
String strACK = "";
String strSMS = "";
String strError = "";
String cmp = "sms:";
String strAct = "AC";
String strTi = "TI";
String strPr = "PR";

int tSend = 0;
int tError = 0;

/*
 * 
 */

void setup(void) {

  Serial.begin(38400);
  Serial.println("	 XBEE AT 
");
  
  readXBee();
}

/*
 * 
 */

void loop(void) {  
    
    if (stringComplete) {

      if ((inputString.substring(INI_MSG,FIN_MSG) == cmp) && (inputString.substring(INI_MAC,FIN_MAC) == (MacAlta + MacBaja))) {
        tSend = 1;     
      }
      else {
        tError = 1;
        tSend = 0;
      }
      
      strSMS = inputString.substring(INI_IDMSG,FIN_IDMSG);   
      
      Send();

      inputString = "";
      stringComplete = false;
    
    }
    
    while (Serial.available() > 0) {
      char inChar = (char)Serial.read(); 
      inputString += inChar;

      if (inChar == '
') {
        stringComplete = true;
        Serial.flush();
      } 
    }
}  

/*
 * 
 */
 
void Send() {
  
  switch (tSend) {
    case 0:
      ERROR();
      break;
    case 1:    
      ACK();
      Read_Message();
      break;
    }
  
  // clean serial buffer
  Serial.flush();  
  
  tSend = 0; 
  strSMS = "";
}

/*
 * 
 */
 
void ERROR() {

  // print message
  Serial.print(cmp); 

  // @MAC
  // 32 bit MSB
  Serial.print(MacAlta);

  // 32 bit LSB    
  Serial.print(MacBaja);
  Serial.print(" ");   

  // ID_MSJ
  Serial.print(strSMS);
  Serial.print(" "); 
  
  // ERROR
  switch (tError) {
    // Mensaje incorrecto
    case 1:
      strError = "ERROR 404 - Not Found";
      break;
    // Parametros erroneos
    case 2:
      strError = "ERROR 406 - Wrong Parameters";
      break;
    //default: 
      // si nada coincide, ejecuta el "default"
      // el "default" es opcional
  }
  
  Serial.print(strError);
  Serial.println(" ");

  // clean serial buffer
  Serial.flush();
  
  tError = NULL;
  strError = "";
}

/*
 * 
 */
 
void ACK() {

  // print message
  Serial.print(cmp); 

  // @MAC
  // 32 bit MSB
  Serial.print(MacAlta);

  // 32 bit LSB    
  Serial.print(MacBaja);
  Serial.print(" ");   

  // ID_MSJ
  Serial.print(strSMS);
  Serial.print(" ");
  
  // ACK
  strACK = "OK";
  Serial.print(strACK);
  Serial.println(" ");

  // clean serial buffer
  Serial.flush();
  
  strACK = "";
}

/*
 * 
 */

void Read_Message() { 

  if ((inputString.substring(INI_ACT,INI_ACT+2) == strAct) 
            && (inputString.substring(INI_TACT,INI_TACT+2) == strTi) 
            && (inputString.substring(INI_PRACT,INI_PRACT+2) == strPr)) {
        
    aCt = inputString.substring(INI_ACT+2,INI_ACT+4).toInt();    
    tAct = inputString.substring(FIN_TACT+2,FIN_TACT+4).toInt();
    prAct = inputString.substring(INI_PRACT+2,FIN_PRACT+4).toInt();
    vAct = inputString.substring(FIN_ACT-2,FIN_ACT).toInt();    
    vTAct = inputString.substring(FIN_TACT-4,FIN_TACT).toInt();    
    vPrAct = inputString.substring(FIN_PRACT-4,FIN_PRACT).toInt();
    
    Serial.println(aCt);
    Serial.println(tAct);
    Serial.println(prAct);
    Serial.println(vAct);
    Serial.println(vTAct);
    Serial.println(vPrAct);
    
    Do_It();
  }
  // ERROR EN MSG DE ACTUACION
  else { 
    tError = 2;
    tSend = 0;     
    Send();    
  }
}

/*
 * 
 */

void Do_It() { 
  
  tProbe = millis();

  // DIGITAL PIN OUTPUT
  pinMode(aCt, OUTPUT);
  
  while ((millis() - tProbe) < vPrAct) {
    init_int_time = millis();    
    
    if (init_int_time - last_int_time > vTAct) {
      digitalWrite(aCt, HIGH); 
    }
    
    if (init_int_time - last_int_time > vTAct) {
      digitalWrite(aCt, LOW); 
    } 
  
    last_int_time = millis();  
  }
  
  digitalWrite(aCt, LOW);

  aCt = NULL;
  tAct = NULL;
  prAct = NULL;
  vAct = NULL;
  vTAct = NULL;
  vPrAct = NULL;
}

/*
 * 
 */

void readXBee() {
  int i = 0;
  MacAlta = "00";
  MacBaja = "";

  delay(100);
  while(i < 15) {  
    char inChar;
    
    Serial.flush();
    Serial.print("+++");
    delay(1000);
    
    while (Serial.available() > 0) { 
      // Get the 'OK' msg
      inChar = (char)Serial.read(); 
    } 
    delay(1000);

    Serial.flush();
    Serial.println("atsh");
    delay(1000);
    while (Serial.available() > 0) {
      inChar = (char)Serial.read(); 
      MacAlta += inChar;
      i++;
    }
    
    delay(1000);
    Serial.flush();
    Serial.println("atsl");
    delay(1000);
    while (Serial.available() > 0) {
      inChar = (char)Serial.read(); 
      MacBaja += inChar;
      i++;
    }
    
    delay(5000);
 }
}

Regards.

It seems that the problem is on the receiver side. I tested with the same FW version and there was no problem receiving up to 84 bytes on both AT and API mode, problems came when the payload exceeds this numbers. Maybe the arduino code is what is wrapping it?

Hi Spastor,

thanks for your answer!

I checked it, and that’s right. It is on receiver side, but I don’t understand why. I’m still trying to find where in the code the problem is.

I tried some arduino code examples (serial and xbee) and they worked fine with more data (xbee not more than 84 bytes in AT mode), but it worked!.

Regards.

Hi,

problem solved!

In the receiver side, the code was wrong. I had been trying to modify MCU register after copying the code here, and because of that, if I sent more than 54 bytes of data it wasn’t work.

Thanks for your help!

Regards.

1 Like

Sorry guys, I’m confused…

Maximum payload size for Digi RF products (article 000001456):
[…] The NP parameter is not available for the following radios and their payload sizes are included here as a reference: […]
XBee = 100 Bytes

This only applies to the point-to-multipoint (non-DigiMesh)

So, on XP868LP can I get NP output or not?
If I try to query on my XBee 868LP I got:

0x7E
0x00
0x07
0x88 // response to AT command
0x52 // frame ID

0x4E // N
0x50 // P
0x00
0x01
0x00

0x86 // Checksum

So how can I read this answer?