Robot Code Not Working (Need Advice on my Code)

I have built a robot to follow a black line (the track) using IR sensors. Throughout the track there are various locations where the robot will have to pick something up (with a gripper that is attached to an arm that is attached to a servo), drop the item off somewhere else, and turn around to go get another item and repeat the above process. I locations of the items and drop-off locations have black tape so an IR sensor will be able to detect and based on the iteration of 'i' in my code, will determine which task to perform. The problem is that my robot just starts the stops then starts then stops and just does some really funky stuff. The readings from the Serial Monitor are not ideal at all. Can someone review the code and give some advice? Maybe some delays are necessary in certain spots, maybe some need removed, or maybe my logic just doesn't make sense. Any advice is appreciated.

Void Loop is what I'm most concerned about but if there are any obvious programming errors, please let me know too. It does compile.

IR Sensor Layout:

1---------2--3--4---------5

Direction of travel can be thought of as going upwards on the screen. ^^^

1 --> Senses tape to perform iterations
2,3,4 --> Control basic traveling stabilization on the track
5 --> Senses tape after robot has turned around to perform iterations. Also detects location for robot to turn around.

#include <Servo.h>
Servo servo; Servo gripper; int i = 1;
void turnaround(); void grabitem(); void releaseitem();    // Defines functions
int pasn = 6; int pasp = 9; int drip = 10; int drin = 11;  // Outputs
int ir1 = 2; int ir2 = 4; int ir3 = 7; int ir4 = 8; int ir5 = 12;  // Inputs
// ir1: Driver outside, ir2: Driver outside-center, ir3: Center, ir4: Passenger outside-center, ir5: Passenger outside
int passpeed = 3; int drispeed = 5;    // Outputs

void setup(){
  servo.attach(A0);     // Servo
  gripper.attach(A1);   // Gripper
  pinMode(pasn, OUTPUT); pinMode(pasp, OUTPUT); pinMode(drip, OUTPUT); pinMode(drin, OUTPUT);
  Serial.begin(9600);
  pinMode(ir1, INPUT); pinMode(ir2, INPUT); pinMode(ir3, INPUT); pinMode(ir4, INPUT); pinMode(ir5, INPUT);
  
}

void loop(){
  delay(250);
  drive();
    Serial.print(i);
    if(digitalRead(ir1)){   // IR 1 senses black tape
      if(i==1 || i==6){     // Pick up item at iteration 1 OR 6
        analogWrite(passpeed, 0);
        analogWrite(drispeed, 0);
        delay(500);
        grabitem();
        drive();
      }else if(i==2 || i==4 || i==5 || i==7){    // Keep moving
        drive();
      }else if(i==3 || i==8){    // Drop off item at iteration 3 OR 8
        analogWrite(passpeed, 0);
        analogWrite(drispeed, 0);
        delay(500);
        if(i==3){
          releaseitem();
          turnaround();
          drive();
        }else if(i==8){
            releaseitem();
            drive();
          }
        }
      }else if(i==9){    // Robot stops and senses to see if it should knock tube over
        delay(500);
        analogWrite(passpeed, 0);
        analogWrite(drispeed, 0);
        // Detect cylinder height
        drive();
      }else if(i==10){   // Robot stops and senses to see if it should knock tube over
        analogWrite(passpeed, 0);
        analogWrite(drispeed, 0);
        // Detect cylinder height
        drive();
      }else if(i==11){   // Robot stops and senses to see if it should knock tube over
        analogWrite(passpeed, 0);
        analogWrite(drispeed, 0);
        // Detect cylinder height
        drive();
      }else if(i==12){   // Robot stops and senses to see if it should knock tube over
        analogWrite(passpeed, 0);
        analogWrite(drispeed, 0);
        // Detect cylinder height
        drive();
      }
      delay(500);
      I++
  }

