Laser Galvo

Arduino driven Laser display: Also on Instructables

Experiments with lasers can lead in all sorts of unexpected directions. It turns out that UV laser pointers (405nm) make glow in the the dark materials light up super bright!

galvo-a09

I sent off for a sheet of luminous vinyl and set about some hacking. Waving the laser pointer round on the vinyl leaves a persistent glowing trace, just like an old style cathode ray tube.

galvo-a07

All sorts of ideas sprung to mind. Could I make an oscilloscope? An ECG? A simple scanning TV style display? Let’s start simple: one of those sine wave displays from old sci-fi movies. I’ve come up with a hardware platform that I hope will let me start simple but then experiment with more complex ideas.

I’m using off the shelf servos driven by an Arduino to steer the beam from the laser.

galvo-a02There are two servos, one for the x axis, one for the y. I’ve attached a small circular mirror tile to the servo.

This stand is made from 3mm laser cut ply – there is a pdf of the parts here.

galvo-a03

I clamped the servos in place rather than gluing then to make it easy to make small adjustments.galvo-a04

All the parts fit together like this:
galvo-a06

…and the servos are connected to the Arduino board. I’ve used pins 9 &10 for the servo control lines.
galvo-a05

Here’s the code for the Arduino:

/* Galvocode
 
 
*/ 

#include <Servo.h> 
 
Servo xservo;  // xaxis servo object 
Servo yservo;  // yaxis servo object 
                
int xcount = 0;    // variable to store the x increment 
int ycount = 0;    // variable to store the y increment 
 
int xpos = 0;    // variable to store the x servo position 
int ypos = 0;    // variable to store the y servo position 

int xamplitude = 20;  //variable stores the max sweep of the servo - maximum value is 180
int yamplitude = 20;  //variable stores the max sweep of the servo - maximum value is 180

int xoffset = 120;  // variable stores x servo offset position 
int yoffset = 100;  // variable stores y servo offset position 

int xcentre = 0; //centre of travel for the servo
int ycentre = 0;

int xwavelength = 100; // number of loops to complete one x cycle
int ywavelength = 300; // number of loops to complete one y cycle

float xangle = 0; //current x angle goes from 0 to 2 
float yangle = 0; //current x angle goes from 0 to 2 

float xstepsize = 0;
float ystepsize = 0;
 
void setup() 

{
  xservo.attach(9);    // attaches the servo on pin 9  to the servo object 
  yservo.attach(10);   // attaches the servo on pin 10 to the servo object 
  
  
  xcentre = xoffset + xamplitude/2; //
  ycentre = yoffset + yamplitude/2; //
} 
 
void loop() 
{ 
  if (xcount == xwavelength) xcount = 0; //reset xpos at the end of cycle
  if (ycount == ywavelength) ycount = 0; //reset ypos at the end of cycle
  
  xcount++; //increment x counter
  ycount++; //increment y counter
  
  xangle = (6.283/float(xwavelength))*xcount; // 2 * Pi rads in a circle
  yangle = (6.283/float(ywavelength))*ycount; // 2 * Pi rads in a circle
  
  xpos = int(xcentre + ((sin(xangle))*xamplitude)/2);
  ypos = int(ycentre + ((cos(yangle))*yamplitude)/2);
  //Serial.println(xangle); debug line
  xservo.write(xpos); 
  yservo.write(ypos); 
  delay(3);

} 

Here’s the code in action.

galvo-a08
Next step, I think I’ll have a go at a simple raster display.