1 Line PHP Servers for Raspberry Pi Projects

I wanted to introduce my daughters to using PHP on Raspberry Pi Projects. My goal has been to try and keep things super minimalist so that they can quickly pull together a project for school without being overwhelmed with installation or dependency issues.

In this blog I will look at:

  • Running a 1-Line PHP server (no other web server will be used or installed)
  • Show Bash diagnostics tools on a PHP page (3 lines of PHP)
  • Use a PHP calls to read/write Rasp Pi GPIO pins

Loading and Running a PHP Server

Typically PHP is loaded with Web server applications like Apache, but PHP can be run as a standalone application. To install PHP on a Raspberry Pi or Ubuntu system:

sudo apt-get install php -y

The syntax to run PHP as a standalone web server:

php -S <addr>:<port> [-t docroot] startpage

# for example
php -S 192.168.0.111:8080 mypage.htm

# to use Bash to get your IP
php -S $(hostname -I | awk '{print $1 ":8080"}') mypage.htm 

It’s important to note that the standalone PHP server is designed for testing and very small projects. It should not be used for any kind of production environment.

Superquick PHP Primer

PHP is an extremely popular Web programming language.

PHP originally stood for : Personal Home Page, but after a lot of enhancements it now stands for: “PHP: Hypertext Preprocessor”.

A PHP file normally contains HTML tags, and some PHP scripting code. A PHP script starts with “<?php” and ends with “?>“. An example would be (test1.php) :

<!DOCTYPE html>
<html>
<body>

<h1>A PHP Test Page</h1>

<?php
// This is PHP script block
$a = 4;
$b = 6;
echo "Hello World! ";
echo "4 x 6 =" . ($a * $b);
?>
<p>Below is a single line of PHP</p>
<?php echo "This is a single line" ?>

</body>
</html>

To learn about the PHP syntax there are some good references.

To run this page:

