iPhone Controller

Overview

YOU NEED TO USE A USB CABLE TO UPLOAD YOUR PROGRAM – YOU CANNOT USE XBEE TO UPLOAD PROGRAMS TO THE BOARD. YOU ALSO NEED TO DISCONNECT THE XBEE FROM THE ARDUINO BOARD WHILE YOU UPLOAD.

In this tutorial, you will learn how to control your Arduino through your iPhone/iPod Touch. The iPhone communicates over Wi-Fi with a Processing sketch running on your laptop. There are two tutorials; the first one lights up an LED and the second one uses two servos to potentially control the movement of your robot. This tutorial assumes some basic knowledge of programming and using the Arduino sketch. The following software must be installed prior to trying the tutorials.

Parts

Arduino microcontroller and carrier board

LiPo battery

iPhone/iPad/iPod Touch

XBee pair with USB dongle(available: ask your instructor)

LED

Jumper wires

Laptop

Figure 1: Routing process courtesy of Maxwell Hill.

Software

1. TouchOSC

The app is available via the iTunes Store and costs $4.99. The TouchOSC app for iPhone, iPod Touch, and iPad uses Open Sound Control messages to communicate with computers and microcontrollers over Wi-Fi. Once downloaded, sync your device with iTunes to install the application.

2. TouchOSC Editor

Download at http://hexler.net/software/touchosc.The editor allows the user to create custom interfaces using knobs, buttons, faders, and even XY pads. Each touch control can be easily edited to output a desirable range of values. Installers are available for Windows, OSX and Linux.

3. Processing

Download at http://processing.org/download/.The values from TouchOSC are sent over Wi-Fi to Processing. Processing also includes graphical tools. Processing is a simple way to create drawings, animations and interactive graphics. Visualization of data coming from an Arduino is fairly straightforward. Code tested with Processing 1.2.1.

4. OpenSound Control

Unzip http://www.sojamo.de/libraries/oscP5/download/oscP5-0.9.6.zip

You need to move the oscP5 folder into the Processing libraries folder. Otherwise, when compiling your sketch in Processing, the following error will pop up: “The package oscP5 does not exist. You might be missing a library.”

For Mac users the libraries folder is located inside ~/Documents/Processing.

For Windows users the libraries folder is located inside folder 'My Documents'/Processing.

Move or copy the entire oscP5 folder into the 'libraries' folder. If 'libraries’ folder does not exist, create it.

Here is the final folder structure:

Processing

libraries

oscP5

examples

library

oscP5.jar

reference

src

After library oscP5 has been successfully installed, restart Processing.

Hardware

Laptop, Arduino board, LED, wires, 2 continuous rotation servos. Instead of USB communication, the computer can talk to the Arduino using XBee radios. Doing so requires no additional software, however you must be sure the baud rate of the radios match in the Arduino and Processing software. 2 XBee radios and an USB dongle for wireless control of the Arduino (limited amount) are available in the supply locker.

Now that we have all of the hardware and software required to make the iPhone talk to the Arduino, let’s get started on a simple program.

LED Control Tutorial

An easy tutorial for how to control an LED with this routing process can be found at: http://www.sparkfun.com/tutorials/152. We will follow the Sparkfun tutorial very closely.

Create LED circuit:

You will need to create a simple circuit with an LED, a resistor, some jumper wires and your Arduino board connected to a computer via a USB cable. The negative/ground jumper is connected to the first row in the breadboard and the other end into one of the ground plugs (GND). Place the negative lead into the same row as the negative jumper. Place the positive end in the next row down. Place either end of the resistor into the same row as the positive end of the LED (second row). Place the other end of the resistor into the third row. Connect the red/positive jumper to pin 11 and the other end of the red jumper into the same row of the end of the resistor (third row). Here is what your Arduino should look like:

Figure 2: Wiring for LED control tutorial

Upload Arduino code

Make sure your Arduino is plugged in via the USB cord and open up the Arduino software on your computer. Copy the following code into the empty Arduino window:

//----------------------Arduino code-------------------------
int message = 0; // This will hold one byte of the serial message
#define redLEDPin 11 // What pin is the red LED connected to?
int redLED = 0; // The value/brightness of the LED, can be 0-255
void setup()
{
Serial.begin(9600); //set serial to 9600 baud rate
}
void loop()
{
    if (Serial.available() > 0)
    { // Check if there is a new message
        message = Serial.read(); // Put the serial input into the message
        if (message == 'R')
        { // If a capitol R is received...
            redLED = 255; // Set redLED to 255 (on)
           }
        if (message == 'r')
        { // If a lowercase r is received...
            redLED = 0; // Set redLED to 0 (off)
        }
    }
    analogWrite(redLEDPin, redLED); // Write an analog value between 0-255
}
//----------------------------end Arduino code--------------------------------

