Autor Tema: Mover servo con potenciometro  (Leído 23287 veces)

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

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
Re: Mover servo con potenciometro
« Respuesta #15 en: 29 de Septiembre de 2007, 07:22:58 »
Hola a Tod@s

Vayamos por partes, y muy simplificado:

La INT_EXT, es una interrupcion que se activa cuando se recibe un pulso externo ( olvidemos por ahora si de subida, bajada...etc), y ya no hace nada mas.

La INT_CCP, en modo capture, se puede activar tambien cuando se recibe un pulso externo (igual que la INT_EXT), pero ademas ella solita lee el valor del timer y lo guarda en una variable, para lo que lo necesites... ( Como bien te aclara el amigo Nocturno ). Esa y alguna otra sutileza, dependiendo de la configuracion, son la diferencia.

Hablemos ahora del TIMER, que no es ninguna interrupcion, es simplemente un dispositivo interno del pic que actua como un contador creciente, de 0 a 255 en un timer de 8 bit  o de 0 a 65535 en un timer de 16 bit. Este contador utiliza la frecuencia del cristal y otras configuraciones para determinar cada cuanto tiempo se incrementa en una unidad ( pero no quiero entrar ahi...), solo quedaros con la idea de que es un contador y que cuando llega al final (se desborda) empieza otra vez desde 0, y asi continuamente. El timer puede ser leido con get_timer, e incluso puedo cambiarle el valor en cualquier momento y asignarle el que yo quiera con set_timer. Si le cambio el valor lo unico que ocurrira es que seguira incrementandose a partir del valor que yo le he puesto. 

La INT_TIMER, es una interrupcion que se activa cuando el timer asociado a ella, llega a su valor maximo (se desborda). Osea esta interrupcion lo unico que hace es contar un tiempo, con la particularidad de que el tiempo que cuenta lo puedo cambiar facilmente utilizando set_timer y poniendo el contador en el valor que me interese en cada momento, osea cuanto mas grande sea el valor que le pongo, mas cerca estara de desbordarse, y menos tiempo pasara para activarse la int.
 
La INT_CCP, en modo compare, se activa cuando coincide el valor del timer con el valor que tu pones en la variable CCP_x ( el timer ni se detiene, ni nada, sigue a su bola), osea sirve para contar un tiempo determinado, igual que la INT_TIMER, pero con la diferencia que para contar un tiempo u otro, no hay que tocar ni modificar el valor del timer, solo hay que variar el valor de CCP_x.


Puede parecer que hay poca diferencia entre una interrupcion u otra, pero esas pequeñas y sutiles diferencias pueden ser fundamentales.

Por ejemplo, se pueden contar dos tiempos diferentes utilizando el mismo timer, y utilizando la INT_TIMER y la INT_CCP en modo compare al mismo tiempo.

Saludos  :-/

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
Re: Mover servo con potenciometro
« Respuesta #16 en: 29 de Septiembre de 2007, 07:47:09 »
Hola otra vez

UPSSSS,   :shock:  el post de REdPic no estaba cuando iba a contestarte Marttyn...


Observaras que solo hay pequeñas diferencias entre una explicacion y la otra, debidas sin duda a los diferentes estilos linguisticos y poeticos derivados de nuestro diferente bagaje y percepcion de la realidad, acaecidas a lo largo de nuestra dilatada experiencia en el noble y sufrido arte de cacharrear y enredar con chismes y cablecitos... 8)

Si hay algo que no coincide con mi post, seguro, pero seguro que yo no llevo razon... :?

Aqui tienes una clara evidencia de quien es el master y quien el pequeño saltamontes, ¡¡¡ no hace falta que especifique quien es quien !!!   :mrgreen:

Saludos  :-/

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #17 en: 25 de Diciembre de 2007, 22:20:37 »
con algunos meses de retraso quiero agradeceros vuestras amables explicaciones!
el tema de ccp compare es muy interesante, y me viene de lujo para el control de servos.
la verdad que creo que solucionara el problema de controlar varios servos a la vez.
a ver si en enero tengo algo de tiempo libre y puedo probar todas estas cosas interesantes!
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 Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #18 en: 28 de Diciembre de 2007, 23:56:14 »
bueno, estuve mirando un poco lo de CCP en modo compare, e hice un pequeño codigo para probarlo... resulto tan facil, o tan dificil como esto:
Código: C
  1. #include <16F88.h>
  2. #device adc=8
  3. #FUSES NOWDT,INTRC_IO,MCLR,PUT,NOBROWNOUT,NOCPD,NOLVP,NOIESO,NODEBUG
  4.  
  5. #use delay(clock=4000000)
  6.  
  7. //--- Constantes ---
  8. #bit SERVO     = 0x06.0    //Pin B0 control del servo
  9. #define ADC    0    //canal adc que se usa para el potenciometro
  10. //------------------
  11.  
  12. //--- Variables ---
  13. int1 flagLeerADC = FALSE;           //indica cuando leer adc
  14. //-----------------
  15.  
  16. //--- Funciones ---
  17. void Calcular_Posicion(void);
  18. //-----------------
  19.  
  20. #int_TIMER1
  21. void TIMER1_isr(void) {       //timer que cuenta 20mS
  22. //Timer de 16 bits --> 65536 = 1 RTCC
  23. //Osc 4Mhz         --> 1 instruccion cada 1uS
  24. //Pescaler de 1:1  --> 1 tick cada 1 uS
  25. //Overflow cada 20mS (65536 - 45536 Ticks)
  26.  
  27.    set_TIMER1(45535);
  28.    SERVO = 1;     //sube el pulso del servo
  29. }
  30.  
  31. #int_CCP1
  32. void CCP1_isr(void){
  33.    
  34.    SERVO = 0;           //baja el pulso del servo
  35.    flagLeerADC = TRUE;  //manda a leer el adc
  36. }
  37.  
  38. void main(void) {
  39.  
  40.    setup_adc_ports(sAN0|VSS_VDD);
  41.    setup_adc(ADC_CLOCK_INTERNAL);
  42.    setup_spi(FALSE);
  43.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  44.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  45.    setup_timer_2(T2_DISABLED,0,1);
  46.    setup_comparator(NC_NC_NC_NC);
  47.    setup_ccp1(CCP_COMPARE_INT);
  48.    setup_vref(FALSE);
  49.    enable_interrupts(INT_TIMER1);
  50.    enable_interrupts(INT_CCP1);
  51.    enable_interrupts(GLOBAL);
  52.    setup_oscillator(OSC_4MHZ|OSC_INTRC);
  53.    set_adc_channel(ADC);
  54.    set_timer1(45535);
  55.    CCP_1 = 47035;
  56.    
  57.         do {
  58.       if(flagLeerADC == TRUE){
  59.          flagLeerADC = FALSE;
  60.          Calcular_Posicion();
  61.       }
  62.         } while(true);
  63. }
  64.  
  65. void Calcular_Posicion(void){
  66.    int16 ValorADC;
  67.    
  68.    ValorADC = read_adc();
  69.    CCP_1 = 46035 + (int16)(ValorADC * 7.8125);  //carga CCP1 con un valor entre 500 y 2500 (mas los 45535 de donde comienza a contar el timer, a menos que haya algun calculo que se desborde :(
  70. }

