Autor Tema: Contador de pulsos y PWM  (Leído 8637 veces)

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

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Contador de pulsos y PWM
« en: 29 de Mayo de 2017, 13:47:43 »
Hola a todos, tengo un problema con el que quisiera me ayudaran ya que no doy con la solucion, por más que he buscado en foros, google, ayuda a un amigo   no he podido entender ni muchjo menos hacer funcionar mi microcontrolador para poder hacer lo que necesito

 :oops: :oops:

Voy describir el problema que debo resolver con un pic 16f877a, no se si se pueda con otro, quedaría a consideración de los expertos que me puedan ayudar.

El problema que debe resolver el microcontrolador es que por via RS232 gracias a un conversor TTL ya sea por Bluetooth o XBEE, eso no es importante en este momento, solo que debe ser por RS232 es:

Teniendo una plataforma robótica que consta de dos motores con encoder el cual debo medir las rpm de cada motor (son 2 motores), enviar esa información al computador via rs232, este debe hacer un proceso cual sea y debe enviar al microcontrolador un dato numérico que debe ser interpretado por el micro para ajustar por PWM la velocidad de cada motor.

El microcontrolador debe estar midiendo en todo momento las rpm de ambos motores y enviando esta informacion para que sea procesada por el computador.

La verdad he leido mucho y por todas partes hay varias opciones pero no logro entender ni que funcione ninguna de ellas aunque sea por mitad. Hasta donde mis conocimientos dan, voy a manejar los PWM por las salidas CCP1 y CCP2 del micro, pero no he podido es medir las rpm constantemente por ningun pin del micro, adjunto un ejemplo de lo que llevo, se que no es mucho pero así se van aclarando las dudas que estas palabras no tan estructuradas puedan generar.

Código: [Seleccionar]
#include <proyecto_0.h>
#include <lcd3.c>
#include <stdlib.h>  //librerias para trabajar con el protocolo RS232
#include <input.c>
#include <string.h>

int16 a=0,b=0;

#INT_TIMER2
void  TIMER2_isr(void)
{
      a=get_timer0();     
      printf(lcd_putc,"\fT1= %lu",a);     
      b=get_timer1();
      printf(lcd_putc,"\nT2= %lu",b);
      set_timer0(0); 
      set_timer1(0);
      set_TIMER2(0);
}

void main()
{
   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);     
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);   
   setup_timer_2(T2_DIV_BY_16,255,16);     
 
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);

   lcd_init();

   lcd_putc("\fReady...\n");

   while(TRUE)
   { 
   }

}

No he podido hacer que el lcd me muestre la frecuencia aumentada de a un hertz, funciona por ratos a 10,100 o 1KHz
pero no siempre es asi, la idea es tener la lectura correcta del tren de pulsos que entrna por los dos timers y luego calcular las rpm, pero no he podido ajustarlas.

Quedo atento a su ayuda :-/


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Contador de pulsos y PWM
« Respuesta #1 en: 29 de Mayo de 2017, 22:26:55 »
Nunca pero NUNCA utilizes funciones que demoran demasiado en las interrupciones ( como es el printf y los delays )

Creo que deberias dividir tu problema y no tratar de realizar todo junto.

Tenes las siguientes partes

- Comunicacion UART / RS232
- Tomar el valor de las RPM de los motores
- Actuar sobre los motores para que tengan una velocidad constante

Y lo bueno de estos 3 es que podes programarlos independientes de cada uno, deberias comenzar a realizar la parte de mantener el motor con una velocidad constante. Lo mas seguro que esta parte sea mejor un PID, el PID te permite tener una referencia ( velocidad deseada ) la cual se compara con lo actual ( velocidad medida ) y luego actua sobre ello. Entonces podrias pensarlo como que tenes 2 variables de entradas y 1 salida que es el PWM. Las variables de entradas son actualizadas por los otras secciones del programa.

Entonces en este caso lo unico que necesitarias es justamente cambiar el valor de estas variables con la nueva velocidad y realimentacion de velocidad y dejar que el lazo cerrado o micro haga lo suyo.
Si pensas si queres una velocidad nueva deberias solamente recibir de la UART y cambiar una variable.

