Algunas pruebas que hice, con los pocos servos que tengo en casa (4), que incluso la prueba la hago con solo uno
Lo que estoy descubriendo es que tengo un problema de ruido, como llego a esa conclusión?
Resulta que hice un programita que atiende las posición de los servos, cantidad 18 hasta ahora porque estoy con el 18f2550, pongo posiciones fijas de a saltos de 10 grados para probar el movimiento de cada servo, es decir, algo así:
Servo[0] = 100
Servo[1] = 90
Servo[2] = 80
.......
osea cada salida tiene ese valor fijo y no lo actualizo en ningún momento.
Y con el mismo servo voy conectando a las distintas salidas que tengo definidas como los servos.
Aparentemente la atención a los servos anda bien porque cuando cambio de una salida a la otra el servo cambia su posición en esos 10 grados de giro, hasta ahí venimos bien.
Pero resulta que el programita que enviaría los datos por el USB se queda tildado, al parecer como que pierde la comunicación con la placa al filtrarse algo de ruido por la conexión y desconexión del servo.
El programita que utilizo es el que provee como ejemplo Microchip, "HID PnP Demo.exe"
Este programita censa el estado de un switch y en algun momento deja de mostrarme el estado, lo que me indica que ha perdido la comunicación.
Ahora, mientras no conecto el servo el programa se mantiene funcionando correctamente.
Les comparto las partes del código donde atiendo a los servos, principalmente es la rutina de la interrupción por TMR0. La base del código es del ejemplo de gu1llermo, o sea generando una interrupción cada 0,04 mseg, lo que me da una resolución de 50 pasos. En breve pruebaré con 100 a ver que hace
/** CONSTANTS ******************************************************/
#define left 65160 // TMR0 Value for 0,5 msec
#define right 52410 // TMR0 Value for 17,5 msec
#define middle 65505 // TMR0 Value for 40 usec (0,04 msec)
void YourHighPriorityISRCode()
{
//Check which interrupt flag caused the interrupt.
//Service the interrupt
//Clear the interrupt flag
//Etc.
if(INTCONbits.TMR0IF)
{
// Rutine to serve all servos
// it has to last 2 msec, if first 0,5 msec are driven by TMR0 interrupt, else 2,5 msec
if(Fase == 52)
{
WriteTimer0(left); // Timer for 0,5 msec
mSERVO_All_On(); // At 0,0 msec all servo pin must go ON
Fase = 0;
INTCONbits.TMR0IF = 0; // Clear interrupt flag
}
if((Fase >= 0) && (Fase < 51))
{
WriteTimer0(middle); // Timer for 20 usec
if (Servo[0] == Fase){mSERVO_0_Off();} // If servo pos < Fase then servo pin OFF
if (Servo[1] == Fase){mSERVO_1_Off();}
if (Servo[2] == Fase){mSERVO_2_Off();}
if (Servo[3] == Fase){mSERVO_3_Off();}
if (Servo[4] == Fase){mSERVO_4_Off();}
if (Servo[5] == Fase){mSERVO_5_Off();}
if (Servo[6] == Fase){mSERVO_6_Off();}
if (Servo[7] == Fase){mSERVO_7_Off();}
if (Servo[8] == Fase){mSERVO_8_Off();}
if (Servo[9] == Fase){mSERVO_9_Off();}
if (Servo[10] == Fase){mSERVO_10_Off();}
if (Servo[11] == Fase){mSERVO_11_Off();}
if (Servo[12] == Fase){mSERVO_12_Off();}
if (Servo[13] == Fase){mSERVO_13_Off();}
if (Servo[14] == Fase){mSERVO_14_Off();}
if (Servo[15] == Fase){mSERVO_15_Off();}
if (Servo[16] == Fase){mSERVO_16_Off();}
if (Servo[17] == Fase){mSERVO_17_Off();}
Fase++;
INTCONbits.TMR0IF = 0; // Clear interrupt flag
}
if(Fase == 51)
{
WriteTimer0(right); // Timer for 17,5 msec
Fase++;
INTCONbits.TMR0IF = 0; // Clear interrupt flag
}
}
#if defined(USB_INTERRUPT)
USBDeviceTasks();
#endif
} //This return will be a "retfie fast", since this is in a #pragma interrupt section
OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_16);
INTCON2bits.TMR0IP = 1; // High priority for Timer0
RCONbits.IPEN = 1; // Enable priority levels
INTCONbits.GIEH = 1; // Enable interrupts
WriteTimer0(1785); // Timer for 85 msec -> only for first interrupt
Lo siguiente es modificar un poco el programa host (en la PC) para poder enviar los datos de los servos y poder variar la posición de cada uno, por el momento con un simple valor manejado con un control slide.