me he basado en el codigo de redpic para controlar un servo (PWM por soft) con un potenciometro...
el codigo funciona, lo he publicado en la seccion de lenguaje C, pero el fallo es que el servo no se queda quieto cuando no estoy tocando el potenciometro
me he metido en esta seccion porque supongo que aqui estareis los grandes "sabedores" de este tema y podreis ayudarme mejor...
el codigo es muy simple, es este:
//--- Constantes ---
#define SERVO PIN_A0 //linea de control por PWM para el servo
#define ADC 1 //canal adc que se usa para los ojos
//------------------
#use delay(clock=4000000)
#use standard_io(a)
//--- Variables ---
int1 flag5RTCC = TRUE; //indica si se completaron 5 RTCC
int1 flag50mS = FALSE; //indica si ocurrio interrupcion de timer1
int1 flagPulso_Alto = FALSE;
int8 Posicion = 93; //donde se posiciona el servo segun la lectura del adc
int8 ContRTCC = 0; //contador de RTCC
//-----------------
//--- Funciones ---
void Calcular_Posicion_Ojos(void);
//-----------------
#int_TIMER0
void TIMER0_isr(void){ //timer que cuenta 20mS
//Timer de 8 bits --> 256 = 1 RTCC
//Pescaler de 1:16
//1 tick cada 16 uS = 0.016mS
//1 RTCC cada 4.0mS (256 - 6 Ticks)
//5 RTCC = 20mS
ContRTCC = ContRTCC + 1;
set_TIMER0(6);
if(ContRTCC == 5){
flag5RTCC = TRUE;
ContRTCC=0;
}
}
#int_TIMER1
void TIMER1_isr(void) { //timer que cuenta 50mS
//Timer de 16 bits --> 65536 = 1 RTCC
//Pescaler de 1:1
//1 tick cada 1 uS
//1 RTCC cada 50mS (65536 - 15536 Ticks)
set_TIMER1(31072);
flag50mS = TRUE;
}
void main(void) {
int8 ValTMR0;
//configuracion del PIC
set_adc_channel(ADC);
do {
//>-----------------------Movimiento del servo--------------------------------->
//--- Calcula posicion servo segun lectura adc ---
if(flag50mS == TRUE){
Calcular_Posicion();
flag50mS = FALSE;
}
//------------------------------------------------
//--- Dispara pulso PWM cuando se completan 5 RTCC ---
if(flag5RTCC == TRUE){
flag5RTCC = FALSE;
output_high(SERVO);
flagPulso_Alto = TRUE;
}
//----------------------------------------------------
//--- Baja pulso PWM cuando corresponda ---
valTMR0 = get_TIMER0() - 6;
if((flagPulso_Alto == TRUE) && (valTMR0 > Posicion)){ //baja el pulso en el tiempo correspondiente a Posicion
output_low(SERVO);
flagPulso_Alto = FALSE;
}
//-----------------------------------------
//<----------------------------------------------------------------------------<
} while(true);
}
void Calcular_Posicion(void){
int16 ValorADC;
ValorADC = read_adc();
Posicion = 31 + (int16)((int16)(ValorADC * 124) / 255);
}no he puesto la configuracion de mi pic porque vale cualquiera que tenga dos timers... yo personalmente uso el 12F683 para mover un servo o el 16F88 para mover 2 servos
supongo que la respuesta a mi problema debe ser generar PWM por soft, que al haber interrupciones mas lo que demora en ejecutarse cada instruccion hace que el PWM no sea de 50hz exactos y eso provoque el tambaleo constante...
se puede solucionar?
incluso mejor, hay algun integrado que se encargue de controlar servos y pueda ser manejado con un microcontrolador?
no es que necesite presicion con esto... pero el servo moviendose constantemente lo unico que hace es un monton de ruido, gastarme las pilas y calentarme el 7805
![redhot :5]](http://www.todopic.com.ar/foros/Smileys/default/redhot.gif)
que puedo hacer?
salu2
--------- EDITO ----------
El problema ya esta resuelto gracias a una aportacion de Nocturno. El codigo funcionando y otras cosas interesantes sobre esto estan mas adelante en este hilo.