The parts for this robot are an Arduino uno, a breadboard, IR Sensor (OPB706A), motor driver, switch, 2 gear motors, and distance sensor. (*Everything is from a SparkFun kit expect the IR sensor)
#include <Wire.h>
#include <SparkFun_MMA8452Q.h>
const int leftIR_PIN = A0; // Sensor1 output voltage
const int rightIR_PIN = A1; // Sensor2 output voltage
const int AIN1 = 13; // Control pin 1 on the motor driver for the right motor
const int AIN2 = 12; // Control pin 2 on the motor driver for the right motor
const int PWMA = 11; // Speed control pin on the motor driver for the right motor
const int PWMB = 10; // Speed control pin on the motor driver for the left motor
const int BIN2 = 9; // Control pin 2 on the motor driver for the left motor
const int BIN1 = 8; // Control pin 1 on the motor driver for the left motor
const int trigPin = 6;
const int echoPin = 5;
const int switchPin = 7; // Switch to turn the robot on and off
const int backupTime = 300; // Amount of time that the robot will back up when it senses an object
const int turnTime = 200; // Amount that the robot will turn once it has backed up
const int baseSpeed = 150; // Base speed for both motors
const float kp = 50; // Proportional gain for line-following
const int minSpeed = 100; // Minimum motor speed
const int maxSpeed = 255; // Maximum motor speed
const float leftThreshold = 4; // Adjust these values according to your setup
const float rightThreshold = 4; // Adjust these values according to your setup
void setup() {
pinMode(leftIR_PIN, INPUT);
pinMode(rightIR_PIN, INPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(switchPin, INPUT_PULLUP);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
Serial.begin(9600);
Serial.println("Hello World!");
}
void loop() {
int proximityADC_left = analogRead(leftIR_PIN);
int proximityADC_right = analogRead(rightIR_PIN);
float proximityV_left = (float)proximityADC_left * 5.0 / 1023.0;
float proximityV_right = (float)proximityADC_right * 5.0 / 1023.0;
float distance = getDistance();
float error = proximityV_left - proximityV_right;
int leftSpeed = baseSpeed - kp * error;
int rightSpeed = baseSpeed + kp * error;
leftSpeed = constrain(leftSpeed, minSpeed, maxSpeed);
rightSpeed = constrain(rightSpeed, minSpeed, maxSpeed);
if (digitalRead(switchPin) == LOW) {
if (distance < 3) { // If an object is detected
rightMotor(-255); // Back up
leftMotor(-255);
delay(backupTime);
rightMotor(255); // Turn away from obstacle
leftMotor(-255);
delay(turnTime);
} else { // If no obstacle is detected, line-follow
if (proximityV_left < leftThreshold && proximityV_right < rightThreshold ) { // Both sensors detect the line
// Code to follow the line
} else if (proximityV_left < leftThreshold && proximityV_right > rightThreshold) { // Left sensor detects the line
// Code to adjust robot's direction towards the right
} else if (proximityV_left > leftThreshold && proximityV_right < rightThreshold) { // Right sensor detects the line
// Code to adjust robot's direction towards the left
} else { // No sensor detects the line
// Code to handle this situation
}
}
} else {
leftMotor(0);
rightMotor(0);
}
delay(10);
}
void rightMotor(int motorSpeed) {
if (motorSpeed > 0) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
} else if (motorSpeed < 0) {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
} else {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
}
analogWrite(PWMA, abs(motorSpeed));
}
void leftMotor(int motorSpeed) {
if (motorSpeed > 0) {
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
} else if (motorSpeed < 0) {
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
} else {
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
}
analogWrite(PWMB, abs(motorSpeed));
}
float getDistance() {
float echoTime;
float calculatedDistance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
echoTime = pulseIn(echoPin, HIGH);
calculatedDistance = echoTime / 148.0;
return calculatedDistance;
}