void drive(){
  Serial.println("Driving");
  if(digitalRead(ir3) && !digitalRead(ir1) && !digitalRead(ir5)){ 
    // Robot goes straight
    analogWrite(passpeed, 200);
    analogWrite(drispeed, 200);
    digitalWrite(drip, HIGH);
    digitalWrite(drin, LOW);
    digitalWrite(pasp, HIGH);
    digitalWrite(pasn, LOW); 
  }
  else if(digitalRead(ir2) && !digitalRead(ir3) && !digitalRead(ir4)&& !digitalRead(ir1)){
    // Goes left
    analogWrite(passpeed, 250);
    analogWrite(drispeed, 250);
    digitalWrite(drip, LOW);
    digitalWrite(drin, HIGH);
    digitalWrite(pasp, HIGH);
    digitalWrite(pasn, LOW);
  }
  else if(digitalRead(ir3) && digitalRead(ir2) && !digitalRead(ir4)&& !digitalRead(ir1)){
    // Goes left
    analogWrite(passpeed, 200);
    analogWrite(drispeed, 250);
    digitalWrite(drip, LOW);
    digitalWrite(drin, HIGH);
    digitalWrite(pasp, HIGH);
    digitalWrite(pasn, LOW);
  }
  else if(digitalRead(ir3) && digitalRead(ir4) && !digitalRead(ir2) && !digitalRead(ir1)){
    // Goes right
    analogWrite(passpeed, 200);
    analogWrite(drispeed, 250);
    digitalWrite(drip, HIGH);
    digitalWrite(drin, LOW);
    digitalWrite(pasp, LOW);
    digitalWrite(pasn, HIGH);
  }
  else if(digitalRead(ir4) && !digitalRead(ir3) && !digitalRead(ir2)&& !digitalRead(ir1)){
    // Goes right
    analogWrite(passpeed, 200);
    analogWrite(drispeed, 250);
    digitalWrite(drip, HIGH);
    digitalWrite(drin, LOW);
    digitalWrite(pasp, LOW);
    digitalWrite(pasn, HIGH);
  }
}

void turnaround(){
  Serial.println("Robot Turning Around");
  analogWrite(passpeed, 100);
  analogWrite(drispeed, 100);
  digitalWrite(pasp, HIGH);
  digitalWrite(drip, LOW);
  digitalWrite(drin, HIGH);
  digitalWrite(pasn, LOW);
  delay(500);
  if(digitalRead(ir3)){
    drive();
  }
}

void grabitem(){
  Serial.println("Gripping Item");
  delay(500);
  servo.write(1);      // Robot arm prepares to grab item
  delay(250);
  gripper.write(180);  // Gripper Closees
  delay(250);
  servo.write(90);     // Robot arm returns to home position
  delay(500);
}

void releaseitem(){
  Serial.println("Releasing Item");
  delay(500);
  servo.write(1);     // Robot arm prepares to drop item
  delay(250);
  gripper.write(60);  // Gripper opens
  delay(250);
  servo.write(90);    // Robot arm returns to home position
  delay(500);
}

what is       I++ in loop().

It does compile.

The code does not compile, so I don't see how you can say it isn't working, or that the readings aren't ideal.

Jsreb:
The problem is that my robot just starts the stops then starts then stops and just does some really funky stuff.

This is a nice entertaining description of the problem. Unfortunately it does not provide any useful information to help with problem solving.

Can you describe in a lot more detail what actually happens and when, and what should happen.

...R

IR Sensors 2, 3, 4 provide directional control for robot to follow line.
IR Sensors 1 & 5 detect lines perpendicular to track and determine which task to perform.

Here is the process:

  1. Start driving (Sensors will start in front of the starting line).
  2. Robot should stop at "ITEM 1 PICKUP". Robot arm will swing out (from a servo motor), gripper will grip the item, and robot arm will return to home position.
  3. Robot will drive to and stop at "ITEM 1 DROP-OFF". Robot arm will swing out, release item, an swing back.
  4. Robot will drive to "TURNAROUND LOCATION 1", turn around, drive to "TURNAROUND LOCATION 2", turn around, and drive to "ITEM 2 PICKUP".
  5. Robot will pick up item 2 and proceed to "ITEM 2 DROP-OFF" where it will drop that item off.
  6. Robot will drive and pass "TURNAROUND LOCATION 1" to proceed to other tasks (that I am not concerned about for the sake of my post.)

For sensor 1, each time it detects a line it will perform an iteration of 'i'. The value of 'i' will determine the task to perform.
Same for sensor 5, but it will perform an iteration of 'j'.

