Autor Tema: Problemas con los servos y las entradas analogicas  (Leído 1636 veces)

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

Desconectado Kanick

  • PIC10
  • *
  • Mensajes: 9
Problemas con los servos y las entradas analogicas
« en: 22 de Septiembre de 2009, 20:13:56 »
Hola a todos,

He estado buscando por el foro información que me pudiera ayudar pero aunque si he encontrado temas de servos no he visto lo que necesitaba (espero no haber abierto un tema innecesariamente).

Me he hecho una controladora de servos siguiendo el método de RedPic de los 8 servos con una sola interrupción. Aprovecho la ocasión para agradecerle su aportación y felicitarlo por dicho código.

Hasta ahora no he tenido ningún problema y me ha funcionado siempre muy bien.

Lo ahora quiero hacer es, conectar un potenciómetro en el puerto analógico del pic y pasar su posición a la salida digital del servo de tal forma que moviendo el potenciómetro se mueva el servo de la misma manera.

Hasta ahí todo bien. Lo he hecho y me funciona perfectamente.

El Problema aparece cuando conecto (físicamente) otro servo (con lo que tengo 2 conectados a la vez). Y lo que pasa es que ambos servos (o todos los que conecte) empiezan a vibrar como locos. Con uno solo bien, pero con mas de uno vibra todo.

Estoy usando un 18F4550 a 48mhz. Los 8 servos con el rtcc (o timer0) los he mapeado al puerto B. Y las entradas analógicas las he mapeado en el puerto AN0, 1, 2 y 3 de la siguiente forma,

AN0 (potenciómetro1) -> B7
AN1 (potenciómetro2) -> B6
AN2 (potenciómetro3) -> B5

(tengo que decir que los potenciómetros son de a su vez de servos desmontados)

Y el código que he hecho es el siguiente:

Código: [Seleccionar]
void main() {
   
   delay_ms(300);
   
   setup_adc_ports(AN0_TO_AN3 | VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   
   setup_wdt(WDT_OFF);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_4);
   enable_interrupts(INT_RTCC);
   enable_interrupts(global);
   set_TIMER0(58035);
   
   set_tris_a(0b00001111);
   set_tris_b(0b00000000);

   output_b(0x00);

   i=0;

   do {
      set_adc_channel(i);                                  // selecciono el puerto analógico
      delay_us(10);
      inclinacio = read_adc();                            // leo el dato
      servo[30-i]=inclinacio*16+2100;               // lo passo al servo correspondiente
     
      i<3?(i++):(i=0);                                      // indice con el que rastreo todos los ANx
     
   } while (TRUE);
}

Dado que el control de los servos ya funciona perfectamente, el resto de código es muy simple.

Posiblemente alguno se haya encontrado con este o algun problema parecido y pueda hecharme un cable de lo que puede estar pasando.

Muchas gracias de antemano.

K

Desconectado matocomasi

  • PIC10
  • *
  • Mensajes: 26
Re: Problemas con los servos y las entradas analogicas
« Respuesta #1 en: 23 de Septiembre de 2009, 05:39:44 »
Hola Kanick,

Primero, debes de asegurarte que tus entradas analogicas no fluctuan, ya que comentas que tus potenciometros son reutilizados, para ello deshabilita el codigo de los servos y centrate solo en el de la lectura de los analogicos. Normalmente la lectura de los ponteciometros fluctua sobre el valor real de posicion del mismo, es decir, si lo tienes posicionado en 127, la lectura ira cambiando constantemente entre valores de 124 a 132, mas o menos. Por lo que si esto te ocurre, debes hacer un filtrado de la posicion del potenciometro. Ya sabes, IF(valor>valor minimo AND valor< valor maximo)(no actualizo la posicion en el servo), donde minimo y maximo seran parametros de ajuste fino que tu tendras que definir. El posicionamiento del servo sera escalonado dependiendo de los intervalos de la posicion del potenciometro.

Segundo, has definido AN0_AN3, lo que implica de quedes tener 4 potenciometros conectados al sistema, si alguno no esta conectado, las lecturas se van a ver afectadas, por lo que tendrias que poner una tension de referencia en el pin del potenciometro no conectado, ya se GND o VDD. Si no lo hicieras, los pines no conectados darian una lectura igual que el ultimo poetenciometro si conectado.

Tercero, deberias incluir todo el codigo, ya que he visto que has usado ciertas variables globales que no se como han sido definidas, ademas de no ver si estas usando una conversion AD de 8 o 10 bit.

Saludos

