Remote Controlled Car¶

Description¶
The remote controlled car is a small car that is is controlled from a phone’s web browser. It consists of an integrated circuit (IC) L293D connected to a pair of gear motor with wheel, the Rpi needs to be connected to the internet. The communication between the phone and the raspberry pi is done using Element n’s IoT engine Scriptr.
Learning Objectives¶
- The Mini Car is a machine that helps students learn and apply the following:
- Coding, electronics, robotics sciences.
- Internet of things using Scriptr.
- Basic web development using html, javascript.
Materials Needed¶
- Raspberry Pi with micro SD card and Raspbian
- Wifi Dongle (if Rpi Version 2 and lower)
- Two gear motor with wheel
- IC, L293D
- Jumper wires
- External Power for motors
- Power bank for raspberry pi
- Breadboard
- Glue gun and glue sticks
- Cutter blades or scissors
- Thin sturdy cardboard (poster or portfolio cardboard)
- Plexiglass
Setup and Functionality¶

Figure 1: shows the layout of our html page.
This picture is the output the html page that the user can open from his phone browser. It consists of 5 different pictures that act as buttons. When one of these buttons are pressed - using javascript - a message will be sent to Scriptr. On Scriptr side, when a message is received, it will be broadcasted to all the subsrcibers on the channel. Our Raspberry Pi will subscribe to this channel and hence will receive the message. The Rpi will analyze this message and act accordingly. For exemple if the forward button is pressed our html page will send a message to scriptr saying ‘forward button is pressed’ - The format of this message is actually different, it is sent as a JSON message (but more on that later) -. Scriptr will then broadcast this message (or edit the message beforehand) through the channel. Our Raspberry Pi being a subscriber to this channel will receive this message and will turn on the motors in order to go forward.
Introduction To Scriptr¶
What is IoT¶
In quick words, the Internet of Things is the a system in which everyday objects have network connectivity, allowing them to send and receive data. Scriptr is an engine developed by a Lebanese company, Element n that helps us connect devices through a certain channel
How does Scriptr Work¶
Simply put, Scriptr opens a channel and broadcast a message through this channel. In fact in scriptr we have two types of users:
Either a user is connected/subscribed to the channel, he then receives all the messages sent to this channel and can in his turn send a message through this channel. Or a user is simply sending messages to this channel to which he’s not subscribed to. We call this way of communication PubSub.
Circuitry and Electronics:¶
The diagram below shows the connections and the circuitry of all the components used in this project:

