iPhone ambient light remote

Ever since I saw in this youtube video how you can use an iPhone to control some fancy light in your living room I wanted to build something similar. Now I finally found some time to play around with this topic.

In this post I’ll show you how easy it is to do what you’ve seen in the video with very little effort. The setup is a bit different, however. I’m not using DMX to control a light. Instead the Arduino board is wired directly to a BlinkM RGB LED via the I2C bus. Furthermore the iPhone does not communicate directly with the Arduino. To keep it simple I’ve decided to use OSC (Open Sound Control) and some existing libraries within Processing to handle the communication.

Here’s my setup:

Touch OSC is available for Android, but it is not possible to import custom layouts to your device at the moment of writing. (Look here for further information)

We’ll begin by creating the remote interface with the Touch OSC Editor.

Touch OSC Editor

On the left you can choose whether the layout should fit on an iPhone/iPod Touch or on an iPad and switch the orientation between vertical and horizontal. By right-clicking on the black area on the right you can insert different UI elements like labels and LEDs for showing some information or fader and buttons to receive user input.

The BlinkM LED consists of three small LEDs with the colors red, green and blue. Each of them can shine with a different luminosity, which allows a nice additive color mixing (example).

To trigger each LED individually there are three faders, one for each color. The resulting layout looks like this:

To use the layout on the iPhone, start the TouchOSC app and configure the network settings properly. Your iPhone and your computer running Processing have to be in the same wifi network. When you’re finished it’ll look similar to this:

Now it’s time to switch to the Processing IDE and write a little program to receive the OSC Messages.

First you’ll need to import the afore-mentioned libraries:

import oscP5.*;
import netP5.*;
import processing.serial.*;

oscP5 and netP5 are written by Andreas Schlegl and are available through his website.

The initial setup consists of three steps.
1. Setup the Processing sketch
2. Instantiate a Osc5 object, which will open a communication port for OSC
3. Instantiate a Serial object, which will handle the communication to the Arduino board

void setup() {
  size(300, 300);
  background(0);
  oscP5 = new OscP5(this, 8000);    // OscP5(Object theParent, int theReceiveAtPort) 

  if(portName == null) {
    portName = (Serial.list())[0];
  }

  port = new Serial(this, portName, portSpeed);

  if(port.output == null) {
    println("ERROR: Could not open serial port: "+portName);
    exit();
  }
}

When Processing runs the draw()-method gets called in a infinite loop. Here we’ll define the behaviour of the sketch.

void draw() {
 // update Processing sketch
 fill(redValue, greenValue, blueValue);
 ellipse(150,150,200,200);

 // send message to BlinkM
 fadeToColor(redValue, greenValue, blueValue);
}

As you can see from the code two things are happening:
1. A filled ellipse (in this case a circle) gets drawn with a color which is specified by three parameters.
2. The method fadeToColor sends the three color values to the Arduino board and finally to the BlinkM. Therefore the values
have to be stored in a byte array. The byte array cmd itself is wrapped into another array cmdfull, which includes the I2C address of the BlinkM.

public void fadeToColor( float r, float g, float b ) {
    byte[] cmd = {'c', (byte)r, (byte)g, (byte)b};
    sendCommand( blinkMAddr, cmd );
}

public synchronized void sendCommand( byte addr, byte[] cmd ) {
    println("sendCommand: "+(char)cmd[0]);
    byte cmdfull[] = new byte[4+cmd.length];
    cmdfull[0] = 0x01;                    // sync byte
    cmdfull[1] = addr;                    // i2c addr
    cmdfull[2] = (byte)cmd.length;        // this many bytes to send
    cmdfull[3] = 0x00;                    // this many bytes to receive
    for( int i=0; i

What’s still missing is the possibility to receive the actual color values from the iPhone.
Because we’ve instantiated an oscP5 object we can include a callback method to receive OSC messages.

void oscEvent(OscMessage theOscMessage) {
 
  String addr = theOscMessage.addrPattern();
  OscArgument arg = theOscMessage.get(0);
 
  if(addr.equals("/1/fader1")) {
     redValue = arg.floatValue();
  } 
 
  if(addr.equals("/1/fader2")) {
     greenValue = arg.floatValue();
  }
 
  if(addr.equals("/1/fader3")) {
     blueValue = arg.floatValue();
  } 
}

You can browse and download the full source code and the TouchOSC layout on my github.

Now let’s look at the result:

As you can see in the video the candle power is not sufficient to lighten up the corner of your living room.
I’ll try the BlinkM MaxM in the near future.
Also, I’ve already purchased a wifi shield for the Arduino to decouple the whole communication through processing.

So, stay tuned for further writings about this topic.

2 Responses to “iPhone ambient light remote”

  1. Tyson writes:

    Marcus,

    Nice Work! Thank You for creating this tutorial.
    I just have a quick question:

    What ‘Firmware’ and Libraries do you have ‘Uploaded’ on your Arduino board to handle the i2C communication and BlinkM commands? And what Pins are the BlinkM connected to on the Arduino Board?

    I have a similar set-up using Arduino Fio and Xbee Wireless following this example: http://www.youtube.com/watch?v=s9etKD2y-Zk, but I was unsure how to communicate with the BlinkM’s. Currently works great, although I just have an RGB LED on the PWM Pins. Would love to plug-in a BlinkM, or MaxM.

    Any help would be appreciated!

    Thank You

    -Tyson

  2. Marcus Ficner writes:

    Hey Tyson, sorry for replying so late!

    I’m glad that you ask, I even haven’t mentioned this part in my post. There’s an example project on the BlinkM’s Website (http://thingm.com/fileadmin/thingm/downloads/BlinkM_Examples.zip) called BlinkMCommunicator. Just upload it to your Arduino and it will handle the communication via I2C. How to connect the BlinkM to an Arduino is described on page 12 of the datasheet (http://thingm.com/fileadmin/thingm/downloads/BlinkM_datasheet.pdf).

Leave a Reply