Camera Robot using Raspberry Pi | Web Controlled surveillance robot
With chassis and motors in place, its time to add some more hardware to our Raspberry Pi robot. To make things interesting, we will create a web based mechanism (Web Control Panel) to control the robot and associated hardware through a browser. This articles covers the details required to build a camera robot capable of streaming real-time video to a remote Web control panel running on a browser of laptop or a smart phone.
Truly remarkable thing about Raspberry Pi is that it can run complex programs just like a PC with modern processor and at the same time it can interact with external hardware through GPIO pins like a microcontroller.
Making use of these capabilities, in this Camera Robot project, Raspberry Pi is has been tasked to perform following:-
- Stream a video (Python script)
- render a Web GUI (PHP, HTML, Javascript)
- Interface with transistor switching circuit for lighting 12 V high brightness LEDs
The robot is built using Raspberry Pi 3A+ which has a dedicated port to connect the Pi Camera module. The hardware interfaced with Raspberry Pi in this project is as follows:-
- 12 V LEDs - 03
- Pi Camera - 01
- BC 557 transistors & 100 ohm resistor
Hardware connections
The hardware connections covered in previous article have been augmented to cater for additional hardware.Three additional GPIO pins are used in this project to interface Raspberry Pi with Transistor Switching Circuit for lighting 12 V LEDs. Since Raspberry Pi operates at 5V, it cannot drive 12 V LEDs directly through its GPIO pins. The Switching Circuit is made using NPN Transistor BC547 and can be interfaced with Raspberry Pi as shown in diagrams below.
GPIO pins 17,18 and 27 are interfaced with the Transistor Switching Circuit to toggle the 12 V LEDs.
A quick recap of other connections is as follows:-
- GPIO 8,11 & 20 control motor 1.
- GPIO 14,15 & 21 control motor 2.
- A two port battery bank provides power to Raspberry Pi and MT 3608 simultaneously.
- MT 3608 converts the 5 V input supply to 12 V required to run the motors and light up the LEDs.
As shown in the diagram above, the base of the transistors is connected to the GPIO pins. By simply making a GPIO pin high or low, we can switch the respective transistor. The actual arrangement of the components on a general purpose PCB is shown below
The 12 V high brightness LEDs used in this Camera Robot project are shown below.
|
Testing the connections
Create a blank file, name it 'test.py' and copy the following Python code. Run the file using terminal. You should the LEDs blinking at one second interval.
import RPi.GPIO as GPIO
from time import sleep # import sleep function from time module
GPIO.setmode(GPIO.BCM) # choose BCM numbering scheme
GPIO.setup(18, GPIO.OUT)# set GPIO 18 as output pin
GPIO.setup(27, GPIO.OUT)# set GPIO 27 as output pin
GPIO.setup(17, GPIO.OUT)# set GPIO 17 as output pin
while True:
GPIO.output(18, True)
GPIO.output(27, True)
GPIO.output(17, True)
sleep(1)
GPIO.output(18, False)
GPIO.output(27, False)
GPIO.output(17, False)
sleep(1)
Camera Setup and Testing
The main ingredient of our Camera Robot is Pi Camera module. Attach the Pi Camera's ribbon cable to the camera port of Raspberry Pi.
To get the camera working you need to first make sure that it is enabled. Use the command "sudo raspi-config" in terminal and go to "interfacing option" to enable the camera.
You can test the camera from terminal through command "raspistill -o image.jpg". Otherwise you can run the following Python code to capture an image.
from picamera import PiCamera
from time import sleep
camera = PiCamera()
camera.resolution = (2592, 1944)
camera.annotate_text_size = 100
camera.annotate_text = "Hello world !!!"
camera.rotation =180
camera.start_preview()
sleep(2)
camera.capture('/home/pi/Downloads/image1.jpg')
camera.stop_preview()
Video Streaming using Pi Camera
The Camera Robot is required to generate a live camera feed which could be monitored through a browser. I searched for an open source solution and found one such solution under advance recipes of the Picamera documentation. The script provided in the document uses Python’s built-in http.server
module to make a simple video streaming server. Once the script is running, the video stream generated by the camera can be accessed by visiting "http://ip-address-of-raspberry-pi:8000"
using a browser on a PC or mobile.
The file 'cam_server.py', placed at 'earthrover > camera_lights' contains the video streaming Python code. This is an off the shelf solution and does not require any coding effort from your side. All we need to do is embedd the html page "http://ip-address-of-raspberry-pi:8000"
in our Web Control Panel and create controls to start and stop the video stream. Next section covers these details.
Web Control Panel of Camera Robot
Web Technologies such as PHP, HTML & Javascript have been used to create the Web Control Panel of our Camera Robot. Download the repository from Github containing the code for this project. You need to have a Webserver running on the Raspberry Pi to deploy this code and access the Web Control Panel. The GUI shown below is generated through 'index.php' file inside the 'earthrover' folder.
Observe the various sections of Web Control Panel and the files associated with respective sections.
HTML5 provides an easy way to embed a web page inside another web page using <iframe> tag. The sections 1 and 2 are simply embedded in 'index.php' file using the following code.
$host=$_SERVER['SERVER_ADDR'];//get the sever address. (In my case it is '192.168.1.20')
$path=rtrim(dirname($_SERVER["PHP_SELF"]), "/\\"); //get the name of the directory where this file resides. (In this case it is 'earthrover')
//URL of remote.php file i.e. http://192.168.1.20/earthrover/remote.php
$link_remote= 'http://'.$host.$path.'/'."remote.php";
//URL of web page generated by 'cam_server.py' i.e. http://192.168.1.20:8000
$link_vid= 'http://'.$host.':8000';
//display the above 02 URLs in this web page
echo"
<iframe src='$link_vid' id='box_video'></iframe>
<iframe src= '$link_remote' id='box_remote'></iframe>
";
Section 1 : Display Video Streaming output of Raspberry Pi Camera
The web page with video streaming output is generated by the file 'cam_server.py'. As long as this file is running in the background, the video streaming remains available on a web page. This web page is embedded in the Web Control Panel using <iframe> tag as shown in code above.
Section 2: Direction and Speed Controls of Camera Robot
The web page containing the direction and speed controls is served through the file 'remote.php'. The functionality of this file is covered in previous article. Again, we can simply embed this page it in our Control Panel using <iframe> tag as shown in code above.
Section 3: Camera ON/OFF controls
This section has buttons 'ON' and 'OFF' to control the camera feed. They are created using <input> tag inside 'index.php' file using following code. Notice that the 'onclick' event of these buttons call the same javascript function 'camera()'. However, the parameter passed to the function is different. This function is defined in a javascript file 'cp.js' placed inside 'earthrover/js' directory.
echo"<input id='cam_on' type='submit' onclick=camera('on'); value='ON'/>";
echo"<input id='cam_off' type='submit' onclick=camera('off'); value='OFF'/>";
The 'camera()' function receives parameter 'on' or 'off' based on the button pressed. It simply passes this value as a POST parameter to a PHP file 'ajax_camera.php' in the server via background ajax call as shown in the code below.
function camera(status)
{
//alert(status);
$.post("camera_lights/ajax_camera.php",
{
camera:status
}
);
sleep(1000);
location.reload();
}
The 'ajax_camera.php' receives the 'on' or 'off' value and executes OS command to either launch or kill the Python script 'cam_server.py'.
<?php
$cam=$_POST["camera"];
//launch the Python script 'cam_server.py'
if($cam=="on"){
os.system("sudo python3 /var/www/html/earthrover/camera_lights/cam_server.py &");
}
// kill the Python script 'cam_server.py'
if($cam=="off"){
os.system("sudo pkill -f cam_server.py");
}
?>
In order to launch or kill a Python script from a PHP file, we need to edit and modify the 'sudoers' file in Raspberry Pi. This file can be edited by issuing 'sudo nano /etc/sudoers' command from terminal. Paste following lines at the end of file and save it to achieve the desired goal.
pi ALL=(ALL) NOPASSWD: ALL
www-data ALL=(ALL) NOPASSWD: ALL
Section 4: Lights ON/OFF controls
This section also has two buttons. One button can toggle the LED Light of camera and other can toggle the front LED lights of the robot. These buttons are also created using <input> tag inside 'index.php' file as shown below. The 'onclick' event of these buttons also call a common javascript function 'toggle_light()' but with different parameters (id of the button). This function is also defined in a javascript file 'cp.js' placed inside 'earthrover/js' directory.
echo"<input id='camlight' style='background-color:lightgray' type='submit' onclick=toggle_light('camlight'); value='OFF'/>";
echo"<input id='headlight' style='background-color:lightgray' type='submit' onclick=toggle_light('headlight'); value='OFF'/>";
The 'toggle_light()' function first toggles the caption & color of the respective button and then calls 'set_lights()' function with button id and its desired state as parameters. The 'set_lights()' function simply passes these two parameters to a PHP file 'ajax_lights.php' in the server via background ajax call as shown in the code below.
function toggle_light(id)
{
button_caption=document.getElementById(id).value;
if(button_caption=="OFF"){
document.getElementById(id).value="ON";
document.getElementById(id).style.backgroundColor="#66ff66";
set_lights(id,1);
}
if(button_caption=="ON"){
document.getElementById(id).value="OFF";
document.getElementById(id).style.backgroundColor="lightgray";
set_lights(id,0);
}
}
function set_lights(id,state)
{
$.post("camera_lights/ajax_lights.php",
{
light_id: id,
state: state
}
);
}
The 'ajax_camera.php' file receives the two parameters (button id and its desired state) via $_POST super global variable. Using these two parameters, it constructs appropriate command to set the corresponding GPIO pins high or low as shown below.
<?php
include_once '../vars.php';
$light_id=$_POST["light_id"];
$state=$_POST["state"];
if ($light_id=="camlight"){
system("gpio -g write $cameralight $state");
}
if ($light_id=="headlight"){
system("gpio -g write $headlight_right $state");
system("gpio -g write $headlight_left $state");
}
echo"$light_id, $state";
?>
Hopefully, the details covered in this article are adequate to build a simple Web Controlled Camera Robot.
Comments
The picamera is replaced by libcamera and it seems like the camera is not responding. I don't know if I'm the only one experiencing the unresponsiveness of the camera due to the upgrade. Is there any way to make it functional again?
Yes. The support for Picamera has been removed from Raspberry Pi OS. As of now, the project can be run on previous OS (buster).. which can be downloaded from here
https://downloads.raspberrypi.org/raspios_armhf/images/raspios_armhf-2021-05-28/
You need a different python script to use a USB cam. You can install OpenCV and use any USB camera or Picamera.