el problema es que no funciona... :( :(
el pic 16F88 parece una joyita de micro... pero me esta trayendo muchos dolores de cabeza  :?
gracias y 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 Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #19 en: 31 de Diciembre de 2007, 17:21:39 »
ya consegui hacer funcionar el servo con el CCP!!!  :-/
el problema era que estaba declarando el pin de salida como #bit, y luego no hacia un tris...
ahora esta solucionado. dejo el codigo que funciona sin problemas
Código: C
  1. #include <16F88.h>
  2. #device adc=8
  3. #FUSES NOWDT,INTRC_IO,MCLR,PUT,NOBROWNOUT,NOCPD,NOLVP,NOIESO,NODEBUG
  4.  
  5. #use delay(clock=4000000)
  6.  
  7. //--- Constantes ---
  8. #bit SERVO     = 0x06.1    //Pin B0 control del servo
  9. #define ADC    0    //canal adc que se usa para el potenciometro
  10. //------------------
  11.  
  12. //--- Variables ---
  13. int1 flagLeerADC = FALSE;           //indica cuando leer adc
  14. //-----------------
  15.  
  16. //--- Funciones ---
  17. void Calcular_Posicion(void);
  18. //-----------------
  19.  
  20. #int_TIMER1
  21. void TIMER1_isr(void) {       //timer que cuenta 20mS
  22. //Timer de 16 bits --> 65536 = 1 RTCC
  23. //Osc 4Mhz         --> 1 instruccion cada 1uS
  24. //Pescaler de 1:1  --> 1 tick cada 1 uS
  25. //Overflow cada 20mS (65536 - 45536 Ticks)
  26.  
  27.    set_TIMER1(45535);
  28.    SERVO = 1;     //sube el pulso del servo
  29. }
  30.  
  31. #int_CCP1
  32. void CCP1_isr(void){
  33.  
  34.    SERVO = 0;           //baja el pulso del servo
  35.    flagLeerADC = TRUE;  //manda a leer el adc
  36. }
  37.  
  38. void main(void) {
  39.  
  40.    setup_adc_ports(sAN0|VSS_VDD);
  41.    setup_adc(ADC_CLOCK_INTERNAL);
  42.    setup_spi(FALSE);
  43.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  44.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  45.    setup_timer_2(T2_DISABLED,0,1);
  46.    setup_comparator(NC_NC_NC_NC);
  47.    setup_ccp1(CCP_COMPARE_INT);
  48.    setup_vref(FALSE);
  49.    enable_interrupts(INT_TIMER1);
  50.    enable_interrupts(INT_CCP1);
  51.    enable_interrupts(GLOBAL);
  52.    setup_oscillator(OSC_4MHZ|OSC_INTRC);
  53.    set_adc_channel(ADC);
  54.    set_timer1(45535);
  55.    set_tris_b(0);
  56.    CCP_1 = 47535;
  57.  
  58.         do {
  59.       if(flagLeerADC == TRUE){
  60.          flagLeerADC = FALSE;
  61.          Calcular_Posicion();
  62.       }
  63.         } while(true);
  64. }
  65.  
  66. void Calcular_Posicion(void){
  67.    int8 ValorADC;
  68.  
  69.    ValorADC = read_adc();
  70.    CCP_1 = 46035 + (ValorADC * 7.8125);  //carga CCP1 con un valor entre 500 y 2500 (mas los 45535 de donde comienza a contar el timer, a menos que haya algun calculo que se desborde :(
  71. }

espero que a alguien le sea util... para mi lo es  :mrgreen:
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 celades

  • PIC10
  • *
  • Mensajes: 6
Re: Mover servo con potenciometro
« Respuesta #20 en: 09 de Octubre de 2010, 13:05:37 »
AMIGO MARTTYN soy nuevo en los foros y ps tambn en programacion de micros... por favor me podrias colaborar para hacer esto mismo, pero con dos servos y ps obvio dos potenciometros, es ke la verdad no se ni por dond empezar, ya monte el circuito con tu programa y si funciona, ahora falta la otra parte. espero me puedas colaborar. muxas gracias!
SALU2

Desconectado celades

  • PIC10
  • *
  • Mensajes: 6
Re: Mover servo con potenciometro
« Respuesta #21 en: 09 de Octubre de 2010, 13:34:29 »
hola amigo marttyn.
soy nuevo, tanto en el foro como en el mundo de la programacion de pics.
quisiera saber como diseñar el programa pero con dos servos y obviamente, dos potenciometros, se que para ustedes es algo obvio, pero para mi, que soy un simple novato en este mundo, es como si me hablaran en cantones  :D .
por favor, podrias publicar el programa con esa modificacion si no es mucho problema? de anteamno muchas gracias.
algun dia podre codearme con los maestros de los micros, por ahora solo agacho la cabeza y escucho con humildad. :)

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #22 en: 09 de Octubre de 2010, 15:34:38 »
Hola Celades!
La modificacion para dos servos es algo que tengo pendiente hace mucho tiempo. No es complicado, pero siempre tengo algo mas importante que hacer. Si lees el codigo seguro conseguiras entender como funciona. Tal vez puedas hacer los cambios necesarios para que funcione con 2 servos.
Espero que tengas suerte!
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 celades

  • PIC10
  • *
  • Mensajes: 6
Re: Mover servo con potenciometro
« Respuesta #23 en: 11 de Octubre de 2010, 12:09:23 »
ok, marttyn, lo intentare, sin embargo si tienes algun tiempo disponible no me caeria mal algo de ayuda. de todos modos te agradezco por la rapida respuesta.
saludos!
 

Desconectado celades

  • PIC10
  • *
  • Mensajes: 6
Re: Mover servo con potenciometro
« Respuesta #24 en: 14 de Octubre de 2010, 16:18:26 »
hola nocturno.
he estado siguiendo este foro, ya que tengo un proyecto similar, la diferencia radica en que implemento un potenciometro digital, no hay problema con eso, mi inconveniente es que por mas que intento añadir otra entrada para habilitar otro servo a partir del programa de marttyn no lo puedo lograr... la razon es obvia... soy muy nuevo en programacion de pics y mas en ccs pcw. me preguntaba si me podias ser de ayuda para mover los dos servos, es decir, la modificacion del programa, es que ese tema de las interrupciones es algo complicado. los potenciometros digitales ya estan listos, solo falta ese "detallito".
hoy, les pido ayuda... mañana, estare colaborando en los foros, lo se ;-)  .
te agradezco por la ayuda
salu2

Desconectado mecatronix89

  • PIC10
  • *
  • Mensajes: 33
Re: Mover servo con potenciometro
« Respuesta #25 en: 30 de Noviembre de 2011, 15:10:30 »
ya consegui hacer funcionar el servo con el CCP!!!  :-/
el problema era que estaba declarando el pin de salida como #bit, y luego no hacia un tris...
ahora esta solucionado. dejo el codigo que funciona sin problemas
Código: C
  1. #include <16F88.h>
  2. #device adc=8
  3. #FUSES NOWDT,INTRC_IO,MCLR,PUT,NOBROWNOUT,NOCPD,NOLVP,NOIESO,NODEBUG
  4.  
  5. #use delay(clock=4000000)
  6.  
  7. //--- Constantes ---
  8. #bit SERVO     = 0x06.1    //Pin B0 control del servo
  9. #define ADC    0    //canal adc que se usa para el potenciometro
  10. //------------------
  11.  
  12. //--- Variables ---
  13. int1 flagLeerADC = FALSE;           //indica cuando leer adc
  14. //-----------------
  15.  
  16. //--- Funciones ---
  17. void Calcular_Posicion(void);
  18. //-----------------
  19.  
  20. #int_TIMER1
  21. void TIMER1_isr(void) {       //timer que cuenta 20mS
  22. //Timer de 16 bits --> 65536 = 1 RTCC
  23. //Osc 4Mhz         --> 1 instruccion cada 1uS
  24. //Pescaler de 1:1  --> 1 tick cada 1 uS
  25. //Overflow cada 20mS (65536 - 45536 Ticks)
  26.  
  27.    set_TIMER1(45535);
  28.    SERVO = 1;     //sube el pulso del servo
  29. }
  30.  
  31. #int_CCP1
  32. void CCP1_isr(void){
  33.  
  34.    SERVO = 0;           //baja el pulso del servo
  35.    flagLeerADC = TRUE;  //manda a leer el adc
  36. }
  37.  
  38. void main(void) {
  39.  
  40.    setup_adc_ports(sAN0|VSS_VDD);
  41.    setup_adc(ADC_CLOCK_INTERNAL);
  42.    setup_spi(FALSE);
  43.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  44.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  45.    setup_timer_2(T2_DISABLED,0,1);
  46.    setup_comparator(NC_NC_NC_NC);
  47.    setup_ccp1(CCP_COMPARE_INT);
  48.    setup_vref(FALSE);
  49.    enable_interrupts(INT_TIMER1);
  50.    enable_interrupts(INT_CCP1);
  51.    enable_interrupts(GLOBAL);
  52.    setup_oscillator(OSC_4MHZ|OSC_INTRC);
  53.    set_adc_channel(ADC);
  54.    set_timer1(45535);
  55.    set_tris_b(0);
  56.    CCP_1 = 47535;
  57.  
  58.         do {
  59.       if(flagLeerADC == TRUE){
  60.          flagLeerADC = FALSE;
  61.          Calcular_Posicion();
  62.       }
  63.         } while(true);
  64. }
  65.  
  66. void Calcular_Posicion(void){
  67.    int8 ValorADC;
  68.  
  69.    ValorADC = read_adc();
  70.    CCP_1 = 46035 + (ValorADC * 7.8125);  //carga CCP1 con un valor entre 500 y 2500 (mas los 45535 de donde comienza a contar el timer, a menos que haya algun calculo que se desborde :(
  71. }

espero que a alguien le sea util... para mi lo es  :mrgreen:
salu2

hola que tal amigo, sobre el control de un servo con CCP, leí el código solo que necesito el código para un pic16f887 y el CCP en ese pic está en el puerto C en RC2, como cambio la dirección de salida del control del servo?

He estado tratando de cambiarlo y no lo consigo, consulté acerca de como hacerlo pero la verdad que no encuentro la manera... y pues nunca había programado el control de un servo...

Otra cosa, en lugar de un pot quiero poner 2 botones, y dependiendo de la cantidad de pulsos cambiar el valor que hace girar al servo, podría sustituirse la entrada ADC por el mismo rango de valores que le dé con los botones, no?

Espero puedas ayudarme saludos  :-/
Para aprender solo hay que intentar hacerlo......

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #26 en: 30 de Noviembre de 2011, 17:01:04 »
Hola amigo!
Lo que intentas hacer es muy simple partiendo del codigo ese.
Primero debes saber que el modulo CCP esta asociado a un pin si usa en modo PWM o en modo CAPTURE. Si lo usas en modo COMPARE lo que hace es generar una interrupcion cuando el TIMER1 y el valor de CCP1 coincidan.
Por lo que puedes poner el servo en el pin que tu prefieras, y no solo en un pin CCP.

Para lo de los dos pulsadores, tendrias que cambiar el bucle del MAIN por algo asi:
Código: C
  1. do{
  2.     if(PIN_A0 == 0)    //incrementa posicion
  3.         CCP_1 = CCP_1 + 100;
  4.  
  5.     if(PIN_A1 == 0)    //decrementa posicion
  6.         CCP_1 = CCP_1 - 100;
  7. }while(TRUE);

deberias agregarle un control para que al pulsar los botones no supere por arriba o por debajo los limites del PWM que en el caso del servo es de 0,5 a 2,5mS. Tambien puedes cambiar el valor de "100" por otro para que el servo se mueva mas o menos con las pulsaciones.

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 mecatronix89

  • PIC10
  • *
  • Mensajes: 33
Re: Mover servo con potenciometro
« Respuesta #27 en: 30 de Noviembre de 2011, 18:50:44 »
ok, pasa que ql puerto por el que sale la señal, lo estoy utilizando para el control del LCD parte del puerto D para los botones y pues el C me queda libre, aparte de que pues tendría que dar una dirección de salida a un determinado puerto, en ese caso cambio esta parte:

"#bit SERVO     = 0x06.1    //Pin B0 control del servo"

en lugar de 0x06.1? ó como darle dirección esa es mi pregunta. y que dirección es porque he intentado mil cosas para ponerlo en el puerto C y el código ó no funciona ó no se cambia el puerto jeje
Para aprender solo hay que intentar hacerlo......

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Mover servo con potenciometro
« Respuesta #28 en: 30 de Noviembre de 2011, 19:01:47 »
En el datasheet de tu PIC, en la pagina 27 puedes ver como esta organizada la memoria.
Como puedes ver, el puerto C corresponde con el byte de la posicion 0x07 de memoria. Asi por ejemplo 0x07.3 corresponde con el pin C3

Luego si usas "fast_io" debes configurar el tris correctamente. El pin del servo es de salida, asi que el bit correspondiente del tris debe ser "0"

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 mecatronix89

  • PIC10
  • *
  • Mensajes: 33
Re: Mover servo con potenciometro
« Respuesta #29 en: 01 de Diciembre de 2011, 16:39:01 »
Hola que tal... Mil gracias por tu ayuda amigo, ya funciona como deseaba, jaja solo que en la simulación de proteus donde tengo el pic lo tení configurado a 20MHz y el pulso lo sacaba muy lento... También había estado checando eso de la fecuencia, no será posible cambiar la configuración de los 4MHz a los 20MHz?

      setup_oscillator(OSC_4MHZ|OSC_INTRC);

para usar el HS a 20MHZ en lugar de INTRC_IO a 4MHZ....

disculpa la terquedad y parece que quiciera que me hicieras el trabajo, pero estube consultando leyendo y tratando varias cosas, pero no me funcionó... y no encontré configuraciones con 20MHZ...

SALUDOS :)
Para aprender solo hay que intentar hacerlo......


 

anything