Animatronic Eyes

The Software
           The software used in this tutorial came from the previous Robotic Eyebrows tutorial and then was modified for controlling 6 servos instead of 2. 4 servos control how the eyes move and 2 servos control how the eyebrows move.

           The PIC's Timer0 is used to refresh the system every 20 miliseconds or at 50 Hz. Timer1 is used to cycle through and create a pulse for each servo that we are using. This system only has 2 servos so there are only two unique states that the system can switch between to send servo PWM pulses.

Servo Pulse Control - Interrupt Routine

------------« Begin Code »------------
void InterruptHandlerHigh() // Declaration of InterruptHandler
{ //Run When Timer overflows from FFFF->0000
     if(INTCONbits.TMR0IF) //If TMR0 interrupt flag set
     {
          WriteTimer0( 0x3CAF ); //Reset Timer0 for 20mS Delay
          WriteTimer1( 0xFC77 ); //Reset Timer1 for 1mS Delay
          count = 0; //Reset Timer1 Interrupt Counter
          INTCONbits.TMR0IF = 0; //Clear TMR0 Flag
     }
     if(PIR1bits.TMR1IF == 1 && PIE1bits.TMR1IE == 1)
     { //If Timer1 interrupts, do your thing...
          count++; //Increment Timer1 Interrupt Counter
          switch(count){ //Choose which servo to modify:
               case 1: PORTD = 0x01;
                    WriteTimer1( servo0 ); //Right Eyebrow
                    break;
               case 2: PORTD = 0x02;
                    WriteTimer1( servo1 ); //Left Eyebrow
                    break;
               case 3: PORTD = 0x04;
                    WriteTimer1( servo2 ); //Left Eye Left/Right
                    break;
               case 4: PORTD = 0x08;
                    WriteTimer1( servo3 ); //Left Eye Up/Down
                    break;
               case 5: PORTD = 0x10;
                    WriteTimer1( servo4 ); //Right Eye Left/Right
                    break;
               case 6: PORTD = 0x20;
                    WriteTimer1( servo5 ); //Right Eye Up/Down
                    break;
               case 7: PORTD = 0x00;
                    WriteTimer1( 0 );
                    break;
          }
          PIR1bits.TMR1IF = 0; //Clear Timer1 flag
     }
....
...
..
------------« End Code »------------

           In addition to controlling the servos with timers 0 and 1, a low priority timer, timer3 was used to so that movement profiles could be built. This means that not only can the location controlled but the movement speeds. This makes it so that eye movement can be slow or quick, helping to create the illusion that they are actually eyes.

PWM Control - Interrupt Routine

------------« Begin Code »------------
..
..
...
if(PIR2bits.TMR3IF == 1){
//If Timer3 interrupts, do your thing...
     if(servo_0_dest < servo_0_current){
          servo_0_current--;
          servo0 = servo_0_current;
     }
     else if(servo_0_dest > servo_0_current){
          servo_0_current++;
          servo0 = servo_0_current;
          }

     if(servo_1_dest < servo_1_current){
          servo_1_current--;
          servo1 = servo_1_current;
     }
     else if(servo_1_dest > servo_1_current){
          servo_1_current++;
          servo1 = servo_1_current;
     }
...
..
...
     WriteTimer3( speed ); // Reset Instruction Speed Until Interrupt
     PIR2bits.TMR3IF = 0; //Clear Timer3 flag
     }
INTCONbits.GIE = 1; //Re-enable all interrupts
}


           There's naturally a lot of other things going on in the software, but I felt these two parts were the key points. Please download the software above and load it onto your PIC. Then you can move to the next phase, testing the system out!



;