Make a remote-controlled rover robot using a Raspberry Pi and a webcam.

Wouldn't it be cool to have a Raspberry Pi robot with a camera on board? For this project, I created a Raspberry Pi rover robot that can be controlled using a smartphone with video streaming! Sound interesting? Here's how:

raspberry-pi-cam-bot-featured-1024x883.jpg

Raspberry Pi Rover Robot Concept

A rover is basically a remote-controlled vehicle used to access areas that are inaccessible by humans. NASA's Curiosity is a well-known rover robot. I decided to build my own simple rover using a Raspberry Pi board and a web camera. The USB webcam acts as the controller's eyes, which is typical of rovers (they are not autonomous). We can then control the movements of the robot using buttons on a locally hosted web page where the same video stream from the camera is embedded. I made the robot control more secure by making the Raspberry Pi a Wi-Fi access point. This means only users that know the Wi-Fi ID and password of the robot can view the video stream and control it.

Raspberry Pi Rover Hardware Assembly

I attached the gearbox and wheels assembly to the edge of the first platform and the ball wheel to the other edge:

raspberry-pi-cam-bot-base-1-711x1024.jpg

On that same platform, I attached the battery pack using a velcro strap. I mounted the motor driver here as well:

IMG_1061-169x300.jpg

Here's the motor driver connection (not seen in the schematic: a 1uF capacitor from VCC to GND):

raspberry-pi-cam-bot-motor-driver-1.jpg

Using plastic posts, I attached the second platform and then attached the Raspberry Pi board (with the Wi-Fi dongle plugged).

raspberry-pi-cam-bot-base-4-190x300.jpg

Here's the robot with the USB webcam attached:

raspberry-pi-cam-bot-base-5-152x300.jpg

Configuring the Software

This is one of those projects where the software configuration is much more difficult than the hardware.


Warning: this stuff might be too complex for beginners.

Installing mjpg-streamer and JPEG Library

First, access your Raspberry Pi via SSH. Then paste the following commands:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install cmake libjpeg8-dev

git clone https://github.com/jacksonliam/mjpg-streamer.git

Go to the extracted mjpg-streamer library then run make:

cd mjpg-streamer/mjpg-streamer/mjpg-streamer-experimental

make

sudo make install

Go one folder above then copy the mjpg-streamer folder to /usr/local/bin. Do the same for the plugins output_http.so and input_uvc.so.

sudo cp mjpg_streamer /usr/local/bin
sudo cp output_http.so input_uvc.so /usr/local/lib/

This enables us to stream the video captured by the webcam. But where can we view it? We need a web page hosted by a server for that. To create a server for the Raspberry Pi, download Apache:

sudo apt-get install apache2 -y

This will create a webpage that can be accessible via a browser. To test the video stream:

export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer -i "input_uvc.so -f 10 -r 320x240 -d /dev/video0 -y" -o "output_http.so -w /var/www/html -p 8080"

Open a browser from a computer or smartphone with the same network as your RPi. To view the stream, just go to your Pi's address. For example, my pi is at http://192.168.1.6. I was able to see the video stream on that address.

Configuring the RPi as an Access Point

Now we want to control the robot only when we are connected to it and not anyone else within the network. To do that, we want the RPi to be the access point.


The first step is to give the RPi a static IP address. To do that, edit /etc/dhcpcd.conf and add the following lines:

#static ip address for eth0
interface eth0
static ip_address=192.168.1.6/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
#static ip address for wlan0
interface wlan0
static ip_address=192.168.0.1/24

This will give the RPi a static IP address of 192.168.1.6 when accessed from the ethernet port (for SSH) and 192.168.0.1 from Wi-Fi (which we'll be our access point to control the robot).

Next, we need to install a DHCP server.

sudo apt-get install isc-dhcp-server

Then edit /etc/dhcp/dhcpd.conf:

sudo nano /etc/dhcp/dhcdp.conf

Comment all lines with "option domain-name" on it by adding "#", for example:

#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

Also, remove the "#" sign in front of the "authoritative;" statement like this:

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

Then add the following lines at the bottom:

subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.21 192.168.0.50;
option broadcast-address 192.168.0.255;
option domain-name "local";
option domain-name-servers 8.8.8.8, 8.8.4.4;
}

Exit from nano using CTRL+X and choose "Y".

You may need to restart the DHCP server:

sudo service isc-dhcp-server restart

Next, we need to install the access point daemon:

sudo apt-get install hostapd

Edit the config file of hostapd:

sudo nano /etc/hostapd/hostapd.conf

And add the following lines at the bottom of the file:

interface=wlan0
driver=nl80211
ssid=rover-wifi
hw_mode=g
channel=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=12345678
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Again, close nano and save the file.

This will create an SSID rover-wifi which we can access using the passcode 12345678.

Lastly, we need to tell hostapd the default configuration file. To do that, edit hostapd:

sudo nano /etc/default/hostapd

And remove the # infront of DAEMON_CONF = "/etc/hostapd/hostapd.conf"

Close nano and save the file.

Creating Control Scripts

Alright, now that we've got the camera stream going and made the RPi an access point, we need to have some sort of control mechanism for the robot. We can edit the index.html file where we embed the video stream and add buttons to it to move or stop the robot.


