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)??

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

Where is the code?

Why do you need two question marks for every question????

Hi,

the two question marks are a trick.

The code in the receiver is like this:

#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("\t XBEE AT \n");
  
  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 == '\n') {
        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);
 }
}

Do you have a clue what Serial.flush() does? Why are you using it all over the place? What version of the IDE are you using?

Do you have any idea how long an XBee stays in command mode? You are waiting for one second after getting a reply. Is that longer or shorter than the XBee stays in command mode in the absence of a command?

Are you using the serial port to talk to the XBee or to talk to the PC? It looks to me like the answer is both, which is the wrong answer.

Some comments in the code would be useful.

Hi,

first of all, thanks for every one!

I'm trying to answer your questions at the best way.

  • Serial.flush(). It's used to clean the Serial port. It's possible that I used it more than neccesary, but sometimes I get some garbage in Serial port (it could be for using '\t' or '\n').

  • IDE 1.0 Linux.

  • How long...? I don't have too much knowledge reading AT commands from MCU yet. So I can't read AT commands faster if I don't wait one second (also I have troubles with, if I set CTS FLOW CONTROL bit (DIO7). [I'll try to avoid Serial.flush in these functions also the 'delay', could you give any tip about?].

  • Serial port. It's used to talk with XBee but at my test, it's the way I can assure the communication is working fine.

  • For receiving data: an Arduino Mega with a Xbee Shield and the code post below (it switches on/off a led for a time). It shows Serial port data by Cutecom app.
    ** For transmitting data: an explorer usb and the X-CTU app, so I can send the message I want.

Regards!

  • Serial.flush(). It's used to clean the Serial port. It's possible that I used it more than neccesary, but sometimes I get some garbage in Serial port (it could be for using '\t' or '\n').

  • IDE 1.0 Linux.

Starting with 1.0, Serial.flush() blocks until the outgoing serial buffer is empty. How is that necessary for you?

Prior to 1.0, Serial.flush() did NOT "clean the Serial port". It discard random amounts of unread data in the incoming serial buffer that had not been read yet. It did nothing about data that had not yet arrived in the buffer. Throwing away random amounts of unread data was not useful then.

What it does now is even less useful. So, get rid of ALL the Serial.flush() calls.

  • How long...? I don't have too much knowledge reading AT commands from MCU yet.

That has nothing to do with how long the XBee takes to enter command mode, or how long it remains in command mode if it does not receive a command.

You need to look at digi.com's site to find that answer.

AT Command Mode
To Enter AT Command Mode:
Default AT Command Mode Sequence (for transition to Command Mode):
• No characters sent for one second [GT (Guard Times) parameter = 0x3E8]
• Input three plus characters (“+++”) within one second [CC (Command Sequence Character)
parameter = 0x2B.]
• No characters sent for one second [GT (Guard Times) parameter = 0x3E8]

So, waiting 1.2 seconds after putting the XBee in command mode is going to find it back in relay mode.

Hi,

thanks!!

The problem was in the receiver code, so for the moment is solved!

I was modifying some MCU register after copying code here, and that was the problem. When I avoid these instructions it began to work fine.

  • The AT command haven't been still tested by myself, so in a few days I hope to can test them.

Regards.