Web Controlled Mobile Home Surveillance

This project is very close to my heart as since I was a child, I used to play with electronics. I used to open them up and desired that one day I would be able to understand it and make things like those. I remember making a torch light when I was a little child but since I didn’t know much about switches, my mother remembers that the torch remained on throughout the night until the battery drained away. I was born to be an engineer but when I graduated from engineering, I learnt nothing. Now 10 years after completing my engineering, I got inspired Aragon style “Become whom you are born to be” and I started to reignite my passion for electronics. I put all my expertise of electronics and robotics which I DIDN’T learn in college and came up with this Arduino and Rapberry Pi powered Web Controlled Home surveillance rover. I have burnt a lot of cash on procuring the components as many were not locally available and little less than equivalent amount on the shipping.10498567_699067163464425_3428803516225232023_o

Components Used

For Body

DFRobotShop Rover Chassis Kitdfrobotshop-rover-chassis-kit-2

This forms the basis of the vehicle. The kit includes Tamiya Twin Motor Gear Box (Kit), Tamiya Track and Wheel Set, DFRobotShop Rover Lexan Plate, Metal Brackets, Mounting hardware and a couple of motors. The problem with these motors are that the optimum voltage required by them is pretty low at around 1-1.5V. So if you drive it continuously at higher voltages, it will spoil the motors. Buy the kit here for USD 39.43.

DFRobotShop Rover Expansion PlateExpansion of rover via lexan plate

This component goes on top of the Chassis Kit and can be used to mount additional hardware. Since there are so many components, it is better to have it although I must say it is expensive. Buy here for USD 20.39.

Brushed DC Motor 6V, 11500rpmbrushed-dc-motor-6v-11500rpm

I used these motors as the Arduino Motor shield is driven by 7.2V (6×1.2V batteries) and thus 6V is closest to it. Also, the motors have the same form factor as the included motors, so it fits perfectly into the Gearbox. Buy here for USD 1.79.

For Brain

Arduino UNOArduino_Uno_-_R3

This component forms the brain of the whole project. This is what controls the speed, direction, brakes, etc. of the rover. Also, this is used to control the Pan Tilt mechanism for the camera. Since I have IR leds mounted up front, it is also used to switch it On and Off. You should be able to procure this item locally as it is very common amongst kids and college students. You can get it online here for around USD 30.

Arduino WiFi ShieldArduino wifi shield official

This is the Official Arduino Wifi Shield which is used to connect the Arduino to the network. It also hosts a webpage via which you can command your Arduino remotely. You might be able to procure this item locally. You can get it online here for around USD 100.

Arduino Motor Shieldarduino-motor-shield-v3

This is the power behind the motors without which you cannot power and control the motors as the current requirement is high and which the Arduino cannot natively provide. It can control 2 independent DC motors. You can get it online here for around USD 30.

For Eyes

Raspberry PiRaspberry Pi in hand

The Raspberry Pi does not play a major role except the eyes of the rover. It hosts a web server on which you can use as a viewfinder. Whenever I buy a Raspberry Pi, it is obligatory for me to install RPi web interface as it is too good. You can get it from here. You should be able to procure the Pi locally for USD 35. I suggest using the Model A as it has lower power requirement and because you won’t require an ethernet port.

 

Raspberry Pi Cameraraspberry-pi-camera-module

I am using a NOIR camera as I want the rover to be able to see in complete darkness using IR leds. You should be able to get it for USD 30.

Dagu Mini Pan and Tilt Kitdagu-mini-pan-and-tilt-kit

This kit is what controls the direction of the camera and the IR leds are mounted on it. You should be able to procure something similar locally. If not, you can get it here for USD 15.

Assembly

I began the assembly with the Tamiya Twin motor gearbox. There are so many components to be put together that you are bound to make mistakes and will have to undo and redo. You can refer to this video if you happen to require help. The gears have to be put in configuration C as we are interested in power rather than speed. Also, because in configuration A and B, the tracks become very tight.tamiya twin motor gearbox

Note: There are other gearboxes available from Tamiya which have different gear ratio options but those gearbox are wider and will not fit the chassis. You will require all custom components if you have to use that.

After assembling the gearbox, it has to be connected to the base plate along with the metal brackets. 2 equal sets of tracks have to made for each side of the rover and you will consume all the pieces of track. While putting the wheels together with the tracks, it is necessary that the wheels are aligned or else the tracks will come off. This completes the body of the rover.