Figure 2: shows the wiring and connections of all the components to the Raspberry Pi.
The function of the Integrated circuit L293D is to control the motors. These motors needs an external source of power, hence the batteries,in order to have an optimal performance. Due to the fact that on a long term, the IC and the motors require more current than what is provided by the Raspberry pi.
Programming¶
HTML & Java Scriptr¶
<!-- This is a comment and will not be analysed.
This html page controls car id#4 => when a button is pressed we will send a message with an id equals to 4.-->
<!-- Car id=1 -->
<html> <!-- this tag should be in the start of every html page it will be closed in the end of html file by the tag </html> -->
<body> <!-- to specify that we are writing in the body of a html page, distinction with <footer>, <header> ... -->
<table> <!-- this tag creates a table in the html layout. -->
<tr> <!-- tr = table row - creates a row in this table. -->
<td/> <!-- td = tag defines - creates a cell in the row. <td/> creates an empty cell. -->
<td> <!-- this cell (#2) is not empty, it contains an image. -->
<img style="height:300px;width:300px" src="up.png" onclick="javascript:forward()" />
<!-- this image is the up.png picture that is in the same folder/directory as the html file.
onclick= when this image is clicked, the javascript function ‘forward’ will be called-->
</td> <!-- end of cell 2 -->
<td/>
</tr>
<tr>
<td><img style="height:300px;width:300px" src="counterclockwise.png" onclick="javascript:left()"/></td>
<td><img style="height:300px;width:300px" src="stop.png" onclick ="javascript:stop()"></td>
<td><img style="height:300px;width:300px" src="clockwise.png" onclick="javascript:right()"/></td>
</tr>
<tr>
<td />
<td><img style="height:300px;width:300px" src="down.png" onclick="javascript:reverse()"/></td>
<td />
</tr>
</table> <!-- closes the table tag -->
</body>
<script> // after this tag we start writing java script // => comment in java script <!-- --> => comment in html.
var ws = new WebSocket("wss://api.scriptr.io/U0VDOUZBRkJFRTpzY3JpcHRyOkZGRDE0M0JFN0ZBMDFEOUE3Q0UzNjYwNzM4RkQ2REM1");
// this instruction creates a *web socket* that is the scriptr api, given to us when we sign up to scriptr
var command;
var id = "1";
var msg;
function left() { // if left button/image is clicked this function will be called.
command ="CounterClockwise";
msg = { //this is the msg that will be sent to scriptr. this message type is called *JSON*.
"method":"move", //move is the file name is scriptr.
"params":{
"id":id,
"command":command
}};
msg = JSON.stringify(msg);
ws.send(msg); //send this msg to web socket = to scriptr.
}
function right() {
command ="Clockwise";
msg = {
"method":"move",
"params":{
"id":id,
"command":command
}};
msg = JSON.stringify(msg);
ws.send(msg);
}
function forward() {
command = "Forward";
msg = {
"method":"move",
"params":{
"id":id,
"command":command
}};
msg = JSON.stringify(msg);
ws.send(msg);
}
function reverse() {
command ="Backward";
msg = {
"method":"move",
"params":{
"id":id,
"command":command
}};
msg = JSON.stringify(msg);
ws.send(msg);
}
function stop() {
command ="Stop";
msg = {
"method":"move",
"params":{
"id":id,
"command":command
}};
msg = JSON.stringify(msg);
ws.send(msg);
}
</script>
</html>
Web socket Definition: | |
---|---|
Simply put, a web socket is equivalent to a telephone call between terminals - computers-. |
|
Json: | JSON (JavaScript Object Notation) is a lightweight data exchange format. It’s used due to its simplicity, In fact it s easy for humans to read and write, and easy for machine to parse and generate. Exemple : {
} this is a JSON message, from this message we can understand that the name of the object is ‘ a green door’ and has an id = 1, its price is 12.50. |
Scriptr¶
Create a file in scriptr called : move and insert these lines of code in it.
var pubsub = require("pubsub");
message = {
id: request.parameters.id, // gets id from the message received
command: request.parameters.command // gets the command from the message received.
}
pubsub.publish("RPI", JSON.stringify(message)); // broadcast the message to the RPI Channel
As we can see from the script, Scriptr does not broadcast the message as it is, we have the possibility to modify the message before broadcasting it. This function in Scriptr will be activated every time a user sends a message to this channel.
Python¶
import RPi.GPIO as GPIO
import time
import websocket
import json
myId = "1"
motor1A = 21
motor1B = 23
motor1E = 19
motor2A = 12
motor2B = 8
motor2E = 10
GPIO.setmode(GPIO.BOARD)
GPIO.setup(motor1A, GPIO.OUT)
GPIO.setup(motor1B, GPIO.OUT)
GPIO.setup(motor1E, GPIO.OUT)
GPIO.setup(motor2A, GPIO.OUT)
GPIO.setup(motor2B, GPIO.OUT)
GPIO.setup(motor2E, GPIO.OUT)
def on_message(ws,message): # As seen below, this function will be called when we receive a message from scriptr.
print 'message ' ,message
message = json.loads(message)
if message["id"] == myId or message["id"] == "0": #If the message received has the Id=1 (ie this RPi/Car) - Analyze the message
action = message["command"]
if action == "Clockwise": #if the Json received has Clockwise command - then call the clockwise function
clockwise()
elif action == "CounterClockwise":
counter_clockwise()
elif action == "Forward":
forward()
elif action == "Stop":
stop()
else:
backward()
def on_error(ws,error):
print 'error: ', error
def on_close(ws):
print 'closed'
def on_open(ws): # This function will be called when the web socket is open.
subscribeMessage = "{\"method\":\"Subscribe\",\"params\":{\"channel\":\"RPI\"}}"
# This string is a json equivalent of:
# {
# method: Subscribe,
# params: {
# channel:RPI
# }
# }
# ===> We're telling scriptr that we want to subscribe to channel RPI.
ws.send(subscribeMessage)
# Send the subscribe message immediatly when we connect to scriptr
# This pi is now subscribed to the channel RPI, it’s going to receive ALL the messages that is being broadcasted on this channel
# [including messages that are sent from this Rpi]
print "opened"
#Controlling the Motors with IC L293D
def backward():
GPIO.output(motor2A, True)
GPIO.output(motor2B, False)
GPIO.output(motor2E, True)
GPIO.output(motor1A, False)
GPIO.output(motor1B, True)
GPIO.output(motor1E, True)
def forward():
GPIO.output(motor2A, False)
GPIO.output(motor2B, True)
GPIO.output(motor2E, True)
GPIO.output(motor1A, True)
GPIO.output(motor1B, False)
GPIO.output(motor1E, True)
def counter_clockwise():
GPIO.output(motor1A, False)
GPIO.output(motor1B, True)
GPIO.output(motor1E, True)
GPIO.output(motor2A, False)
GPIO.output(motor2B, True)
GPIO.output(motor2E, True)
def clockwise():
GPIO.output(motor1A, True)
GPIO.output(motor1B, False)
GPIO.output(motor1E, True)
GPIO.output(motor2A, True)
GPIO.output(motor2B, False)
GPIO.output(motor2E, True)
def stop():
GPIO.output(motor1E, False)
GPIO.output(motor2E, False)
try:
stop()
# Creating websocket with scriptr
# And specifying the callback functions.
# When we receive a message from scriptr we will be called on: on_message
# When there is an error with Scriptr we will be called on: on_error
# When we close the connection the scriptr we will be called on: on_closed
# When we first open the connection with scriptr we will be called on: on_open
ws = websocket.WebSocketApp("wss://api.scriptr.io/U0VDOUZBRkJFRTpzY3JpcHRyOkZGRDE0M0JFN0ZBMDFEOUE3Q0UzNjYwNzM4RkQ2REM1",
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.on_open = on_open
ws.run_forever()
except KeyboardInterrupt:
stop()