Desconectado _Maxi

  • PIC10
  • *
  • Mensajes: 34
Re: Problemas con los servos y las entradas analogicas
« Respuesta #2 en: 25 de Septiembre de 2009, 02:47:25 »
http://www.todopic.com.ar/foros/index.php?topic=27641.msg227973#msg227973

Fijate si mi código te sirve en algo. Aclaro que sólo lo simulé.

Desconectado Kanick

  • PIC10
  • *
  • Mensajes: 9
Re: Problemas con los servos y las entradas analogicas
« Respuesta #3 en: 30 de Septiembre de 2009, 14:58:46 »
Hola,

Bueno, disculpad el retraso por no haber podido contestar hasta ahora.

Gracias por tus comentarios matocomasi. Lo he estado mirando y esto es lo qe he visto,

Citar
debes de asegurarte que tus entradas analogicas no fluctuan

En mi caso creo que las entradas analógicas no fluctuan (o en todo caso es despreciable) ya que conectando todos los potenciómetros como tu dices, en todas las entradas, si conecto un solo servo funciona perfecto. Poniendolo emparejado con qualquier potenciómetro siempre va bien.

En el momento en que conecto un segundo (o mas) servo es cuando empiezan a vibrar. No ocurre lo mismo si en vez de un segundo servo conecto un led. En este caso (1 servo + 1 led) no aparece ninguna vibración.

Citar
IF(valor>valor minimo AND valor< valor maximo)(no actualizo la posicion en el servo)

No he acabado de entedner el filtro que propones ya que si el valor del potenciómetro se encuentra dentro del intervalo, bien, pero si se encuentra en uno de sus límites, no deberia tener el mismo efecto de vibración pasando de un escalón a otro?

Despúes de estar haciendo varias pruebas, al final, he probado la interrupción #int_ad. El resultado és el mismo, para un servo va perfectamente pero para mas de uno vibra (es como si se mezclaran las señales).

Otra cosa que veo es que no he podido usar la directiva #device adc=xx, a lo mejor es que este pic solo tiene conversion de 10 bits?

Adjunto la última version del código completo,

Código: [Seleccionar]
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VREGEN
#use delay(clock=48000000)

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)

int8 i=0;

int1 flagB;
int1 flagC;
int1 flagD;

int8 contB=0x00;
int8 contC=0x00;
int8 contD=0x00;

int16 inclinacio = 126;
int1 adc_active=FALSE;

int16 tSERVO[30]={4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200,4200};

#int_RTCC                  //Port B
void RTCC_isr()
{
   if(flagB==0)
   {
      output_high(31752+contB);   
      set_TIMER0(65535 - tSERVO[23+contB]);
   }
   if(flagB==1)
   {
      output_low(31752+contB); 
      set_TIMER0(65535 - 7500 + tSERVO[23+contB]);
      if(++contB>7) contB=0;
   }
   ++flagB;
}

#int_ad
void adc_handler()
{
   inclinacio = read_adc(ADC_READ_ONLY);
   tSERVO[30-i]=inclinacio*16+2100;
   i<2?(i++):(i=0);
   adc_active=FALSE;
}


void main() {
   
   delay_ms(300);
   
   setup_adc_ports(AN0_TO_AN2 | VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   
   setup_wdt(WDT_OFF);

   setup_counters(RTCC_INTERNAL,RTCC_DIV_4);

   enable_interrupts(INT_AD);
   enable_interrupts(INT_RTCC);

   enable_interrupts(global);
   
   set_TIMER0(58035);
   
   set_tris_a(0b00000111);
   set_tris_b(0b00000000);
   set_tris_c(0b00000000);
   set_tris_d(0b00000000);
   set_tris_e(0b00000000);

   output_b(0x00);
   output_c(0x00);
   output_d(0x00);
   output_e(0x00);
 
   i=0;

   do
   {
      if(adc_active==false)
      {
         set_adc_channel(i);
         delay_ms(30);
         adc_active=true;
         read_adc(ADC_START_ONLY);
      }

   } while (TRUE);
}


_Maxi,

Esto es justamente lo que pretendo, pasar la lectura de una serie de entradas analógicas a los servos de salida, y si te fijas en el código que puse en mi primer post, estamos haciendo prácticamente lo mismo. Por lo tanto, yo creo que así deberia funcionar pero hay algo se me escapa o no estoy haciendo bien  :(

Bueno, si a alguien se le ocurre algo será muy bienvenido, por mi parte seguiré probando lo que pueda.

Gracias


Kanick