How to program a startup sequence that only runs once?

I am new to arduino's and programming. I have a DFR robotshop rover and another arduino that has a joystick to control the movement of the rover. I am using the easy transfer serial library to communicate. I have the rover set up to run autonomously with an ultrasonic sensor when not in manual mode. When I turn the rover on it goes straight into autonomous mode and I need it to wait until the xbee sync's.

I have tried to use:

while( Serial.available()>0){
do my stuff
}

but sometimes I think it looses communication, and the rover will keep driving when I let off the stick or will not stop when in autonomous mode.

What other methods are available to accomplish a start up delay basically that only runs once and allows the xbee to sync?

Thanks Dan

I have tried to use:

while( Serial.available()>0){
do my stuff
}

Tried to use that where? What is in the "do my stuff" block?

but sometimes I think it looses communication, and the rover will keep driving when I let off the stick or will not stop when in autonomous mode.

If it looses communication, it will not receive any serial data, so as long as "do my stuff" includes actually reading the serial data, and as long as the sender sends a continuous stream of data, and as long as the "do my stuff" block include stopping, that should work. That it doesn't implies that one of the assumptions is not being met.

Here is the code for the rover:

#include <Servo.h>
#include <EasyTransfer.h>

//create two objects
EasyTransfer ETin, ETout; 
//create servo
Servo pan;
Servo tilt;
int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control
const int light1 = 3;
const int light12 = 2;
const int camera1 = 12;
const int camera12 = 4;
const int motionSensorReceive=13;
const int sonarPin=11;
int leftspeed = 255;//Motor speed settings 
int rightspeed = 255;//255 is maximum speed
int light=HIGH;
int manual=HIGH;
int camera=HIGH;
int alarmState=0;
int inches=0;
char drive;
unsigned long value=0;

struct RECEIVE_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int cameraOn;
  int lightOn;
  int manualDrive;
  int pan;
  int tilt;
  char drFR;
  int count;
};

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int alarm;
};


//give a name to the group of data
RECEIVE_DATA_STRUCTURE rxdata;
SEND_DATA_STRUCTURE txdata;


void setup(){
  Serial.begin(9600);
  //start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
  ETin.begin(details(rxdata), &Serial);
  ETout.begin(details(txdata), &Serial);
  pinMode(5, OUTPUT);//Motor pin setup
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
 pinMode(light1,OUTPUT);
 pinMode(light12,OUTPUT);
 pinMode(camera1, OUTPUT);
 pinMode(camera12, OUTPUT);
 pinMode(sonarPin,INPUT);
 pinMode(motionSensorReceive, INPUT);
 digitalWrite(motionSensorReceive,HIGH);//pullup
 pan.attach(9);
 tilt.attach(10);
 //setup rover to all off and servos centered
 pan.write(10);
 tilt.write(30);
 digitalWrite(camera1,HIGH);
    delay(4);
    digitalWrite(camera1,LOW);
    delay(100);
    digitalWrite(light1,HIGH);
    delay(4);
    digitalWrite(light1,LOW);
}

