Introduction: 8-bit CNC Light Painting Long Exposure Tutorial!

About: I recently finished med school and spend every little time that isn't used on my doctoral thesis or work on my hobbies!

Hi everyone. You have an old 3D printer / laser cutter / CNC mill lying around? You have always been fascinated by long exposure pictures and have a fondness of 8-bit graphics? Well, look no further! Let me show you how I turned my old (and still in use) 3D printer into a tiny G-Code controlled artist!

The concept is very easy: Get your machine to position a RGB LED on programmed coordinates and display single colorful pixels to produce one total picture on a camera set on long exposure photography. Also the premise is to use a preexisting system that can afterwards still be used in its original manner without interference. An Upgrade!

Many systems nowadays offer swappable tool heads. But I've never seen a LED tool head. Why? Well, with this instructable you can make your own! (Have you ever seen a LED tool head? Let me know in the comments!)

How does it work?

CNC machines are programmed by G-Code. To put simply, it is a text file that contain coordinates, speeds, tools and other settings that are interpreted by the machine to movements along different axis. If you take a look at the files you send to your 3D printer or laser cutter you will find things like this:

M104 S230 ; set temperature
G92 E0
G1 Z0.300 F3600.000
G1 X-0.000 Y22.956 F3600.000
G1 E1.50000 F1800.00000
G1 X-30.000 Y22.956 E1.80732 F1440.000
G1 X-31.139 Y22.904 E1.81901

In this instructable I will show you how to use G-Code M42 or M106 to program your CNC machine in order to control a RGB LED that is connected to your machine.

