Introduction: RGB LED Pen for Lightpainting

About: I am a hobby photographer specialized in lightpainting and building tools for this. If you want to see more of my art check my FB, Instagram or Flickr page! You can find me under the same name there.

This is a complete build instruction for a light painting tool that uses an RGB LED controller. I use this controller a lot in my advanced tools and thought a documentary of how this is built and programmed can help some people.

This tool is a modular RGB light pen meant for light writing, light drawing and lighting graffiti. It is easy to use because you only have the pen in your hand and you can quickly change the colour.

The tool consists of:

  • a case that is 3D printed
  • an Arduino Micro
  • a WS2816B LED
  • two potentiometer (10K or 100K)
  • two switches
  • a push button
  • and some cables.

An Arduino Micro is perfect for this because it is extremely small and great to control RGB LEDs. You also might use even smaller microcontrollers like a LilyPad or even an ATtiny85, but I often use the Micro because it is easy to use as it comes with an USB connector ready to use. Both the Arduino and the LED are powered with 5V, so you have to take care of proper power support. This tool is designed to use four AAA rechargeable batteries because they usually have 1.2V and combined 4.8V which is enough to power both the Arduino and the LED. Take care not to use regular AAA batteries, because they have 1.5V and the combined voltage might be too much for the components and might damage them. If you want to use regular batteries please use only three, the voltage should still be enough. I used another great 3D printed part from someone else for the battery case that can be found here: "Flexing battery holders".

Step 1: Programming

First you need the Arduino IDE to program the micro controller which is free to download and use. This sounds quite complicated at first sight, but really is pretty simple. After installing the software you will get a simple text editor window that is used to code the sketch that is uploaded to the Arduino. This tool also uses the FastLED library which is a great and easy to use library that to control almost any kind of RGB LED you can buy. After downloading the library you have to install by placing the files in the library folder created by the Arduino IDE. This can usually be found under „C:\Users\{User Name}\Documents\Arduino\libraries“ if you haven’t changed it. After putting the library in this folder you have to restart the IDE if it is already running. Now we are ready to create the code for the controller.

Step 2: The Code

To use the FastLED library first we have to include it in our code. This is done at the top of the code before anything else with this line:

#include <FastLED.h>

Next we are going to define a few constants. This is done because these values will not change while the code is running and also to keep it more readable. You could put these values directly into the code, but then if you need to change anything you would have to go through the whole code and change every line the value is used in. By using defined constants you only need to change it at one place and don’t need to touch the main code. First we define the pins that are used by this controller:

 #define HUE_PIN   		A0
 #define BRIGHT_PIN   		A1
 #define LED_PIN		3
 #define LIGHT_PIN		6
 #define COLOR_PIN		7
 #define RAINBOW_PIN		8

The numbers or names are the same that are printed on the Arduino. Analog pins are identified by an A in front of its number, digital pins only use the number in code but are sometimes printed with a leading D on the board.

The potentiometer on pin A0 is used to control the hue of the colour, the potentiometer on pin A1 is used to control the brightness. Pin D3 is used as a signal to the LED so the Arduino can send data to control the color. Pin D6 is used to toggle the light and pin D7 and D8 are used to set the mode of the controller. I have implemented to modes in this controller, one simply puts the color defined by the colour potentiometer on the LED, and the other will fade through all colors. Next we also need a few definitions for the FastLED library:

 #define COLOR_ORDER	GRB
 #define CHIPSET	WS2811
 #define NUM_LEDS	5

Chipset is used to tell the library what kind of LED we are using. FastLED supports almost any RGB LED that is available (like NeoPixel, APA106, WS2816B, etc). The LED I use is sold as WS2816B but seems to be a bit different so it works best using the WS2811 chipset. The order of bytes send to the LED to set the color can also differ between manufacturers, so we also have a definition for the byte order. The definition here just tells the library to send the color in the order green, red, blue. The last definition is for the amount of LEDs that are connected. You can always use less LEDs then you define in code, so I set the number to 5 because with this tool I won’t be designing pens with more than 5 LEDs. You could set the number much higher but because of performance I keep it as small as I need it.

For the main code we also need a few variables:

 int brightness = 255;
 unsigned int pot_Reading1 = 0;
 unsigned int pot_Reading1 = 0;
 unsigned long lastTick = 0;
 unsigned int wheel_Speed = 10;

These variables are used for brightness, readings from the potentiometers, remembering the last time the code was executed and how fast the color fade will be.

Next we define an array for the LEDs which is an easy way to set the color. The defined amount of LEDs is used to set the size of the array here:

CRGB leds [NUM_LEDS];

After taking care of definitions we can now write the setup function. This is quite short for this program:

void setup() {
  FastLED.addLeds(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  pinMode(LIGHT_PIN, INPUT_PULLUP);
  pinMode(COLOR_PIN, INPUT_PULLUP);
  pinMode(RAINBOW_PIN, INPUT_PULLUP);
}

The first line initializes the FastLED library using the definitions we set previously. The last three lines tell the Arduino that these pins are used as input and that if not connected to anything their voltage should be set to high (PULLUP). This means we have to connect these pins to GND to trigger something.

Now we can take care of the main program. This is done in the loop function. First we are setting some variables and read out the potentiometers:

void loop() {
  static uint8_t hue = 0;
  static uint8_t wheel_Hue = 0;
 
  pot_Reading1 = analogRead(HUE_PIN);
  hue = map(pot_Reading1, 0, 1023, 0, 255);
 
  pot_Reading2 = analogRead(BRIGHT_PIN);
  brightness = map(pot_Reading2, 0, 1023, 0, 255);

The first two lines set variables that are later used for the color. The two following blocks take care of reading the potentiometer values. Because you get a value between 0 and 1023 if you read out a pin using “analogRead” but the hue and brightness needs a value between 0 and 255 we use the “map” function to translate the readout from one value region to another. The first parameter of this function is the value you want to translate, the last four are the minimum and maximum of the regions you want to use for translation.

Next we are going to evaluate the pushbutton:

if (digitalRead(LIGHT_PIN) == LOW) {

We check the reading against LOW because we defined the pin to be high if not triggered. So if the push button is pressed the pin will be connected to GND and would read low. If the pins is not pressed there is not much to do.

First let’s take care of just lighting the LED in one color:

if (digitalRead(COLOR_PIN) == LOW) {
      if (hue < 2) {
        FastLED.showColor(CRGB::White);
        FastLED.setBrightness(brightness);
      } else {
        FastLED.showColor(CHSV(hue, 255, brightness));
        FastLED.setBrightness(brightness);
      }
      delay(10);

We need to evaluate the color pin to know that we want to use this mode. Then we can check what color is needed. Since the HSV colour model is used here we only need the hue to define a color. But this also creates the problem that we don’t have a way to set the color to white. Since hue 0 and hue 255 both translate to red I use a little trick here and check if the reading from the hue potentiometer is smaller than 2. This means the potentiometer is turned all the way to one side and we can use this to set white. We still have red on the other side so won’t lose anything here.

So either we set color to white and then the brightness or else we set the color based on the hue reading and also the brightness.

Afterwards I added a small delay because it is much better to give the controller a little downtime to save power and a delay of 10 milliseconds will not be felt.

Next we are coding the color fade:

 else if (digitalRead(RAINBOW_PIN) == LOW) {
      wheel_Speed = map(pot_Reading1, 0, 1023, 2, 30);
      if (lastTick + wheel_Speed < millis()) {
        wheel_Hue += 1;
        if (wheel_Hue > 255) {
          wheel_Hue = 0;
        }
        lastTick = millis();
      }
      FastLED.showColor(CHSV(wheel_Hue, 255, brightness));
    }

First the pin to toggle this mode is checked. Since I didn’t want to add a third potentiometer to control the speed of the fade and since the hue potentiometer is not used in this mode we can use that potentiometer to set the speed. Using the map function again we can translate the reading to a delay that is translated into the speed of the fade. I used a value between 2 and 30 for the delay because from experiences this is a good speed. The function “millis” will return the milliseconds since the Arduino was powered on, so we can use this to measure time. The last change of hue is stored in a variable we defined earlier and this is compared each time to see if we have to change the hue again. The last line just sets the color that needs to be displayed next.

To finish the code:

 } else {
    FastLED.showColor(CRGB::Black);
  }
}

We just need to turn off the LED if the button is not pressed by setting the color to black and close any open brackets.

As you can see this is a pretty short and easy code that can be used for a lot of tools that use RGB LEDs.

Once you have the full code you can upload it to the Arduino. For this hook up the Arduino to your PC with a USB cable and select the Arduino type in the IDE.

In this instructions I use the Arduino Pro Micro. After setting the Arduino model you have to select the port where the IDE can find it. Open up the port menu and you should see your connected Arduino.

Now the only thing to do is uploading the code to the Arduino by pressing the second round button on the top of the window. The IDE will build the code and upload it. After this was successful you can disconnect the Arduino and continue assembling the controller.

Step 3: Assembly of the Electronics for the Controller

Since we took care of coding the Arduino we can now assemble the controller hardware. We start by putting the components inside the case. The potentiometers go in the two round holes on the left, the switch for power is at the bottom, switch for the mode is at the top right and the Arduino goes in the holder in the middle.

Step 4:

Start by soldering a red cable from the power switch to the RAW pin of the Arduino. This pin is the go to pin for power supply since it is connected to a voltage regulator, so even if the voltage is higher than 5V this pin can be used to power the Arduino. Next solder another red wire to the VCC pin since we need the high level voltage for the potentiometer. Solder two white wires to the A0 and A1 pins to be used for the potentiometer readings.

Step 5:

Now put a long white and a long green wire through the opening at the top which are later used to connect the LED. Solder the green to pin 3 and the white to pin 6 and press them flat on the Arduino. Solder two black wired to the GND pins on the left side of the Arduino, these are used for the low level voltage for the potentiometers. Solder two blue wires to pin 7 and pin 8 to be used for the mode switch.

Step 6:

The red cable we soldered on the VCC pin now needs to be soldered to one of the outer pins of the first potentiometer. Use another red cable to continue this to the second potentiometer. Take care to use the same side on both potentiometers so full on will be the same side on both. Solder the two black cables to the other side of the potentiometers and the white cables from Pins A0 and A1 on the middle pin. Potentiometers work by setting the voltage on the middle pin to a voltage between the voltages applied to the outer pins, so if we connect high and low voltage we can get a voltage in between on the middle pin. This completed the wiring for the potentiometers and they can be turned a little so the pins are out of the way.

Step 7:

Solder a black cable to the middle pin of the mode switch and put a long black cable through the opening leading to the power supply. Put another long black cable through the top opening to be used as GND for the LED.

Step 8:

The black cable coming from the power supply is soldered to another black wire that is connected to the last free GND pin of the Arduino. Solder the wire leading to the LED and the black wire on the mode switch together and finally solder the two pairs of black wires you now have together. Use shrinking tube to isolate the soldering to prevent shorts inside the controller.

Step 9:

As a last step we can now solder the two blue wires to the mode switch. These switches work by connecting the middle pin to one of the outer pins depending on which side the switch is on. Since pin 7 and 8 are set up to be triggered when connected to GND we can use the outer pins of the switch for the pins and the middle for GND. This way one of the pins is always triggered.

Finally put a red wire through the power opening and solder it on the middle pin of the power switch and put another long red wire through the opening to the LED and solder this to the same pin on the power switch that the Arduino is connected to.

Step 10:

Solder the power cables to the battery holder and screw in the clip that holds the cables leading to the LED. This completes the wiring for the controller.

Step 11: Assembly of the Light Pen

Since this tool is meant to be modular and use different pens we need a connector on the wires for the LED. I used a cheap 4 terminal molex connector that can usually be found on cables used for fans in a computer. These cables are cheap and easy to get, so they are perfect.

Step 12:

When I started wiring the controller I did not check the colours of the cables on the connectors so they are a little different, but easy to remember. I connected the black wires, power to yellow, green on green and white on blue, but you can use any combination you like, just remember it for the other pens too. Take care to isolate the soldered areas with shrinking tube to prevent shorts.

Step 13:

Put a long red and a long green wire through the pen and solder black wires to one side of the push button and white wire to the other side. These kind of push buttons have four pins of which two are connected in pairs. You can see which pins are connected by looking at the bottom of the button, there is a gap between the pairs that are connected. If you push the button the two sides are connected to another. The white and one black cable are then pulled through to the end of the pen starting at the opening for the button. The other black cable is pulled through to the front. Make sure you have enough cable at both sides to work with.

Step 14:

Press fit the button in the opening and prepare the rest of the cables. It is best to solder the cables to the LED so that they are facing towards the middle of the LED because the cables run through the middle of the pen. Solder the red wire to the 5V solder pad, the black wire to the GND solder pad and the green wire to the Din solder pad. If you have more than one LED the Dout solder pad of the first LED is connected to the Din of the next LED and so on.

Step 15:

Now push the button in the front of the pen and put a drop of glue behind it to hold it in place.

Now you just have to solder the wires at the end of the pen to the other side of connector keeping in mind of the colors.

It is best to use a drop of glue and some tape to stress release the cables at the end of the pen to prevent them from breaking.
This completes the assembly of the light pen.

Step 16: Examples

Finally I want to show you a few examples where I used this tool. The angled pen is great to light the lines of a graffiti and the straight pen is great to draw and write stuff in the air (for which I have only little talent).

This is the main purpose of this tool. As you can see the possibilities are amazing if you combine long exposures with this tool.

To start with this kind of photography try to use lowest ISO setting your camera supports and high aperture. A good way to find the right settings is putting your camera in aperture mode and close the aperture till your camera shows an exposure time of around the time you need to draw what you want to add into the picture. Then switch to manual and either use that exposure time or use bulb mode.

Have fun trying these out! It is amazing art form.

I added this instruction to the inventors and unusual uses challenge, so if you like it leave a vote ;)

Step 17: The Files

I also added models for strap holders that are meant to be glued on the bottom of the controller case so you can strap it on your arm and a clip for the pen that can be glued to the lid for when you don’t need the pen in your hand.

There are also diffuser caps that can be used to make the light smoother and prevent flares when the pen points directly into the camera.

Invention Challenge 2017

Participated in the
Invention Challenge 2017

Unusual Uses Challenge 2017

Participated in the
Unusual Uses Challenge 2017