I’ve finished my obstacle avoiding robot project.

Basically its an ATmega328p microcontroller that uses an HC-SR04 ultrasonic sensor to detect obstacles.

The head moves using an SG-90 servo and a L293D dual H-bridge drives the two motors, using a library I’ve written and put on GitHub.

The whole robot is powered by two 3.7v 18650 Li-Ion batteries with a DC/DC converter that drops it to 6v for the motors and a diode (and smoothing cap) to drop it further to 5v for the microcontroller and servo.

My next robot will be remote controlled using Bluetooth or Wifi. I may use an old Android phone for camera/GPS, and maybe some LED’s or laser pointers.

The code is below:

// include libraries
#include <Servo.h>
#include <DCMotor.h>

// setup servo
#define SERVORIGHT   50
#define SERVOCENTRE 100
#define SERVOLEFT   150
#define SERVOPIN      4
Servo servo;

// setup sensor
#define TRIGPIN 2
#define ECHOPIN 3

// setup motors - en1, m1-i1, m1-i2, m1-speed, en2, m2-i1, m2-i2, m2-speed
DCMotor motors(6,7,8,255,9,10,11,255);

int ping()
{
    // pause for 50ms between scans
    delay(50);

    // send ping
    digitalWrite(TRIGPIN, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIGPIN, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIGPIN, LOW);

    // read echo
    long duration = pulseIn(ECHOPIN, HIGH);

    // convert distance to cm
    unsigned int centimetres = int(duration / 2 / 29.1);

    return centimetres;
}

char scan()
{
    // ping times in microseconds
    unsigned int left_scan, centre_scan, right_scan;
    char choice;

    // scan left
    servo.write(SERVOLEFT);
    delay(300);
    left_scan = ping();

    // scan right
    servo.write(SERVORIGHT);
    delay(600);
    right_scan = ping();

    // scan straight ahead
    servo.write(SERVOCENTRE);
    delay(300);
    centre_scan = ping();

    if (left_scan>right_scan && left_scan>centre_scan)
    {
        choice = 'l';
    }
    else if (right_scan>left_scan && right_scan>centre_scan)
    {
        choice = 'r';
    }
    else
    {
        choice = 'c';
    }

    return choice;
}

void setup()
{
    // set the servo data pin
    servo.attach(SERVOPIN);

    // set the trig pin to output (send sound waves)
    pinMode(TRIGPIN, OUTPUT);

    // set the echo pin to input (receive sound waves)
    pinMode(ECHOPIN, INPUT);
}

void loop()
{
    // get distance from obstacle straight ahead
    unsigned int distance = ping();

    if (distance < 50 && distance > 0)
    {
        if (distance < 10)
        {
            // turn around
            motors.backward();
            delay(300);
            motors.left();
            delay(500);
        }
        else
        {
            // stop both motors
            motors.stop();

            // scan for obstacles
            char turn_direction = scan();

            // turn left/right or ignore and go straight
            if (turn_direction == 'l')
            {
                motors.left();
                delay(200);
            }
            else if (turn_direction == 'r')
            {
                motors.right();
                delay(200);
            }
        }
    }
    else
    {
        // no obstacle, keep going forward
        motors.forward();
    }
}