Buggy Cam is a device that looks like a small toy car where a camera is mounted to take photos & videos. In this post, I will share How did I make my own homemade Buggy Cam ESP8266 Arduino DIY for just $10. You can also say it ” WiFi Controlled Moving CCTV Camera”.

What is Buggy Cam
Buggy cam is a remote-controlled car where a powerful camera is mounted to take photos & videos. Buggy cam is widely used in cricket matches where the small camera car is in the boundary line & moves towards the cricket call when it reaches the boundary line.

This Buggy Cam is also used in wildlife photography to take animal close shots where any human can reach like a close to tiger or lion.
Buggy Cam ESP8266 Arduino DIY
When I watched this camera in a cricket match, it made me curious to make my own Buggy Cam ESP8266 Arduino DIY. So I took some cheap hardware from my home store room & took my Wemos D1 (ESP8266) to make this project happen.
Hardware Required
The following components are required to make Buggy Cam which costs me approx $10.
All the products I bought from the local offline shops. This costs cheap. If you wish to buy online links are given, but the price will be high.
- Plastic Box
- Thin Iron Sheet
- 4V 1A Lead- Acid Battery (2 pcs)
- 18650 Li-Ion Battery
- Power Bank Module
- L293D IC
- IC Base
- Female Header
- Zero PCB
- 5mm PlyWood 30cm by 15 cm
- 2-inch caster wheel (2pcs)
- Dual shaft BO motor with wheel (2pcs)
- Tripod Mobile Mount
- Screw nut
- Any Spare Android Mobile
How to make Buggy Cam at home
Attach wheels
First, attach 4 wheels in the plywood board. In the front caster wheels will be and in back Bo motor.

Electronics Components case
In the plastic small box, I have separated sectors for battery Wemos D1 and other circuits. I used some metal sheets & hot glue to make sectors.

Connect Circuits
Connect all the components according to the circuit diagram given below.

After Connecting all the Components final Buggy Cam will be looks like this.

So Now just we have to connect any old Android Mobile and it is done.
Circuit Diagram for Buggy Cam ESP8266 Arduino

