top of page
Search

Raspberry Pi Powered Internet Controlled RC Car

While browsing one of my favorite sites Instructables for a reason to use my Arduino Uno, I came across this tutorial for an Internet controlled RC car. I really liked the idea repurposing a cheap children’s toy to be Internet accessible while also having a live FPV video feed. My objectives for the project were as follows


Control the RC car from anywhere on the Internet (see previous blog post)

Web page that includes video feed and directional button controls

RC car range limited to home wifi network


Bonus Points:

Make webpage password protected

Manage user sessions so single user has control at a time

Create Ad Hoc connection to RC car so not limited to established Wifi network (for locally controlling only)


The Arduino Uno by its own does not include an Ethernet port or wireless card so an additional “shield” must be purchased in order to give the device network accessible. In the tutorial, they added an Ethernet shield to the Uno which did make it network accessible, but a wired connection would negate my third objective of giving my car range of the perimeter of my wifi network. The tutorial relies on the Uno sitting on his desk, wired to the RC controller. This means that the car is limited to the original RC car radio controller range. I don’t like this idea at all. I need a solution that I could mount on the car and access my network wirelessly. Wifi shields for the Uno are available, but can cost up to $90. I really didn’t want to invest that much just to make this wireless. It was pretty much at that moment I figured the Raspberry Pi was the platform to go with.


There are plenty of advantages that I could see for going with the RPi over the Uno for this project:

Apache/PHP instead of static script building web page

SSH access to make modifications

Easier/Cheaper Wireless USB

Same price as UnoPowered by micro USB


For the video feed, I decided to not go with the security camera as suggested and instead use my old Motorola Moto X running a free IP camera app. This turned out to be really great because I didn’t really have to rely on a separate power source to power my camera because of the phone’s battery.


Using the Instructables tutorial as more of a starting point, my project used the following:

RPi as controller and web server

Wireless USB dongle attached to RPi for wireless network access

Moto X running IP camera app for video feed

USB battery power bank powering RPi and Phone

GPIO pins on PRi controlling 4 channel relay wired to RC car controller

All components mounted to RC car

Duck DNS Dynamic DNS service running on home PC for access to car from Internet


Parts list:

Micro USB cables

8GB Micro SD card


Once I had my plan of action and components, I needed to prepare my RPi as a web server and install all necessary software. I loaded NOOBS from the official Raspberry Pi website on to the SD card and installed Raspbian, the Debian derivative for the RPi as the host OS. I referred to official Raspberry Pi website for installing Apache and PHP on the Pi. In order to interface with the GPIO pins from the command line for testing purposes and system calls from my PHP scripts to control the car, I installed a GPIO wiring utility called WiringPi by following the install instructions on the WiringPi install page. The WiringPi is a great utility. From the terminal, I can see the current status and layout of all the GPIO pins by issuing the command, “gpio readall”, change the mode of a pin by using, “gpio mode [pin number] [out/in], or write a high/low signal by using, “gpio [pin number] [1/0].



I can issue these commands using PHP by using system(). For example, to initiate GPIO pins 1 and 2 as output pins, I would run the following PHP:

<?php

system(“gpio mode 1 out”);

system(“gpio mode 2 out”);

?>

I wrote several PHP files that would be called on when the directional buttons on the web page are clicked. Each PHP file is a short script that initializes the mode of the designated GPIO pin(s), turns the pin(s) on for half a second, and finally turns the pin(s) off. I designated the following GPIO pins to these directions: 0 Forward, 1 Backward, 2 Left, 3 Right. For example, I created the following forward.php file:

<?php

    system("gpio mode 0 out");

    system("gpio write 0 1");

    usleep(500000);

    system("gpio write 0 0");

?>

The PHP sleep() function pauses PHP scripts by full seconds so I used usleep(), which is in milliseconds. So, the script sets the GPIO pin to mode “out”, sets the pin to high, waits 0.5 seconds, and then turns off the pin.


In order to allow the car to move in directions like forward-right or backward-left, I created PHP scripts that turn on multiple GPIO pins. The logic is pretty much the same, just using multiple directions at the same time. For example, the PHP file for back-left, bleft.php file:

<?php
    system("gpio mode 1 out");
    system("gpio mode 2 out");
    system("gpio write 1 1");
    system("gpio write 2 1");
    usleep(500000);
    system("gpio write 1 0");
    system("gpio write 2 0");
?>

To create the directional buttons on the web page, I modified an image of an arrow using GIMP to create a single image with that arrow duplicated for each direction. I used GIMP’s image map filter to create hyperlinks for areas on the image.