php -S $(hostname -I | awk '{print $1 ") test1.php

It’s useful to know that PHP code can be run directly with the PHP interpreter:

# A single line of PHP (note: -r for single line)
$ php -r '$a=4; $b=5; echo  $a * $b . "\n" ; '
20

# Run a PHP script 
$ php test1.php

<!DOCTYPE html>
<html>
<body>

<h1>A PHP Test Page</h1>

Hello World! 4 x 6 =24<p>Below is a single line of PHP</p>
This is a single line
</body>
</html> 

Command line Diagnostics on a Web Page

Linux command line utilities can have their output viewable on a Web page. The example below (vmstats.php) uses the PHP shell_exec call to execute the vmstat command line utility and the results are echoed to the web page. The <pre> tag is used to present the results in fixed-width font.

<?php
// vmstats.php - A PHP test page to some CPU stats 
echo "<pre>";
echo shell_exec('vmstat');
echo "</pre>";
?>

A 1 line PHP web server command to call this page is:

php -S $(hostname -I | awk '{print $1 ":8080") vmstats.php

PHP Interfacing to Pi GPIO

There are a few ways to access the GPIO pins in PHP:
1. use a PHP library
2. shell to the gpio command

Using a PHP library allows for a standard PHP interface, with an object model.

However from testing I found that the PHP libraries were not as flexible as the standard gpio command. For example you could not access extended GPIO pin numbers (i.e. 200).

GPIO Command Line Utility

PHP can shell out to the gpio command line utility. I liked this approach because I could test the actions manually before putting them into a PHP web page.

A simple gpio read example would be:

<html lang="en">
<head>
</head>
<body>
<?php
$ret = shell_exec('gpio read 7');
echo "Pin 7 status = " . $ret;
?>
</body>
</html>

And a gpio write example (with reading back the result) would be:

<html>
<head>
</head>
<body>
<?php
exec("gpio write 7 1");
$ret = shell_exec('gpio read 7');
echo "Pin 7 status = " . $ret;
?>
</body>
</html>

Control A Pi Rover using PHP

The Raspberry Pi rover project is a good example that pulls together:

  • Control of Pi GPIO pins
  • PHP Forms
  • Cascading Style Sheets (CSS) for mobile phone presentations

Motors should not be connected directly to a Raspberry Pi because they could potential damage the Pi hardware. It is recommended that some intermediate equipment or a motor top be used. For this project we used a Pimoroni ExplorerHat Pro.

PHP Forms

This example uses an HTML post method that is defined in the <form> tag. The buttons pass the values of: go, stop, left and right.

The PHP code look for the post value and then does a gpio write for the required action. For example a go will turn on both GPIO motor pins.

The full PHP code is below:

<?php
// rover.php - control Rasp Pi GPIO pins using PHP form with buttons
//

// adjust pins for the specific motor setup 
$leftpin = 7;
$rightpin = 2;

// Get post feedback message
if (isset($_POST['submit'])) {
	switch ($_POST['submit']) {
		case "go":
			exec("gpio write " . $leftpin . " 1");
			exec("gpio write " . $rightpin . " 1");
			break;
		case "stop":
			exec("gpio write " . $leftpin . " 0");
			exec("gpio write " . $rightpin . " 0");
			break;
		case "left":
			exec("gpio write " . $leftpin . " 1");
			exec("gpio write " . $rightpin . " 0");
			break;
		case "right":
			exec("gpio write " . $leftpin . " 0");
			exec("gpio write " . $rightpin . " 1");
			break;
	}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <title>PHP/Pi Rover Controls</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">

  <h2>PI Four Button Example</h2>
  <form action="" method="post">
    <div class="form-group">

    <button type="submit" name="submit" class="btn-success btn-lg" style="width:100%" value="go">Forward</button>
    <button type="submit" name="submit" class="btn-info btn-lg" style="width:49%" value="left">Left</button>
    <button type="submit" name="submit" class="btn-info btn-lg" style="width:49%" value="right">Right</button>
    <button type="submit" name="submit" class="btn-danger btn-lg" style="width:100%" value="stop">Stop</button>
  </form>
</div>

</body>
</html>

Mobile CCS Templates

There are quite a few good mobile templates to choose from. Bootstrap (http://getbootstrap.com/) is one of the most popular frameworks, and for Pi applications it seems to be a good fit.

Some of the key items are:

  • Add references in to the bootstrap ccs and js files
  • Add tags with the required class definitions:
    • the btn-lg class will make a large button, instead of standard sized btn 
    • different button colours are possible using btn-info, btn-success. btn-danger
    • Button width is defined with style=”width: xx%” . For multiple buttons the sum of the width needs to <100%

Further Examples

Below are some pictures of a mobile rocket launcher project.  The Web page had two sections. The top section controlled bi-directional motors that were connected to a Explorer HAT Pro shield. The bottom section controlled the rocket launcher turret. The missile launcher was connected via a USB cable to the Pi.

Screenshot
OLYMPUS DIGITAL CAMERA

 

 

Pi Rover using a Bottle Web Framework

There are a lot of Python web library choices, with each of the libraries offering different features and functions.

For simple Raspberry Pi Web application I was really impressed by the Python Bottle library. In this blog I’d like to document a Raspberry Pi rover project that I did using bottle.

Getting Started

To install the Python bottle library:

pip install bottle

There are some good tutorials for bottle. Probably the most important item is defining a decorator for a URL, and then linking the decorator to a function:

@route('/') # define a decorator for the start page
def my_homefuntion() # call a function for the start page
   return static_file("startpage.htm", root='') # call the start page

@route('/otherpage') # define a decorator for another page 
def my_otherpage_function() # call a function for the start page
   # do some stuff...

For the RaspPi rover I used a low cost car chassis (~$15).

It is not recommended to connect motors directly to Rasp Pi pin, for a few reasons:

  • larger motors require more power that a Pi GPIO pin can supply
  • power surges on motors can damage the Pi hardware
  • forward/backward motor directions require extra hardware
  • GPIO pins will only do ON/OFF, no variable speed settings.

There are a number of Raspberry Pi motor shield that can be used. For this project I used the Pimoroni Explorerhat Pro ($23). The Explorerhat has an excellent Python library that allows you to easily control the motor’s direction and speed.

Web Page

The goal for the web page (bottle1.htm) was to have 5 buttons for the controls and use AJAX to send the action request and then return the action code and display it on the page. The returned action would appear above the buttons ( in the lastcmd  paragraph tag).

Screen_bottle

For this example the button push was sent in the header as a GET request. So a forward button push would be a myaction: forward header item. In previous projects I’ve used POST request with parameters, however I found that header items can make things a little simpler.

<!DOCTYPE html>
<html>
<head> 
<title>Python Bottle Rover</title> 
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,"> 
<style>
  html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
  h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}
  .button{display: inline-block; background-color: #4286f4; 
  border-radius: 4px; color: white; font-size: 30px; width:100%; height: 75px}
  .button2{background-color: green ;width:31%}
  .stop{background-color: red; width:33%}
</style>
</head>
<script>
function sendcmd(thecmd) {
  // send the action as a header item 
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET","/action" , true);
  xhttp.setRequestHeader("myaction", thecmd);
  xhttp.send()
  xhttp.onreadystatechange = function() {
	// Get the response and put on it the screen
	if (this.readyState == 4 ) {	
		document.getElementById("lastcmd").innerHTML = "Last Command:<b>" +xhttp.responseText;
	}
  }
}
</script>
 
<body>
<h2>Python Bottle Rover</h2> 
<p id='lastcmd'></p>
<button onclick="sendcmd('forward')" class="button">FORWARD</button>
<button onclick="sendcmd('left')" class="button button2">LEFT</button>
<button onclick="sendcmd('stop')" class="button stop">STOP</button>
<button onclick="sendcmd('right')" class="button button2" >RIGHT</button>
<button onclick="sendcmd('backward')" class="button button">BACKWARD</button>
  
</body>
</html>

 

Bottle Rover App

For the rover app, there are two URL endpoints. The root (/) which would display the bottle1.htm page, and an action (/action) URL which would only be called from AJAX script when a button was pushed.

For this project the Raspberry Pi ip address was hardcoded into the code, for future projects dynamically getting the ip would be recommend. Also a web port of 8000 was used so as to not conflict with a dedicated web server (like Apache) that could be running on the Pi.

# Bottle2rover.py - web control for a RaspPi rover<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>
#
from bottle import route, run, static_file, request

# Define RaspPi I/O pins
import explorerhat

# Send Action to Control Rover
def rover(action):
  if action == "forward":
    explorerhat.motor.one.speed(100)
    explorerhat.motor.two.speed(100)
  if action == "left":
    explorerhat.motor.one.speed(100)
    explorerhat.motor.two.speed(0)
  if action == "right":
    explorerhat.motor.one.speed(0)
    explorerhat.motor.two.speed(100)
  if action == "stop":
    explorerhat.motor.one.speed(0)
    explorerhat.motor.two.speed(0)
  if action == "backward":
    explorerhat.motor.one.speed(-50)
    explorerhat.motor.two.speed(-50)

# use decorators to link the function to a url
@route('/')
def server_static():
  return static_file("bottle1.htm", root='')
# Process an AJAX GET request, pass the action to the rocket launcher code
@route('/action')
def get_action():
  action = request.headers.get('myaction')
  print("Requested action: " + action)
  rover(action)
  return request.headers.get('myaction')

# Adjust to your required IP and port number
run(host = '192.168.0.106', port=8000, debug=False)

Final Comments

I was happily surprised how easy it was to get a Python bottle web app running. The bottle documentation was straightforward and I found that the code was quite lean.

NodeJS Raspberry Pi Rover

My typical Raspberry Pi projects are done in Python. I thought that I’d try some Node.js testing because I find the standalone Python Webserver (http.server library) to be a little slow on the Pi hardware.

Getting Started with Node.js on Raspberry Pi

Node.js can be installed on your Pi by:

$ sudo apt-get update
$ sudo apt-get install -y nodejs

There are a few options on how to talk to the GPIO (General Purpose Input/Output) pins on the Pi. I tested a few and I found that pigpio worked well for my setup. It is installed by:

sudo apt-get install pigpio

To set a GPIO pin to be an output and next to turn it on, a simple Node.js program (gpio.js) would be:

// gpio.js - set GPIO pin 4 to ON

const Gpio = require('pigpio').Gpio; 
const led = new Gpio(4, {mode: Gpio.OUTPUT});
led.digitalWrite(1);

To run the program:

sudo node gpio.js

It is important to note that access to the GPIO pins require admin rights so you will need to run your scripts with sudo (super user do).

Node.js Webserver

To make a simple webserver (mywebserver.js) :

// mywebserver.js - a simple websever on port 8080
//
var http = require('http').createServer(handler); //require http server, and create server with function handler()
var fs = require('fs'); //require filesystem module

http.listen(8080); //listen to port 8080

function handler (req, res) { //create server
  fs.readFile(__dirname + '/index.html', function(err, data) { //read file index.html in public folder
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'}); //display 404 on error
      return res.end("404 Not Found");
    } 
    res.writeHead(200, {'Content-Type': 'text/html'}); //write HTML
    res.write(data); //write data from index.html
    return res.end();
  });
}

This script references the http and the fs (file system) modules, and this allow us to reference an external index.html page. The handler function is used to manage the HTTP requests.

Next you’ll need to make an index.html page, below is a simple example:

<!DOCTYPE html>
<html>
<body>
<h1>Dummy HTML Test Page</h1><hr>
</html>
</body>
</html>

To test this page run: node mywebserver.js , and from a browser use your Pi’s IP address with port 8080, for example : 

dummy

Make the Web Page Dynamic

To make the Web Page dynamic we can use the socket.io package. It is installed by:

$ npm install socket.io --save

By using socket.io, javascript functions on the web page can communicate to functions running on the Node.js web server.socketio

Once a function is created in the Node.js webserver application the Web page can pass data to that function.

The Raspberry Pi Rover

There are some low cost Arduino car frames that cost under $10. These car frames can be used with a Raspberry Pi but you will need to be careful on how the motors are powered. Depending on the motors you might be able to drive them directly from Pi GPIO pins, however it is recommended that you use some external hardware to protect your Pi. There are some good Pi motor top options available, for my project I used the Pimoroni Explorer Hat Pro

js_rover2

My hardware setup used a Pi 3 with a portable phone charger. I used some duct tape to secure the wiring, charger and Pi together.

The motor pins will vary based on hardware that you use, so my code my need to be tweeked for your setup. The ‘control’ function is what I used to define the motor state. Some key words : forward, left, right, stop or back were passed between the web page and the server app to define the rover’s motor action. 

// ws_2_rover.js - NodeJS WebServer App to control a Rover

var http = require('http').createServer(handler); //require http server, and create server with function handler()
var fs = require('fs'); //require filesystem module
var io = require('socket.io')(http) //require socket.io module and pass the http object (server)

const Gpio = require('pigpio').Gpio;
// modify for your motor pinouts
const MOTOR1 = new Gpio(21, {mode: Gpio.OUTPUT}); 
const MOTOR2 = new Gpio(19, {mode: Gpio.OUTPUT}); 
const MOTOR3 = new Gpio(20, {mode: Gpio.OUTPUT}); 
const MOTOR4 = new Gpio(26, {mode: Gpio.OUTPUT}); 

// Ensure that the rover app starts without the motors running
function rover_stop() {
    MOTOR1.digitalWrite(0);
    MOTOR2.digitalWrite(0);
    MOTOR3.digitalWrite(0);
    MOTOR4.digitalWrite(0);
}

http.listen(8080); //listen to port 8080

function handler (req, res) { //create server

  fs.readFile(__dirname + '/web_2_rover.htm', function(err, data) { //read file index.html in public folder
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'}); //display 404 on error
      return res.end("404 Not Found");
    } 
    res.writeHead(200, {'Content-Type': 'text/html'}); //write HTML
    res.write(data); //write data from index.html
    return res.end();
  });
}

rover_stop();

io.sockets.on('connection', function (socket) {// WebSocket Connection
  console.log('A user connected');
  var controlvalue = ""; // variable for current status of the rover

  socket.on('control', function(data) { //get light switch status from client
    controlvalue = data;
    console.log('control input: ' + data);

    rover_stop(); // stop the motors, and then do the required action

    if (controlvalue == "forward") { 
      MOTOR1.digitalWrite(1); 
      MOTOR2.digitalWrite(1); 
    }
    if (controlvalue == "left") { 
      MOTOR2.digitalWrite(1); 
    }
    if (controlvalue == "right") { 
      MOTOR1.digitalWrite(1); 
    }

    if (controlvalue == "backward") { 
      MOTOR3.digitalWrite(1); 
      MOTOR4.digitalWrite(1); 
    }

  });
});

I used the Bootstrap template to offer a mobile friendly web interface. A button onclick function was used to pass the requested motor action (forward, left, right, stop, backward) to the control socket function. Below is my web page (web_2_rover.htm):

<!DOCTYPE html>
<html>
<head>
<title>NodeJS Web Rover Control</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>

<script>
var socket = io(); //load socket.io-client and connect to the host that serves the page
</script>
</head>

<body>
<div class="container">
  <h1>NodeJS Web Rover Control</h1>
  <button onclick="socket.emit('control','forward')" class="btn btn-success" style="width: 100%">Forwards</button>
  <button onclick="socket.emit('control','left')" class="btn btn-primary" style="width: 49%">Left</button>
  <button onclick="socket.emit('control','right')" class="btn btn-primary" style="width: 49%">Right</button>
  <button onclick="socket.emit('control','stop')" class="btn btn-danger" style="width: 100%">Stop</button>
  <button onclick="socket.emit('control','backward')" class="btn btn-warning" style="width: 100%">Backwards</button>     
</div>
</body>
</html>

To run the rover app enter:

sudo node ws_2_rover.js

Final Comments

I have done this project also in Python. The Python code is a little cleaner because the Pimoroni Explorer Hat has a Python library so I could easily adjust the motor speeds. However I found that the Node.js web interface to be a little faster than Python on the Pi.

 

 

Le gocart (Python Tkinter GUI)

For this project we wanted to control a Lego vehicle with a Python Tkinter app. Next we added a short cut to the Pi desktop and then we used VNC to see the Pi desktop and our app on a tablet.

Hardware Setup

Our hardware components were:

  • Raspberry Pi 3
  • Pimoroni ExplorerHat Pro – supports bi-directional DC motors
  • Dexter Connectors – allow 2 wire connections to Lego Mindstorms parts
  • 2 Lego Mindstorms motors
  • Portable USB charger
  • lots of Lego parts
  • 4 jumpers

le_gocart_parts

The Lego Mindstorms parts are little pricey but they allow you to make some pretty funky contraptions. The other thing that we like about the Mindstorms motors is that they have a lot of torque for a 5V DC motor.

There are a few options for the cabling (like cutting the cable and exposing the individual wires) we used the Dexter connectors that are breadboard friendly. ANA and GND connections on the Dexter side go to Motor + and Motor – on the ExplorerHat Pro board.

le_gocart_wiring

 

Python Tkinter

The Tkinter library allows you to create a simple graphic user interface (GUI) with components like: buttons, sliders, lists, text, labels etc.

For our interface we created a grid of 3 rows and 2 columns with 5 buttons. We made a simple motor function where we passed the speed and direction of the wheels. A negative speed is backwards, zero is stop, and a positive speed is forward.

import Tkinter
import explorerhat 

top = Tkinter.Tk()
top.title("Car Control")

explorerhat.motor.one.speed(0)
explorerhat.motor.one.speed(0)

#Define the buttons

def motor(Left,Right):
 explorerhat.motor.one.speed(Right)
 explorerhat.motor.two.speed(Left)

B_Left = Tkinter.Button(top, text ="Left", bg = "green", fg = "white", width= 15, height= 5, command = lambda: motor (50,0)).grid(row=1,column=1)
B_Right = Tkinter.Button(top, text ="Right", bg = "green", fg = "white", width= 15, height= 5, command = lambda: motor (0,50)).grid(row=1,column=2)
B_Forward= Tkinter.Button(top, text ="Forward", bg = "green", fg = "white", width= 15, height= 5, command = lambda: motor (50,50)).grid(row=2,column=1)
B_Backward = Tkinter.Button(top, text ="Backward", bg = "green", fg = "white", width= 15, height= 5, command = lambda: motor (-50,-50)).grid(row=2,column=2)
B_Stop = Tkinter.Button(top, text ="Stop", bg = "red", fg = "white", width= 33, height= 3, command = lambda: motor (0,0)).grid(row=3,column=1,columnspan=2)

top.mainloop()

VNC1

Pi Shortcut

To create a Pi shortcut, create a file:

nano $HOME/desktop/pi.desktop

Inside this file define the name, path, and icon info for your new application:

[Desktop Entry]
Name=Car Controls
Comment=Python Tkinter Car Control Panel
Icon=/home/pi/car1.png
Exec=python /home/pi/mycarapp.py
Type=Application
Terminal=false
Categories=None;

VNC (Virtual Network Computing)

VNC is install on the Raspbian image. To enable VNC run:

sudo raspi-config

Then select the interfacing option, and then select VNC and enable.

raspi-config-vnc

Finally you will need to define a VNC password and load some VNC software on your Tablet. There are a lot of packages to choose from. We have an Android table and we used RemoteToGo without any problems.

Note, when your Pi boots without a HDMI monitor connected the desktop resolution will be at a low setting (probably 800×600) this can be adjusted. For us we simply resized the desktop to fit our tablet screen.

Pi/Node-Red Car

The goal of the Pi/Node-Red car project was to create a small vehicle that can be controlled from a smart phone . For the project we used:

  • 1 Car chassis for Arduino ($15)
  • 1 Pimoroni Explorer HAT Pro  ($23)
  • 1 Portable microUSB charger
  • 1 USB WiFi Adapter
  • 4 short alligator clips and 4 connectors
  • Duct tape

The Arduino car chassis may require a small amount of assembly. Rather than soldering connections we like to use short alligator clips. It is not recommended to wire DC motors directly to a Raspberry Pi so the Pimoroni Explorer HAT Pro is used to connect the 2 DC motors.

The Raspberry Pi and the portable microUSB charger are secured to the top of the car chassis with duct tape. The left motor is wired to the motor 1 connectors on the Explorer Hat, and the right motor is wired to motor 2 connectors. Note you may have to do a little trial and error on the Explorer HAT “+” and “-” motor connections to get both wheels spinning in a forward direction.

The Explorer HAT Node-Red library is installed by:

 cd $HOME/.node-red
npm install node-red-dashboard 

The Web dashboard presentation is configured in the “dashboard” tab. For this example we create 2 groups: a control group to drive the vehicle, and a light group to turn on the Explorer Pro lights. Use the “+group” button to add a group, and the “edit” to change an existing group.
dash_conf

To control a motor, an “Explorer HAT” node and a dashboard button node are dropped and connected together. All the configuration is done in the button node . The button configure options are:

  • the group the button will appear in (Controls)
  • the size of the button (3×1 = 50% of width and narrow)
  • Topic, motor.one or motor.twois used for motor control
  • Payload, -100 = reverse, 0=stop, 100 = forward

Control_conf

The Explorer HAT has 4 colored LEDs. To toggle the LEDS, the topic is light.color with 1=ON, and 0=OFF . We thought that it would be fun to also add some Web dashboard button to control the colored lights.

light_conf

The Node-Red dashboard user interface is accessed by: ipaddress:1880/UI, so for example 192.168.1.102:1880/ui. Below is a picture that shows the final vehicle logic and the Web dashboard.

 

final_logic2

 

 

 

Remote Controlled Rocket Launcher

We’ve made a number of different versions of the mobile rocket launcher, and all of them have been fun. The version above is using the a PI 1 with a PiFace Digital module for the motor controls and a wireless keyboard for the controls.

The version shown below is using a PI 3, with an ExploreHAT Pro for the motor controls and a Python Web Server program for the controls. By using some simplified HTML tagging we were able to use an old PSP as a remote interface console.

launcher

Rocket Launcher Sample Code

We found the rocket launcher in a sale bin, but they call be purchased at: http://dreamcheeky.com/thunder-missile-launcher. The rocket launcher comes with it’s own Windows based program.

Below is some Python code that will control the rockets launchers turret and fire a missile. Based on this sample code you should be able to make some cool projects. A couple of notes from our testing:

  • you need to manually stop the turret motion once you start it. So you need to set your own wait time
  • you need 3-4 seconds between each missile firing. It might be a coincident but we damaged our first rocket launcher trying to issue fast firing commands.
 import usb
import sys
import time

device = usb.core.find(idVendor=0x2123, idProduct=0x1010)

# On Linux we need to detach usb HID first
try:
device.detach_kernel_driver(0)
# except Exception, e:
except Exception:

pass # already unregistered

device.set_configuration()

endpoint = device[0][(0,0)][0]

down = 1 # down
up = 2 # up
left = 4 # rotate left
right = 8 # rotate right
fire = 16 # fire
stop = 32 # stop

#device.ctrl_transfer(0x21, 0x09, 0x0200, 0, [signal])

while True:

print('r = right, l = left, u = up, d = down, f = fire ')
key = raw_input ('enter key:')
if (key == 'l'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, left, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'u'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, up, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'r'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, right, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'd'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, down, 0x00,0x00,0x00,0x00,0x00,0x00])
if (key == 'f'):
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, fire, 0x00,0x00,0x00,0x00,0x00,0x00])
time.sleep(4)
time.sleep(0.1)
device.ctrl_transfer(0x21, 0x09, 0, 0, [0x02, stop, 0x00,0x00,0x00,0x00,0x00,0x00]) 

 

 

 