El tema esta en como obtener los valores de la velocidad.

El Timer2 lo usas para el PWM en ambos CCP.
Podrias usar el Timer 0 y el Timer 1 para tener los valores de la velocidad. El problema esta en que ya no tenes mas Timers para tu libre uso, podrias usar el Timer 2 como estas haciendo, lo cual va a depender de la frecuencia de trabajo. Y si los timers pueden contar los suficientes pulsos.
« Última modificación: 29 de Mayo de 2017, 22:43:24 por KILLERJC »

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #2 en: 29 de Mayo de 2017, 23:15:20 »
Primero que todo, gracias por responder, no sabia que no debia usar delay y printf en las interrupciones, entiendo lo del control pero este debe ser procesado por el computador con los datos recibidos del pic, hoy he estado todo el día haciendo la lectura de las frecuencias y ya pude pero sé que con lo que respondes todo funciona pero no es la forma correcta, pude hacer que la interrupcion del timer2 lea correctamente las frecuencias introducidas pero no les va a gustar el codigo que hice en la interrupcion para que funcionara, que es le siguiente:

 
Código: [Seleccionar]
void  TIMER2_isr(void)
{
      delay_ms(30);                         
      a=get_timer0();
      a=a*4;
      b=get_timer1();                    //CONT Pulsos       
      b=b*4;

      set_timer0(0); 
      set_timer1(0);
      set_TIMER2(0);
}

con ese codigo, la lectura la hace bien y solo hay error de 1 o 2 hz siempre y cuando la frecuencia sea superior a 8Hz segun lo simulado en proteus, digamos que funciona bien pero al momento de recibir el dato por el RS232 la lectura del timer1 se vuelve loca y no he logrado que funcione al tiempo.

Si me pueden dar alguna guia de como proceder, agradeceria mucho. :oops: :oops:


:UPDATE:

Ya corregi algunas cosas pero sigue generando anomalias.
« Última modificación: 29 de Mayo de 2017, 23:50:27 por JebusITO »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Contador de pulsos y PWM
« Respuesta #3 en: 30 de Mayo de 2017, 00:21:51 »
2 problemas.

Si usas el CCP que usa el Timer2, vos NO debes ponerlo a 0, lo hace solo el CCP.

Si usas funciones como printf, divisiones que ocupan demasiado tiempo, cuando estas en una interrupcion hace que no pueda entrar de nuevo si es que ocurre una nueva interrupcion.
Entonces si usas el tiempo del Timer2 para tener una referencia de cuantos pulsos entraron, ya cuando entre de nuevo puede que pasen 2, 3 o mas veces la interrupcion del Timer2.

De esa forma es imposible tener una lectura correcta. Ya que vos esperas que tome la lectura del timer cada interrupcion del Timer2, pero lo que en realidad ocurre es que seguramente gracias a los printf y divisiones termine pasando 2 o mas interrupcioens del Timer2.

Si la PC es quien va a hacer de PID entonces tampoco multipliques por 3 o dividas por 10 en el micro, dejalo que lo haga la PC.

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #4 en: 30 de Mayo de 2017, 19:46:10 »
Hola KILLERJC, gracias por tu paciencia, he arreglado parte del codigo, pero tengo enredado el funcionamiento de los timers y por eso no he podido avanzar mucho, ya quité de la interrupcion todo el codigo "basura" y quedó algo asi:

Código: [Seleccionar]

void  TIMER2_isr(void)
{
      delay_ms(30);                         
      a=get_timer0();
      b=get_timer1();                    //CONT Pulsos       

      set_timer0(0); 
      set_timer1(0);
}


No he podido quitar el delay porque si no, no puedo contabilizar correctamente los pulsos, los timers los tengo configurados así:

Código: [Seleccionar]
void main()
{   
   //    Configuracioin de los temporizadores y contadores
   setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1|RTCC_8_bit);      //65,5 ms overflow
   setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);      //65,5 ms overflow
   setup_timer_2(T2_DIV_BY_16,195,16);      //50,0 ms overflow

