> For the complete documentation index, see [llms.txt](https://docs.idew.org/code-robotics/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.idew.org/code-robotics/tutorials/detect-lines-on-surface/e-3-avoid-line.md).

# E-3 Avoid Line

Next, you'll code an app that uses the IR line sensors to make your robot avoid a line. The line acts a border to keep the robot inside (or outside) a certain area or path.

## Use Existing Line on Surface

You'll use the same line as you did in the previous test — except for this test, the robot will be placed **inside** the area enclosed by the line. As the robot drives around, it will turn away from the line whenever the line is detected. In this case, the line will act like a border to keep the robot **inside** the area.

![](/files/-LWvxOA90Nj4pNLtTET2)

If you were to place the robot **outside** the area, then the line would act as a border to keep the robot **outside** of the area.

## How Line Avoiding Works

The robot's goal when avoiding a line is to check for a line as the robot drives and turn away when a line is detected. To do this, the robot can just check the left and right IR line sensors (rather than all three).

![](/files/-LWxCDtepp4gz1ryflsb)

If the robot is trying to avoid a line, there are 3 possible situations when a line is detected:

* **If both the left and right IR line sensors detect the line**, this means the robot has "hit" the line head-on. In this situation, the robot should turn around to avoid the line.
* **If only the left IR sensor detects the line**, this means robot has "hit" the line at angle from the left. In this situation, the robot should turn right to avoid the line.
* **If only the right IR line sensor detects the line**, this means robot has "hit" the line at angle from the right. In this situation, the robot should turn left to avoid the line.

## Save Copy of App With New Name <a href="#save-copy-of-app-with-new-name" id="save-copy-of-app-with-new-name"></a>

In your Arduino code editor, use the "Save As" command to save a copy of the `follow_line_test` app as a different app named: `avoid_line_test`

Once you saved the new app name, modify the block comment near the beginning of the app code to change `Follow Line Test` to `Avoid Line Test`.

## Add Custom Function to Avoid Line

You'll add a custom function named `avoidLine()` which will contain code to use readings from the left and right IR line sensors to decide whether to drive straight, turn left, turn right, or turn around the right.

Similar to following a line, avoiding a line works best at slower speeds (otherwise the robot might drive past the line before detecting it), so this function uses a value of `100` for the motor power.

This function assumes that your robot will be avoiding a dark line on a light-colored surface. However, you can modify the function to instead avoid a light line on a dark surface.

This function generates a **random** number for the amount of time (in milliseconds) for each turn (pivot) in order to produce variation in the robot's new direction. The ranges for the random numbers were selected to make the pivot times close to a 90° turn or a 180° turn. However, you can modify the function to instead use **fixed** pivot times (such as 650 ms for a 90° turn and 1300 ms for a 180° turn).

{% hint style="success" %}
**MINIMUM PIVOT:**  Be sure to make the robot turn at least 90° whenever it detects a line. If the robot were to "hit" a line at a nearly perpendicular angle (almost head-on), then a pivot of less than 90° might **not** be enough to turn away from the line.
{% endhint %}

Add this custom function **after** the `loop()` function:

```cpp
void avoidLine() {
  /* AVOID LINE
  To avoid dark line on light surface:
  Use high threshold & see if sensors greater than threshold

  To avoid light line on dark surface:
  Use low threshold & see if sensors less than threshold
  */

  // adjust value if necessary
  int lineThreshold = 800;

  // get IR sensor readings (only need left and right)
  int leftSensor = leftLine.read();
  int rightSensor = rightLine.read();

  // if either sensor detects line, first brake motors
  if (leftSensor > lineThreshold || rightSensor > lineThreshold) {
    motors.brake();
    delay(250);
  }

  // if both sensors on line, turn around (about 180 degrees)
  if (leftSensor > lineThreshold && rightSensor > lineThreshold) {
    long randomNum = random(975, 1625); // approx 135-225 degree pivot
    motors.pivot(100);
    delay(randomNum);
    motors.stop();
  }
  // if line under left sensor only, turn right (min 90 degrees)
  else if (leftSensor > lineThreshold) {
    long randomNum = random(650, 975); // approx 90-135 degree pivot
    motors.pivot(100); // pivot clockwise to right
    delay(randomNum);
    motors.stop();
  }
  // if line under right sensor only, turn left (min 90 degrees)
  else if (rightSensor > lineThreshold) {
    long randomNum = random(650, 975); // approx 90-135 degree pivot
    motors.pivot(-100); // pivot counter-clockwise to left
    delay(randomNum);
    motors.stop();
  }
  // otherwise, keep driving straight
  else motors.drive(100);

  delay(25);  // can change delay to adjust line detection sensitivity    
}
```

## Modify Code to Perform When Robot is Started

When the D12 button is pressed to "start" the robot, we want make the robot drive forward while avoiding the line.

First, **delete** the existing code statement **within** the `if` statement in the `loop()` function that calls the `followLine()` function  when `started` is `true`.

Then add this code statement **within** the `if` statement in the `loop()` function, so it will be performed when `started` is `true`:

```cpp
    avoidLine();
```

## Upload App to Robot

Follow the steps to connect your robot to your computer, and upload the app.

Unplug the USB cable from the robot, and place the robot **inside** the area enclosed by the line, so **none** of the robot's IR line sensors are on the line.

Press the D12 button to "start" the robot. The robot should start driving and should avoid the line by making turns to stay within the area enclosed by the line.

When you're done testing the robot, you can pick it up, and press the D12 button to "pause" the robot (or you can press the Reset button).

If you want to test further, place the robot back on the line, and press the button to "start" the robot again.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.idew.org/code-robotics/tutorials/detect-lines-on-surface/e-3-avoid-line.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
