Mini IR Theremin

Program Download:

Main C File
Mini_IR_Theremin.c
IR_Theremin.hex

The Software
           The software running on the PIC contains 3 main portions:
    -A/D Input Interrupt
    -Timer Output Interrupt
    -Main Switch Function


The A/D Input Interrupt is a quick and simple low priority interrupt. The timer interrupt takes high priority because we want the speaker sound to be crystal clear.

Low and High Priority Interrupts

------------« Begin Code »------------
void InterruptHandlerHigh()
{
   if(INTCONbits.TMR0IF)
   {
     //Reset The Timer Value
   WriteTimer0( timer0_val );
     //If a valid 'note' is stored in timer0_val, Play It!
      if( timer0_val <= 0xFB55 && timer0_val >= 0xED56){
      sound_state = (sound_state ^ 0xFF) & new_volume;
      PORTD = sound_state;
      }
   INTCONbits.TMR0IF = 0;
   }
INTCONbits.GIEH = 1; //Re-enable all high priority interrupts
return;
}
void InterruptHandlerLow()
{
   if(PIR1bits.ADIF == 1){
      //AD Interrupt Triggered, Read The Value
   ad_val = ReadADC();
      //Set AD Value Ready
   ad_ready = 1;
   PIR1bits.ADIF = 0;
   }
INTCONbits.GIEL = 1; //Re-enable all low priority interrupts
return;
}
------------« End Code »------------

           The code above should be straight forward. The interrupts are not suppose to be processor hogs, they should be quick, simple and as short as possible.

Main Switch

------------« Begin Code »------------
..
...
ConvertADC(); // Start conversion
if(ad_ready == 1){
    //Calculate The Distance Using The Formula
 result = pow(3027.4/ad_val,1.2134);
    //Convert The Distance From Float to Integer
 distance = (int) result;
    //Clear AD_ready because we used the ADC result
 ad_ready = 0;
    //Change The Timer0_val according to distance
 switch(distance){
   //C4
   case 11 :
   case 12 :
   case 13 :
   case 14 :
   case 15 : timer0_val = 0xED56;
   break;
   ..
   ...
   ....
   ..
   //C5
   case 46 :
   case 47 :
   case 48 :
   case 49 :
   case 50 : timer0_val = 0xF6AB;
   break;
   default : timer0_val = 0x0000;
 }
}
Delay10KTCYx(1);
...
..
------------« End Code »------------

           The main function of this project tells the A/D converters to start and then computes the distance away the object is from the sensor and passes that value to a switch statement. Depending on what value timer0_val gets updated with tells the timer0 to play a different tone on PORTD. This process happens over and over forever until the batteries die.



;