Iterations of 'i' (my assumption):
1 -- Stop at "ITEM 1 PICKUP", perform grabitem() function, proceed to drive.
2 -- Do nothing at "ITEM 2 PICKUP".
3 -- Stop at "ITEM 1 DROP-OFF", perform releaseitem() function, proceed to drive.
4 -- This will also be iteration 1 of 'j' (for sensor 5). Performs turnaround() function until sensor 3 detects track again. Robot proceeds to drive.
5,6 -- Detected during turnaround. Do nothing.
7 -- This will also be iteration 7 of 'j' (for sensor 5). Performs turnaround() function until sensor 3 detects line again. Robot proceeds to drive.
8,9 -- Detected during turnaround. Do nothing.
10 -- Do nothing at "ITEM 1 PICKUP".
11 -- Stop at "ITEM 2 PICKUP", perform grabitem() function, proceed to drive.
12 -- Do nothing at "ITEM 1 DROP-OFF".
13 -- Stop at "ITEM 2 DROP-OFF", perform releaseitem() function, proceed to drive.
14 -- Do nothing at "TURNAROUND LOCATION 1".

NEW CODE

#include <Servo.h>
Servo servo; 
Servo gripper; 
turnaround(); 
grabitem(); 
releaseitem();

int i = 0;
int j = 0;

// INPUTS
int ir1 = 2;   // DriverOutside Sensor
int ir2 = 4;   // Driver-Middle Sensor
int ir3 = 7;   // Middle Sensor
int ir4 = 8;   // Passenger-Middle Sensor
int ir5 = 12;  // Passenger Outside Sensor

// OUTPUTS
int pasn = 6;  // Passenger Motor Reverse Motion
int pasp = 9;  // Passenger Motor Forward Motion
int drip = 10; // Driver Motor Forward Motion
int drin = 11; // Driver Motor Reverse Motion
int passpeed = 3; // Passenger Motor Speed Control
int drispeed = 5; // Driver Motor Speed Control

void setup(){
  servo.attach(A0);     // Servo
  gripper.attach(A1);   // Gripper
  pinMode(pasn, OUTPUT); 
  pinMode(pasp, OUTPUT); 
  pinMode(drip, OUTPUT); 
  pinMode(drin, OUTPUT);
  Serial.begin(9600);
  pinMode(ir1, INPUT); 
  pinMode(ir2, INPUT); 
  pinMode(ir3, INPUT); 
  pinMode(ir4, INPUT); 
  pinMode(ir5, INPUT);
}

void loop(){
  drive();
  Serial.print(i);
  if(digitalRead(ir1)){  // IR 1 senses black tape
    i = i + 1;
    delay(250);
  }
  if(digitalRead(ir5)){  // IR 5 senses black tape
    j = j + 1;
    delay(250);
  }

  if(i==1 || i==11){    // Pick up item at iteration 1 OR 11  
    grabitem();
    drive();
  }else if(i==2 || i==5 || i==6 || i==8 || i==9 || i==10 || i==12 || i==14){  // Keep moving (MAYBE DELETE THIS STATEMENT??)
    drive();
  }else if(i==3 || i==13){  // Releases item 1
    releaseitem();
    drive();
  }else if(i==4 && j==1){   // Turns around 
    turnaround();
  }else if(i==7 && j==7){   // Turns around
    turnaround();
  }else if(i==15 || i==16 || i==17 || i==18){  // Robot stops and senses to see if it should knock tube over
    // Detect cylinder height (TBD)
    drive();
  }
}
void drive(){
  Serial.println("Driving");
  if(!digitalRead(ir1) && digitalRead(ir3) && !digitalRead(ir5)){ // IR3 reads black
    // Robot goes straight
    analogWrite(passpeed, 200);  // Fast speed
    analogWrite(drispeed, 200);  // Fast speed
    digitalWrite(drip, HIGH);
    digitalWrite(drin, LOW);
    digitalWrite(pasp, HIGH);
    digitalWrite(pasn, LOW); 
  }else if(digitalRead(ir2) && !digitalRead(ir3) && !digitalRead(ir4)&& !digitalRead(ir1)){ // IR2 reads black
    // Goes left
    analogWrite(drispeed, 200);  // Fastest speed
    analogWrite(passpeed, 250);  // Fast speed
    digitalWrite(drip, LOW);
    digitalWrite(drin, HIGH);
    digitalWrite(pasp, HIGH);
    digitalWrite(pasn, LOW);
  }else if(!digitalRead(ir1) && digitalRead(ir2) && digitalRead(ir3) && !digitalRead(ir4)){ // IR2 & IR3 read black
    // Goes left
    analogWrite(drispeed, 200);  // Fastest speed
    analogWrite(passpeed, 250);  // Fast speed
    digitalWrite(drip, LOW);
    digitalWrite(drin, HIGH);
    digitalWrite(pasp, HIGH);
    digitalWrite(pasn, LOW);
  }else if(!digitalRead(ir1) && !digitalRead(ir2) && digitalRead(ir3) && digitalRead(ir4)){ // IR3 & IR4 read black
    // Goes right
    analogWrite(drispeed, 250);  // Fastest speed
    analogWrite(passpeed, 200);  // Fast speed
    digitalWrite(drip, HIGH);
    digitalWrite(drin, LOW);
    digitalWrite(pasp, LOW);
    digitalWrite(pasn, HIGH);
  }else if(!digitalRead(ir1) && !digitalRead(ir2) && !digitalRead(ir3) && digitalRead(ir4)){ // IR4 reads black
    // Goes right
    analogWrite(drispeed, 250);  // Fastest speed
    analogWrite(passpeed, 200);  // Fast speed
    digitalWrite(drip, HIGH);
    digitalWrite(drin, LOW);
    digitalWrite(pasp, LOW);
    digitalWrite(pasn, HIGH);
  }
}

