Autor Tema: mi servo no se queda quieto (NUEVO RETO)  (Leído 44129 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
mi servo no se queda quieto (NUEVO RETO)
« en: 08 de Mayo de 2007, 00:22:52 »
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:
Código: [Seleccionar]
//--- 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  :5]
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.
« Última modificación: 20 de Junio de 2007, 20:18:19 por Marttyn »
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: mi servo no se queda quieto
« Respuesta #1 en: 11 de Mayo de 2007, 18:19:23 »
Yo tambien tengo una rutina para controlar un servo por el ADC, con el 16F88, y algunas veces hace un poco de ruido el servo, y es por culpa del potenciometro
que queda en una posicion inestable, y produce variaciones en la lectura del ADC.
Te recomiendo que visualices los valores del ADC a ver si son la causa. En el caso de que sea asi mira la zona muerta de tu servo, creo que suele estar de 5 a 10uSeg., y filtra las lecturas del ADC para que no varien dentro de este margen.
Saludos desde Granada, España.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: mi servo no se queda quieto
« Respuesta #2 en: 11 de Mayo de 2007, 21:33:30 »
hmmm  :?
nunca habia comunicado un micro con el PC, pero lo intentare para ver que me cuenta el adc... lo que si, el pot lo filtro con un condensador del pin del pic a masa de 0.1uf. crei que eso me solucionaria la impresicion del pot...
lo que no entiendo muy bien es que es la zona muerta del servo
gracias dogflu por tu ayuda  :P
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: mi servo no se queda quieto
« Respuesta #3 en: 12 de Mayo de 2007, 04:25:38 »
Visualizas el adc con un muestreo suficientemente rapido para ver si hay variaciones o muestras valores maximos y minimos, lo pasas a tiempo y si las variaciones estan muy cerca o superan a la zona muerta del servo, este vibrara. Esta zona es un tiempo del duty cycle en el que el servo puede que no responda y por lo tango no se desplace a la posición siguiente inmediata.

El periodo de la señal de control del servo no tiene que ser muy exacto, ya que aquí si se permite una tolerancia de varios mSeg.
Pero las variaciones en la parte de señal del duty cycle solo se permite si es igual o inferior a la zona muerta del servo, mejor menor.
Saludos desde Granada, España.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: mi servo no se queda quieto
« Respuesta #4 en: 12 de Mayo de 2007, 12:38:26 »
pero si te fijas en mi codigo, tomo la muestra del adc cada 50ms...
pero que raro... le di la orden para que se quedara quieto en una posicion sin leer el adc y si que sabe quedarse quieto en esa posicion...
debes tener razon con lo del adc... pero no entiendo como, si las muestras son cada 50ms  :?
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: mi servo no se queda quieto
« Respuesta #5 en: 12 de Mayo de 2007, 13:35:43 »
jejejeee, lo de tomar la muestra rapido era para saber el grado de variacion del adc.

cuanto mas espaciadas tomes las muestras menos se movera, pero claro perderas ese tacto o control del servo con el pot.
en mi caso tomaba las muestras cada 100mSeg. y cuando cogia una zona no estable del pot. seguia con la mania de moverse..
Saludos desde Granada, España.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: mi servo no se queda quieto
« Respuesta #6 en: 12 de Mayo de 2007, 15:12:22 »
y entonces cual es la solucion? he intentado filtrar la señal del pot con condensadores mas grandes, pero es lo que tu dices, pierde sensibilidad al tacto y no se soluciona el problema...  :x
que me propones?
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3549
Re: mi servo no se queda quieto
« Respuesta #7 en: 12 de Mayo de 2007, 17:02:56 »
Pues nose no he llegado todavia a ese punto.
si hay diferencia entre la medicion anterior y la actual activaria un contador, que se hace reset cada vez que se cambia de valor el ADC, si al termino del contador procederia al cambio de posicion. Como los antirrebores de las teclas.
« Última modificación: 12 de Mayo de 2007, 18:20:12 por dogflu66 »
Saludos desde Granada, España.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: mi servo no se queda quieto
« Respuesta #8 en: 12 de Mayo de 2007, 17:16:08 »
:cry:
me lo temia....
esa es la solucion que pense yo tambien, pero no la puse en practica xq la verdad no me apetecia ponerme a hacer el codigo para eso... pero bueno, visto que no encuentro mas soluciones tendre que ponerme a trabajar en ello.
alguien mas que haya hecho algo asi tiene alguna solucion? :(
gracias dogflu
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Duende_Azul

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 908
Re: mi servo no se queda quieto
« Respuesta #9 en: 12 de Mayo de 2007, 19:21:50 »
y que tal si en lugar de tomar una muestra, tomas 10, las promedias y ese valor se lo envias al servo?

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: mi servo no se queda quieto
« Respuesta #10 en: 13 de Mayo de 2007, 00:53:07 »
pues no es mala idea... y me parece mas simple de implementar que un "antirebotes" para el POT  :)
lo probare y os digo que tal
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado vicent

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 144
    • Web de Vicent
Re: mi servo no se queda quieto
« Respuesta #11 en: 13 de Mayo de 2007, 16:10:23 »
A mi se me ha ocurrido lo mismo que a duende_azul.
Me pasó una vez con un sensor de temperatura, alguien me comentó que hiciera un promedio y mostrara el reloj y se estabilizó mucho.

Un saludo. Au.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1836
    • IDEAA
Re: mi servo no se queda quieto
« Respuesta #12 en: 14 de Mayo de 2007, 21:05:46 »
estaba por ponerme a ello... lo de promediar 10 resultados....
lo iba a hacer de la manera tipica, sumar 10 resultados y despues dividirlos entre 10... vamos lo tipico, pero me doy cuenta que si por ejemplo tengo 9 resultados de "100" y uno de "99" la suma va a ser 999, y el promedio 99.9, y si le aplico "ROUND" (en C) lo que hace es truncar.... con lo que se  queda en 99... y si luego tengo 9 resultados "100" y uno "101", el promedio sera 100.1, que al trucar me dara 100... y nuevamente a vibrar....
hay alguna funcion que realmente redondee a la antigua usansa? (por encima de 0.5 sube, y por debajo trunca)
todo esto lo estoy diciendo desde la teoria...
lo probare a ver que tal, pero aun asi creo que se podra atenuar aun mas la vibracion del servo si pudiera redondear  :mrgreen:
acepto sugerencias en C  :-)
salu2
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Carli

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 109
Re: mi servo no se queda quieto
« Respuesta #13 en: 14 de Mayo de 2007, 21:18:26 »
Como ex-aeromodelista he tenido dicho problema con servos Futaba y los solucionaba limpiando el potenciometro que esta dentro del mismo y colocandole un poco de grasa, a veces las pistas del potenciometro al ser "raspadas" por los patines del mismo desprenden un poco de suciedad y hace que el servo tome un valor erratico del potenciometro y tiemble.

Lo mismo es si el potenciometro no se centra siempre en el mismo lugar, es el potenciometro sucio o juego en los engranajes.

Espero les sirva mi aporte, y sino a segir con el codigo!!!!!!!

Suerte.
Nueve de Julio - Buenos Aires - Argentina

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
Re: mi servo no se queda quieto
« Respuesta #14 en: 16 de Mayo de 2007, 01:47:29 »
hay alguna funcion que realmente redondee a la antigua usansa? (por encima de 0.5 sube, y por debajo trunca)

Hay un viejo truco que te servirá, mira:
NúmeroRedondeado = Truncar ( NúmeroConDecimales + 0.5 )

Haz algunas pruebas y verás cómo funciona como quieres.


 

anything