void loop(){
  value=pulseIn(sonarPin, HIGH);
    ETin.receiveData();
while(Serial.available()<0){
    stop();
    break;
}
    
while(Serial.available()>0){
manual=rxdata.manualDrive;
light=rxdata.lightOn;
camera=rxdata.cameraOn;
drive=rxdata.drFR;
pan.write(map(rxdata.pan, 0, 1023, 0, 179));
tilt.write(map(rxdata.tilt, 0, 1023, 0, 100)); 

while(camera==HIGH){//only turns light on when camera is on
    
    digitalWrite(camera12,HIGH);
    delay(2);
    digitalWrite(camera12,LOW);
    break;
  }//end camera on
  
while(camera==LOW){//turns light off
      digitalWrite(camera1,HIGH);
      delay(2);
      digitalWrite(camera1,LOW);
      break;
    }//end camera off
    
while(light==HIGH){//only turns light on when camera is on
    digitalWrite(light12,HIGH);
    delay(2);
    digitalWrite(light12,LOW);
    break;
  }//end light on
  
while(light==LOW){//turns light off
      digitalWrite(light1,HIGH);
      delay(2);
      digitalWrite(light1,LOW);
      break;
    }//end light off
   
while(manual==HIGH){
 switch(drive) // Perform an action depending on the command
{
case 'w'://Move Forward
forward (leftspeed,rightspeed);
break;
case 's'://Move Backwards
reverse (leftspeed,rightspeed);
break;
case 'a'://Turn Left
left (leftspeed,rightspeed);
break;
case 'd'://Turn Right
right (leftspeed,rightspeed);
break;
case 'x':
stop();
default:
stop();
break;
}  //end drive switch    
break;
}//end manual drive high

while(manual==LOW){
  stop();
  
  while(rxdata.count==HIGH){
    stop();
    alarmState=digitalRead(motionSensorReceive);
if (alarmState==LOW)
txdata.alarm=HIGH;
else 
txdata.alarm=LOW;
  break;
  }
  while(rxdata.count==LOW){
    txdata.alarm=LOW;
    measureDistance(value);
    autonomous (leftspeed,rightspeed,inches);
 break;
 } 
  break;
}//end manual drive low


 ETout.sendData(); 
break;
}//end serial available
delay(50);//receive delay 
}//end loop

void measureDistance(char b){
 inches=value/147; 
}

void autonomous(char a, char b, char c)
{
  forward(leftspeed,rightspeed);
 if(inches<=12)
 right(leftspeed,rightspeed);
 if(inches<=8)
 reverse(leftspeed,rightspeed);
}//end autonomous

//drive functions taken from WASD file.
void stop(void) //Stop
{
digitalWrite(E1,LOW);
digitalWrite(E2,LOW);
}
void forward(char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,LOW);
analogWrite (E2,b);
digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}
void left (char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,LOW);
}
void right (char a,char b)
{
analogWrite (E1,a);
digitalWrite(M1,LOW);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}

Here is the code for the controller:

#include <EasyTransfer.h>

//create two objects
EasyTransfer ETin, ETout; 
int driveFR;
int driveLR;
char dr;
const int alarmOff=3;
const int alarmOn=2;
const int lightSwitch=4;
const int manualSwitch=5;
const int cameraSwitch=6;
const int alarmReset=7;
const int LEDpin=13;
const int buzzer=11;

int manualSwitchState=LOW;
int cameraSwitchState=LOW;
int lightSwitchState=LOW;
int alarmResetState=LOW;
int alarmState=LOW;

unsigned long value=0;
long previousMillis=0;
long interval=100;
long counter=0;


struct RECEIVE_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int alarm;
};

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  int cameraOn;
  int manualDrive;
  int lightOn;
  int pan;
  int tilt;
  char drFR;
  int count;
};

//give a name to the group of data
RECEIVE_DATA_STRUCTURE rxdata;
SEND_DATA_STRUCTURE txdata;


void setup(){
  Serial.begin(9600);
  //start the library, pass in the data details and the name of the serial port. Can be Serial, Serial1, Serial2, etc.
  ETin.begin(details(rxdata), &Serial);
  ETout.begin(details(txdata), &Serial);
  
  pinMode(alarmOn,OUTPUT);
  pinMode(alarmOff,OUTPUT);
  pinMode(lightSwitch,INPUT);
  //digitalWrite(lightSwitch,HIGH);//enabled pullup
  pinMode(manualSwitch, INPUT);
  //digitalWrite(manualSwitch,HIGH);//enalbed pullup
  pinMode(cameraSwitch, INPUT);
  //digitalWrite(cameraSwitch,HIGH);//enabled pullup
  pinMode(alarmReset, INPUT);
  digitalWrite(alarmReset,HIGH);
  pinMode(LEDpin,OUTPUT);
  digitalWrite(LEDpin,HIGH);
  pinMode(buzzer,OUTPUT);
  //turns alarm off when powered up
  digitalWrite(alarmOff,HIGH);
    delay(2);
    digitalWrite(alarmOff,LOW);
  
}

