TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: RALF2 en 29 de Diciembre de 2010, 22:20:59

Título: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 29 de Diciembre de 2010, 22:20:59
Que tal amigos!
Tengo un problemita a ver si me pueden ayudar  :mrgreen:
Estoy utilizando un pic18f252 @ 10MHZ y el ccs, el proyecto consiste en hacer un programa para manejar un servo motor por medio de un potenciometro conectado al adc del pic.
El programa consiste en utilizar el timer1 con interrupcion cada 20ms, este marca el periodo.
Y el modulo CCP1 para controlar el tiempo en que la señal esta en ON.
En principio todo funciona bien, en cuanto a la interrupcion y el modulo ccp, pero el valor que se carga en la variable ccp1, la cual controla el tiempo en que la señal esta en on, la quiero variar con el adc del pic  :?
Los valores calculados para el servo que usare son: 64035 para que el servo se vaya a cero grados y 59535 para que el servo se vaya a 180 grados, estos valores deben cargarse en la variable ccp1.
El adc a utilizar varia de 0 a 1023 (10bits).
Alguna idea de como puedo hacer esto?


Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: MLO__ en 29 de Diciembre de 2010, 22:39:43
Hola.

Para ello creo que hay una función (set_pwm_duty()), pero no se si sea eso lo que buscas ...  :?

No se puede asignar directamente en CCP_1?

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: jhozate en 29 de Diciembre de 2010, 23:13:11
el pwm en ese pic no es de 16bit?
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 29 de Diciembre de 2010, 23:57:56
Que tal amigos!
bueno lo que quiero es que cuando el adc me cargue 0, en la variable ccp_1 sea igual a por ejemplo 59535 y cuando el adc tenga 1023 la variable ccp_1 tenga ahora 64035.
No le paren al resto  :D

jhozate el pwm es de 10bits
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 00:47:45
  Yo creo que se debería emplear la ecuación de una recta que pasa por dos puntos. Y = aX + b
Tomamos como "X" el valor leído del ADC. "Y" serían los valores que querés que tome el módulo CCP.

  Para el caso que "X" valga 0, la fórmula queda "Y" = (a * 0) + b --> 59535 = (a * 0) + b --> b = 59535. Ya tenemos despejado el valor de b.
  Ahora nos ocupamos del otro caso ("X" valiendo 1023) Y = aX + b --> Y = (a * 1023) + 59535 --> 64035 = (a * 1023) + 59535 --> 64035 - 59535 = (a * 1023) --> 4500 = (a * 1023) --> 4500/1023 = a --> a es aproximadamente 4.3988.

  Para corroborar el resultado podemos suponer un punto intermedio del pote... y = aX + b --> Y = (4.3988 * 511) + 59535 -->
Y = 2247.7868 + 59535 --> Y = 61782.7868. Y corroboramos el valor haciendo el promedio de los dos valores que vos querías
Y = (64035 + 59535) / 2 --> Y = 123570 / 2 --> Y = 61785
Valor entero calculado de punto medio      61785
Valor entero con el ADC entregando 511   61782
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 30 de Diciembre de 2010, 01:21:41
Correcto angelgris le diste cerquitica  :mrgreen:
Solo falta implementar eso en el pic con ccs como lo harias? alli estas utilizando punto flotante y los registros del pic operan con numeros enteros en este caso el ccp_1 opera a 16bits  :shock:

Como seria la formula que deberia colocar en ccs para implementar lo que brillantemente deducistes  :mrgreen:

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 09:48:11
  No sé como sería en CCS, pero en ANSI C hay que hacer casting. Básicamente sería algo así...

 
Código: C
  1. void main(void)
  2. {
  3.   int valor_adc;
  4.   int valor_ccp;
  5.  
  6.   while (1)
  7.   {
  8.     valor_adc = readadc();
  9.     valor_ccp = (int)((4.3988 * valor_adc) + 59535);
  10.   }
  11. }

  Fijate que pongo int entre paréntesis antes de la cuenta. Eso indica que se trate el resultado como un valor entero, y luego se almacena en la variable "valor_ccp"
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: MLO__ en 30 de Diciembre de 2010, 11:55:07
No tocaría hacer el casting con float? y de ahí cargarlo a CCP_1.

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 11:59:26
No tocaría hacer el casting con float? y de ahí cargarlo a CCP_1.

Saludos

  Ah, que duda que me generaste.... Creo que no, porque si yo trato a la cuenta como FLOAT y lo intento guardar en una variable INT debería generar un error porque son distintos tipos de datos.

  Voy a probar....
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: MLO__ en 30 de Diciembre de 2010, 12:01:38
Hola.

Es que las variables son int (que deberían ser long) pero la operación es la que se hace como si fueran float (para no perder exactitud), si haces las operaciones haciendo el casting como int o long, te va a dar cero .... porque estas usando punto flotante no?

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 12:16:01
  Yo creo que la operación se hace como float (porque hay involucrado un operando de ese tipo).

  Esto es lo que encontré en internet al respecto "En programación, un casting (o cast) sirve para cambiar el tipo de dato del valor resultante de una expresión."

  Yo entiendo que si una expresión da un float, pero le hago el cast como int voy a tener el resultado entero de dicha operación... A ver si con un ejemplo me explico mejor.... A = 11/2 --> A = 5.5 al hacerlo con cast sería A = (int) (11/2) --> A = 5. O sea que en A tengo la parte entera del resultado.

  Lo tengo así en un frecuencímetro y me funcionaba bien... "Frecuencia = (int) (2.5e6/Periodo);"
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 30 de Diciembre de 2010, 12:45:45
Ok amigos excelente analisis algelgris!
Solo unos detallitos que hay que afinar  :mrgreen:

La formula seria:  ccp_1= (long)(read_adc()*4.3988) + 59535;
Claro el unico problema esta en que al pasar de float a long se perderian unos decimales que alterarian un poco los resultados  :shock:

Pero bueno es lo mas cercano que podemos hacer con el metodo empleado  :mrgreen:
Mlo__ la variable tipo ccp_1 es de tipo long como dices, por lo que si le  cargas un float este te truncara los decimales y el error que obtendrias seria mayor.
Es mejor utilizar float para hacer los calculos y luego pasar ese valor a long como lo coloco en la formula.  :mrgreen:

Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 12:59:59
  Y si.... siempre se va a perder algo de precisión al perder los decimales. También he de notar entrar en la rutina de interrupción lleva más tiempo en C que en ASM, así que ahí también se está introduciendo un error (el cual se puede compensar alterando levemente el valor que se almacene en CCP).

  Yo traté la variable como INT porque para HiTech, una variable de 16 bits es int. No sé para CCS. En HiTech el tipo long es de 32 bits
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: MLO__ en 30 de Diciembre de 2010, 13:07:44

Estoy utilizando un pic18f252 @ 10MHZ y el ccs, el proyecto consiste en hacer un programa para manejar un servo motor por medio de un potenciometro conectado al adc del pic.


Raro, yo he hecho lo que digo para el velocímetro:

Código: [Seleccionar]
Variable.Velocidad= ((float)(Variable.Metros*FactorVelocidad)/(float)(Variable.SetPointPulsos))/((float)(CCP_1*0.0000016)+Timer.Desbordes);


Variable.Velocidad es del tipo char y todas las otras variables son diferentes a float. Si usaba el casting (long) ... me daba cero ....

Ya probaras y nos diras tus resultados RALF.

Un saludo
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 13:49:14
  Sí MLO__, así como lo ponés vos lo que hacés es que se trate como FLOAT a cada argumento. Y tal vez el resultado es "casteado" implícitamente a char por el compilador.

  Hice la prueba de poner -tomo como ejemplo la línea que puse de mi frecuencímetro- "Frecuencia = (float) (2.5e6/Periodo);" y el compilador arrojo un "warning" diciendo que había una conversión implícita de float a int. Tal vez -siguiendo con la línea de mi ejemplo- debería poner algo así "Frecuencia = (int) (2.5e6/(float)Periodo)". Así la división se hace entre dos tipos float y luego todo el resultado es "casteado" a int.
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 30 de Diciembre de 2010, 14:36:03
Que tal amigos!
AngelGris en ccs las variables tipo int son de 8 bits y las long son de 16bits!.
El hitech nunca lo he utilizado.
MLO__ interesante ecuacion que colocas es en ccs?
El programa esta listo desde ayer cuando angelgris coloco su respuesta era exactamente lo que estaba pensando  :mrgreen:  de hecho asi lo habia estado haciendo solo queria saber si se podria hacer de otra forma  :mrgreen:
Y para que vean lo que hice y como premio a su ayuda les coloco aqui todo lo hecho por si tienen algunas sugerencias para mejorar el control de servos con el ccp_1 y el timer1  ;-)

Citar
#include <18f252.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading


#use delay(clock=10000000)

long var1;

#int_TIMER1
void  TIMER1_isr(void)
{
   set_timer1(15536);
   setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
   ccp_1= var1;
}

void main()
{
   setup_adc_ports(an0);
   setup_adc(adc_clock_internal);
   set_adc_channel(0);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);      //26.2 ms overflow
   setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   set_timer1(15536);
   ccp_1= 61786;
   while(1)
   {
      ccp_1= (long)(read_adc()*2.44)+ 60536;
      delay_us(20);  
   }
}

Adjunto simulacion en proteus!
Nota: Cambie algunos tiempos para adaptarlo al servo del proteus  :mrgreen:

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: MLO__ en 30 de Diciembre de 2010, 15:09:53
Hola.

Es que CCS tiene sus cosas  :) me imagino que hace el cast automáticamente a la hora de asignar el valor.

Citar
MLO__ interesante ecuacion que colocas es en ccs?

Si, es en CCS, es para un velocímetro (http://www.todopic.com.ar/foros/index.php?topic=22842.msg278803#msg278803) que hice.

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 30 de Diciembre de 2010, 15:49:25
Que tal MLO__
Mira como defines esas variable.velocidad esa sintaxis no la habia visto.
Utilizaste algun #define para crearla?

Y como dices el casting es el que se encarga de realizar la conversion entre diferentes tipos de datos muy util  :mrgreen:
Vi el video muy interesante el uso de sensores de efecto hall nunca los he utilizado ellos sensan algun metal, me podrias explicar?

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: MLO__ en 30 de Diciembre de 2010, 16:16:10
Hola.

La variable es de una estructura, no mas  :)

El sensor de efecto Hall te da un 1 o un 0 eléctrico en función de si hay o no campo magnético, por lo que están sensando el paso del imán permanente que está pegado en las aspas del ventilador ... muy útiles los Sensores Hall (http://es.wikipedia.org/wiki/Sensor_de_efecto_Hall)  :mrgreen:

Saludos
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: AngelGris en 30 de Diciembre de 2010, 16:24:07
Hola.

La variable es de una estructura, no mas  :)

El sensor de efecto Hall te da un 1 o un 0 eléctrico en función de si hay o no campo magnético, por lo que están sensando el paso del imán permanente que está pegado en las aspas del ventilador ... muy útiles los Sensores Hall (http://es.wikipedia.org/wiki/Sensor_de_efecto_Hall)  :mrgreen:

Saludos

  Los sensores hall se suelen utilizar en algunos motores trifásicos BLDC. Claros ejemplos de ello son los DRUM y los CAPSTAN de los ya viejos sistemas de VHS. El DRUM es el motor que hace girar el cabezal y el CAPSTAN es el motor de arrastre de cinta. También se encuentran en algunas caseteras de audio y son utilizados para el contador y también para saber si está funcionando la casetera o está trabada.
Título: Re: Ayuda con modulo CCP y ccs
Publicado por: RALF2 en 30 de Diciembre de 2010, 23:20:26
Gracias por sus respuestas MLO__ y AngelGris.
No me recordana lo de las estructuras MLO__ interesante tu aplicacion.
Muy instructivo lo de los tipos de los motores AngelGris.

Gracias a todos por su ayuda!