Save your Arduino sketch by going to the File menu, then Save As. Compile/verify your sketch by hitting the play button, wait for the status bar to say “Done compiling”. Upload the code to your Arduino board by selecting the right arrow button in the Arduino interface. Once uploaded open the Serial monitor and try typing an upper case “R” and hitting enter, this should make the LED light up. If you type a lower case “r” it should turn the LED off.

If Arduino software can't connect to the Arduino hardware, try the following:

1) Windows update needs to download the Arduino driver.

2) Make sure you've configured serial port + device correctly:

->tools ->board -> Arduino Duemilanove or Nano w/ ATmega328

->tools ->Serial Port ->COM # (whichever one pops up)

Run Processing code

Code tested with Processing 1.2.1. Your host computer (i.e. laptop) must be on the same Wi-Fi network as your iPhone/iTouch so that they can communicate. Open Processing. Copy the code from below and paste it into an empty Processing window:

//-----------------Processing code-----------------
import oscP5.*;        //  Load OSC P5 library
import netP5.*;        //  Load net P5 library
import processing.serial.*;    //  Load serial library
Serial arduinoPort;        //  Set arduinoPort as serial connection
OscP5 oscP5;            //  Set oscP5 as OSC connection
int redLED = 0;        //  redLED lets us know if the LED is on or off
int [] led = new int [2];    //  Array allows us to add more toggle buttons in TouchOSC
void setup()
{
 size(100,100);        // Processing screen size
 noStroke();            //  We don’t want an outline or Stroke on our graphics
oscP5 = new OscP5(this,8000); // Start oscP5, listening for incoming messages at port 8000
arduinoPort = new Serial(this, Serial.list()[0], 9600); // Set arduino to 9600 baud
}
void oscEvent(OscMessage theOscMessage)
{
// This runs whenever there is a new OSC message
String addr = theOscMessage.addrPattern(); // Creates a string out of the OSC message
if(addr.indexOf("/1/toggle") !=-1){
            // Filters out any toggle buttons
int i = int((addr.charAt(9) )) - 0x30; // returns the ASCII number so convert into a real number by subtracting 0x30
led[i] = int(theOscMessage.get(0).floatValue()); // Puts button value into led[i]
// Button values can be read by using led[0], led[1], led[2], etc.
}
}
void draw()
{
 background(50);        // Sets the background to a dark grey, can be 0-255
   if(led[1] == 0){        //  If led button 1 if off do....
    arduinoPort.write("r");    // Sends the character “r” to Arduino
    redLED = 0;        // Sets redLED color to 0, can be 0-255
  }
 if(led[1] == 1){        // If led button 1 is ON do...
  arduinoPort.write("R");    // Send the character “R” to Arduino
  redLED = 255;        // Sets redLED color to 255, can be 0-255
  }
fill(redLED,0,0);            // Fill rectangle with redLED amount
   ellipse(50, 50, 50, 50);    // Created an ellipse at 50 pixels from the left...
                // 50 pixels from the top and a width of 50 and height of 50 pixels
}
//--------------end processing code------------------------------------

Run the Processing sketch by hitting the play button, it looks very similar to the Compile button in Arduino. Whenever you want to control your Arduino with your iPhone, Processing has to run on your laptop.

Create User Interface with TouchOSC:

Open TouchOSC on your laptop. You may need to install java if TouchOSC isn't working correctly. Click on the black empty interface window and select Toggle Button.

Figure 3: TouchOSC Interface

Make sure that you leave the name of the toggle button as “toggle1”. Save your interface as whatever name you want, select SYNC. If you cannot sync with your iPhone, you might need to create a network on your laptop. See tricks and trouble shooting below.

Trick: If you have trouble syncing with your iPhone, go to “Layout”, then “Add” in the TouchOSC app. The “Add Layout” menu allows you to directly enter a host IP address. Once entered, tap on “Editor Hosts”. Select “Sync” on your laptop. This should do the trick. Or, follow the trouble shooting instructions to setup your own Wi-Fi network.

Setup your iPhone:

There are several steps in order to get your iPhone ready to communicate with the Arduino. Since we are communicating over Wi-Fi, we need to make sure we have know some network configurations.

1) Determine your computer (host) IP address

Mac Instructions:

Click on the "Apple" in the main menu bar and select "About this Mac" then select "More Info" and them select "Network", note the IP address given on the IPv4 Address line.