Wii Controlled Lego Rover

Use your Raspberry Pi (or a Linux PC) to talk to a Lego NXT rover and then use a Wii remote to drive the rover.

Python Libraries

There are 2 sets of libraries that we used:

  • nxt-python : to talk to the Lego Mindstorm NXT
  • cwiid : to talk to Wii remotes

To install these libraries:

wget https://nxt-python.googlecode.com/files/nxt-python-2.2.2.tar.gz
tar -zxvf nxt-python-2.2.2.tar.gz
cd nxt*
sudo python setup.py install
sudo apt-get install python-cwiid

The Lego NXT brick needs to have Bluetooth turned on. Check the top left corner of the Brick’s screen to see if the Bluetooth symbol is showing. If it is not showing go into the Bluetooth options and turn it on.

nxt_bt

The next step is to ensure that the Raspberry Pi can see the Lego NXT. The Pi can scan Bluetooth devices with the command:

hcitool scan

If the Bluetooth is working then you will see the Bluetooth address of the NXT., (for example: 00:16:53:04:23:3D). Using the NXT’s Bluetooth address you can pair the Pi and the Lego NXT by:

sudo bluez-simple-agent hci0 00:16:53:04:23:3D

For the pin code use the default of: 1234
The NXT will beep and prompt you for the pairing passkey.

