2
votes

I am trying to configurate my XBee module by an Arduino pro mini that is connected to my computer by de FTDI basic from sparkfun. I already can write and send data from the Xbee to another Xbee module by the Arduino. My problem is that I want to configure the Xbee by the arduino. I am sending ‘+++’ with the arduino to my Xbee and want to receive the ‘OK’ from the Xbee with the serial monitor from the arduino editor. The problem is that I can send it but never receive and ‘OK’, and when I am trying to configure the Xbee the configuration never happened. So I cant reach the Xbee command line.

    uint8_t pinRx = 0, pinTx = 1; //Initialise pins on the Arduino
    char GotChar;
    long BaudRate = 4800;
    int incomingByte=0;
    SoftwareSerial mySerial( pinRx , pinTx );  //Initialise SoftwareSerial
    
    void init_USB()
    {
      Serial.begin(BaudRate);    
      Serial.println("Start");   
      mySerial.begin(BaudRate);  
    }
    
    void init_XBee()
    {
      Serial.begin(9600);
      int check = 0;
      while(T_XBEE_CONTROLLER_CheckOK() == 0)
      {
        Serial.println("CheckOK");
        Serial.write("+++");
        delay(2000);
      }
      Serial.println("ATCH 8\r");
      delay(2000);
      Serial.write("ATID 1234\r");
      delay(2000);
      Serial.write("+++");
      delay(2000);
      Serial.write("ATPL 0\r");
      delay(2000);
      
      Serial.write("+++");
      delay(2000);
      Serial.write("ATAP 2\r");
      delay(2000);
    }

    int T_XBEE_CONTROLLER_CheckOK()
    {
            char ch[2];
            ch[0] = 0x00;
        while(! ((ch[0] == 'O' ) && (ch[1] == 'K')  ))
        {
                ch[0] = mySerial.read();
                ch[1] = mySerial.read();
                if((ch[0] != 'O') && (ch[1] != 'K') && (ch[2] != '\r'))
                {
                  Serial.println("FAILED");
                        return 0;
                }
                Serial.println("SUCCES");
                return 1;
        }
        return 0;
}
3

3 Answers

0
votes

it is a stupid answer but first of all, you should check that your Xbee is configured as AT device instead of API device. If it is API mode, the module wont understand the messages.

To do that you just have to use X-CTU application and read the configuration of the module, and change it to AT device.

Hope that helps.

0
votes

Thanks for the response and the help, and also sorry for the late response.

I already solved the problem. The problem was the function write(). If you want to reach the command mode from the XBee you should only send "+++". If there is some kind of character behind the "+++" you can't reach the command line. The function write put a (for me) unknown character behing the "+++". So that's the problem for not reaching the command line.

To resolve this problem just use the function print("+++"). After using this function it is possible to reach the command line.

0
votes

You have to read from the serial right after you send the +++ command, because this is where the xbee writes 'OK'. Also a better way to respect the guard times is to wait for a reply, and test to see if it is 'OK'.

Here is my code, I don't remember if it was working the last time I checked but I will just paste it here and you can modify it as you like. All it does is broadcast A1, B2, C3, etc.

There's a lot of commenting out where I was experimenting, but the regular comments are informative. Make sure you go through it step by step, it's quite simple when you get your head around it. Don't forget to change the destination address low to 0xFFFF if you want to broadcast.

In the end you'll come to the same realisation I did that AT mode is not suitable for configuring the xbee by writing programs.

For example I had an xbee constantly transmitting the number '2', and when another xbee was entering command mode using this code, it would receive the number 2 from the remote xbee when it should have received the 'OK' message from the local xbee, thus the program didn't acknowledge it being in command mode and breaking. When entering command mode you'd think an xbee would turn it's receiver off, but that's not the case so you can easily get into trouble.

If you want to do it the right way, have a look at API mode. I have series 1 xbee's so I'm implementing the Digimesh protocol, which so far I haven't seen anyone online do, but it's almost identical to the Zigbee so it's easy. If you'd like I can give you my code for that which can serve as a simple example.

    /*
      unicast_configure
     Configure an XBee for unicast transmission and transmit
     some characters to test
     */
    
    #include <SoftwareSerial.h>
    
    // Pins on Bees Shield:
    SoftwareSerial xbee(2, 3);  // TX, RX
     
    boolean configured;
    char c = 'A';
    
    boolean configureRadio() {
      
       // Set the data rate for the SoftwareSerial port:
       xbee.begin(9600);
       
      // Put the radio in command mode:
      Serial.write("Entering command mode\r");
      delay(1000);
      while(xbee.available()>0) {xbee.read();}
      xbee.write("+++");
      while(xbee.available()>0) {xbee.read();}
      //delay(1000);
      //while(xbee.available() > 0) {Serial.write(xbee.read());}
      
      String ok_response = "OK\r"; // The response we expect
      
      // Read the text of the response into the response variable
      // This satisfies the guard time by waiting for the OK message
      String response = String("");
      while (response.length() < ok_response.length()) {
        if (xbee.available() > 0) {
          response += (char) xbee.read();
        }
      }
      Serial.println("response1: " + response);
      
      // If we got received OK, configure the XBee and return true:
      if (response.equals(ok_response)) {
        Serial.println("Enter command mode successful");
        
        // Restore to default values:
        Serial.println("Restoring default values before making changes");
        xbee.write("ATRE\r");
        Serial.println("Setting addr high");
        xbee.write("ATDH0\r");  // Destination high
        //while(xbee.available() > 0) {Serial.write(xbee.read());}
        Serial.println("Setting addr low");
        xbee.write("ATDL1\r");  // Destination low-REPLACE THIS
        //while(xbee.available() > 0) {Serial.write(xbee.read());}
        Serial.println("Setting MY address");
        xbee.write("ATMYFFFF\r");
        
        // Apply changes:
        Serial.println("Applying changes");
        xbee.write("ATAC\r");
    /*    
        ///////////////////////////////////////////////
        // Write to non-volatile memory:
        // Use similar technique as above to satisfy guard time
        Serial.write("Saving\r");
        xbee.write("ATWR\r");
        String response2 = String("");
        //while (xbee.available() > 0) {Serial.write(xbee.read());}
        while (response2.length() < ok_response.length()) {
          if (xbee.available() > 0) {
            response2 += (char) xbee.read();
          }
        }
        Serial.println("response2: " + response2);
        
        if (response2.equals(ok_response)) {
          Serial.println("Save successful");
        }
        else { Serial.println("Save not successful");
               return false;
        }
        
        // And reset module:
        Serial.println("Resetting");
        xbee.write("ATFR\r");
        ///////////////////////////////////////////////
        
    */
        Serial.write("Exit command mode\r");
        xbee.write("ATCN\r");  // Exit command mode
        //while(xbee.available() > 0) {Serial.write(xbee.read());}
        Serial.write("Finished\r");
        return true;
      } else {
        return false; // This indicates the response was incorrect
      }
    }
        
    void setup() {
      Serial.begin(9600);  // Begin serial
      configured = configureRadio();
    }
    
    void loop() {
      // Test transmission:
      if (configured) {
        xbee.print(c);
        Serial.print(c);
        c = c + 1;
        if (c > 'Z') { c = 'A'; }
      }
      else {
        Serial.println("Not configured (in loop)");
        delay(5000);
        Serial.println("Retrying configuration");
        configured = configureRadio();
      }
      
      delay(1500);
    }