....
.....


Entonces no se que hacer, había pensado en multiplexar la entrada para usar los dos timers y dejar el de los PWM libre, pero como dije anteriormente, el uso de esta función no la tengo toda clara.

Quedo atento a sus comentarios.



2 problemas.

Si usas el CCP que usa el Timer2, vos NO debes ponerlo a 0, lo hace solo el CCP.

Si usas funciones como printf, divisiones que ocupan demasiado tiempo, cuando estas en una interrupcion hace que no pueda entrar de nuevo si es que ocurre una nueva interrupcion.
Entonces si usas el tiempo del Timer2 para tener una referencia de cuantos pulsos entraron, ya cuando entre de nuevo puede que pasen 2, 3 o mas veces la interrupcion del Timer2.

De esa forma es imposible tener una lectura correcta. Ya que vos esperas que tome la lectura del timer cada interrupcion del Timer2, pero lo que en realidad ocurre es que seguramente gracias a los printf y divisiones termine pasando 2 o mas interrupcioens del Timer2.

Si la PC es quien va a hacer de PID entonces tampoco multipliques por 3 o dividas por 10 en el micro, dejalo que lo haga la PC.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Contador de pulsos y PWM
« Respuesta #5 en: 30 de Mayo de 2017, 20:19:09 »
Te voy a dar un ejemplo espero que mas sencillo de entender.

Tu interrupcion del Timer2 esta atado a la frecuencia del PWM, supongamos que tenes una frecuencia de PWM 1KHz es decir cada 1ms tendrias una interrupcion del Timer2. (Valor tal ves no correcto pero que sirve de ejemplo )
Otra condicion que te dije es que si te quedas dentro de la interrupcion no entra a otra interrupcion hasta que sale finalmente.

Esto ocurriria en tu programa:

Tiempo transcurrido - Accion
1ms - Entro a la interrupcion del Timer2
31ms - Termina el delay y sale de la interrupcion, aca me perdi 30 interrupciones del Timer2, el problema es que apenas salga como queda pendiente vuelve a entrar
31ms - Entro de nuevo a la interrupcion del Timer2
61ms - Repito el ciclo de salir

Existe un problema. NUNCA tengo otro tiempo. Apenas sale de la interrupcion como hay otra pendiente vuelve a entrar. La otra es que poseas un PWM de 50Hz y el tiempo te sobre. Otro problema de esto es que pasa si tenes un codigo en el while del main? Y ocurre este caso?. Nunca lo vas a poder ejecutar. Por eso nuevamente no uses delays en la interrupcion

Si (con el tiempo que suponimos) mi interrupcion del Timer2 es 1ms. Y quiero leer cada 30 ms el valor de los Timers. Que evita que yo ponga un contador en ves de un delay? Es decir cuando entre 30 veces a la interrupcion recien ahi tome el valor de los timers.

Código: C
  1. void  TIMER2_isr(void)
  2. {
  3.       if (contador >= 30)
  4.       {
  5.             a=get_timer0();
  6.             b=get_timer1();                    //CONT Pulsos      
  7.  
  8.             set_timer0(0);  
  9.             set_timer1(0);
  10.             contador = 0;
  11.       }
  12.       contador++;
  13. }

De esta forma ejecutar la interrupcion es rapida, y no me detengo dentro de la misma para siempre. Revisar si el contador tiene el valor correcto llevara 5 ciclos de instruccion como mucho si cuento el incremeto tambien.

-------------------------------------------------

Ahora vamos a los tiempos que posee tu programa

Timer2 tiene un OV cada 50ms

Y encima necesitas 30ms mas para poder obtener buenos valores en los demas Timers.

Por que no directamente implementas un contador y que cada 100ms proceda a tomar los valores de los Timers 0 y 1.
El Timer0 podes contar hasta 511 ( si pensas en el flag de interrupcion como un noveno bit ) Y te aseguras de que nunca supere este valor con los preescalers.
El Timer1 no vas a tener problemas.