Step 1: What You Will Need


  • Any 2 or more axis CNC
  • Teacup as your firmware
    • Any firmware should work because we use valid G-Code. In this instructable I use Teacup, a widespread and open source firmware. If your machine runs on something else don't worry! We will look at your options later.
    • (I haven't tried marlin, yet. But it should work as well.)
  • ATmega2560 as your machines hardware
    • Any board should work though, as long as it has free usable PWM outputs.
    • (Including an electronics board like RAMPS or Sanguinololu etc. I use a self made electronics board.)
    • you can get 10x of these on eBay for about 5€. I got 100x from china and payed even less per item.
    • common cathode type! Any RGB LED consists simply of three (or more) single LEDs of different color that are put together into one package. Common cathode means that all the negative connections of these LEDs are combined internally into one single leg of the RGB LED to make the package smaller.
    • try to get diffused ones for better light "mixing"
  • Resistors + cables and connectors
    • a few cents each at any electronic store
      • we will determine the value of the needed resistors in the next step
  • Black foam and paper
    • optional, to manage the emitted light
    • some tools for cutting, gluing and making holes
  • Camera
    • with bulb mode - a setting to leave the shutter of the camera open for as long as the button is pressed.
    • a tripod - obligatory for long exposure photography
    • recommended: a remote control to minimize vibrations while taking the picture
      • 1x 2,5mm to 3,5mm converter
      • 1x regular 3,5mm audio extension cord male to male
      • 1x crocodile/alligator clips
  • A Windows PC
    • my application is compiled into an .exe format
    • if you run a different OS you might get it to work on a virtual pc


  • Soldering Iron
  • A picture to G-Code converter
    • Download mine (of course it's free and always will be)
      • if you find errors or have suggestions let me know in the comments!

Price: cheap

Difficulty: medium - hard

In theory this is a very simple instructable but unfortunately chances are that your CNC uses a different Hardware and/or Firmware. Therefore hits can only be seen as a guideline of steps to follow. You will likely need to adjust to your own system. That makes it a bit harder. I'll try to help along the way. If any question remains unanswered leave a message!

Step 2: The Hardware: RGB LED - Resistor Calculation

Preparing the RGB LED is the easiest part. It's the same as connecting any LED to a PWM output of your microcontroller. It's just 3 of them in a single package! The negative leads (also known as cathodes) are just typically combined together into a single leg of the LED to save space and materials.

First of all let's look at the datasheet and find out the values we need.

Forward current:

  • typically 20mA
  • the maximum allowed current to flow through the LED to produce the brightest light

Forward voltage drop:

  • typically between 2V - 3,5V depending on used color and material of LED
  • is determined by the characteristics of the diode of the Light Emitting Diode

In our case:

  • 20mA for all three colors
  • 2V forward voltage drop for RED
  • 3,4V forward voltage drop for GREEN and
  • 3,4V forward voltage drop for BLUE

To calculate the necessary resistor value "R" that needs to go in series with the LEDs we'll use good old Ohms Law:

R = U / I or Ohm = Volt / Ampere

Ampere is given with 20mA = 0,02A.

Volt is our systems logic voltage - the forward voltage drop of the LED 5V - 2V = 3V (RED) and 5V - 3,4V = 1,6V (GREEN and BLUE).

Putting that in out formula gives us:

R = (5V - 2V) / 0,02A = 150 ohms (RED)

R = (5V - 3,4V) / 0,02A = 80 ohms (GREEN and BLUE)

Because there is not an infinite amount of resistor values to choose from one normally settles for the next bigger option (or puts resistors in series). In our case 150 ohms and 82 ohms.

NOTE: These calculated resistor values also play a role in the color spectrum of the produced image. More about that in the end of this instructable.

Too fast? Don't worry there are plenty of good instructables to cover this topic. See here or look what Evil Mad Scientist has to say about that.

Step 3: The Hardware: Building the RGB LED

Now let's solder everything together!

  • cut legs of LED to different lengths
  • solder wires to legs
  • don't forget to put two sets of shrinking tube on for both ends!
  • solder on pins at the end of wire
  • use shrinking tube to isolate the solder joints

I recommend to cut the legs of the LED in a stair like fashion instead of equal length. This way the blobs of solder on each leg are on a different height and do not interfere with each other over time under the vibration of the CNC.

Alternatively you can directly solder on the resistors at this point. I however chose to breadboard them instead, to be able to change the resistance later on. In case I wanted to adjust maximum brightness. Also it is easier to solder this way.

NOTE: I recommend to wash hands after soldering to get rid of any metal residue before eating. People might argue about this and tell you that it is not necessary because of only minuscule amounts of metal, but hey. It definitely won't hurt either.

NOTE: Always solder in a well ventilated area and try to avoid the fumes.

Step 4: The Hardware: Building the RGB LED Cover

You can build one of these covers if you want your CNC artist to produce a colorful dot at each stop that is supposed to be smaller than the RGB LED you use. Also you could have it shaped differently. A heart maybe?

For me it also increased the contrast of the resulting picture and helped reduce "background illumination" from the LED.

If you only have a clear LED I definitely recommend using one.

  • draw a circle on a piece of foam and cut it out
  • take anything you find to punch (or melt) a hole through your black foam disc
    • precision is important, any rugged edge will be visible on the final picture!
  • take a strip of foam and wrap it around your LED
  • tape it in place
  • glue a piece of paper on one side of the disc
  • glue the cylinder on top of the paper
    • make sure that the opening of the disc and the cylinder are aligned!
    • leave the LED in the cylinder to help it retain its shape
    • be careful not to glue the LED in place

Step 5: The Firmware: Tweaking Teacup

To get and set up Teacup and its configuration-tool follow the instructions here on this website or go directly to the GitHub page.

Follow the instructions for the to set up your CNC if you haven't done that already. In order to additionally prepare the machine for our use try the following methods:


  • Open
  • Go on: Board >>> Heaters >>> Add
  • Add three fans and chose the PWM pins the system offers. Write them down, you are going to use them later!
  • Next step: Printer >>> Miscellaneous >>> Fast PWM
  • Check the box to enable the function

NOTE: as stated by the firmware if you turn on the Fast PWM options you might run into troubles with overheating MOSFETs because of high switching frequencies (and other cool physics. I recommend this great video). Keep an eye on them if you are using this setting for the first time!

That's it! Save and upload to you hardware and you are ready for the next step!

If you however have problems using the follow the next instructions.


  • Go to your Teacup folder, typically named Teacup_Firmware-master and open the <config> folder
  • Look for board.yourBoard.h and open it in editor or WordPad
  • Scroll down until section 4. HEATERS
  • It should look like the picture above.
  • Find DEFINE_HEATER(name, pin, invert, pwm) and add three more fans, just like you would have done in the EASY METHOD
  • save and close
  • Go back to the folder and open printer.yourPrinter.h
  • scroll down until section 7. MISCELLANEOUS OPTIONS and look for FAST_PWM
  • change //#define FAST_PWM to #define FAST_PWM by deleting "//" in front of the statement
  • save and close

Done. Upload and ready for the next step.

NOTE: if you are using an ATmega2560 you can see which DIOpin corresponds with which Hardware-pin in the list above and you can use the pin mapping of the CPU (from to determine where to plug in your LEDs on the board. If you use a different CPU look under Teacup_Firmware-master >>> arduino_yourCPU.h to find your pin assignments.


In case you don't use Teacup check here under M42 and M106 to see if your firmware supports any of those two methods for user set PWM output. I'm sorry I can't give you instructions with that! Try the comments section or google for hints if you have problems at this stage.

Step 6: The Hardware: Connecting the RGB LED

Remember the output pins you defined in your firmware? If you use an ATmega2560 you can use the table and picture above to figure out your physical pins to connect the LEDs to.

In my picture you can see three jumper wires in the corresponding colors that connect to the LEDs through the resistors we calculated. (You can see the use of 150ohm resistors only. I put two in parallel to get 75 ohms for GREEN and BLUE because I didn't have anything else at the time. I know, I know...)

Black goes to GND on one of the ATmega2560 ground pins.

NOTE: Even when the LED is supposed to be off it will still glow dimly. The reason for that lies in the way PWM works. For these pictures it won't matter though! So no worries.

The LED itself is just taped to the extruder of my printer! If you made one, you can slip your LED cover on, as well.


Step 7: The Software: Turning Your Picture Into G-Code

I'll show you how to turn a picture into G-Code with my self made application you can download here. For more information about the settings read the manual.txt.

To get started just load a picture and follow the green buttons with the standard settings. It will get you a reference point to start with. Then start again and begin tweaking the options!

At any point in the program you can go back to previous options by using the buttons in the Workflow area at the top left of the screen.

Open Image / Led spacing

  • Find and download any picture you would like to convert into CNC pixel art
  • Start SuperDweeb v0.7.exe
  • glare at extremely funny starting screen
  • click Open Image to load a .jpg or .bmp file
  • under Led Spacing choose how many pixels you want
    • keep in mind that this will indirectly determine the resulting size of the final picture
  • click Apply
  • when you are happy with the way the resulting grid covers your input picture continue to the next step by clicking LED colors in the workflow overview

LED colors

  • The LED color value options are not completely developed, yet. :(
  • but you can use show background / box grid to change the preview image to see the adjustments more easily
  • click Apply
  • click Export G-Code to get to the last step

Export G-Code

  • chose M106 if you use Teacup and followed my instructable so far or M42 if you set up your printer differently
  • RGB Fan #No. Remember when we set the pins for the Fans in under Heaters or in the text files ourselves? The position in the list at which we added those "fans" is now the number you have to insert into these textboxes. Be aware that the numbers of these pins are zero indexed. Which means that the first element in the list has the number 0 and not 1 which would seem more natural.
  • Spacing between dots on X-axis [mm] put in the size of your LED or the size of the opening of the LED cover you made
    • this will also calculate the Resulting size [mm] that you can use later to set up your camera correctly
  • Choose whether you use X and Y axis or X and Z.
  • Set the speed you want the separate axis to move (in mm per minute!!)
  • click Export and choose a path and filename
  • G-Code generation is done!!! Go try it out

Step 8: The Picture: Setting Up Your Camera & Go!

When everything is prepared it's time to go to the last step. Taking the picture!

The Camera

  • Set your camera on lowest light sensitivity. Otherwise the picture you take will easily overexpose because of the longtime exposure in bulb mode.
  • I use: ISO100, f-stop 22, exposure time: bulb, white balance: automatic on a Canon EOS 600D with a EF 50mm 1:1.8 II prime lens.
  • Set up your camera on your tripod and aim at your CNC machine
  • Put the RGB LED in the bottom left corner of you view finder and zoom in / out enough to capture the whole expected travel path of the LED
    • use Resulting size [mm] from the program and a ruler to help you with that
  • Set up your remote-control-ghetto-fix apparatus
    • plug in the 2,5mm to 3,5mm converter into the remote control jack of your camera
    • connect the extension cable to the converter
    • attach alligator clips to shown areas of the aux cable plug
  • Focus your camera on the LED and switch off the automated focus of your lens
    • focusing is not overly crucial at this point because of the high f-stop


  • Depending on your system either:
    • load the generated G-Code file on your PC and connect it to your CNC to start the "print" or
    • transfer your file to your CNC machine and be ready to press start
  • Make sure the room is completely dark
  • Start the G-Code!
    • depending whether you turned the initial wait [ms] function on or off the machine will delay the specified amount of milliseconds before the LED goes on
      • it might start moving though!
  • start the camera before it starts blinking
    • i.e. attach the alligator clip to the end of the aux plug
  • wait and enjoy!
    • Appx. total time xxx min. gives you a rough estimate on the time you need to wait
  • stop bulb mode when the machine stops blinking
    • i.e. rip off alligator clips

NOTE: You are going to stare a rapidly blinking lights in a dark room. I feel like I need to insert a disclaimer about Epilepsy. This can definitely be a trigger! If you had any problems with this in the past go see a physician! Even people who never had problems with this before can have a seizure when staring at blinking lights (for a prolonged period of time, when other circumstances are met, as well). Be warned. Be safe. I will not be responsible for any harm done. When in doubt, don't do it.

Step 9: Examples and Further Thoughts

    Showing a few more examples and talking about some (not very relevant) info regarding the output quality of this system:

    • The RGB LED you use will not be completely white balanced. This means that when you turn the LEDs on at full power the result will not be a perfectly clear white. This is because of several reasons:
      • The three separate LEDs in the package produce light at different intensities as stated in the datasheet
      • even if the LEDs would be perfectly balanced, the human eye isn't. The sensitivity towards light is not constant along the complete range of the wavelength of visible light. It depends on the physical properties of the cone cells in the retina.
      • even if the human factor would be considered by the - at this point extremely thorough - RGB LED manufacturer, the CMOS sensor of my camera also has a different sensitivity spectrum compared to my eyes. What seems white to me, will always be - ever so slightly - differently colored to a machines perception.
        • arguably you could also say that for the difference in perception between two humans as well!
      • even if all this factory would miraculously be taken into account and if I had a RGB LED that was specifically made for my eyes, my camera and this instructable. Temperature influences the generated wavelengths of LEDs. So this whole setup would need to be placed inside a room that would meticulously be kept at a constant temperature. Check out this cool video!
      • In my case though: It looks kinda white, so that's good enough for me...
    • Furthermore, the output brightness of any LED is never completely linear compared to the input signal
      • This means that mixing them at different values can lead to different colors.
        • Basically: Full RED + full GREEN will result in a different shade of yellow than half RED + half GREEN
      • This input / brightness relation can be influenced by the value of our used resistors

    If you enjoyed this instructable or even MADE YOUR OWN CNC ARTIST let me know in the comments!!!

    Lights Contest 2017

    Participated in the
    Lights Contest 2017

    Photography Contest 2017

    Participated in the
    Photography Contest 2017