Windows Instructions:

Click the Start menu button on the Windows taskbar. Click 'Run...' on this menu. Type 'cmd' in the text box that appears. A command prompt window launches on the desktop. In this command window, type 'ipconfig /all'. Details are shown for each of the computer's network adapters. Computers installed with VPN software or emulation software will possess one or more virtual adapters. The 'IP Address' field states the current IP address for that network adapter.

2) Go to the "setting" on your iPhone/iPod. Select Wi-Fi. On the Wi-Fi page, select the name of the Wi-Fi network (most likely “MIT”). A check mark appears by the selected network. Now close the iPhone's Settings.

3) Open the TouchOSC application (on the iPhone) and go into the network setting. Set the Host to the IPv4 Address number from the first step. Set the Port (outgoing) to something like 8000 and the Port (incoming) to something like 9000. Now, make a note of the "Local IP address".

4) Return to the main menu in TouchOSC app. Under options, turn “Stay Connected” on.

5) Next select your new interface from the list of preset interfaces.

Finally hit “Done”. The toggle button you created on your iPhone should now turn the LED on/off and update the Processing graphics in real-time as well.

Servo Control Tutorial

Here is a more advanced tutorial that allows you to drive 2 continuous rotation servos. You will need the Arduino servo library. Plug the servos into channels 8 and 9 of your Arduino board. No wiring is actually needed for this tutorial. If you want more servos or actuators, you will have to rewrite some of the code provided.

Figure 4: Arduino with 2 servos attached (Channels 8 and 9)

Upload Arduino code

//----------------------------start Arduino code--------------------------------
#include <Servo.h> // include servo headers
// this would be whatever pin you want to use
#define SERVOR 8
#define SERVOL 9 
// global variables
Servo servoL; // initialize left servo
Servo servoR; // init right servo
int message = 0; // This will hold one byte of the serial message
// played around with values that sets the servos to neutral position
// these values need to be set for each servo!!!
const int servoneutralLeft = 1515;
const int servoneutralRight = 1520;
// set neutral range for servos
const int minneutral = 1400;
const int maxneutral = 1600;
//--- Function: Setup ()
void setup()
{
pinMode (SERVOL, OUTPUT);
pinMode (SERVOR, OUTPUT);
servoL.attach(SERVOL);
servoR.attach(SERVOR);
servoL.writeMicroseconds(servoneutralLeft); // set servo to mid-point
servoR.writeMicroseconds(servoneutralRight); // set servo to mid-point
Serial.begin(9600); //set serial to 9600 baud rate
}
//--- Function: loop ()
void loop()
{
// Check if there is a new message
if (Serial.available() > 0)
{
message = Serial.read(); // Put the serial input into the message
int val=message; // val to match pwm delay in ms
int tempval=0; // temp storage
// we can send values from 0 to 255 to the arduino.
// both fadders are set up to go from 0 to 1.
// left servo: 0-127, right servo 128-255. should be enough resolution
int minpulse = 127*8/2; // max storage is 0-255.
// Begin LEFT servo code
if (val <= 127)
{
// scale everything from 1000 to 2000
tempval = val*8 + servoneutralLeft - minpulse;
if (tempval > minneutral && tempval < maxneutral)
{
    // Creates dead zone at midpoint of the
    servoL.writeMicroseconds(servoneutralLeft); // fader range (neutral) and trims input to neutral
}
else
{
    servoL.writeMicroseconds(tempval);
}
}
// End LEFT servo code
           // Begin RIGHT servo code
if (val > 128)
{
// scale everything from 1000 to 2000
tempval = val*8 + servoneutralRight - minpulse - 128*8;
if (tempval > minneutral && tempval < maxneutral)
{
    servoR.writeMicroseconds(servoneutralRight);
    // fader range (neutral) and trims input to neutral value
}
else
{
    servoR.writeMicroseconds(tempval);
}
} // End RIGHT servo code 
}
}
//----------------------------end Arduino code--------------------------------

Run Processing code