Que velocidades va a tener y cuantos pulsos por revolucion van a entrar en cada caso ?

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #6 en: 30 de Mayo de 2017, 22:28:06 »
Hola KILLERJC, gracias por tu ayuda, ya hice las modificaciones pertinentes y el programa simulado esta funcionando con el PWM aumentando o disminuyendo sin problemas de que el micro se bloqueara en algún momento, esto gracias al contador y el if que me sugeriste introducir en la interrupción.

En cuanto al motor a usar y el encoder que voy a usar es el siguiente:





Como puedes ver el encoder tiene 20 ranuras para ser medidas, las especificaciones del motor supuestamente es:

------
For Motor:
Voltage                    DC 3V                 DC6V            DC 7.2V
Current                    160mA                220mA      250mA
No-load Speed       120 rpm/min   200 rpm/min   250 rpm/min
Load Speed       100 rpm/min   175 rpm/min   210 rpm/min
Torque                 0.45 kg.cm   1.0 kg.cm   1.5 kg.cm
Reduction Ratio   1:48
Noise   ≤65dB
Motor Size   65mm x 18mm x 22mm(L*W*H)

--------------------------------------

La duda que me queda, es que haciendo la conversión directa de de RPM a Frecuencia, la frecuencia me da con decimales y el pic en las pruebas solo mide frecuencias enteras entonces no se si al implementar esto sea una traba o deba hacer algún ajuste a la lectura.


Te voy a dar un ejemplo espero que mas sencillo de entender.


-------------------------------------------------

Ahora vamos a los tiempos que posee tu programa

Timer2 tiene un OV cada 50ms

Y encima necesitas 30ms mas para poder obtener buenos valores en los demas Timers.

Por que no directamente implementas un contador y que cada 100ms proceda a tomar los valores de los Timers 0 y 1.
El Timer0 podes contar hasta 511 ( si pensas en el flag de interrupcion como un noveno bit ) Y te aseguras de que nunca supere este valor con los preescalers.
El Timer1 no vas a tener problemas.

Que velocidades va a tener y cuantos pulsos por revolucion van a entrar en cada caso ?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Contador de pulsos y PWM
« Respuesta #7 en: 30 de Mayo de 2017, 23:22:26 »
Citar
La duda que me queda, es que haciendo la conversión directa de de RPM a Frecuencia, la frecuencia me da con decimales y el pic en las pruebas solo mide frecuencias enteras entonces no se si al implementar esto sea una traba o deba hacer algún ajuste a la lectura.

Y cual es el problema?

Vos estarias tomando lecturas cada 100ms.. Eso te va a dar RPM/20. Enviale eso a la PC y que la PC se encargue. Vos dijiste que la PC deberia hacer el control de velocidad, entonces que sea la PC que se encargue de hacer los calculos completos.

Es decir en tu PIC solo tomarias esos datos y lo enviarias y listo. Se termino el trabajo del PIC.
« Última modificación: 30 de Mayo de 2017, 23:46:15 por KILLERJC »

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #8 en: 31 de Mayo de 2017, 19:13:58 »
Vale, entocnes ya casi resuelvo todo lo que debe hacer el pic, pero revisando el post completo y la simulacion, mencionaste la limitación del t0cki en cuanto a que llega a 512 como máximo, aqui tengo problemas porque solo me mide hasta 255, eso uno y dos si necesitase más frecuencia ejemplo 1kHz que podria hacer ahi?


Citar
La duda que me queda, es que haciendo la conversión directa de de RPM a Frecuencia, la frecuencia me da con decimales y el pic en las pruebas solo mide frecuencias enteras entonces no se si al implementar esto sea una traba o deba hacer algún ajuste a la lectura.

Y cual es el problema?

Vos estarias tomando lecturas cada 100ms.. Eso te va a dar RPM/20. Enviale eso a la PC y que la PC se encargue. Vos dijiste que la PC deberia hacer el control de velocidad, entonces que sea la PC que se encargue de hacer los calculos completos.

