Header image  
Technology Tinkering  
 
 

Laser Harp Construction I: Arduino MPU

<< Back to Introduction


NEW- LASER HARP PLANS!!


BUILD YOUR OWN LASER HARP!

(and dazzle your friends)

Full parts list, circuit diagrams, schematics and source code are now avaliable for purchase in the online store,
22 years of research
available now...

Click Here For The Plans


 

Commercial laser show systems using a very fast moving mirror under computer control to bounce the laser light around very quickly. Much quicker than the human eye can see. The device that generates the signal that moves the mirror is called Digital to Analog Convertor (DAC). The first challenge in building a laser harp is to create this DAC system.

I chose an Arduino board to use as it supported all the key elements required for the harp:

  • SPI interface - to connect to a DAC chip
  • Timer interrupts - to control the signal pattern we must output
  • Hardware interrupt pins - to react to signals coming back in from a sensor.
  • Serial output - to transmit the MIDI messages to the synthesizer.
  • Easy to program using the WIRING / C++ language
  • Good community support.
  • Inexpensive!!!

Arduino

You can find out more about the Arduino here: www.arduino.cc
and you can buy them here, here, and here

The next thing we need is a DAC chip, similar to what you might find in a CD player. Based on the work of this gentleman I chose the TLV5618 12bit DAC, available here.

This chip supports the SPI interface, additionally requiring GND, 5V and a reference voltage. I used a potential divider with a bypass capacitor to feed 2.048v into the reference input - which is where it should be, according to the Datasheet.

DAC

Wire up the Arduino pins as shown, this connects the hardware SPI interface to the TLV5618. You might want to add another bypass cap to the +5v power supply just to keep things smooth. R is 20K, and C is a standard bypass cap 0.1uF. We are going to use the output from DAC A - this will be the input to the circuit on the next page.

THE CODE

The DAC is 12bit, so we need to operate over a 0-4095 range. We need to write a function that takes an integer value and sets the DAC to that output level.

// DAC Data Transfer
#define SLAVESELECT 10 // CS
#define DATAOUT 11 // DIN
#define SPICLOCK 13 // SCLK

First thing we need to do is configure the SPI interface correctly inside the Arduino.This routine should be put inside the setup() function:

// Setup SPI Interface code BEGIN ///////////////////////////////////////////
byte clr;
pinMode(DATAOUT, OUTPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(SLAVESELECT,OUTPUT);

digitalWrite(SLAVESELECT,HIGH); //disable device

//The SPI control register (SPCR) has 8 bits, each of which control a particular SPI setting.

// SPCR
// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |0000000000000000000
// | SPIE | SPE | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |

// SPIE - Enables the SPI interrupt when 1
// SPE - Enables the SPI when 1
// DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0
// MSTR - Sets the Arduino in master mode when 1, slave mode when 0
// CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0
// CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0'
// SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)

SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA);
clr=SPSR;
clr=SPDR;
delay(10);

So now we can write a function SetVoltage(int) that will change the DAC output.

/////////////////////////////////////////////////////////////////////
// DAC SPI Interface
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}

/////////////////////////////////////////////////////////////////////
// Set the voltage on the 12bit DAC
byte SetVoltage(short Voltage)
{
Voltage = Voltage | 32768; // Use DAC A

digitalWrite(SLAVESELECT,LOW);

//2 byte opcode -- for some reason we have to do this twice to make it stick with the TLV5618
spi_transfer(Voltage>>8);
spi_transfer(Voltage);

spi_transfer(Voltage>>8);
spi_transfer(Voltage);

digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
}

So now we can set voltage output from the DAC very quickly - this will come in handy later when we have to steer the laser beam.

If you don't have access to an oscilloscope, then you might find this project difficult. My first laser harp in 2005 was static and used this device to connect the electronics to a pc - it also operates as a 50Khz oscilloscope. The following image shows the output from the DAC - this is the waveform we need to create to drive the mirror and create the 10 beams.

Arduino 10 beams Note - this shows a differential signal - the next section will show how you take the output of the DAC (0-5v) and create the signal shown above.

MIDI INTERFACE

Standard MIDI is really simple to implement on the Arduino - complete instructions can be found here You need to wire in a DIN connector, and set the serial port interface to the MIDI rate 31250 bps.

Note - it's actually possible to create a MIDI interface over the USB connector on the Arduino - direct to the PC. I forget exactly where I got this information, but it's worth showing here :

You will need to download the Roland to Serial to MIDI Driver from their website - sorry I don't have the link offhand but I googled it fairly quickly.

Next, you will have to edit the FTDI drivers that come with arduino so that you can run the serial port at 31250 bps. You will need to make a few changes to FTDIPORT.inf

Look for [FtdiPort232.NT.HW.AddReg] and change the the second line below to the one that i've got here.

HKR,,"ConfigData",1,11,00,3F,3F,10,27,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,
71,02,00,00,38,41,00,00,9C,80,00,00,60,00,00,00,34,00,00,00,1A,00,00,00,0D,00,00
,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00

This will map 38400 bps to 31250 which you need for MIDI communication. Whenever windows thinks it's running the port at 38400, the driver will actually run it at 31250. Use Serial.begin(31250) in your code.

Reinstall the arduino FTDI drivers, install the Roland drivers, and VOILA!

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\FTDIBUS\VID_0403+PID_6001+A400
1drJA\0000\Device Parameters]
"PortName"="COM4"
"PollingPeriod"=dword:00000000
"ConfigData"=hex:11,00,3f,3f,10,27,00,00,88,13,00,00,c4,09,00,00,e2,04,00,00,\
71,02,00,00,38,41,00,00,9c,80,00,00,60,00,00,00,34,00,00,00,1a,00,00,00,0d,\
00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,d0,80,00,00
"MinReadTimeout"=dword:00000000
"MinWriteTimeout"=dword:00000000
"LatencyTimer"=dword:00000010

If you are new to the Arduino then I suggest you try some of the simpler programming examples here

Want to know more? get the full plans here...

Questions? Send me a message here