Arduino Robot
Arduino Robot
Using a line follower and a touch sensor, we turned a basic Arduino robot into an autonomous navigator. The robot was coded to follow specific tracks and dodge obstacles based on logic. This challenge was a great way to see how software programming directly controls physical machines.
Coding the Arduino robot
The Arduino robot
Success!!
Our Code: Python
// ============================================================
// VERSION 2: auto-calibrating line follower + obstacle avoidance
// Based on SparkFun's official "Getting Started with the RedBot"
// tutorial: uses setBGLevel()/setDetectLevel() so the sensors
// calibrate THEMSELVES - no more manual threshold guessing.
//
// Line sensors: A3 (left), A6 (center), A7 (right)
// Whisker bumpers: pin 3 (left), pin 11 (right)
// (official tutorial uses pin 10 for left - change below if
// your left whisker never registers)
// Onboard D12 button = calibrate/start. D13 LED = status.
//
// ---------------- HOW TO USE (calibration ritual) ----------------
// 1. Power on. LED BLINKS SLOWLY.
// -> Hold the robot so ALL THREE sensors are over BARE FLOOR.
// -> Press the onboard D12 button. (LED flashes fast = floor saved)
// 2. LED BLINKS FAST.
// -> Turn the robot sideways so the tape line runs LEFT-TO-RIGHT
// underneath ALL THREE sensors at once.
// -> Press the D12 button again. (LED goes solid = tape saved)
// 3. LED SOLID = ready. Put the robot on the track (line under the
// center sensor, robot pointing along the line). It starts after
// 2 seconds.
// ------------------------------------------------------------------
#include <RedBot.h>
RedBotMotors motors;
RedBotSensor left = RedBotSensor(A3);
RedBotSensor center = RedBotSensor(A6);
RedBotSensor right = RedBotSensor(A7);
RedBotBumper leftBumper = RedBotBumper(3); // tutorial uses 10; try it
RedBotBumper rightBumper = RedBotBumper(11); // if 3 never triggers
#define BUTTON_PIN 12
#define LED_PIN 13
const int SPEED = 100; // cruising speed (below ~75 may not have
// enough torque to start moving)
const int TRIM = 7; // left-motor correction for drift
const int TURN_90 = 400; // ms of pivot for ~90 degrees
void driveStraight(int speed) {
motors.leftMotor(-(speed - TRIM));
motors.rightMotor(speed);
}
// LED blink helper
void blinkLED(int times, int ms) {
for (int i = 0; i < times; i++) {
digitalWrite(LED_PIN, HIGH); delay(ms);
digitalWrite(LED_PIN, LOW); delay(ms);
}
}
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
// ---- STEP 1: calibrate the FLOOR (background) ----
// Slow blink while waiting: put all three sensors over bare floor,
// then press the button.
while (digitalRead(BUTTON_PIN) == HIGH) {
digitalWrite(LED_PIN, HIGH); delay(400);
digitalWrite(LED_PIN, LOW); delay(400);
}
left.setBGLevel(); // sensors memorize what "floor" looks like
center.setBGLevel();
right.setBGLevel();
blinkLED(6, 60); // fast flash = floor saved
delay(300);
// ---- STEP 2: calibrate the TAPE (line) ----
// Fast blink while waiting: lay the tape line sideways under all
// three sensors, then press the button.
while (digitalRead(BUTTON_PIN) == HIGH) {
digitalWrite(LED_PIN, HIGH); delay(120);
digitalWrite(LED_PIN, LOW); delay(120);
}
left.setDetectLevel(); // sensors memorize what "tape" looks like
center.setDetectLevel();
right.setDetectLevel();
digitalWrite(LED_PIN, HIGH); // solid = calibrated and ready
delay(2000); // time to place it on the track
}
void loop() {
// check() = true when a sensor sees the tape (per its own calibration)
bool lOn = left.check();
bool cOn = center.check();
bool rOn = right.check();
// Debug (Serial Monitor, 9600 baud)
Serial.print("L:"); Serial.print(left.read());
Serial.print(lOn ? "*" : " ");
Serial.print(" C:"); Serial.print(center.read());
Serial.print(cOn ? "*" : " ");
Serial.print(" R:"); Serial.print(right.read());
Serial.print(rOn ? "*" : " ");
Serial.print(" LB:"); Serial.print(leftBumper.read());
Serial.print(" RB:"); Serial.println(rightBumper.read());
// --- 1. Obstacle check (whisker pressed = LOW) ---
bool hitL = (leftBumper.read() == LOW);
bool hitR = (rightBumper.read() == LOW);
if (hitL && hitR) {
motors.brake(); // head-on: stop hard, back up, 180
delay(300);
driveStraight(-SPEED);
delay(700);
motors.pivot(SPEED);
delay(TURN_90 * 2);
driveStraight(SPEED);
delay(800);
return;
}
else if (hitL || hitR) {
driveStraight(-SPEED); // back away
delay(700);
if (hitL) motors.pivot(SPEED); // left hit -> 90 right
else motors.pivot(-SPEED); // right hit -> 90 left
delay(TURN_90);
driveStraight(SPEED); // drive off in the new direction
delay(800);
return;
}
// --- 2. Line following: move ONLY when a sensor sees the tape ---
if (cOn) {
driveStraight(SPEED); // tape under center -> straight
}
else if (lOn) {
motors.pivot(-SPEED); // tape drifted left -> turn left
}
else if (rOn) {
motors.pivot(SPEED); // tape drifted right -> turn right
}
else {
motors.brake(); // no tape anywhere -> hard stop
}
}