Es decir en tu PIC solo tomarias esos datos y lo enviarias y listo. Se termino el trabajo del PIC.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Contador de pulsos y PWM
« Respuesta #9 en: 31 de Mayo de 2017, 19:23:30 »
Lo que digo del Timer0 es que tenes 8 bits, pero tambien tenes un flag de interrupcion que se pone a 1 cuando la cuenta supera los 255.
Cuando se produce el overflow se activa el flag, no va a entrar a la interrupcion si es que esta desactivada la interrupcion. Pero el flag sigue activandose en ese caso.

Supongamos que comenzas con estos valores:

TMR0 = 0
TMR0IF = 0

Contas hasta llegar a 255  y te queda asi:

TMR0 = 0xFF
TMR0IF = 0

Al pasar a 0x00 se activa el flag, podrias pensar que en realidad el valor es de 0x100

TMR0 = 0x00
TMR0IF = 1

Asi hasta llegar a 0xFF nuevamente, que tendrias el valor 0x1FF ( 511 ) si tomas el bit del flag como el bit numero 9..
Te decia que tenes que preocuparte de que JAMAS pase de del valor 0x1FF ya que volveria a 0x100, es decir no podes saber cuantas veces entro.

---------------------

La otra si queres complicartela un poco mas o tal ves simplificartela es activar la interrupcion del TMR0.
Y en la interrupcion del Timer0 poner un contador. Entonces cuando vayas a tomar los valores el contador serian tus 8 bits de mayor peso y los 8 del TMR0 los de menor peso. Como si fuera uno de 16bits. Precauciones extras debes tener con esto obviamente.

---------------------

De ultima no te compliques y asegurate de que no se active el flag del TMR0.

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #10 en: 31 de Mayo de 2017, 22:56:54 »
Vale KILLERJC, ya con esto creo que podre avanzar, en caso de necesitar mas frecuencia en el timer0 entonces para no complicarme usaré el multiplexor en el timer1, ahora estoy viendo como por RS232 enviar el dato para el PWM pero no doy con la conversión de cadena a entero, la interrupción del USART que llevo es la siguiente:

Código: [Seleccionar]