nxt_pair

After the Raspberry Pi is paired with the Lego NXT brick you are able to use Python to read the NXT sensors and control the motors. No NXT coding is required. In the Python NXT directory there are some examples, mary.py  is a good test example because it does not require any sensors or motors.

Our full Python code to control the NXT Rover with a Wii remote is below:

import cwiid
import time
import nxt.locator
from nxt.motor import *

print 'Looking for a Lego NXT ... may take up to 15 seconds...'
b = nxt.locator.find_one_brick()
print 'Lego NXT Connected'

left = Motor(b, PORT_B)
right = Motor(b, PORT_C)

print 'Press 1+2 on your Wiimote now...'
wii = cwiid.Wiimote()
time.sleep(1)
wii.rpt_mode = cwiid.RPT_BTN 
print 'WII Remote Connected'

while True:
 buttons = wii.state['buttons']
 if (buttons & cwiid.BTN_LEFT):
 right.brake()
 left.run(power = 100,regulated=False)
 time.sleep(0.1)

if (buttons & cwiid.BTN_RIGHT):
 left.brake()
 right.run(power = 100,regulated=False)
 time.sleep(0.1)

if (buttons & cwiid.BTN_UP):
 right.run(power = 100,regulated=False)
 left.run(power = 100,regulated=False)
 time.sleep(0.1)

