16×8-pixel-laser-projector

As I was playing with my Arduino and a laser from an old DVD-writer I wanted to see if I could build a ‘proof-of-principle‘ DIY laser projector. Long story short: I did and I could. Now that I have almost overcome all the possible challenges that I have met in this process, I have shared my experiences on this website for others who’d like to start a similar challenge (or are just interested).

 

Basic idea

As I got inspired from all the other DIY laser projectors out there I wanted to build my own. Just knowing that I would pick-up on a fair deal of knowledge along the process was motivation enough for me to get started. At first I was pretty cynical on succeeding on an actual multi-line multi-pixel laser projector, as my programming skills were very basic at the time. Luckily my aim was to learn and experience the process of soldering and coding, so I was happy with very small victories at the start. Just getting one projected line on which I could control 4 pixels was my first sub-goal. In order to get a laser projection of multiple pixels on multiple lines, I used the following components:

A laser diode salvaged from an ‘old’ 16x DVD-Writer and an IR sensor to sync the laser pulses with the rotation of the mirrors

 

 

 

 

 

 

A LM317-based laser driver with an added TIP31A linear switching transistor to control the laser via the Arduino

 

 

 

 

 

 

 

An Arduino and an XBee to wirelessly process incoming bytes into laser pixels

 

 

 

 

 

 

A hard disk platter with multiple mirrors, each positioned at a slightly different angle on a motor which spins the disc at around 20 times per second.

 

Capabilities:
Draw real-time images with the laser projector using the mouse and move image horizontally and vertically using the arrow keys on the keyboard.
Save and load previously drawn images and display them on the laser projector. Do this 20 times a second: Laser movie!
Display scrolling text from manually entered strings or loaded from websites (for example the latest weather update). Each character has been drawn and saved as explained in the first two steps.
Use the video feed of a webcam, translate to a black and white image of 16×8 pixels, and display on the laser projector.

Serial communication

To be able to display monochromatic images of 16 pixels in width and 8 pixels in height, the Processing sketch loads the pixel data of each image into 16 individual bytes. Each bit within a byte represents a pixel. The first byte holds the top 8 left-most pixels, the seconds byte holds the 8 top right-most pixels, etc. See the image below for how the image is build-up.

 

I used a pair of XBee’s for wireless data transmission. This was actually a side-effect as I just needed an extra hardware serial buffer next to the serial buffer of the Arduino in order to precisely control when the serial data get’s processed by the serial buffer of the Arduino. I found out that the Arduino buffers serial incoming data using an interrupt routine. This routine takes around a few hundred microseconds which is enough to disrupt the timing of the laser pixels (as the pixel length is 100 microseconds). I use the XBee serial buffer to catch the incoming data and forward the data when the Ready-To-Send pin of the XBee is de-asserted by the Arduino exactly at the moment the Arduino is in between painting pixels.

Check out the Arduino code here.

Check out the Processing codes here.

Things learned

  • Serial communication including handshaking, buffering and syncing
  • Interrupt handling
  • Bit shifting and byte splitting and rebuilding
  • Laser non-resilience or the importance of a thoroughly tested voltage regulator for driving the laser ( I lost 4 laser diodes in the process)
  • The importance of efficient coding when microsecond precision is required
  • A higher-than-zero-volts baseline on the laser driver is needed when the laser needs to be switched on and off for tens of microseconds. A completely turned off laser takes significantly more time to energize than a slightly activated one.