Major work will go into the electronics as not only will it have to be connected properly but also programmed. As far as the electronics are concerned, we have 4 major components 1) Arduino Uno R3, 2) Arduino WiFi shield 3) Arduino motor shield and 4) Raspberry Pi. Arduino is the microcontroller which will control every input and output. A wifi shield is attached to the Arduino to give it Internet capabilities with the Yaler service. The motor shield is for driving 2 motors independently. The Raspberry Pi serves the purpose of a camera and does not have any other purpose. Arduino shields are designed to be stacked but it is not necessary that all of the shields can be stacked with all of the other shields. This is because there are many shields which have fixed pins for communication and it could be possible that these pins are common among many shields. In this case, the communication pins of the wifi shield coincide with the control pins of the motor. To alleviate this issue, only the Arduino and wifi shield were stacked together and the motor shield was kept separate. Arduino uno stacked with wifi shieldSince the control pins on the motor shield are fixed and many of those have already been used by the wifi shield, separate pins have been assigned on the Arduino to control the motor shield. These different pins will still go to the fixed pins of the motor shield using cables. Interesting to note is that the the Analog input pins on the the Arduino Uno can be used as digital outputs, so we have utilised those for mapping with the motor shield. The new mapping done for motor shield is as below

Arduino Pin         Motor shield pin

5                         3   Speed motor A
6                         11 Speed motor B
A0                       12 Direction motor A
A1                       9   Brake motor A
A2                       13 Direction motor B
A3                       8   Brake motor B

Arduino Uno stacked with wifi shield and connected to motor shield

In order for the motor shield to function properly, you need a minimum connections with the base shield. The Vcc and gnd of the motor shield and arduino uno should be connected to each other or else the motors will not work properly. Since there will be many components connected to Vcc and gnd, I have used a piece of perfboard for common Vcc and gnd connections. Also note that I have not connected the Vin together. I am using independent power for the motor shield and the Arduino Uno. This is because when the Vins are connected, the batteries are not able to provide enough power to the motors and the motors are very slow.

Note: The polarities on the input terminal of the motor shield is + and – from right to left but the battery terminal is opposite. I have connected once the battery terminal wrong and the whole circuit got shorted and the battery holder plastic melted due to the heat. Luckily none of the component got damaged.

We have used the Raspberry Pi to form the eye of the project. What good would it be if we are not able to move the Raspberry Pi camera especially in the presence of an Arduino. I have connected a Pan Tilt mechanism to move the camera in different directions. The control pins of the servo motor has been connected to A5 and A6 pins of the Arduino Uno. Since the camera has IR capabilities, I have connected a set of IR Leds upfront so as to be able to see in pitch darkness.Dagu mini pan tilt kit

Following is the web page from which we can control the rover

web page rover control

Sample Video

This is a sample video of the rovers capabilities. The video shows the view from the rover and the inset is the shot of the rover and its movements.

Arduino Code

/*
// 5 pwm a 3
//6 pwm b 11
//A0 dira 12
//A1 br a 9
//A2 dirb 13
//A3 br b 8
f forward
l left
e end
r right
b back
v front
s front low
x front higher
z left
u little left
w up
t little right
y right
o start head lamp
d disable head lamp
*/
#include <SPI.h>
#include <WiFi.h>
#include <Servo.h>
#include <YalerWiFiServer.h>
Servo myServo1;
Servo myServo2;
int angle1 = 82;
int angle2 = 15;
const int DirA = A0; // connected to pin 5 for direction of Motor A
const int DirB = A2; // connected to pin 5 for direction of Motor B
const int SpeedA = 5; // connected to pin 3 for Speed of Motor A
const int SpeedB = 6; // connected to pin 4 for Speed of Motor B
const int BreakA = A1; // connected to pin 9 for Break of Motor A
const int BreakB = A3; // connected to pin 8 for Break of Motor B
int motoraSpeed = 0; // speed of the motor
int motorbSpeed = 0; // speed of the motor

char ssid[] = “********”; // your network SSID (name)
char pass[] = “********”; // your network password
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
//WiFiServer server(80);
YalerWiFiServer server(“try.yaler.net”, 80, “************”);