void loop(){
 manualSwitchState = digitalRead(manualSwitch); 
 lightSwitchState=digitalRead(lightSwitch);
 cameraSwitchState=digitalRead(cameraSwitch);
 alarmResetState=digitalRead(alarmReset);
 txdata.pan = analogRead(0);
 txdata.tilt = analogRead(1);
 

driveLR=analogRead(2);
driveFR=analogRead(3);
 if(driveFR>=600)
dr='w';//forward
if(driveFR<=400)
dr='s';//reverse
if(driveLR>=700)
dr='a';//left
if(driveLR<=400)
dr='d';//right
if(((driveFR>=401&&driveFR<=599)&&(driveLR>=401&&driveLR<=701 )))
dr='x';//stop
txdata.drFR=dr;

while (cameraSwitchState==HIGH){
  txdata.cameraOn=HIGH;
  break;
}
while (cameraSwitchState==LOW){
  txdata.cameraOn=LOW;
  break;
}

while(lightSwitchState==HIGH){
  txdata.lightOn=HIGH;
  break;
}
while(lightSwitchState==LOW){
  txdata.lightOn=LOW; 
  break;
}
while (manualSwitchState==HIGH){
  counter=0;
  digitalWrite(LEDpin,LOW);
txdata.manualDrive=HIGH;
break;
}  
ETin.receiveData();
while(manualSwitchState==LOW){
  txdata.manualDrive=LOW;
  unsigned long currentMillis = millis();
    if(currentMillis-previousMillis>interval){
      previousMillis=currentMillis;
      counter++;
    }//end counter increment
    if (counter==600){
        counter=0;
      }//end counter reset
      
   while(alarmResetState==HIGH){
      if(rxdata.alarm==HIGH){
        digitalWrite(alarmOn,HIGH);
        delay(2);
        digitalWrite(alarmOn,LOW);
        tone(buzzer,2093,250);
        delay(100);
        noTone(buzzer);
      }//end alarm 
      else{
        digitalWrite(alarmOff,HIGH);
        delay(2);
        digitalWrite(alarmOff,LOW);
        noTone(buzzer);
      }//end no alarm
    while(counter<=300){
      txdata.count=HIGH;
      digitalWrite(LEDpin,HIGH);
      break;
    }//end alarm read
    while(counter>=301&&counter<=600){
      txdata.count=LOW;
      digitalWrite(LEDpin,LOW);
      break;
    }//end autonomous drive
  break;  
  }//end alarm reset off
  while(alarmResetState==LOW){
   digitalWrite(alarmOff,HIGH);
    delay(2);
    digitalWrite(alarmOff,LOW);
    noTone(buzzer);
    break;
    }//end alarm reset on
  break;
}//end manual drive low
//then we will go ahead and send that data out
ETout.sendData();
//delay for good measure
  delay(100);
}

while(Serial.available()<0){
stop();
break;
}

Serial.available() returns the number of bytes in the buffer that have not been read. It is simply not possible for there to be less than 0 bytes available, so your while statement will never be true.

A quick peak at your code shows that you appear to not understand what while and break do. You appear to be using while and break together where what you really want is an if statement. The above is a good example. Why is there a break in there? If you corrected the comparison, to == 0, instead of < 0, breaking out of the while loop immediately after stopping has exactly the same effect as

if(Serial.available() < 0)
{
   stop();
}

A quick peak at your code shows that you appear to not understand what while and break do.

You are more than likely correct. I have not been programming long and it seemed logical so that if I got stuck in the loop that it could get out of it using the break statement.

If there is never a chance for Serial.available to be <0 I should use

if ( Serial.available()>0){
my code
}

instead of
while(Serial.available()>0){
my code
}

and totally get rid of the Serial.available<0 part?

dans37buick:
You are more than likely correct. I have not been programming long and it seemed logical so that if I got stuck in the loop that it could get out of it using the break statement.

There is no point to unconditionally breaking from a loop. This:

while(Serial.available()>0)
{
  // do whatever
  break;  // leave the loop
}

... is going to be exactly the same as:

if(Serial.available()>0)
{
  // do whatever
}

As a general principle, if you are waiting on serial communication you do something when the required data has arrived.

Fairly lengthy description here: