Go Down

Topic: Loop stops running after several cycles - XBee S2 network (Read 796 times) previous topic - next topic

nikki

Hi,

I'm running a ZBee network of 1 AT coordinator and up to 4 AT routers.

All radios are Series 2 and attached to RBBB arduino boards.
The sketches on the arduinos is adapted from the examples by Rob Faludi, linked to from this page: http://www.faludi.com/itp_coursework/meshnetworking/XBee/XBee_example.html

Can anyone tell me why the coordinator code seems to run for about 6 cycles and then stop?

Thanks,
nikki
(newbie to programming, very newbie to XBee, so please bear in mind I will probably have to google your answers to be able to understand them!)

Here's the Coordinator code:

Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial XbeeSerial(8, 7);

// a digital input is on port 12
int switchPin = 12;

// a status light is on port 13
int ledPin = 13;

// a byte to send out data:
char thisByte = 0;


void setup () {
 // set pins to input and output appropriately
 pinMode(ledPin, OUTPUT);
 pinMode(switchPin, INPUT);

 // start up the serial connection with 9600-8-n-1-true (non-inverted):
 Serial.begin(9600);
XbeeSerial.begin(9600);
 // blink the status LED
 blinkLED(ledPin, 3);

 // for some reason it seems to help to send an arbitrary character first
 //then pause for the guard time before requesting command mode
 XbeeSerial.print("X");
 Serial.print("X");
 delay(1100);
 // put the XBee in command mode
 XbeeSerial.print("+++");
 Serial.println("+++ setting local radio");
  delay(1100);
 // wait for a response from the XBee for 2000 ms, or start
 // over with setup if no valid response comes

 
 if (returnedOK() == 'T') {
   // if an OK was received then continue
                Serial.println("command mode acheived!");
 }
 else {
                Serial.println("failed to connect");
   setup(); // otherwise go back and try setup again

 }
 
XbeeSerial.print("ATID2001,");
Serial.print("ATID2001,");
XbeeSerial.print("DH00000000,DL0000FFFF,");
Serial.print("DH00000000,DL0000FFFF,");
 // exit command mode (note that we use Serial.printLN here
//to issue a linefeed that completes the command sequence)
 XbeeSerial.println("CN");
 Serial.println("CN");
 
  if (returnedOK() == 'T') {
   // if an OK was received then continue
    Serial.println("T");
 }
 else {
   setup(); // otherwise go back and try setup again
        Serial.println("failed to ok");
 }

}


void loop () {
 // read the switch:
 int startTime = millis();
while (millis() - startTime < 2000) {
   thisByte = 1;
   XbeeSerial.print(thisByte, DEC);
   Serial.println(thisByte, DEC);
}
while ((millis() - startTime) >= 2000 && (millis() - startTime) < 4000) {
   thisByte = 0;
   XbeeSerial.print(thisByte, DEC);
   Serial.println(thisByte, DEC);
}

} //end loop

void blinkLED(int targetPin, int numBlinks) {
 // this function blinks the status LED light as many times as requested
 for (int i=0; i<numBlinks; i++) {
   digitalWrite(targetPin, HIGH);
   Serial.println("LED HIGH");  // sets the LED on
   delay(250);                     // waits for a second
   digitalWrite(targetPin, LOW);
    Serial.println("LED LOW");  // sets the LED off
   delay(250);
 }
 

}


char returnedOK () {
 // this function checks the response on the serial port to see if it was an "OK" or not
 char incomingChar[3];
 char okString[] = "OK";
 char result = 'n';
 int startTime = millis();
 while (millis() - startTime < 2000 && result == 'n') {  // use a timeout of 10 seconds
   if (XbeeSerial.available() > 1) {
     // read three incoming bytes which should be "O", "K", and a linefeed:
                  Serial.println("serial available");
     
     for (int i=0; i<3; i++) {
       incomingChar[i] = XbeeSerial.read();
     }
     if ( strstr(incomingChar, okString) != NULL ) { // check to see if the respose is "OK"
//     if (incomingChar[0] == 'O' && incomingChar[1] == 'K') { // check to see if the first two characters are "OK"
       result = 'T'; // return T if "OK" was the response
           Serial.println("OK");
     }  
     else {
       result = 'F'; // otherwise return F
                   Serial.println("NOT OK");
     }
   }
 }
 return result;
}





And the Router code:
Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial XbeeSerial(8, 7);

// an output light is on port 11
int outputPin = 13;

