Introduction: How to Build an Internet Controlled Mars Rover

This Instructable will explain everything you need to know to build an internet controlled all terrain robot. This one just happens to be modelled on the Mars Curiosity rover. This robot is controllable from any internet enabled device so you can control this thing on the other side of the planet (or Mars if only it had the internet). This project is all powered by the amazing Electric Imp (an SD card sized device that allows you to connect anything to the internet) and an Arduino.

This project was created by Michael Shorter, Tom Metcalfe, Jon Rogers and Ali Napier at the Product Design Research Studio, Dundee.



What you will need:

6WD Wild Thumper Arduino Chassis - http://robosavvy.com/store/product_info.php/products_id/1167?osCsid=5e99bbe12a25938cbf4267ea6bc497ea

Wild Thumper Arduino Controller - http://robosavvy.com/store/product_info.php/products_id/1168

LiPo Battery - 7.2V 5000mah 

3mm Acrylic

5mm Acrylic

10cm diameter drainpipe

35mm diameter pipe

aluminium rods

Electric Imp

Electric Imp breakout board

Some jumper cables

Skateboard grip tape

Step 1: Building the Rover

Attached are the Adobe Illustrator files to allow you to laser cut all the parts you need. There are three files in total. One file for all the 3mm thick parts, one for the 5mm thick parts and one for the grip tape parts.

Hopefully the images below give a good idea of how to stick the new chassis for your Wild Thumper 6WD together. 

The wiring of the Electric Imp to the Arduino is easy:
Imp pin 1 - Arduino pin 10
Imp pin 2 - Arduino pin 9
Imp pin 8 - Arduino pin 12
Imp pin 9 - Arduino pin 2

The Electric Imp will also need either 5V or 3.3V depending on your breakout board, as well as ground.

I decided to wire in a toggle switch in line with the battery to make it easy to turn on and off.

Step 2: The Web Side of Things

Here’s some code for you….
Squirrel for imp (adapted from an online source that I can no longer find…) :

================================================
server.show(“”);
// remote control for rover
ledState <- 0;
function blink()
{
// Change state
ledState = ledState?0:1;
server.log(“ledState val: “+ledState);
// Reflect state to the pin
hardware.pin9.write(ledState);
}
// input class for LED control channel
class inputHTTP extends InputPort
{
name = “power control”
type = “number”
function set(httpVal)
{
server.log(“Received val: “+httpVal);
if(httpVal == 1) {
hardware.pin9.write(1);
imp.sleep(0.1);
hardware.pin9.write(0);
}
else if(httpVal == 2) {
hardware.pin8.write(1);
imp.sleep(0.1);
hardware.pin8.write(0);
}
else if(httpVal == 3) {
hardware.pin2.write(1);
imp.sleep(0.1);
hardware.pin2.write(0);
}
else if(httpVal == 4) {
hardware.pin1.write(1);
imp.sleep(0.1);
hardware.pin1.write(0);
}
else{
;
}
}
}
function watchdog() {
imp.wakeup(60,watchdog);
server.log(httpVal);
}
// start watchdog write every 60 seconds
//watchdog();
// Configure pins as an open drain output with internal pull up
hardware.pin9.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin8.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin2.configure(DIGITAL_OUT_OD_PULLUP);
hardware.pin1.configure(DIGITAL_OUT_OD_PULLUP);
// Register with the server
imp.configure(“Reomote Control for Rover”, [inputHTTP()], []);
================================================




Arduino code (thanks Chris Martin!)…
================================================

/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
int pinf=2;
int pinl=12;
int pinr=10;
int pinb=9;

#define LmotorA 3 // Left motor H bridge, input A
#define LmotorB 11 // Left motor H bridge, input B
#define RmotorA 5 // Right motor H bridge, input A
#define RmotorB 6 // Right motor H bridge, input B
#define v 255

#include <Servo.h>
//Servo myservo;
//int led = 12;
int pos = 0;
// the setup routine runs once when you press reset:
void setup() {
//myservo.attach(9);
// pinMode(led, OUTPUT);
pinMode(pinf,INPUT); // initialize serial communication at 9600 bits per second:
pinMode(pinl,INPUT);
pinMode(pinr,INPUT);
pinMode(pinb,INPUT);
Serial.begin(9600);
digitalWrite(pinf,LOW);
digitalWrite(pinl,LOW);
digitalWrite(pinr,LOW);
digitalWrite(pinb,LOW);

//288000
// this is different on the serial monitor not sure if it is up or down
// Serial.begin(14400);
}
int lls=0;
int rls=0;
int al=0;
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue1 = digitalRead(pinf);
int sensorValue2 = digitalRead(pinl);
int sensorValue3 = digitalRead(pinr);
int sensorValue4 = digitalRead(pinb);
// print out the value you read:
Serial.print(sensorValue1);
Serial.print(” : “);
Serial.print(sensorValue2);
Serial.print(” : “);
Serial.print(sensorValue3);
Serial.print(” : “);
Serial.println(sensorValue4);
delay(25); // delay in between reads for stability

if (sensorValue1 == 1) {
analogWrite(RmotorA,0);
analogWrite(RmotorB,120);
analogWrite(LmotorA,0);
analogWrite(LmotorB,120);
delay (500);
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
// myservo.write(10);
// delay (500);
}
else{
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
}
if (sensorValue2 == 1) {
// digitalWrite(led, HIGH);
analogWrite(RmotorA,0);
analogWrite(RmotorB,250);
analogWrite(LmotorA,250);
analogWrite(LmotorB,0);
delay (100);
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
// myservo.write(10);
// delay (500);
}
else
{
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
}
if (sensorValue4 == 1) {
// digitalWrite(led, HIGH);
analogWrite(RmotorA,250);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,250);
delay (100);
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
// myservo.write(10);
// delay (500);
}
else
{
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
}
if (sensorValue3 == 1) {
// digitalWrite(led, HIGH);
analogWrite(RmotorA,120);
analogWrite(RmotorB,0);
analogWrite(LmotorA,120);
analogWrite(LmotorB,0);
delay (500);
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
// myservo.write(10);
// delay (500);
}
else
{
analogWrite(RmotorA,0);
analogWrite(RmotorB,0);
analogWrite(LmotorA,0);
analogWrite(LmotorB,0);
}
}
================================================


Now for the user interface. Unzip the folder attached; all the code needed should be in there. All you need to do is paste in your unique Electric Imp API into the index.html file in the appropriate space. I have labeled this within the file.

Step 3: Let's Give It Some Visuals

I decided to put an old iPhone in the head unit displaying footage of Mars. This could be anything, even a video camera so you can see where you are driving via Skype or Facetime...

Step 4: Let's Get Roving!

Here is a quick video of The Mini Mars Rover hanging out at a NASA event at SWSW 2013! 


SXSW rover from michael shorter on Vimeo.



The great thing about this project is that it is easy to tweak the code to change the behaviours, or interface, of the robot.

Enjoy!

M
Remote Control Contest

Finalist in the
Remote Control Contest

Microcontroller Contest

Participated in the
Microcontroller Contest