void setup() {
myServo1.attach(A4);
myServo2.attach(A5);
//Serial.begin(9600); // initialize serial communication
//Setup Channel A
pinMode(DirA, OUTPUT); //Initiates Motor Channel A pin
pinMode(BreakA, OUTPUT); //Initiates Brake Channel A pin

//Setup Channel B
pinMode(DirB, OUTPUT); //Initiates Motor Channel A pin
pinMode(BreakB, OUTPUT); //Initiates Brake Channel A pin
pinMode(2, OUTPUT);

// check for the presence of the shield:
//if (WiFi.status() == WL_NO_SHIELD) {
// Serial.println(“WiFi shield not present”);
//while (true); // don’t continue
//}

//String fv = WiFi.firmwareVersion();
//if ( fv != “1.1.0” )
//Serial.println(“Please upgrade the firmware”);
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
//Serial.print(“Attempting to connect to Network named: “);
//Serial.println(ssid); // print the network name (SSID);

// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
server.begin(); // start the web server on port 80
printWifiStatus(); // you’re connected now, so print out the status
}
void loop() {
WiFiClient client = server.available(); // listen for incoming clients

if (client) { // if you get a client,
//Serial.println(“new client”); // print a message out the serial port
String currentLine = “”; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client’s connected
if (client.available()) { // if there’s bytes to read from the client,
char c = client.read(); // read a byte, then
// Serial.write(c); // print it out the serial monitor
if (c == ‘\n’) { // if the byte is a newline character

// if the current line is blank, you got two newline characters in a row.
// that’s the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what’s coming, then a blank line:
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-type:text/html”);
client.println();

// the content of the HTTP response follows the header:
client.println(“<h1>Rover Control</h1>”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“<input type=submit value=Forward style=width:100px;height:90px onclick=location.href=’/F’>”);
client.print(“<br>”);
client.print(“<br>”);
client.println(“<input type=submit value=Left style=width:92px;height:90px onclick=location.href=’/L’>”);
client.println(“<input type=submit value=Stop style=width:100px;height:90px onclick=location.href=’/E’>”);
client.println(“<input type=submit value=Right style=width:92px;height:90px onclick=location.href=’/R’>”);
client.println(“<br>”);
client.println(“<br>”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.println(“<input type=button value=Backward onmousedown=location.href=’/B’>”);
client.println(“<h1>Camera Control</h1>”);
//client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
// client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
// client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.println(“<input type=button value=Front-Low onmousedown=location.href=’/V’>”);
//client.println(“<input type=button value=Front onmousedown=location.href=’/S’>”);
client.print(“<input type=submit value=Front style=width:100px;height:90px onclick=location.href=’/S’>”);
// client.println(“<br>”);
// client.println(“<br>”);
// client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
// client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
//client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.println(“<input type=button value=Front-Higher onmousedown=location.href=’/X’>”);
client.print(“<br>”);
client.println(“<br>”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.println(“<input type=button value=Left onmousedown=location.href=’/Z’>”);
//client.println(“<input type=button value=Little-Left onmousedown=location.href=’/U’>”);
client.println(“<input type=button value=Up onmousedown=location.href=’/W’>”);
//client.println(“<input type=button value=Little-Right onmousedown=location.href=’/T’>”);
client.println(“<input type=button value=Right onmousedown=location.href=’/Y’>”);
client.println(“<h1>Head Lamp</h1>”);
client.print(“&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”);
client.print(“<input type=submit value=Off style=width:100px;height:90px onclick=location.href=’/D’>”);
client.print(“<input type=submit value=On style=width:100px;height:90px onclick=location.href=’/O’>”);

// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
}
else { // if you got a newline, then clear currentLine:
currentLine = “”;
}
}
else if (c != ‘\r’) { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}

// Check to see if the client request was “GET /H” or “GET /L”:
if (currentLine.endsWith(“GET /F”)) {
digitalWrite(BreakA, HIGH); //Engage the Brake for Channel A
digitalWrite(BreakB, HIGH); //Engage the Brake for Channel B
delay(1000);
//Motor A forward @ full speed
motoraSpeed = 245;
digitalWrite(DirA, LOW); //Establishes forward direction of Channel A
digitalWrite(BreakA, LOW); //Disengage the Brake for Channel A
analogWrite(SpeedA, motoraSpeed); //Spins the motor on Channel A

//Motor B forward @ full speed
motorbSpeed = 255;
digitalWrite(DirB, LOW); //Establishes backward direction of Channel B
digitalWrite(BreakB, LOW); //Disengage the Brake for Channel B
analogWrite(SpeedB, motorbSpeed); //Spins the motor on Channel B
}
if (currentLine.endsWith(“GET /B”)) {

digitalWrite(BreakA, HIGH); //Engage the Brake for Channel A
digitalWrite(BreakB, HIGH); //Engage the Brake for Channel B
delay(1000);
//Motor A backward @ full speed
motoraSpeed = 255;
digitalWrite(DirA, HIGH); //Establishes forward direction of Channel A
digitalWrite(BreakA, LOW); //Disengage the Brake for Channel A
analogWrite(SpeedA, motoraSpeed); //Spins the motor on Channel A

//Motor B backward @ full speed
motorbSpeed = 255;
digitalWrite(DirB, HIGH); //Establishes backward direction of Channel B
digitalWrite(BreakB, LOW); //Disengage the Brake for Channel B
analogWrite(SpeedB, motorbSpeed); //Spins the motor on Channel B
}
if (currentLine.endsWith(“GET /L”)) {

digitalWrite(BreakA, HIGH); //Engage the Brake for Channel A
digitalWrite(BreakB, HIGH); //Engage the Brake for Channel B
delay(1000);
//Motor A backward @ half speed
motoraSpeed = 255;
digitalWrite(DirA, LOW); //Establishes forward direction of Channel A
digitalWrite(BreakA, LOW); //Disengage the Brake for Channel A
analogWrite(SpeedA, motoraSpeed); //Spins the motor on Channel A

//Motor B forward @ full speed
motorbSpeed = 100;
digitalWrite(DirB, LOW); //Establishes forward direction of Channel B
digitalWrite(BreakB, LOW); //Disengage the Brake for Channel B
analogWrite(SpeedB, motorbSpeed); //Spins the motor on Channel B
}
if (currentLine.endsWith(“GET /R”)) {

digitalWrite(BreakA, HIGH); //Engage the Brake for Channel A
digitalWrite(BreakB, HIGH); //Engage the Brake for Channel B
delay(1000);
//Motor A forward @ half speed
motoraSpeed = 100;
digitalWrite(DirA, LOW); //Establishes forward direction of Channel A
digitalWrite(BreakA, LOW); //Disengage the Brake for Channel A
analogWrite(SpeedA, motoraSpeed); //Spins the motor on Channel A

//Motor B backward @ half speed
motorbSpeed = 255;
digitalWrite(DirB, LOW); //Establishes forward direction of Channel B
digitalWrite(BreakB, LOW); //Disengage the Brake for Channel B
analogWrite(SpeedB, motorbSpeed); //Spins the motor on Channel B
}
if (currentLine.endsWith(“GET /E”)) {

//Motor A backward @ full speed
digitalWrite(BreakA, HIGH); //Disengage the Brake for Channel A

//Motor B backward @ full speed
digitalWrite(BreakB, HIGH); //Disengage the Brake for Channel B
}
if (currentLine.endsWith(“GET /V”)) {
//front low
angle1 = 82;
angle2 = 0;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);
}
if (currentLine.endsWith(“GET /S”)) {
//front
angle1 = 82;
angle2 = 15;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);
}
if (currentLine.endsWith(“GET /X”)) {
//front higher
angle1 = 82;
angle2 = 30;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);
}
if (currentLine.endsWith(“GET /W”)) {
//up
angle1 = 82;
angle2 = 90;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);
}
if (currentLine.endsWith(“GET /Y”)) {
//right
angle1 = 0;
angle2 = 15;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);

}
if (currentLine.endsWith(“GET /Z”)) {
//left
angle1 = 180;
angle2 = 15;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);

}
if (currentLine.endsWith(“GET /T”)) {
//little right
angle1 = 45;
angle2 = 0;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);

}
if (currentLine.endsWith(“GET /U”)) {
//little left
angle1 = 135;
angle2 = 0;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);

}
if (currentLine.endsWith(“GET /U”)) {
//little left
angle1 = 135;
angle2 = 0;
myServo1.write(angle1);
// wait for the servo to get there
delay(15);
myServo2.write(angle2);
// wait for the servo to get there
delay(15);

}
if (currentLine.endsWith(“GET /O”)) {
digitalWrite(2, HIGH);
}
if (currentLine.endsWith(“GET /D”)) {
digitalWrite(2, LOW);
}
}
}
// close the connection:
client.stop();
//Serial.println(“client disconnected”);
}
}
void printWifiStatus() {
// print the SSID of the network you’re attached to:
//Serial.print(“SSID: “);
//Serial.println(WiFi.SSID());

// print your WiFi shield’s IP address:
IPAddress ip = WiFi.localIP();
//Serial.print(“IP Address: “);
//Serial.println(ip);

// print the received signal strength:
long rssi = WiFi.RSSI();
//Serial.print(“signal strength (RSSI):”);
//Serial.print(rssi);
//Serial.println(” dBm”);
// print where to go in a browser:
//Serial.print(“To see this page in action, open a browser to http://&#8221;);
//Serial.println(ip);
}

 

 

4 thoughts on “Web Controlled Mobile Home Surveillance

  1. Pingback: Arduino YUN powered Home Surveillance Rover | Baba AweSam

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.