//----------------------------------start processing code------------------------------------
import oscP5.*; // Load OSC P5 library
import netP5.*; // Load net P5 library
import processing.serial.*; // Load serial library
Serial arduinoPort; // Set arduinoPort as serial connection
OscP5 oscP5; // Set oscP5 as OSC connection
float [] fader = new float [4]; // Array allows us to add more toggle buttons in TouchOSC
int val1 =0; // Fader 1 value
int val2 =0; // Fader 2 value
//--- Function: setup
void setup()
{
oscP5 = new OscP5(this,8000); // Start oscP5, listening for incoming messages at port 8000
arduinoPort = new Serial(this, Serial.list()[0], 9600); // Set arduinoPort to 9600 baud
}
//--- Function: oscEventThis runs whenever there is a new OSC message
void oscEvent(OscMessage theOscMessage)
{
    String addr = theOscMessage.addrPattern(); // Creates a string out of the OSC message 
    // this handles the faders
    if(addr.indexOf("/1/fader") !=-1)
    {
        String list[] = split(addr,'/');
        int xfader = int(list[2].charAt(5) - 0x30); // returns the ASCII number so convert into a real number by subtracting 0x30
        if(theOscMessage.get(0).floatValue() !=0)
        {
            fader[xfader] = theOscMessage.get(0).floatValue(); // Puts fader value into fader[i]
            // we can send values from 0 to 255 to the arduino.
            // both fadders are set up to go from 0 to 1.
            // left servo: 0-127, right servo 128-255. should be enough resolution
            val1 = (int) (fader[1] * 127.0); // val1 defines and scales outputs from fader 1, LEFT servo
            val2 = (int) (fader[2] * 127.0 + 128.0);  // val2 defines and scales outputs from fader 2, RIGHT servo
         }
    }
}
//--- Function: draws servo on/off
void draw()
{
arduinoPort.write(val1); // Sends val1 to Arduino, left servo
arduinoPort.write(val2); // Sends val2 to Arduino, right servo
// this is some debugging code to figure out the message sent.
// comment once you are certain the values processing is sending matches your servos.
// int test1 = val1 / 127.0; // Arduino code, message is scaled.
//int test2 = val2 / 127.0 - 128; // Arduino code, message is scaled.
// uncomment if you want to take a look at the values the Arduino is receiving.
//println("Left servo value: " + test1);
//println("Right servo value: " + test2);
}
//----------------------------------end processing code------------------------------------

Create User Interface with TouchOSC

You will need to create 2 fader bars. The values should range from 0 to 1. Select centered. Save interface and sync with iPhone just as before. Fader1 will be the left servo. Fader2 is the right servo.

Figure 5: Blue fadder corresponds to left servo, red fadder corresponds to right servo.

Address messages sent over TouchOSC

To access different controls (such as the accelerometer data), the TouchOSC manual has details on all OSC addresses that control the default layout. All values are either Boolean, integer or floating points:

http://hexler.net/pub/touchosc/touchosc-manual-v1-1.pdf

In more detail, ("/1/toggle") means that there is one toggle button on page 1.

("/2/toggle") means that there is one toggle button on page 2.

("/1/toggle4") means that we are looking at toggle button 4 on page 1.

For the example, the accelerometer is hosted under “/accxyz”. The best way to figuring out these different addresses is listen in on the communication by using println(theOscMessage) inside the oscEvent function, and looking at the console at the moment of interaction to pinpoint the address corresponding to the given action. This address is typically followed by a string corresponding to a set of data variables, like “ff” for two float values.

Troubleshooting

Here is what you need to do to create a computer-to-computer network with TouchOSC and an iPhone or iPod Touch if you cannot connect over existing Wi-Fi. These instructions are for a Mac. You might also want to consider switching your iPhone to Airplane mode and then turn only Wi-Fi back on.

1) Click AirPort Status in the OSX menu bar and select "Create Network".

2) Name the network and click "ok".

3) Your AirPort Status icon on the computer should change the way it looks

4) Now click on the "Apple" in the main menu bar and select "About this Mac" then select "More Info" and them select "Network", note the IP address given on the IPv4 Address line.

5) Now go to the "setting" on your iPhone/iPod. Select Wi-Fi. On the Wi-Fi page, select the name of the Wi-Fi network you created in step 2. A check mark appears by the selected network. Now close the iPhone's Settings.

6) Open the TouchOSC application (on the iPhone) and go into the network setting. Set the Host to the IPv4 Address number from step 4. Follow the rest of the instructions above to set up your phone.

Resources

http://hexler.net/software/touchosc

http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=152

http://www.sojamo.de/libraries/oscP5/

http://www.projectallusion.com/1/post/2009/11/iphone-controlled-solar-powered-arduino-tank.html

http://opensoundcontrol.org/

http://www.makesomecode.com/2009/12/30/arduino-osc-iphone-and-dmx/

http://vlrevolution.com/blog/?p=14

http://www.videolife.tk/touchosc/

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1269840697

http://kennysblogworld.com/arduino-projects/

http://innerqube.com/?p=591

http://snipplr.com/view/28120/touchosc-and-processing-accelerometer-example-code/