Web UI Design for Buggy Cam ESP8266 Arduino
To Control Buggy Cam we have to design an HTML web page. Below the source code given. If you wish to change anything you can. This web UI is designed in such a way it will support android Mobile & desktop both.
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | <!DOCTYPE html> <html> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta charset="utf-8"/> <meta name="description" content="Wi-Fi Controlled Moving CCTV Camera powered by ESP8266 NodeMCU made by by Som Tips" /> <title>Wi-Fi Controlled Moving CCTV Camera Car using NodeMCU by Som Tips</title> <head> <style> body {background-color: rgb(255, 255, 255); float:center;text-align: center;-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;} h1 {color: blue;} h2 {color: rgb(105, 0, 0);} h3 {color: rgb(143, 117, 0);} div{margin: 0 auto;} button {text-align: center;border-radius: 15px;font-size: 20px;color: white;padding: 10px;} #forward { width: 0; height: 0; margin-bottom: 5px; border-left: 25px solid transparent; border-right: 25px solid transparent; border-bottom: 50px solid rgb(255, 30, 30); } #carleft { display:inline-block; margin-right:25px ; width: 0; height: 0; border-top: 25px solid transparent; border-right: 50px solid rgb(68, 0, 114); border-bottom: 25px solid transparent; } #carright { display:inline-block; margin-left: 25px; width: 0; height: 0; border-top: 25px solid transparent; border-left: 50px solid rgb(68, 0, 114); border-bottom: 25px solid transparent; } #backward { margin-top:4px; width: 0; height: 0; border-left: 25px solid transparent; border-right: 25px solid transparent; border-top: 50px solid rgb(0, 0, 0); } </style> </head> <body> <h1>Moving CCTV Camera</h1> <div id= "opencamera"> <button style="background-color: green">Open Camera</button> </div> <h2>Car Control</h2> <div id ="forward" ></div> <div id ="carleft" ></div> <div id ="carright"></div> <div id ="backward"></div> <h2>Camera Control</h2> <h3>Camera Switch</h3> <button id ="frontcam" style="background-color: #9966ff">Front Cam</button> <button id ="backcam" style="background-color: #ff4d4d">Back Cam</button> <h3>Front LED</h3> <button id ="frontflashon" style="background-color: #540099">On</button> <button id ="frontflashoff" style="background-color: #006779">Off</button> <h3>Back LED</h3> <button id ="backflashon" style="background-color: #540099">On</button> <button id ="backflashoff" style="background-color: #006779">Off</button> <br><br> <a href="http://192.168.0.50:2222/browserfs.html" target="_blank"><button style="background-color: rgb(0, 0, 0)">Full Screen Camera</button></a> <div id ="settings"> <br><br> <button style="background-color: rgb(197, 105, 0)">Camera Settings</button> </div> <br><br> <footer>©Som Tips</footer> <script> document.getElementById("forward").addEventListener("mousedown", forward ); document.getElementById("forward").addEventListener("touchstart", forward ); document.getElementById("backward").addEventListener("mousedown", backward ); document.getElementById("backward").addEventListener("touchstart", backward ); document.getElementById("forward").addEventListener("mouseup", stop ); document.getElementById("forward").addEventListener("touchend", stop ); document.getElementById("backward").addEventListener("mouseup", stop ); document.getElementById("backward").addEventListener("touchend", stop ); document.getElementById("carleft").addEventListener("mousedown", carleft ); document.getElementById("carleft").addEventListener("touchstart", carleft ); document.getElementById("carright").addEventListener("mousedown", carright ); document.getElementById("carleft").addEventListener("mouseup", stop ); document.getElementById("carleft").addEventListener("touchend", stop ); document.getElementById("carright").addEventListener("mouseup", stop ); document.getElementById("carright").addEventListener("touchend", stop ); document.getElementById("carright").addEventListener("touchstart", carright ); document.getElementById("settings").addEventListener("mouseup", settings ); document.getElementById("settings").addEventListener("touchend", settings ); document.getElementById("opencamera").addEventListener("mouseup", opencamera ); document.getElementById("opencamera").addEventListener("touchend", opencamera ); document.getElementById("frontcam").addEventListener("mouseup", frontcam ); document.getElementById("frontcam").addEventListener("touchend", frontcam ); document.getElementById("backcam").addEventListener("mouseup", backcam ); document.getElementById("backcam").addEventListener("touchend", backcam); document.getElementById("frontflashon").addEventListener("mouseup", frontflashon ); document.getElementById("frontflashon").addEventListener("touchend", frontflashon); document.getElementById("frontflashoff").addEventListener("mouseup", frontflashoff ); document.getElementById("frontflashoff").addEventListener("touchend", frontflashoff); document.getElementById("backflashon").addEventListener("mouseup", backflashon ); document.getElementById("backflashon").addEventListener("touchend", backflashon ); document.getElementById("backflashoff").addEventListener("mouseup", backflashoff ); document.getElementById("backflashoff").addEventListener("touchend", backflashoff ); function opencamera() { document.getElementById("opencamera").innerHTML = ' <iframe src="http://192.168.0.50:2222/browserfs.html" frameborder="0" height="175px" scrolling="no"> </iframe>'; } function settings() { document.getElementById("settings").innerHTML = ' <iframe src="http://192.168.0.50:2222/settings_window.html" width="80%" height="300px" frameborder="0"> </iframe>'; } function forward() { var xhr = new XMLHttpRequest(); xhr.open('GET', "forward", true); xhr.send(); } function backward() { var xhr = new XMLHttpRequest(); xhr.open('GET', "backward", true); xhr.send(); } function stop() { var xhr = new XMLHttpRequest(); xhr.open('GET', "stop", true); xhr.send(); } function carleft() { var xhr = new XMLHttpRequest(); xhr.open('GET', "carleft", true); xhr.send(); } function carright() { var xhr = new XMLHttpRequest(); xhr.open('GET', "carright", true); xhr.send(); } function left() { var xhr = new XMLHttpRequest(); xhr.open('GET', "left", true); xhr.send(); } function right() { var xhr = new XMLHttpRequest(); xhr.open('GET', "right", true); xhr.send(); } function frontcam() { var xhr = new XMLHttpRequest(); xhr.open('GET', "http://192.168.0.50:2222/settings/ffc?set=on", true); xhr.send(); } function backcam() { var xhr = new XMLHttpRequest(); xhr.open('GET', "http://192.168.0.50:2222/settings/ffc?set=off", true); xhr.send(); } function frontflashon() { var xhr = new XMLHttpRequest(); xhr.open('GET', "http://192.168.0.50:2222/enabletorch", true); xhr.send(); } function frontflashoff() { var xhr = new XMLHttpRequest(); xhr.open('GET', "http://192.168.0.50:2222/disabletorch", true); xhr.send(); } function backflashon() { var xhr = new XMLHttpRequest(); xhr.open('GET', "backflashon", true); xhr.send(); } function backflashoff() { var xhr = new XMLHttpRequest(); xhr.open('GET', "backflashoff", true); xhr.send(); } </script> </body> </html> |
HTML Page to String for Arduino
To convert any HTML page content to a single String for the Arduino IDE, just go to the following link and & convert.
Static IP Settings for Buggy Cam
To use this Buggy Cam in an efficient way, we have to make the device IP Static. To make any Android device IP static, we have to go to advanced settings during Wi-Fi Connect.
To make ESP8266 based Board IP static, we can do it inside Arduino code or from the Wi-Fi Router admin panel. Here I have set the Static IP from my Router settings under DHCP.