Create a folder in the home directory:

mkdir rover

Next, create a shell script named init.sh with these contents:

#!/bin/sh

echo 17 > /sys/class/gpio/export
echo 27 > /sys/class/gpio/export
echo 22 > /sys/class/gpio/export
echo 23 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio17/direction
echo out > /sys/class/gpio/gpio27/direction
echo out > /sys/class/gpio/gpio22/direction
echo out > /sys/class/gpio/gpio23/direction

These will reserve the pins 17, 27, 22, and 23 for motor control.

Then we need four scripts to make the robot go forward, turn left, turn right, and stop:

fwd.sh:

#!/bin/sh 
echo 1 > /sys/class/gpio/gpio17/value 
echo 0 > /sys/class/gpio/gpio27/value 
echo 1 > /sys/class/gpio/gpio22/value 
echo 0 > /sys/class/gpio/gpio23/value

rwd.sh:

#!/bin/sh

echo 0 > /sys/class/gpio/gpio17/value
echo 1 > /sys/class/gpio/gpio27/value
echo 0 > /sys/class/gpio/gpio22/value
echo 1 > /sys/class/gpio/gpio23/value

ll.sh:

#!/bin/sh

echo 0 > /sys/class/gpio/gpio17/value
echo 1 > /sys/class/gpio/gpio27/value
echo 1 > /sys/class/gpio/gpio22/value
echo 0 > /sys/class/gpio/gpio23/value

rr.sh:

#!/bin/sh

echo 1 > /sys/class/gpio/gpio17/value
echo 0 > /sys/class/gpio/gpio27/value
echo 0 > /sys/class/gpio/gpio22/value
echo 1 > /sys/class/gpio/gpio23/value

stop.sh:

#!/bin/sh

echo 0 > /sys/class/gpio/gpio17/value 
echo 0 > /sys/class/gpio/gpio27/value 
echo 0 > /sys/class/gpio/gpio22/value 
echo 0 > /sys/class/gpio/gpio23/value

Editing the Web Page

We're not done yet! Delete the index.html page where the video was streamed earlier:

sudo rm /var/www/html/index.html

Then create a new index.html file:

sudo nano /var/www/html/index.html

With this as content:

<html>
<head>
<meta charset="UTF-8">
<title>RaspberryPi Camera Robot</title>
<script type="text/javascript">
function button(value) {
var request = false;
if(window.XMLHttpRequest){
request = new XMLHttpRequest();
}else if(window.ActiveXObject){
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
request = new ActiveXObject("Msxml.XMLHTTP");
}
}
//XMLHttpRequest failed
if(!request){
alert("XMLHttpRequest failed...");
return false;
}
//query
var send = 'code=' + value;
request.open('POST','/rover.php',true);
//HTML header
request.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
request.setRequestHeader('Content-Length',send.length);
request.setRequestHeader('Connection','close');
request.send(send);
}
</script>
</head>
<body>
<img src="http://192.168.0.1:8080/?action=stream" />
<br>

<input type="button" value="right" onClick="button('right')">
<input type="button" value="front" onClick="button('front');">
<input type="button" value="back" onClick="button('back');">
<input type="button" value="left" onClick="button('left');">
<input type="button" value="stop" onClick="button('stop');">

</body>
</html>

Close nano and save the file.

We also need a rover.php file that will allow us to issue shell commands from the web page:

<?php 
$code = $_POST['code']; 
switch($code){
case "right": system("sudo /home/pi/rover/rr.sh"); 
break; 
case "front": system("sudo /home/pi/rover/fwd.sh"); 
break; 
case "back": system("sudo /home/pi/rover/rwd.sh"); 
break;
case "left": system("sudo /home/pi/rover/ll.sh"); 
break; 
case "stop": system("sudo /home/pi/rover/stop.sh"); 
break; default: } 
?>

Writing the Stream Script

We need to make a script for the video stream. On the same folder rover we created, create a stream.sh script:

sudo nano stream.sh

Paste this:

#!/bin/sh

PORT="8080"
ID="rover"
PW="1234"
SIZE="320x240"
FRAMERATE="10"

export LD_LIBRARY_PATH=/usr/local/lib
mjpg_streamer -i "input_uvc.so -f $FRAMERATE -r $SIZE -d /dev/video0 -y" -o "output_http.so -w /var/www/html -p $PORT"

And save it.

Making the Scripts Load on Boot

Finally, to make these scripts run as the Raspberry Pi is opened, edit rc.local.

sudo nano /etc/rc.local

Add the following lines below the file:

#RPi Rover
sleep 2
/home/pi/rover/stream.sh &
/home/pi/rover/init.sh

This will run stream.sh and init.sh when the RPi boots up.

All the needed shell scripts, as well as the webpages, are found on my Raspberry Pi rover robot repository. That's it for the software part!

Finished Robot

To start controlling the robot, use a smartphone or laptop and connect to the robot Wi-Fi access point rover-wifi with password 12345678.


Use your favorite browser and open the page http://192.168.0.1. You should see something like this:

Press the buttons and watch the robot move!

Here's the Raspberry Pi rover robot in action:

Roland Pelayo
Professor of electronics engineering -- gone Maker Professional.

Forks

Related Projects