NightCrawler
Introduction & Usage
It's a Wifi controlled spy Robot. It is a drivable device that can be controlled from anywhere using a WiFi connection (If you have wifi connection all over your country you can control it from anywhere😉). it gives live stream is used to view it's surroundings. Users can view and go through tight Unaccessible places and also can investigate dark areas. when the NightCrawler reaches the dark areas Led will blink so user can view the video clearly. It can also be use for Spying, taking pictures, and making films.
Picture of the complete version
Making & Assembling the Structure
The following electronics components are used in this Structure
1)Arduino Uno
2)WiFi Shiled module (ESP8266)
3)H-bridge module (For controlling motor)
4)1 kohm resistors
5)10 kohm resistors
6)5V USB Power bank
7)Jumper wires
8)Led lights
9)Photo resistor
10)ultrasonic sensor
11)buzzer
First design the mechanical structure of the robot, which is easy you can buy the structure from the following link http://www.lankatronics.com/smart-car-chassis.html and can build it easily.
Then the connection of the electronic components, the circuit here uses an Arduino Uno as the main controller, which interfaces with a WiFi Shiled module (ESP8266) for wifi communication. The Arduino controls the DC motors using a H-bridge driving circuit, which is able to control up to two motors, rotating them independently in both directions. Connect the LDR and LED to the circuit to avoid the darkness. The power bank is use to power Arduino and provides 5v Voltage. Connect all the components using jumper wires.
Connected Picture
Explanation of Code
The code uses one serial port for the communication between the Arduino and the WiFi shield Module, and another is for communication between the Arduino and the computer. Once the Arduino Uno only have one serial port, Software Serial library is use to create a secondary port, using digital pins 2 and 3.
During the setup, both serial communications have to be started, and their baudrate defined. Notice that my WiFi module was set to 115200 kbps.
Some Explanation for commands
- AT+RST: Reset WiFi module
- AT+CWMODE: set module to access point
- AT+CWJAP: connect a Wi-Fi network given by its SSID and password
- AT+CIPMUX: set module for multiple connections or single connection
- AT+CIPSERVER: start communication
An auxiliary function is used for sending data , reading and displaying the response on Serial Monitor.
Five possible commands are define (cm1 to cm5). Whenever the Arduino receives one of those commands they are moving forward, moving backward, moving right, moving left and stand by, it enters in one of five possible commands\ and continue in that command until it receives a different command.
Each state defines the signals for motors pins. I use digitalWrite(pin, LOW) when I want to set a pin to 0V and analogWrite(pin, motoSpeed) when I want to turn on a pin. Using analogWrite allowed me to change the speed of the motor, and make the robot move slower.
Notice that the motors work between 3 and 6V.
A html interface is design for the control of the NightCrawler.
An Android smart phone was used to broadcast the live video and audio from the robot to the control interface. You can find the app on Google Play store.(https://play.google.com/store/apps/details?id=com.pas.webcam).
Html Code Explain
The html interface has two divisions, one is for audio and video (from IP Webcam) and the other one is for the five commands.
Audio and video division has a form with a text box and a button. This is used as an input for specifying Webcam IP address. It comes with a standard IP address (192.168.0.5), but the user can enter a different IP which will be there in IP webcam. Video and audio are loaded when we enter the IP address which will show in the serial monitor.
JavaScript is used for dealing with the interface and sending data to the Arduino. Those scripts are coded in different files, and added on html header.
By using the laptop navigation keys you can control the crawler.
Light & Dark Detection
If the NightCrawler goes into dark places you can't see the video clearly because of the lack of light, for that purpose i'm using LDR which detects darkness and turn on the LED. so that you can see the clear vision of the video
Picture of the Circuit
Future Enhancements
Detect obstacles and their distance
Control camera angles through app
Record Streamed video and audio
Arduino Code
//include libraries
#include <SoftwareSerial.h>
SoftwareSerial esp8266(3, 2); //RX pin = 3, TX pin = 2
//definition of variables
#define DEBUG true //show messages between ESP8266 and Arduino in serial port
int state = 5; //define initial state of the robot (5 = stand-by)
//define motor pins
const int motor1Pin1 = 5;
const int motor1Pin2 = 6;
const int motor2Pin1 = 9;
const int motor2Pin2 = 10;
//led blink
int sensepin = 0;
int ledpin = 12;
//define motor speed
int motorSpeed = 150; //motor speed (PWM)
//*****
//SETUP
//*****
void setup()
{
//set pin modes
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(motor2Pin1, OUTPUT);
pinMode(motor2Pin2, OUTPUT);
//start communication
Serial.begin(115200);
esp8266.begin(115200);
sendData("AT+RST\r\n", 2000, DEBUG); //reset module
sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //set station mode
sendData("AT+CWJAP=\"ghost\",\"sam12346\"\r\n", 2000, DEBUG); //connect wi-fi network
delay(5000); //wait for connection
sendData("AT+CIFSR\r\n", 1000, DEBUG); //show IP address
sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); //allow multiple connections
sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); // start web server on port 80
//led blink
// put your setup code here, to run once:
analogReference(DEFAULT); //not necessary
// Serial.begin(9600);
pinMode(ledpin, OUTPUT);
}
//*********
//MAIN LOOP
//*********
void loop()
{
if (esp8266.available()) //verify incoming data
{
if (esp8266.find("+IPD,")) //if there is a message
{
String msg;
esp8266.find("?"); //look for the message
msg = esp8266.readStringUntil(' '); //read whole message
String command = msg.substring(0, 3); //first 3 characters = command
Serial.println(command);
//move forward
if(command == "cm1") {
state = 1;
}
//move backward
if(command == "cm2") {
state = 2;
}
//turn right
if(command == "cm3") {
state = 3;
}
//turn left
if(command == "cm4") {
state = 4;
}
//do nothing
if(command == "cm5") {
state = 5;
}
}
}
//STATE 1: move forward
if (state == 1) {
analogWrite(motor1Pin1, motorSpeed);
digitalWrite(motor1Pin2, LOW);
analogWrite(motor2Pin1, motorSpeed);
digitalWrite(motor2Pin2, LOW);
}
//STATE 2: move backward
if (state == 2) {
digitalWrite(motor1Pin1, LOW);
analogWrite(motor1Pin2, motorSpeed);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor2Pin2, motorSpeed); }
//STATE 3: move right
if (state == 3) {
analogWrite(motor1Pin1, motorSpeed);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor2Pin2, motorSpeed);
}
//STATE 4: move left
if (state == 4) {
digitalWrite(motor1Pin1, LOW);
analogWrite(motor1Pin2, motorSpeed);
analogWrite(motor2Pin1, motorSpeed);
digitalWrite(motor2Pin2, LOW);
}
//STATE 5: do nothing
if (state == 5) {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
digitalWrite(motor2Pin2, LOW);
}
int value = analogRead(sensepin);
value = constrain(value, 20, 250);
int ledlevel = map(value, 50, 250, 255, 0);
analogWrite(ledpin, ledlevel);
}
//*******************
//Auxiliary functions
//*******************
String sendData(String command, const int timeout, boolean debug)
{
String response = "";
esp8266.print(command);
long int time = millis();
while ( (time + timeout) > millis())
{
while (esp8266.available())
{
char c = esp8266.read();
response += c;
}
}
if (debug)
{
Serial.print(response);
}
return response;
}
Html Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="author" content="Igor Fonseca Albuquerque">
<title>Control interface</title>
<script>
$.ajaxSetup({timeout:100});
var latch = false;
function readUrlAV (form) {
TextVar = form.inputbox.value;
VideoVar = "http://"+TextVar+":8080/video";
AudioVar = "http://"+TextVar+":8080/audio.opus";
document.getElementById("video").setAttribute('data', VideoVar);
document.getElementById("audio").setAttribute('data', AudioVar);
}
function testarArduino (form) {
TextVar = myform2.inputbox.value;
ArduinoVar = "http://" + TextVar + ":80";
$.get( ArduinoVar, { "cm3": 7000 }) ;
{Connection: close};
}
document.onkeydown = checkKeyDown;
document.onkeyup = checkKeyUp;
function checkKeyDown(e) {
e = e || window.event;
if (e.keyCode == '38') {
// up arrow
if (latch == false) {
TextVar = myform2.inputbox.value;
ArduinoVar = "http://" + TextVar + ":80";
$.get( ArduinoVar, { "cm1": 1000 }) ;
{Connection: close};
latch = true;
}
}
else if (e.keyCode == '40') {
// down arrow
if (latch == false) {
TextVar = myform2.inputbox.value;
ArduinoVar = "http://" + TextVar + ":80";
$.get( ArduinoVar, { "cm2": 1000 }) ;
{Connection: close};
latch = true;
}
}
else if (e.keyCode == '37') {
// left arrow
if (latch == false) {
TextVar = myform2.inputbox.value;
ArduinoVar = "http://" + TextVar + ":80";
$.get( ArduinoVar, { "cm3": 1000 }) ;
{Connection: close};
latch = true;
}
}
else if (e.keyCode == '39') {
// right arrow
if (latch == false) {
TextVar = myform2.inputbox.value;
ArduinoVar = "http://" + TextVar + ":80";
$.get( ArduinoVar, { "cm4": 1000 }) ;
{Connection: close};
latch = true;
}
}
}
function checkKeyUp(e) {
e = e || window.event;
if ((e.keyCode == '38')||(e.keyCode == '40')||(e.keyCode == '37')||(e.keyCode == '39')) {
// up arrow
setTimeout(doNothing, 200);
}
}
function doNothing(){
TextVar = myform2.inputbox.value;
ArduinoVar = "http://" + TextVar + ":80";
$.get( ArduinoVar, { "cm5": 1000 }) ;
{Connection: close};
latch = false;
}
</script>
</head>
<body>
<div id="main">
<div id="video_and_audio" style="position: absolute; top: 50px; width:25%">
<form name="myform" action="" method="GET">
IP Webcam (IP):
<input type="text" name="inputbox" value="192.168.0.5">
<input type="button" name="button1" value="Load" onClick="readUrlAV(this.form)">
</form>
<object id="video" type="text/html" data="http://192.168.0.5:8080/video"
style="position: absolute; width:100%; height:480px;">
</object>
<object id="audio" type="text/html" data="http://192.168.0.5:8080/audio.opus"
style="position: absolute; width:388px; height:30px; left:8px; top:425px;">
</object>
</div>
<div id="commands" style="position: absolute; top: 50px; left:35%; width:65%">
<form name="myform2" action="" method="GET">
Arduino IP Address:
<input type="text" name="inputbox" Value="192.168.0.5">
<input type="button" name="button3" Value="Test" onClick="testarArduino(this.form)">
</form>
<img src="images/keyboard.png" style="margin-left:100px; margin-top:50px;">
<h4> Press and hold keyboard arrow keys to move the robot </h4>
</div>
</div>
</body>
</html>




This article is giving a clear explanation of 'NightCrawler'. Good work! Keep it up
ReplyDelete