If you wish to change the IP or connect with Mobile Hotspot, you can. Then you have to change the IP address in all the HTML & Arduino code. The IP will start 192.168.43.X for Mobile Hotspot.
Have a look at this post where I said about how to configure static IP in ESP8266 Arduino Code.
IP Address for the ESP8266 & Mobile
ESP8266 IP: 192.168.0.40
Mobile Cam IP: 192.168.0.50
Router IP(Gateway): 192.168.0.1
Install IP WebCam
We have to install IP WebCam App from the play store to use our android mobile as Buggy Cam. You can use the free version. But I used the Pro Version from Google. You know what I mean. 🙂
Set HTTP Port
By default, the IP WebCam app uses port no 8080 for streaming. But I customized Port no 2222 for this project. After all the settings have done start the Camera server and mount it in the car mobile mount socket.
Arduino Code for Buggy Cam ESP8266 Arduino
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 | /*Wi-Fi Controlled Buggy Cam using ESP8266 NodeMCU by Som Tips */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> String html ="<!DOCTYPE html> <html> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> <meta charset=\"utf-8\"/> <meta name=\"description\" content=\"Wi-Fi Controlled Moving CCTV Camera powered by ESP8266 NodeMCU made by by Som Tips\" /> <title>Wi-Fi Controlled Moving CCTV Camera Car using NodeMCU by Som Tips</title> <head> <style> body {background-color: rgb(255, 255, 255); float:center;text-align: center;-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;} h1 {color: blue;} h2 {color: rgb(105, 0, 0);} h3 {color: rgb(143, 117, 0);} div{margin: 0 auto;} button {text-align: center;border-radius: 15px;font-size: 20px;color: white;padding: 10px;} #forward { width: 0; height: 0; margin-bottom: 5px; border-left: 25px solid transparent; border-right: 25px solid transparent; border-bottom: 50px solid rgb(255, 30, 30); } #carleft { display:inline-block; margin-right:25px ; width: 0; height: 0; border-top: 25px solid transparent; border-right: 50px solid rgb(68, 0, 114); border-bottom: 25px solid transparent; } #carright { display:inline-block; margin-left: 25px; width: 0; height: 0; border-top: 25px solid transparent; border-left: 50px solid rgb(68, 0, 114); border-bottom: 25px solid transparent; } #backward { margin-top:4px; width: 0; height: 0; border-left: 25px solid transparent; border-right: 25px solid transparent; border-top: 50px solid rgb(0, 0, 0); } </style> </head> <body> <h1>Moving CCTV Camera</h1> <div id= \"opencamera\"> <button style=\"background-color: green\">Open Camera</button> </div> <h2>Car Control</h2> <div id =\"forward\" ></div> <div id =\"carleft\" ></div> <div id =\"carright\"></div> <div id =\"backward\"></div> <h2>Camera Control</h2> <h3>Camera Switch</h3> <button id =\"frontcam\" style=\"background-color: #9966ff\">Front Cam</button> <button id =\"backcam\" style=\"background-color: #ff4d4d\">Back Cam</button> <h3>Front LED</h3> <button id =\"frontflashon\" style=\"background-color: #540099\">On</button> <button id =\"frontflashoff\" style=\"background-color: #006779\">Off</button> <h3>Back LED</h3> <button id =\"backflashon\" style=\"background-color: #540099\">On</button> <button id =\"backflashoff\" style=\"background-color: #006779\">Off</button> <br><br> <a href=\"http://192.168.0.50:2222/browserfs.html\" target=\"_blank\"><button style=\"background-color: rgb(0, 0, 0)\">Full Screen Camera</button></a> <div id =\"settings\"> <br><br> <button style=\"background-color: rgb(197, 105, 0)\">Camera Settings</button> </div> <br><br> <footer>©Som Tips</footer> <script> document.getElementById(\"forward\").addEventListener(\"mousedown\", forward ); document.getElementById(\"forward\").addEventListener(\"touchstart\", forward ); document.getElementById(\"backward\").addEventListener(\"mousedown\", backward ); document.getElementById(\"backward\").addEventListener(\"touchstart\", backward ); document.getElementById(\"forward\").addEventListener(\"mouseup\", stop ); document.getElementById(\"forward\").addEventListener(\"touchend\", stop ); document.getElementById(\"backward\").addEventListener(\"mouseup\", stop ); document.getElementById(\"backward\").addEventListener(\"touchend\", stop ); document.getElementById(\"carleft\").addEventListener(\"mousedown\", carleft ); document.getElementById(\"carleft\").addEventListener(\"touchstart\", carleft ); document.getElementById(\"carright\").addEventListener(\"mousedown\", carright ); document.getElementById(\"carleft\").addEventListener(\"mouseup\", stop ); document.getElementById(\"carleft\").addEventListener(\"touchend\", stop ); document.getElementById(\"carright\").addEventListener(\"mouseup\", stop ); document.getElementById(\"carright\").addEventListener(\"touchend\", stop ); document.getElementById(\"carright\").addEventListener(\"touchstart\", carright ); document.getElementById(\"settings\").addEventListener(\"mouseup\", settings ); document.getElementById(\"settings\").addEventListener(\"touchend\", settings ); document.getElementById(\"opencamera\").addEventListener(\"mouseup\", opencamera ); document.getElementById(\"opencamera\").addEventListener(\"touchend\", opencamera ); document.getElementById(\"frontcam\").addEventListener(\"mouseup\", frontcam ); document.getElementById(\"frontcam\").addEventListener(\"touchend\", frontcam ); document.getElementById(\"backcam\").addEventListener(\"mouseup\", backcam ); document.getElementById(\"backcam\").addEventListener(\"touchend\", backcam); document.getElementById(\"frontflashon\").addEventListener(\"mouseup\", frontflashon ); document.getElementById(\"frontflashon\").addEventListener(\"touchend\", frontflashon); document.getElementById(\"frontflashoff\").addEventListener(\"mouseup\", frontflashoff ); document.getElementById(\"frontflashoff\").addEventListener(\"touchend\", frontflashoff); document.getElementById(\"backflashon\").addEventListener(\"mouseup\", backflashon ); document.getElementById(\"backflashon\").addEventListener(\"touchend\", backflashon ); document.getElementById(\"backflashoff\").addEventListener(\"mouseup\", backflashoff ); document.getElementById(\"backflashoff\").addEventListener(\"touchend\", backflashoff ); function opencamera() { document.getElementById(\"opencamera\").innerHTML = ' <iframe src=\"http://192.168.0.50:2222/browserfs.html\" frameborder=\"0\" height=\"175px\" scrolling=\"no\"> </iframe>'; } function settings() { document.getElementById(\"settings\").innerHTML = ' <iframe src=\"http://192.168.0.50:2222/settings_window.html\" width=\"80%\" height=\"300px\" frameborder=\"0\"> </iframe>'; } function forward() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"forward\", true); xhr.send(); } function backward() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"backward\", true); xhr.send(); } function stop() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"stop\", true); xhr.send(); } function carleft() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"carleft\", true); xhr.send(); } function carright() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"carright\", true); xhr.send(); } function left() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"left\", true); xhr.send(); } function right() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"right\", true); xhr.send(); } function frontcam() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"http://192.168.0.50:2222/settings/ffc?set=on\", true); xhr.send(); } function backcam() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"http://192.168.0.50:2222/settings/ffc?set=off\", true); xhr.send(); } function frontflashon() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"http://192.168.0.50:2222/enabletorch\", true); xhr.send(); } function frontflashoff() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"http://192.168.0.50:2222/disabletorch\", true); xhr.send(); } function backflashon() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"backflashon\", true); xhr.send(); } function backflashoff() { var xhr = new XMLHttpRequest(); xhr.open('GET', \"backflashoff\", true); xhr.send(); } </script> </body> </html>"; //SSID and Password of your WiFi router const char* ssid = "**"; const char* password = "**"; ESP8266WebServer server(80); //Server on port 80 int led=D8; int i1=D5; int i2=D2; int i3=D3; int i4=D4; int en=D6; void setup(void){ pinMode(i1, OUTPUT); pinMode(i2, OUTPUT); pinMode(i3, OUTPUT); pinMode(i4, OUTPUT); pinMode(en, OUTPUT); pinMode(led, OUTPUT); WiFi.hostname("Moving_CCTV"); WiFi.begin(ssid, password); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); } //If connection successful server.on("/", root); server.on("/forward",forward); server.on("/backward",backward); server.on("/stop",stop); server.on("/carleft", carleft); server.on("/carright", carright); server.on("/backflashon", backflashon); server.on("/backflashoff", backflashoff); server.begin(); digitalWrite(i1, LOW); digitalWrite(i2, LOW); digitalWrite(i3, LOW); digitalWrite(i4, LOW); digitalWrite(en, HIGH); } void loop(void){ server.handleClient(); } void root() { server.send(200, "text/html", html); } void forward() { if(WiFi.RSSI()>-90) { digitalWrite(i1,LOW); digitalWrite(i2,HIGH); digitalWrite(i3,LOW); digitalWrite(i4,HIGH); } server.send(200, "text/html"); } void backward() { digitalWrite(i1,HIGH); digitalWrite(i2,LOW); digitalWrite(i3,HIGH); digitalWrite(i4,LOW); server.send(200, "text/html"); } void stop() { digitalWrite(i1, LOW); digitalWrite(i2, LOW); digitalWrite(i3, LOW); digitalWrite(i4, LOW); server.send(200, "text/html"); } void carleft() { if(WiFi.RSSI()>-90) { digitalWrite(i1, LOW); digitalWrite(i2, LOW); digitalWrite(i3, LOW); digitalWrite(i4, HIGH); } server.send(200, "text/html"); } void carright() { if(WiFi.RSSI()>-90) { digitalWrite(i1, LOW); digitalWrite(i2, HIGH); digitalWrite(i3, LOW); digitalWrite(i4, LOW); } server.send(200, "text/html"); } void backflashon() { digitalWrite(led, HIGH); server.send(200, "text/html"); } void backflashoff() { digitalWrite(led, LOW); server.send(200, "text/html"); } |
Project Outcome of Buggy Cam ESP8266 Arduino
Watch this video to see how did I made this Buggy Cam ESP8266 Arduino DIY & how it is working in real life.
Final Thoughts
In my opinion, this is a very good way to replicate Orginal Buggy Cam by an IoT project in just &10. You can make this in your final year college project. In the project, use the original Robot car chassis & Arduino Camera for a better look.