if (buttons & cwiid.BTN_DOWN):
 left.brake()
 right.brake()
 time.sleep(0.1)

 

 

littleBits Rover

Create a remote control littleBits rover using the littleBits wireless transmitter (w12) Bit ($40) and the wireless receiver (w11) Bit ($40). These wireless bits can also be  found in some of the littleBits kits, (for example the Gizmo and Gadgets kit).

The wireless modules can pass up to 3 signals. Depending on what you are trying to remotely control you could mix and match between dimmers, buttons and toggle switches. If you add some littleBits proto modules you could come up with some interesting designs.

Step 1 : Build the Remote

To create the wireless remote for the a Rover we needed to control the left and right motors , for this we used the following components:

  •  1- littleBits mounting plate (comes with base set)
  • 1 – littleBits fork module ($12)
  • 2 – littleBits dimmer($8) or slide switches ($10)
  • 1 – littleBits wireless transmitter
  • 1-  littleBits power module with battery ($6)

We connected the power module to a fork module and then the fork module powered our dimmer modules. We mounted all the components on a littleBits mounting plate, and we taped the battery to the back.

frontremote

backremote

The littleBits motor circuit is quite simple, the only important thing is to ensure that you have the wheels turning in the same direction.

motor1.png

 

Android Controlled Robot Arm