#INT_RDA
void  RDA_isr(void)
{
   
   k = getc();       
     if(k!=0)     
         if(k=='1')
         {
            set_pwm1_duty(10);

solo que los valores que envia el PC pueden ser desde -255 hasta 255 (como para usar el timer0) y el codigo se em extenderia si hiciera un if por número, :D :D :D :D
queria  intentar un codigo como el siguiente pero no se porque no hace la conversión correctamente.

Código: [Seleccionar]

#INT_RDA
void  RDA_isr(void)
{
   
   k = getc();
   x = atol(k);
   set_pwm1_duty(x);


pero el error que me dice es que el getc(); solo es para comparación  :? :?

Lo que digo del Timer0 es que tenes 8 bits, pero tambien tenes un flag de interrupcion que se pone a 1 cuando la cuenta supera los 255.
Cuando se produce el overflow se activa el flag, no va a entrar a la interrupcion si es que esta desactivada la interrupcion. Pero el flag sigue activandose en ese caso.

Supongamos que comenzas con estos valores:

TMR0 = 0
TMR0IF = 0

Contas hasta llegar a 255  y te queda asi:

TMR0 = 0xFF
TMR0IF = 0

Al pasar a 0x00 se activa el flag, podrias pensar que en realidad el valor es de 0x100

TMR0 = 0x00
TMR0IF = 1

Asi hasta llegar a 0xFF nuevamente, que tendrias el valor 0x1FF ( 511 ) si tomas el bit del flag como el bit numero 9..
Te decia que tenes que preocuparte de que JAMAS pase de del valor 0x1FF ya que volveria a 0x100, es decir no podes saber cuantas veces entro.

---------------------

La otra si queres complicartela un poco mas o tal ves simplificartela es activar la interrupcion del TMR0.
Y en la interrupcion del Timer0 poner un contador. Entonces cuando vayas a tomar los valores el contador serian tus 8 bits de mayor peso y los 8 del TMR0 los de menor peso. Como si fuera uno de 16bits. Precauciones extras debes tener con esto obviamente.

---------------------

De ultima no te compliques y asegurate de que no se active el flag del TMR0.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Contador de pulsos y PWM
« Respuesta #11 en: 01 de Junio de 2017, 11:54:31 »
Citar
solo que los valores que envia el PC pueden ser desde -255 hasta 255

No entiendo ya que la carga del duty si o si es sin signo. A no ser que esa sea la diferencia de lo que esta puesto. Bueno eso lo vas a ver vos.
Primero que nada no uso mucho CCS asi que tomalo entre comillas al codigo (funciones,preprocesadores,etc) que escriba.

Vamos al ejemplo... Supongamos que la computadora envia en ASCII el valor.

"250"
"100"
"10"
"-10"
"-125"

Primero que nada uno debe saber cuando es que termina lo que se esta enviando, asi que por ahi es bueno que se envie otro caracter mas. Podria ser un 0x00 para indicar que termino.

Entonces tu PC deebria enviar todo esto:

'2','5','0',0x00
'-','1','2','5',0x00

Esto deberias ponerlo en un array. Y recien cuando esta completo ( recibimos ese ultimo caracter) procedemos a convertirlo.

Código: C
  1. #include <stdlib.h>
  2.  
  3. char RX_Buffer[10];
  4. char i = 0;
  5. signed int16 numero;
  6.  
  7. #INT_RDA
  8. void  RDA_isr(void)
  9. {
  10.    
  11.    k = getc();        
  12.    if(k != 0){
  13.       // Aca todavia no esta completo y siguen llegando valores
  14.       RX_Buffer[i] = k;
  15.       i++;
  16.       // Proteccion de que no supere los 10 lugares que posee el array RX_Buffer (Recordando de dejar uno al ultimo siempre, por eso 9)
  17.       if(i >= 9) {
  18.             i=0;
  19.       }
  20.    } else {
  21.       // Aca se completo, por que recibimos el 0x00
  22.       RX_Buffer[i] = '\0'; //Termino el string ya se habia pre-incrementado antes la i
  23.  
  24.       // Aca convierto a entero
  25.       numero = atoi(RX_Buffer);
  26.       // Termino de hacer lo que necesite
  27.       set_pwm_duty(numero);
  28.    }

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #12 en: 01 de Junio de 2017, 19:04:41 »
 :-/ :-/
Wow KILLERJC con esta explicación aprendí lo que no había podido hacer leyendo en foros ni el manual de CCS ni videos de youtube, gracias, ahora te comento que después de trabajar y modificar el ejemplo que me dejaste tengo una duda, creo que ya es de las últimas porque espero tener el carro armado el próximo lunes para trabajar todo en vivo y directo  :lol:
 debido a que el controlador lo va a hacer el computador, debo tener alguna forma de decirle al PIC que motor va a modificar el PWM pues estos se controlan por aparte  :D  entonces debo hacer dos comparaciones, es cierto que el PWM debe ser sin signo, fue mi error ahi ya que el negativo lo debe procesar el PC, así que he pensado enviar al Pic algo asi:

Para el motor izquierdo:
la letra i, luego el numero que debe tener el PWM

- 'i' '2' '0' '0' '0x0D'

que significa izquierdo 200 enter o 0 todavía no he decidido que es mejor, y para el derecho algo así:

- 'd' '2' '0' '0' '0x0D'

pero no me sirve este código:

Código: [Seleccionar]

void  RDA_isr(void)
{
   k = getc();   
   if(k == 'i')   //  Aqui verifico si es motor izquierdo
   {
   if(k != 0x0D)
      {
      // Aca todavia no esta completo y siguen llegando valores
      RX_Buffer[i] = k;
      i++;
      // Proteccion de que no supere los 10 lugares que posee el array RX_Buffer (Recordando de dejar uno al ultimo siempre, por eso 4)
      if(i >= 9)
         {
            .............


if(k == 'd')   //  Aqui verifico si es motor derecho
   {
   if(k != 0x0D)
      {



ni este otro:  :5] :5]

Código: [Seleccionar]

 if(k != 0x0D)
      {
   if(k=='i')
     {
      // Aca todavia no esta completo y siguen llegando valores
      RX_Buffer[i] = k;
      i++;
      // Proteccion de que no supere los 10 lugares que posee el array RX_Buffer (Recordando de dejar uno al ultimo siempre, por eso 9)
      if(i >= 9)
           ....................



Citar
solo que los valores que envia el PC pueden ser desde -255 hasta 255

No entiendo ya que la carga del duty si o si es sin signo. A no ser que esa sea la diferencia de lo que esta puesto. Bueno eso lo vas a ver vos.
Primero que nada no uso mucho CCS asi que tomalo entre comillas al codigo (funciones,preprocesadores,etc) que escriba.

Vamos al ejemplo... Supongamos que la computadora envia en ASCII el valor.

"250"
"100"
"10"
"-10"
"-125"

Primero que nada uno debe saber cuando es que termina lo que se esta enviando, asi que por ahi es bueno que se envie otro caracter mas. Podria ser un 0x00 para indicar que termino.

Entonces tu PC deebria enviar todo esto:

'2','5','0',0x00
'-','1','2','5',0x00

Esto deberias ponerlo en un array. Y recien cuando esta completo ( recibimos ese ultimo caracter) procedemos a convertirlo.

Código: C
  1. #include <stdlib.h>
  2.  
  3. char RX_Buffer[10];
  4. char i = 0;
  5. signed int16 numero;
  6.  
  7. #INT_RDA
  8. void  RDA_isr(void)
  9. {
  10.    
  11.    k = getc();        
  12.    if(k != 0){
  13.       // Aca todavia no esta completo y siguen llegando valores
  14.       RX_Buffer[i] = k;
  15.       i++;
  16.       // Proteccion de que no supere los 10 lugares que posee el array RX_Buffer (Recordando de dejar uno al ultimo siempre, por eso 9)
  17.       if(i >= 9) {
  18.             i=0;
  19.       }
  20.    } else {
  21.       // Aca se completo, por que recibimos el 0x00
  22.       RX_Buffer[i] = '\0'; //Termino el string ya se habia pre-incrementado antes la i
  23.  
  24.       // Aca convierto a entero
  25.       numero = atoi(RX_Buffer);
  26.       // Termino de hacer lo que necesite
  27.       set_pwm_duty(numero);
  28.    }

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #13 en: 01 de Junio de 2017, 19:46:23 »
Para simplificar un poco el código y no volverme loco con el mismo he decidido implementar  el siguiente código:

Código: [Seleccionar]
char RX_Buffer[5];

RDA_isr()//void  RDA_isr(void)
{
   k = getc();   
   if(k != 0x0D)
      {
      // Aca todavia no esta completo y siguen llegando valores
      RX_Buffer[i] = k;
      i++;
      // Proteccion de que no supere los 6 lugares que posee el array RX_Buffer (Recordando de dejar uno al ultimo siempre, por eso 5)
      if(i >= 4)
         {
            i=0;
         }
      }
      else
      {
      // Aca se completo, por que recibimos el 0x00
      RX_Buffer[i] = '\0'; //Termino el string ya se habia pre-incrementado antes la i
 
      // Aca convierto a entero
      numero = atoi(RX_Buffer);
      printf("\fnum: %lu",numero);
     
    if(numero >=300)
      {
      // Termino de hacer lo que necesite
      numero = 300-numero;
      set_pwm1_duty(numero);
      }
   else
      // Termino de hacer lo que necesite
      set_pwm2_duty(numero);
     
     
      }
 return numero;
}

pero igual si introduzco algo como 301 no  ejecuta el PWM1 no se que pueda ser.  :oops:
« Última modificación: 01 de Junio de 2017, 19:53:39 por JebusITO »

Desconectado JebusITO

  • PIC10
  • *
  • Mensajes: 15
Re:Contador de pulsos y PWM
« Respuesta #14 en: 01 de Junio de 2017, 19:51:29 »
Listo ya arreglé el problema, tarde me di cuenta que estaba usando "atoi" y debía usar "atol" , espero el lunes tener el carro y probar como funciona  :-/ :-/ :-/ :-/ :-/
« Última modificación: 01 de Junio de 2017, 21:35:32 por JebusITO »