Let's Make Robots!

Light Painter Arm

Draws light trails in long exposure photographs.

My heads been buzzing with project ideas lately and one such idea revolves around a light painting (aka light graffiti) robot. Too often I don't follow through with my ideas so in order to try and progress this one I thought I'd build a prototype. The prototype is built with bits and pieces I have lying around: two regular size servos, some balsa wood and zip ties. An LED (or two now three!) is mounted to a socket at the end of the arm. I'm using my Arduino Mega ADK and a Wii Nunchuck to control the arm.

Light painting, or light graffiti, uses long term exposures (where the camera sensor is exposed to the light from the scene for 30 seconds or more) and allows for various effects with light sources moved through the scene. In this case the camera is set on a tripod and the light painting arm moves an LED around to draw a sphere. Other methods of making these light orbs include swirling an LED around on the end of a string or attached to a fixed rod or pole.

My first light orb
My first light orb. No fancy analog control of the LED brightness in this one though.

I wasn't finished with just making a light orb. I played with varying the brightness of the LED as a function of the position, then I tried reproducing images on the orb. Images were converted from png to an array of bytes for the Arduino using a simple Processing sketch.

Light orb with parametric brightness
Orb with brightness dependant on position.

Light orb displaying an image
Light orb displaying an image (reads 'Hi').

LMR Light Orb
Smoother, more definition and 100% more LetsMakeRobots!


Update 24/09/12: Added a stripboard with three LEDs (Red, Green & Blue) to the end of the arm allowing for colour blending and hopefully some full colour images (once I figure out how to get around the memory limits).


Upgraded LEDs
Three LEDs are better than one! Red, Green and Blue LEDs on stripboard.

First colour blending result.
First colour blending result. Needs more green I think.


Update 30/09/12:


Well I've moved away from processing images in Processing and storing them in the Arduino C code (though I'll leave the Processing sketch at the bottom of this page in case it is of any use to anyone). The photograph below shows my current setup in which the Arduino Ethernet Shield is used to read a micro SD card. Images are saved in bmp with 24-bit colour and the sketch on my Arduino reads out the individual pixel data byte by byte. To do this I swatted up on the bmp format using the wikipedia entry and the Arduino SD reference (as this was my first time experimenting with the Ethernet shield or reading SD cards).

To begin with the file name was hard-coded in the Arduino sketch but I wanted some way to select from any of the bmp files on the SD card so I added an LCD (Nokia 3310 only needs 5 digital pins and 3.3v power) and included the Wii Nunchuck, though adding some push-buttons would have sufficed. Finally, I added a wireless trigger which I wired to an opto-isolator. The wireless trigger can either be used to trigger a flash or, as I'm using it, remotely control the shutter of a camera.

Current setup, a bit untidy but this is only the prototype after all.

I intend to use an SD Shield to tidy this up, soldering onto it connectors for the servos, Wii Nunchuck adapter, wireless trigger and LED cables. Hoping to downgrade to an Arduino UNO or similar for this project as I don't need all the extra pins or USB Host of the Mega ADK.



Update 01/10/12:

Received my BlinkM RGB LED today. I also received an UNO and SD Shield but will be leaving them in the box for now as I play with the code. So far I have the I2C comms working fine and colours update nicely. BlinkM is a bit too bright for such close quarters, I'll look at toning it down in code. I do have one major issue though, the Arduino is now locking up (no more movement from servos, LED constant colour). Possibly a memory leak or something.

I can complete some light paintings without trouble but not others. This is one taken with a rubber band to obscure the transparent body of the LED which was leaking light and smudging the image.



Update 10/10/12:

After spending several evenings fruitlessly trying to get the code to work on the Arduino UNO I gave up and instead concentrated on getting the microSD shield populated with the connectors I need to provide a more permanent (and I was hoping a more compact and tidy) home for this project. I've cut down on the number of jumper wires however still need a few as I need to connect the shield to the correct pins on the Mega.

Arduino Mega ADK and populated Sparkfun microSD shield