Create a mobile robot arm that you can control from an Android smart phone.

We found a used robot arm (OWI-535) on Kijiji, but you could buy a new one for $30-$60.  We then mounted it on an Arduino car chassis ($20) with some duct tape. Luckily the OW-535 robot arm has all its wiring exposed and it comes with a good wiring document.

Parts

For this project we used:

  • 1- OWI-535 robot arm
  • 1- Car chassis ($17)
  • 1- Four motor Arduino shield ($10)
  • 1- Two motor Arduino shield ($10)
  • 1- JY-MCU Bluetooth module ($7)
  • 1- Arduino Mega
  • Duct tape, jumpers and 4 alligator clips
  • 1- Small USB charger
  • 1- Small Box (to house all the components)

OLYMPUS DIGITAL CAMERA

Wiring

The biggest challenge is to control the 5 robot motors and 2 wheel motors. For this we used an Arduino Mega and 2 motors shields. Depending on the motor shields that you use you probably won’t be able stack the motor shields. We stacked one motor shield and we had the second motor shield floating.

robot-arm-circuit

Some of the key wiring connections were:

  • Mega Pin 44 -> Floating Motor Shield pin 4
  • Mega Pin 45 -> Floating Motor Shield pin 5
  • Mega Pin 46 ->Floating Motor Shield pin 6
  • Mega Pin 47 -> Floating Motor Shield pin 7
  • Mega Pin 5V -> Floating Motor Shield pin 5V and VIN
  • Mega Pin 19 RX1 -> Bluetooth module TX
  • Mega Pin 18 TX1 -> Bluetooth module RX