<img src="dpad.png" width="377" height="294" border="0" usemap="#map" />

    	<map name="map">
		<!-- #$-:Image map file created by GIMP Image Map plug-in -->
		<!-- #$-:GIMP Image Map plug-in by Maurits Rijk -->
		<!-- #$-:Please do not edit lines starting with "#$" -->
		<!-- #$VERSION:2.3 -->
		<!-- #$AUTHOR:jalawler -->
		<area shape="rect" coords="0,0,131,147" href="Forward-Left" />
		<area shape="rect" coords="131,0,242,147" href="Forward" />
		<area shape="rect" coords="131,147,242,292" href="Backward" />
		<area shape="rect" coords="0,147,131,293" href="Back-Left" />
		<area shape="rect" coords="242,147,377,294" href="Back-Right" />
		<area shape="rect" coords="243,0,376,147" href="Forward-Right" />
		</map>
		
		<br><button type="button" id="fleft">Forward-Left</button><button type="button" id="Forward">Forward</button><button type="button" id="fright">Forward-Right</button><br>
		<button type="button" id="bleft">Back-Left</button><button type="button" id="Backward">Backward</button><button type="button" id="bright">Back-Right</button>

These hyperlinks would initiate the respective PHP file associated with the direction the arrow represents. So, clicking on the up arrow would call on the forward.php file making the car move forward for 0.5 seconds. I achieved this without having the page navigate to the PHP files by using AJAX calls.

<script type="text/javascript">
    		$(document).ready(function(){
				$('#Forward').click(function(){
					var a = new XMLHttpRequest();
					a.open("GET","forward.php");
					a.onreadystatechange=function(){
						if(a.readyState==4){
							if(a.status == 200){
							}
							else alert("HTTP ERROR")
						}
					}
					a.send();
				});
				$('#Backward').click(function(){
					var a = new XMLHttpRequest();
					a.open("GET","backward.php");
					a.onreadystatechange=function(){
						if(a.readyState==4){
							if(a.status == 200){
							}
							else alert("HTTP ERROR")
						}
					}
					a.send();
				});
				$('#bleft').click(function(){
					var a = new XMLHttpRequest();
					a.open("GET","bleft.php");
					a.onreadystatechange=function(){
						if(a.readyState==4){
							if(a.status == 200){
							}
							else alert("HTTP ERROR")
						}
					}
					a.send();
				});
				$('#bright').click(function(){
					var a = new XMLHttpRequest();
					a.open("GET","bright.php");
					a.onreadystatechange=function(){
						if(a.readyState==4){
							if(a.status == 200){
							}
							else alert("HTTP ERROR")
						}
					}
					a.send();
				});
				$('#fleft').click(function(){
					var a = new XMLHttpRequest();
					a.open("GET","fleft.php");
					a.onreadystatechange=function(){
						if(a.readyState==4){
							if(a.status == 200){
							}
							else alert("HTTP ERROR")
						}
					}
					a.send();
				});
				$('#fright').click(function(){
					var a = new XMLHttpRequest();
					a.open("GET","fright.php");
					a.onreadystatechange=function(){
						if(a.readyState==4){
							if(a.status == 200){
							}
							else alert("HTTP ERROR")
						}
					}
					a.send();
				});
			});
		</script>

Wiring remote control to the relays was pretty straight forward. Each directional button on the controller is a momentary push button switch that completes the circuit on the controller board.


The relays would take over that responsibility and act as that push button, temporarily completing the circuit and sending the proper direction signal to the receiver on the car. After connecting the 0-3 GPIO signal wires to the relays, I connected a 5V and ground pin to the relay board.



I started by disassembling the remote controller so that I just the PCB and the battery compartment.




I then desoldered the 4 push buttons for the Forward, Backward, Left and Right wheel turn actions.



Each button has 4 solder points (2 on each side of the circuit) which the button would bridge when pressed. I soldered a wire to each side of the circuit and covered them in hot glue so no chance of short circuiting.



The other end of those wires went into the 4 channel relay module. I installed them so that at a resting state, the circuit was open so that when the power is off on the RPi, the buttons on the remote control are not engaged. Before this project, I had no experience with relays and found this great video explaining how to use relays with the RPi .


To get a first person view my Moto X is running IP Webcam, a free app from the Google play store. In order to embed that video feed into my web page, I grabbed the IP address assigned to my Moto X and embedded the following into the page:

<img src="http://[MY IP]:8080/video" width='640' onload='setTimeout(function() {src = src.substring(0, (src.lastIndexOf("t=")+2))+(new Date()).getTime()}, 1000000)' onerror='setTimeout(function() {src = src.substring(0, (src.lastIndexOf("t=")+2))+(new Date()).getTime()}, 5000)' alt='' />

To get a good mounting point for all my components, I first removed the truck cab from the chassis. I then modified a piece of scrap plexiglass I bought at SkyCraft and mounted that to the chassis with some zip ties.



I Velcro-ed my RPi, relay board, and wireless controller to the plexiglass base. The power bank was zip tied to the front bumper and the Moto X was mounted on the RAM suction cup mount in the center. Finally, the micro USB cables were ran from the power bank to my RPi and phone.



bottom of page