I've spent some more time on the software, adding a menu system to allow for changes to some parameters which were previously hard-coded. In the image above the menu is in the Resolution tab, having already selected a file from the File tab. Here I can chose to have a canvas larger than the image (resulting in a light painting that does use the full range of motion of the robot arm) or equal to the image resolution to strech the image out to the extremes of the robot arms space envelope. The next tab is Exposure, where the duration of the light painting is estimated and options are provided for changing the delay experienced at each pixel etc. The final tab is 'Settings' which is for misc options and currently holds a toggle for switching to an alternative function for the actual painting, which reads in an entire row instead of reading the SD card a pixel at a time.

Using some thin sheets of balsa wood I made a cover for the BlinkM to block out the light leakage. The LED still needs a diffuser as I'm still getting the lensing effect which is most evident in the first photo at the top of this page.

BlinkM with balsa cover



Simple sketch I threw together to grab the pixels from an image and turn them into an array for the Arduino sketch. Last updated 25/09/12.

int x_res = 32;
int y_res = 32;
String filepath = "heart32.png";
  // hard code image name/path
  // load image
  // read pixel by pixel and write value to text file
  // format as arduino array
  // copy and paste array from Processing output into Arduino sketch
  // sketch runs through the array and analog writes to the LED pin
void setup() {
  PImage b;
  b = loadImage(filepath);
  image(b, 0, 0);
  print("static const byte image[][");
  println("] = {");
  for(int y=0; y<y_res; y++) {
    for(int x=0; x<x_res; x++) {
// use one of the following lines:
//      print(int(red(get(x,y))));
//      print(int(green(get(x,y))));
//      print(int(blue(get(x,y))));
      if (x != x_res-1) print(",");
    if (y != y_res-1) println("},");
    else println("}};");

void draw() {

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

As I am currently also thinking about a wall light paint robot from this type. Your's is nice as well. 

Btw: you have succeeded the Write LMR Challenge.

NilsB, that's a nifty laser painter, could easily see something like that being set up as a wall clock (though it'd be a bit noisy for most places). Some folk use spinning/tilting lasers to redirect the laser path rather than moving the whole laser, but I guess that requires more than the usual spare parts bin would contain.

As for the Write LMR Challenge I guess I need to think about how I can make a video of this in action. Perhaps some clever video editing to layer all the previous frames in a video together to build up the orb image over the length of the video? Either that or time lapse long exposure shots (could look into controlling the time lapse/exposure duration with the Arduino).

Hmm, so many ideas, so little time.

Amazingly slick!

I love how the LED is kinda magnified in the "big globe". I wonder what it would look like, if you placed a small, tiny piece of black tape on one side / across some of the top of the LED, and just did a straight up "globe"?

And yer, you should submit on the challenge page: http://letsmakerobots.com/node/2023

Bowing to peer pressure I have submitted an image to the challenge page.

The light disperal shape is quite evident in that photo. In the latest photo (LMR logo) I've added an elastic band to block some light leakage. I'll need to look into a mask and some sort of diffuser to get a more even application of light.

I have a nice globe image on the sd card but currently it's one of the images which crashes the arduino. Once I've figured out what's holding the Arduino back I'll have a globe posted here for you fritsl =D.

Sorry - when I wrote "globe", i was thinking of "sphere" / "ball".

And the ones you already show, has what I think is a cool .. actually a magnified version of the small LED. So I was wondering if you / we would be able to see it as a "cutout", if there was tape, as described; Unevenly, like a spot, making the LED have a "dark spot" on it; Would that dark spot show on "the ball" on the photo, I wonder?

Apart from all this, if you are just looking to have clear versions of your displayed bitmaps, I think all you need to do, is to dip the LED in some hot glue. BUT DO THE TAPE-thingey FIRST :) Thanks!

Really like this project.. I think I have one of those nokia LCD's lying around, how'd you get it working?

Can't find the source of info I used originally but there is a wealth of info on the use of these Nokia 3310/5110 LCDs with Arduinos/PICs/etc.

http://ladyada.net/products/nokia5110/ http://www.myplace.nu/mp3/nokialcd.htm http://www.electro-tech-online.com/microcontrollers/32933-pic-interfacing-nokia-3310-lcd.html to name a few such sources.

I pulled some code off a website and adapted it to my needs. As for physically connecting it I stripped the ends of a ribbon cable and soldered them to the spring tabs on the back of the LCD (not all these LCDs have the spring tabs, some use a conductive rubbery strip for which a custom PCB may be required).