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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 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();
}
}