// a status light is on port 13
int ledPin = 11;

// a byte to receive data:
char inByte = 0;


void setup () {
 // set pins to input and output appropriately
 pinMode(ledPin, OUTPUT);
 pinMode(outputPin, OUTPUT);

 // start up the serial connection with 9600-8-n-1-true (non-inverted):
 Serial.begin(9600);
XbeeSerial.begin(9600);
 // blink the status LED
 blinkLED(ledPin, 3);

 // for some reason it seems to help to send an arbitrary character first
 //then pause for the guard time before requesting command mode
 XbeeSerial.print("X");
  Serial.print("X");
 delay(1100);
 // put the XBee in command mode
 XbeeSerial.print("+++");
 Serial.print("+++");
 delay(1100);
 // wait for a response from the XBee for 2000 ms, or start
 // over with setup if no valid response comes


 if (returnedOK() == 'T') {
   // if an OK was received then continue
 }
 else {
   setup(); // otherwise go back and try setup again
 }



 // set the PAN (personal area network) ID number
 // this example uses 0x3330, but you'll want to choose your own
 // unique hexadecimal number between 0x0 and 0xFFFE
 // (note the comma at the end of the command which indicates that another command will follow)
 XbeeSerial.print("ATID2001,");
 Serial.println("ATID2001, ");
//  XbeeSerial.print("ATNIBLUE");
//    Serial.println("ATNIBLUE");
//      XbeeSerial.print("ATDNCOORD");
//  Serial.println("ATDNCOORD");
   
 // exit command mode (note that we use Serial.printLN here to issue a linefeed that completes the command sequence)
XbeeSerial.println("CN");
 Serial.println("CN");

 // wait for a response from the XBee for 2000 ms, or start
 // over with setup if no valid response comes

 if (returnedOK() == 'T') {
   // if an OK was received then continue
 }
 else {
   setup(); // otherwise go back and try setup again
 }

}


void loop () {
// get any incoming data:
    if (XbeeSerial.available() > 1) {
     // read a byte
       inByte = XbeeSerial.read();

  // light the LED if a 1 has been received
    }
  if (inByte == '1') {
  digitalWrite(outputPin, HIGH);
    Serial.println("LED HIGH");
  }
  // douse the LED if anything else was received
  else if (inByte == '0'){
  digitalWrite(outputPin, LOW);
       Serial.println("LED LOW");
  }
}

void blinkLED(int targetPin, int numBlinks) {
 // this function blinks the status LED light as many times as requested
 for (int i=0; i<numBlinks; i++) {
   digitalWrite(targetPin, HIGH);   // sets the LED on
   delay(250);                     // waits for a second
   digitalWrite(targetPin, LOW);    // sets the LED off
   delay(250);
        Serial.print("BLINK");
        Serial.println(i);
 }
}


char returnedOK () {
 // this function checks the response on the serial port to see if it was an "OK" or not
 char incomingChar[3];
 char okString[] = "OK";
 char result = 'n';
 int startTime = millis();
 while (millis() - startTime < 2000 && result == 'n') {  // use a timeout of 10 seconds
   if (XbeeSerial.available() > 1) {
     // read three incoming bytes which should be "O", "K", and a linefeed:
     for (int i=0; i<3; i++) {
       incomingChar[i] = XbeeSerial.read();
     }
     if ( strstr(incomingChar, okString) != NULL ) { // check to see if the respose is "OK"
//      if (incomingChar[0] == 'O' && incomingChar[1] == 'K') { // check to see if the first two characters are "OK"
       result = 'T'; // return T if "OK" was the response
                   Serial.println("OK");
     }  
     else {
       result = 'F'; // otherwise return F
     }
   }
 }
 return result;
}





PaulS

Code: [Select]
    setup(); // otherwise go back and try setup again
You shouldn't call setup() from within setup(). You could end up setting up a recursive situation that you can't get out of.

You should not be reconfiguring the XBee(s) in setup. That should be done using X-CTU before the XBee is attached to the Arduino.

Code: [Select]
  int startTime = millis();
Time for you to hit the reference page again. As soon as the Arduino has been running for more than 32 seconds, this variable will overflow, causing startTime to be negative.


nikki

Thanks for that PaulS,

I'd woken up this morning asking myself why I was keeping all the command mode stuff from the example and have stripped all that out now.

I wouldn't have caught the int mistake, though! That explains what I was seeing with some other code!

Thanks :)

Go Up