To power this project we found that a portable USB charger was enough. If however you find that a USB charger does not deliver enough power the OWI-535 robot arm has a built in power pack with exposed power connections.

The motor terminals on the car chassis are a little fragile, so rather than soldering wires we used alligator clips. We also duct taped the wires under the car chassis to keep them secure.

The Arduino wiring was pretty ugly so we stuffed all the loose components into a small box. The box was duct taped to the back of the robot arm, and 2 cuts were made to feed the wires through.

inside_box.png

Code

For the Arduino code you’ll need to add the appropriate motor libraries. For our motor shields  we used the Adafruit V1 motor shield (https://github.com/adafruit/Adafruit-Motor-Shield-library).

Because the first motor shield blocked the RX0/TX0 pins, we used RX1 and TX1 on pins 19 and 18. For the Bluetooth communications it meant the Serial1 was used in the Anduino code instead of Serial.

For our commands we used:

  • 0 = Hand open (motor 1 forward)
  • 1 = Hand closed (motor 1 backward)
  • 2 = Wrist down (motor 2 forward)
  • 3 = Wrist up (motor 2 backward)
  • 4 = Elbow down (motor 3 forward)
  • 5 = Elbow up (motor 3 backward)
  • 6 = Shoulder up (motor 4 forward)
  • 7 = Shoulder down (motor 4 backward)
  • g = Go forward (pins: 44/46=HIGH, 45/47=255)
  • s = Stop (pins: 44/46=HIGH, 45/47 =0)
  • r = Right turn (pins: 44/46=HIGH, 45=0, 47 =255)
  • l = Left turn (pins: 44/46=HIGH, 45=255, 47 =0)
  • b = Go backward (pins 44/46= LOW, pins 45/47 =255)
  • o = Light ON, (pin 50 = HIGH)
  • f = Light OFF, (pin 50 = LOW)

Our final Arduino code is:

//
// Bluetooth control of a mobile robot arm
//
#include 

char inByte;
// Define remapped pins for 'floating' motor shield
int E1 = 45; 
int M1 = 44; 
int E2 = 46; 
int M2 = 47; 
int LIGHTpin = 50;

// DC motor on M1
AF_DCMotor motor1(1); // hand
AF_DCMotor motor2(2); // wrist
AF_DCMotor motor3(3); // elbow
AF_DCMotor motor4(4); // shoulder


void setup() {
 pinMode(M1, OUTPUT); 
 pinMode(M2, OUTPUT);

pinMode( 19, INPUT_PULLUP ); // For better Bluetooth stability
 Serial1.begin(9600); 
 Serial1.println("Robot Commands");
 Serial1.println("Menu...");
 Serial1.println("Enter: 0-7 for robot arm, g/s/l/r/b for wheels ");
}

void loop() {
 
 if (Serial1.available() > 0) {

// read the incoming byte:
 inByte = Serial1.read();
 if (inByte == '0') { runmotor(motor1,FORWARD); }
 if (inByte == '1') { runmotor(motor1,BACKWARD); }
 if (inByte == '2') { runmotor(motor2,FORWARD); }
 if (inByte == '3') { runmotor(motor2,BACKWARD); }
 if (inByte == '4') { runmotor(motor3,FORWARD); }
 if (inByte == '5') { runmotor(motor3,BACKWARD); }
 if (inByte == '6') { runmotor(motor4,FORWARD); }
 if (inByte == '7') { runmotor(motor4,BACKWARD); }
 if (inByte == 'g') { runwheels(HIGH,HIGH,255,255); } 
 if (inByte == 's') { runwheels(HIGH,HIGH,0,0); } 
 if (inByte == 'r') { runwheels(HIGH,HIGH,0,255); } 
 if (inByte == 'l') { runwheels(HIGH,HIGH,255,0); } 
 if (inByte == 'b') { runwheels(LOW,LOW,255,255); } 
 if (inByte == 'o') { digitalWrite(LIGHTpin, HIGH); }
 if (inByte == 'f') { digitalWrite(LIGHTpin, LOW); } 
 }
}
//--------------------------------------------------
void runwheels (int M1dir,int M2dir,int E1speed, int E2speed) {
 // For control of wheels direction and speed
 digitalWrite(M1, M1dir); 
 digitalWrite(M2, M2dir); 
 analogWrite(E1, E1speed);
 analogWrite(E2, E2speed); 
}
//--------------------------------------------------
void runmotor(AF_DCMotor themotor, int direction) {
 // Robot Arm motor control
 themotor.setSpeed(250);
 themotor.run(direction);
 delay(250);
 themotor.run(RELEASE); 
}

Android App

MIT’s App Inventor is free and it’s a great way to quickly make Android apps: http://ai2.appinventor.mit.edu/.

For this app we used:

  • 1 TableArrangement
  • 1 Listpicker
  • 15 Buttons
  • 7 Labels
  • 1 BluetoothClient (non-visible)

app1.PNG

A TableArrangement component with 3 columns and 11 rows is used to position all of the buttons and labels. After a component is positioned into the table, select the component and then use the Properties window to change its text, color, or sizing. The Components window is used to rename the component.

In the Blocks screen, blocks are dragged from the left Blocks section to the main viewer section. The following key blocks were used:

  • when Screen1.Initialize. This is called when the app is opened and it will show a list of all the phone’s paired Bluetooth device. This list is generated by connecting the blocks: BluetoothClient1.AddressesAndNames to set ListPicker1.Elements
  • when ListPicker1.BeforePicking. This block is called after the JY-MCU Bluetooth module (typically HC-06) is selected. Inside this block ListPicker1.Selection is an input to the Call BluetoothClient1.Connect block.
  • when .Click. This block is called when a “command” button is clicked. This block will send the required Bluetooth text command, so for example “g” is sent to go forward, and “s” is sent to stop.

app3

The full AppInventor code is:

full_logic

Once all the logic is created, you can download the app (APK file) or use a QR quick code to put it on your phone.

app2qr

The final step is to power up your Arduino project. When you do this the JY-MCU Bluetooth module will start to blink. This is telling you the module is ready to pair with your phone. On your phone’s SETUP->BLUETOOTH SETTINGS scan for new devices and you should see the JY-MCU Bluetooth module (it’ll probably be called HC-06). The pairing code is: 1234.

Now you are ready to open your new Android app. A dialog will ask you which device to connect to. Select your HC-06 device.

select

For this point on you will be able to control the robot with your phone.

screenshot