Firmware of the Laser Harp

 
 
The microcontroller is programmed in C language, when a beam events occur, a flag system signal the processor to send the MIDI note (storage in memory). An interrupt timer run very fast to steer the beam, so the human eye can't to see the only one beam but the full harpe beams.

MIDI digitally communicates musical data between devices as a string of MIDI messages. These messages are transmitted through a standard MIDI line at a speed of 31,250 bits/sec using an asynchronous serial data byte comprising 1 Start bit, 8 Data bits (0 to 7) and 1 Stop bit.
In a typical MIDI message, three pieces of information will be sent: the action (note on, note off, pitch bend, etc.), the pitch (plain old musical pitch) and the velocity (basically, how loud you want the sound to play). A typical MIDI message might be something like this (in hexadecimal notation): 9A 45 45
This message says "play a middle C on the tenth MIDI channel, medium volume."

DAC (digital-to-analog converter), device that converts a digital (usually binary) code to an analog signal, is used to move the laser mirror, each voltage level mean a beam position.

SPI (Serial Peripheral Interface) bus is a synchronous serial data link standard, used to attach the DAC chip to the microcontroller.

ADC (analog-to-digital converter) is a device that converts a continuous quantity to a discrete time digital representation, used to select the sensor, to sense the hand height (pitch bend or modulation) and to adjust the sensor trigger.

I2C (Inter-Integrated Circuit) is a multi-master serial single-ended computer bus that is used to attach the EEPROM memory to the microcontroller.

PWM (Pulse-width modulation) interrupt is used to run the follow beam, moved the mirror and selected the color beam.

I/Os (input/output) are used to communicate with the remote control, the LCD controller, the RGB beams, and the buttons controls.


This source code shows an abstract of the program
     /***** LaserHarp.c *****
     #include "laserharp.h"
     const flash char szCartridge[] = "Copyright HARPELASER-00.00.01-04/16/2010";

     /**********************************************************
      Beam PWM Timer 0 interrupt (60 Hz)
     **********************************************************/
     interrupt [TIM0_OVF] void timer0_ovf_isr(void)
     {
           if ((szNotesPlayed[cNotesPositions] == 0) && (!SENSOR_TRIGGER))
                 szNotesPlayed[cNotesPositions] = 1;
           else if ((szNotesPlayed[cNotesPositions] == 2) && (SENSOR_TRIGGER))
                 szNotesPlayed[cNotesPositions] = 3;
           BEAM_LIGHT = DISABLE;
           DAC_write(iszNotesPositions[cNotesPositions], 2048);
           BEAM_LIGHT = ENABLE;
           if (cNotesPositions++ >= cMaxNotes) cNotesPositions = 0;
     }

     /**********************************************************
     ######### MAIN ###########################################
     /**********************************************************
     void main(void)
     {
           IOs_initialisation();
           #asm("sei")
           EEPROM_param_read();
           DAC_initialisation();
           SENSOR_initialisation();
           LCD_initialisation();
           main_display();

           ///**************** Main loop ********************
           while (1)
           {
                 // loop on each beams
                 for (i=0; i<cMaxNotes; i++)
                 {
                       if (szNotesPlayed[i] == 1)
                       {
                             szNotesPlayed[i] = 2;
                             send_MIDI_Note_ON(i);
                       }
                       else if (szNotesPlayed[i] == 3)
                       {
                             szNotesPlayed[i] = 0;
                             send_MIDI_Note_OFF(i);
                       }
                 }
           }
           ///*********************************************
     }