How do I make a line following robot turn around?

I bought a Make-It-Robotics line following robot, built it, used it, and it was fun. But I wanted to see what else I could do with it. When the robot hits the end of the track, there is a black line. I want it to turn around and search for a new line to follow, in this case it would be picking up the same line it came from. I was able to do it by setting it to turn for a set period of time, but that only works if the line is perpendicular to the end line.

Here is the code that I have for the robot, I didn’t write most of it, just changed the bottom portion (marked each line with a star:

#include <MakeItRobotics.h>//include library
MakeItRobotics line_following;//declare object
// **************************************************************************
// *                            Power Up Initial
// **************************************************************************
void setup()
{
  Serial.begin(10420);                     //tell the Arduino to communicate with Make: it PCB
  delay(500);                              //delay 500ms
  line_following.line_following_setup();   //initialize the status of line following robot
  line_following.all_stop();               //all motors stop
}
// **************************************************************************
// *                            Main Loop
// **************************************************************************
void loop()
{ 
  static int sensor_in;                  //variable to store the value of read_optical function feedback
  static int sensorValue1 = 0;           //variable to store optical1 status
  static int sensorValue2 = 0;           //variable to store optical2 status
  static int sensorCnt = 0;              //variable to count for trigger which optical
  static long sensorTimer1 = millis();   //last triggered time
  static long sensorTimer2 = millis();   //now time
  static int action1 = 0;                //now action
  static int action2 = 0;                //last action
*  static int action3 = 0;
  //************************************************************************
  //  Trigger Left/Right optical every 15 milliseconds
  //************************************************************************
  sensorTimer2 = millis();                 //read now time
  if (sensorTimer2 - sensorTimer1 > 15)    //if now time minus last triggered time is greater than 15ms, then trigger another optical
  {
    sensorTimer1 = sensorTimer2;           //last triggered time = now time
    /***********************************************************************
       -> trigger optical1 -> greater than 15ms -> trigger optical2 -> greater than 15ms ->|
       |-----------------------------------------------------------------------------------|
    ***********************************************************************/
    if (sensorCnt == 0)
      line_following.trigger_optical1();
    else if (sensorCnt == 1)
      line_following.trigger_optical2();
    sensorCnt++;
    if (sensorCnt == 2)
      sensorCnt = 0;
  }           
  //***********************************************************************
  //  Read Left/Right optical status
  //***********************************************************************
  sensor_in=line_following.read_optical(); 
  /************************************************************************
    read_optical()
    Description
      Reads the value from optical1(Right side) or optical2(Left side)
    Syntax
      read_optical()
    Parameters
      none
    Returns
      0x000  optical1 black
      0x0ff  optical1 white
      0x100  optical1 white
      0x1ff  optical1 black
      0x2XX  not ready; don't use this value     
  *************************************************************************/
  if((sensor_in & 0xf00)==0)
    sensorValue1=sensor_in & 0xff;
  else if((sensor_in & 0xf00)>>8==1) 
    sensorValue2=sensor_in & 0xff;
  if (sensorValue1 == 0x00)
    action1 =action1 & 0xfe;
  if (sensorValue1 == 0xFF)
    action1 = action1 | 0x01;
  if (sensorValue2 == 0x00)
    action1 = action1 | 0x02;
  if (sensorValue2 == 0xFF)
    action1 = action1 & 0xfd; 
  /************************************************************************
    action1
             left        right
    0x00    black        black
    0x01    black        white
    0x02    white        black
    0x03    white        white
  *************************************************************************/ 
  /************************************************************************
     Make Robot Move
     if action1 is not equal to action2, then change motor status
     if action1 is equal to action2, then do nothing
  *************************************************************************/
  if(action1 != action2)
  {
    if (action1 == 3 )
      line_following.go_forward(50);
    if (action1 == 1)
      line_following.line_following_turn_left(50);   
    if (action1 == 2)
      line_following.line_following_turn_right(50); 
*    if (action1 == 0){
*      line_following.turn_right(50);
*      delay(1500);                //gives the robot time to turn enough to get both sensors over white
*       action1=action3;
*       while (action3 != 1)                 //should continue the turn while the action3 does not equal 1 
*         line_following.turn_right(50);   // (left sensor black, right sensor white)
*         return;
*       if (action3 == 1)                      // once condition 1 is met, should move forward and begin the
*         line_following.go_forward(50);  // loop
*        action3=action2;                    
*    }
  }
  action2=action1; 
}

My comments are what I think the code should do, but I am the noobiest of noobs, just started this a couple days ago. Using this code the robot hits the black line and then just spins. I think what is happening is it gets stuck on the while command but I can’t figure out where to go next. So far I haven’t found any answers, I’m thinking this is such a basic concept that nobody has needed the help.

The while loop would be more conventionally written as

while (action3 != 1)                 //should continue the turn while the action3 does not equal 1
  {
    line_following.turn_right(50);   // (left sensor black, right sensor white)
  }

It makes it clearer which commands will be executed if the test in the while returns true. In this case it does not actually matter, but with the braces it is easier to add more commands to be executed.

As to your problem, can anything happen in that while loop to change the action3 variable from 1 to another value, even assuming that it is 1 in the first place ?

UKHeliBob:
As to your problem, can anything happen in that while loop to change the action3 variable from 1 to another value, even assuming that it is 1 in the first place ?

Sorry, I don't think I understand the question. Maybe if I walk through the steps you can figure out where I am lost.

When both sensors see black (action1 == 0) the robot rotates clockwise. It does this for 1.5 second, (delay(1500)) and then the next command, the while loop, goes into effect. It will kick on while both sensors detect white (action3 would == 3, which is != 1), and would continue to rotate right. This continues until the right sensor sees black (action3 would == 2, which is still != 1) so it would continue rotating right. Then the left sensor would read black, the right would read white (action3 == 1) and at that point it should go forward, ending the loop. At least that's what I thought would happen.

So in the while loop action3 should only change to 1 at the end of the loop. I hope that answered your question.

I am sorry but your explanation made no sense to me. Perhaps it is because I am not familiar with the MakeItRobotics library, but the meaningless variable names do not help.

Can you please explain what

line_following.turn_right(50);

does and which variables are affected and how.

If it means turn right at speed 50 then how will the value of action3 be changed by turning right continuously whilst not reading the sensors ?

 static int action3 = 0;
...
      while (action3 != 1)                 //should continue the turn while the action3 does not equal 1 
        line_following.turn_right(50);   // (left sensor black, right sensor white)

Yes, it would spin around. action3 is not equal to 1, and it never will be. That loop does not change action3.

Personally I would make all this a function:

sensor_in=line_following.read_optical(); 
  /************************************************************************
    read_optical()
    Description
      Reads the value from optical1(Right side) or optical2(Left side)
    Syntax
      read_optical()
    Parameters
      none
    Returns
      0x000  optical1 black
      0x0ff  optical1 white
      0x100  optical1 white
      0x1ff  optical1 black
      0x2XX  not ready; don't use this value     
  *************************************************************************/
  if((sensor_in & 0xf00)==0)
    sensorValue1=sensor_in & 0xff;
  else if((sensor_in & 0xf00)>>8==1) 
    sensorValue2=sensor_in & 0xff;
  if (sensorValue1 == 0x00)
    action1 =action1 & 0xfe;
  if (sensorValue1 == 0xFF)
    action1 = action1 | 0x01;
  if (sensorValue2 == 0x00)
    action1 = action1 | 0x02;
  if (sensorValue2 == 0xFF)
    action1 = action1 & 0xfd;

Then you could call that while turning. I don't know anything about these robots but I gather from the code you have two lights (LEDs?) that you turn on or off and then take a reading. If all that was done in a function or two, it would be easier to add extra things like checking when the turn is over. Or is it easier than that?

line_following.turn_right(50);

Can you just turn whatever-it-takes to do a 180° turn?

Its optical sensors on the bottom of the robot. The track is a black line on white paper so when one of the sensors sees black it turns the robot the other way to keep the black in between the sensors.

I am actually thinking it was a bad idea to jump into this stuff so quickly. I think I am going to put this robot aside for now and try to find a book to teach me the basics of programming. I don't even know enough to describe my problem, and that tells me I'm in over my head. Thanks for the help though, and I will see you back here once I know what I'm doing.

Good idea, and good luck! You should have fun improving your skills, and then making the robot do what you want.