void turnaround(){
  Serial.println("Robot Turning Around Counter-Clockwise");
  analogWrite(drispeed, 150);  // Medium speed
  analogWrite(passpeed, 150);  // Medium speed
  digitalWrite(drip, LOW);
  digitalWrite(drin, HIGH);
  digitalWrite(pasp, HIGH);
  digitalWrite(pasn, LOW);
  delay(1000);
  if(digitalRead(ir3)){  // Stops turning around after IR3 is sensed
    drive();
  }
}

void grabitem(){
  Serial.println("Gripping Item");
  analogWrite(drispeed, 0);  // Stops driver side motor
  analogWrite(passpeed, 0);  // Stops passenger side motor
  delay(1000);
  servo.write(1);      // Robot arm prepares to grab item
  delay(1000);
  gripper.write(180);  // Gripper Closees
  delay(1000);
  servo.write(90);     // Robot arm returns to home position
  delay(500);
}

void releaseitem(){
  Serial.println("Releasing Item");
  analogWrite(drispeed, 0);  // Stops driver side motor
  analogWrite(passpeed, 0);  // Stops passenger side motor
  delay(1000);
  servo.write(1);     // Robot arm prepares to drop item
  delay(1000);
  gripper.write(60);  // Gripper opens
  delay(1000);
  servo.write(90);    // Robot arm returns to home position
  delay(500);
}

Jsreb:
Here is the process:

You have given a clear description of what you would like to happen.

Now describe, in similar detail, what actually happens.

...R

Robin2:
You have given a clear description of what you would like to happen.

Now describe, in similar detail, what actually happens.

...R

I just tested. The robot initially makes about a 45 degree counter clockwise turn and stops (it looks like it stops as soon as sensor 1 reads the starting line). It then runs grabitem() then releaseitem() over and over endlessly. Not once does it drive straight.

You've got debug prints.
What do they tell you?
Do you need some more?

Jsreb:
I just tested. The robot initially makes about a 45 degree counter clockwise turn and stops (it looks like it stops as soon as sensor 1 reads the starting line). It then runs grabitem() then releaseitem() over and over endlessly. Not once does it drive straight.

Is this code you wrote yourself, or is it code you got from somewhere else.

If you wrote it yourself I think you need to save a copy of it and then strip everything out except the "go forward" code and don't add anything else until that works perfectly.

...R

Robin2:
Is this code you wrote yourself, or is it code you got from somewhere else.

If you wrote it yourself I think you need to save a copy of it and then strip everything out except the "go forward" code and don't add anything else until that works perfectly.

...R

Yes I wrote this myself. It drives just fine but as soon as other tasks are introduced into the program, it goes haywire. I'll strip it down again and take it step by step. Are there any obvious programming errors that I have made?