TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: mue en 24 de Abril de 2008, 13:15:38

Título: Diagrama de flujo CCS
Publicado por: mue en 24 de Abril de 2008, 13:15:38
Hola a todo el mundo!

Como comenté hace tiempo estoy haciendo un proyecto sobre un seguidor de maxima potencia de una placa fotovoltaica a partir del meodo de la conductancia incremental, este metodo lo defino en el diagrama de flujo que adjunto en jpg (si alguien lo quiere en otro formato que me lo pida).

Mi problema es que de aqui muy poco tengo que entregar el proyecto y no tengo ni idea de C y C en CCS muy poco, alguna alma caritativa me podria ayudar y resolver mi problema?? o parte de el?

Me han dicho (no se si es verdad), que alguien que domine el CCS hace este programilla en 10 minutos.

El pic es 16F877,

De todas formas se aceptan consejos, criticas y comentarios .

Muchisimas gracias por mirartelo, me ayudes o no

Un saludo cordial
Título: Re: Diagrma de flujo CCS
Publicado por: Modulay en 24 de Abril de 2008, 14:02:55
Con esto tienes para ir abriendo boca

Código: C++
  1. void algoritmo()
  2. {
  3.   // COMIENZO
  4.   Medida: V(t1) e I(t1);
  5.  
  6.   while(TRUE)
  7.     {
  8.  
  9.     Medida: V(t2) e I(t2)
  10.     dV = V(t2) - V(t1);
  11.     dI = I(t2) - I(t1);
  12.  
  13.     if(dV == 0)
  14.       {
  15.       if(dI != 0)
  16.         {
  17.         if(dI/dV > -(I/V))
  18.           {
  19.           Vref(t3) = Vref(t2) + C;
  20.           }
  21.         else
  22.           {
  23.           Vref(t3) = Vref(t2) - C;
  24.           }
  25.         }
  26.       }
  27.     else
  28.       {
  29.       ///////////////////////////////////////////////////////////////////////////
  30.       // Aquí debe ir todo el código correspondiente a cuando dV es distinto de 0
  31.       //
  32.       //
  33.       ///////////////////////////////////////////////////////////////////////////
  34.       }
  35.  
  36.     }
  37. }
Título: Re: Diagrma de flujo CCS
Publicado por: mue en 25 de Abril de 2008, 07:37:12
Muchas gracias Modulay por el aperitivo, te lo agradezco de veras,

Tengo una duda... donde pones medida no haría falta alguna instrucción del CCS de lectura...
o donde guarde variables...
no se una que guarde V  y otra V anterior...

un saludo, trabajaré en el resto del algoritmo y lo colgaré para que me corrijais, si hace falta.
Título: Re: Diagrma de flujo CCS
Publicado por: Modulay en 25 de Abril de 2008, 12:05:46
El tipo de lectura que lleves a cabo depende del hardware.
Imagino que el sensado lo harás obteniendo variaciones de voltaje a partir de las variaciones de conductancia.
Para la medición de voltajes analógicos se usan los conversores AD del pic,que convierten la tensión analógica en un valor digital (que suelen tener una resolución típica de 8-10 bits) dentro de una escala dada por una o dos tensiones de referencia.
En CCS,la función que te permite almacenar dicho valor digital en una variable es "read_adc()":

Lectura = read_adc();

La cual almacena en la variable "Lectura" el valor digital de la conversión.
Dependiendo de la resolución del conversor y de las tensiones de referencia usadas,tendrás que hacer el cálculo correspondiente tras cada lectura para adecuar el valor leído y obtener a partir de él el valor de tensión,conductancia,etc, correspondiente.

Por lo que veo en el diagrama,tomas el primer punto del intervalo incremental una única vez,y después,en cada iteración del bucle,tomas el segundo punto...no se yo si esto es del todo correcto...podría serlo si llamases al algortimo cada cierto tiempo y,entre la primera lectura y la segunda,transcurriese también cierto tiempo con el fin de que el incremento temporal sea lo suficientemente grande como para que sea factible detectar y medir incrementos de la variable dependiente,dado que la resolución del conversor es limitada.

Yo replantearía el diagrama de flujo y lo adaptaría para hacer una única lectura...tras la lectura,haría las comparaciones y acciones correspondientes en función de la lectura que se obtuvo la vez anterior...así podrías controlar el tiempo incremental simplemente estableciendo el intervalo de tiempo entre cada llamada al algoritmo.

Todo esto,evidentemente,siempre y cuando lo que quieras calcular sea la variación incremental tomando cada vez 2 puntos nuevos...si el primer punto siempre es el mismo y el único que cambia es el segundo,el diagrama está bien planteado.
Título: Re: Diagrma de flujo CCS
Publicado por: mue en 25 de Abril de 2008, 12:25:33
Yo tambien habia pensado en lo de la primera lectura, creo que es mas factible tu propuesta pero lo intentaré primero con este diagrama y si no me sale lo haré de tu manera e incluiré los dos algoritmos en el proyecto (el antes y el despues).

El diagrama lo saque de un libro y la veradad que me extrañó que la primera lectura estubiera fuera del bucle. No se... (a lo mejor divago).

Otra consulta: La finalidad del programa es que trabaje siempre en el punto de maxima potencia, variando el Duty clicle automaticamente que va a parar al convertidor (buck-bost) gracias al lazo cerrado, en mi diagrama el duty donde estaria?? (se que es una pregunta tonta pero es que no lo se), seria la Vref(t2) +/- C ?? la C?? o no lo tengo en cuenta... uff!!!

gracias.
Título: Re: Diagrma de flujo CCS
Publicado por: Modulay en 25 de Abril de 2008, 12:41:46
Con los pocos datos que das no puedo ser del todo concreto,aunque,por lo que voy deduciendo,Vref parece ser la tensión de entrada del convertidor,por lo que, en teoría, el duty debe permanecer constante para que el lazo cerrado juegue su papel.Imagino que C tendrá un valor constante.
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 25 de Abril de 2008, 12:59:26
Lo único que se seguro es que el duty debe variar, para que el punto de maxima potencia sea constante dentro de lo posible.

Tengo una placa fotovoltaica que va a parar al convertidor (reductor-elevador), éste va a parar a una carga (bateria). Entre medio se cogen las lecturas de la intensidad y la tension (gracias a un sensor). Las dos lecturas van al Pic 16F877, que tiene dos CCP (PWM) ,que segun el algoritmo debe hacer variar el tanto por ciento del duty para que el la potencia no varie.

Tambien creo que C es una constante.

Si un caso no se entiende (que es lo mas probable, no lo entiendo ni yo...) escanearé el esquema el lunes y lo cuelgo.

gracias por tu paciencia.
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 28 de Abril de 2008, 11:33:03
Ahí va mi algoritmo, por favor me lo podeis corregir para ver si está bien??? tengo dudas existenciales de como le explico al ccs que vref es el duty, sobretodo nomenclatura de ccs que haya puesto mal. Gracias


Código: C
  1. void algoritmo()
  2. {
  3. // COMIENZO
  4. lecturaV = read_adc();    
  5. lecturaI = read_adc();
  6. V1 = lecturaV;
  7. I1 = lecturaI;
  8.  
  9. while(TRUE)
  10.         {
  11.         lecturaV = read_adc();
  12.         lecturaI = read_adc();
  13.         V2 = lecturaV;
  14.         I2 = lecturaI;
  15.  
  16.         V2 = V1 + 1;    /// Medida: V(t2) e I(t2)
  17.         I2 = I1 + 1;
  18.         dV = V(t2) - V(t1);
  19.         dI = I(t2) - I(t1);
  20.         if(dV == 0)
  21.                 {
  22.                 if(dI != 0)
  23.                         {
  24.                         if(dI/dV > -(I/V))
  25.                                 {
  26.                                 Vref(t3) = Vref(t2) + C;
  27.                                 }
  28.                         else
  29.                                 {
  30.                                 Vref(t3) = Vref(t2) - C;
  31.                                 }
  32.                         }
  33.                 }
  34.                 else
  35.                 {
  36.                 if(dI/dV != -(I/V))
  37.                                 {
  38.                                 if(dI/dV > -(I/V))
  39.                                         {
  40.                                         Vref(t3) = Vref(t2) + C;
  41.                                         }
  42.                                 else   
  43.                                         {
  44.                                         Vref(t3) = Vref(t2) - C;
  45.                                         }
  46.                                 }
  47.                 }
  48.         }
  49. }
Título: Re: Diagrama de flujo CCS
Publicado por: Modulay en 28 de Abril de 2008, 16:11:31
Deberías poner un esquema.
El pic lleva varios canales de conversión AD,y dependiendo de cómo conectes para hacer mediciones,hay que hacer las lecturas de una forma u otra.
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 29 de Abril de 2008, 06:25:17
Adjunto el esquema, no se si es lo que me pides, pero las lecturas son por separado, en la entrada del convertidor DC/DC hay unos sensores que miden tension y intensidad esto va a parar al Convertidor A/D del pic.
Título: Re: Diagrama de flujo CCS
Publicado por: Modulay en 29 de Abril de 2008, 06:49:46
Tendrías que hacer uso de 2 canales A/D,por ejemplo el 0 y el 1.
Dado que vas a ir alternando la lectura entre uno y otro,precediendo a cada lectura,tienes que añadir una instrucción para seleccionar el canal en cuestión:

set_adc_channel(0);
valor1 = read_adc();
...
...
set_adc_channel(1);
valor2 = read_adc();

El pic lleva un módulo hardware generador de pwm y ccs lleva unas instrucciones específicas para su manejo,entre ellas la variación del duty.
Te aconsejo que busques ejemplos,en este foro los hay a montones.

Puedes empezar por aquí

http://www.todopic.com.ar/foros/index.php?topic=4530.0 (http://www.todopic.com.ar/foros/index.php?topic=4530.0)
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 29 de Abril de 2008, 07:00:30
Gracias por tu tiempo, me lo miraré y cuando lo tenga terminado lo volveré a colgar para posibles correcciones, opiniones o por si alguien quiere hacerle un buen uso.

Gracias de nuevo.
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 07 de Mayo de 2008, 14:36:00
Como ves he cambiado de diagrama de flujo y de algoritmo este nuevo metodo lo veo mas facil y eficaz, cuelgo los dos archivos. Me podrias decir si esta bien el algoritmo o si ves que le falta algo, tengo una duda con V= Vk y I= Ik del final del diagrama de flujos, tengo que ponerlo tantas veces??

Gracias por tu tiempo,

Código: C
  1. void algoritmo()
  2. {
  3.  
  4. // COMIENZO
  5. // Lecturas
  6.  
  7.  
  8. while(TRUE)
  9.         {
  10.         set_adc_channel(0);
  11.         Vk = read_adc();            // Vk e Ik son el valor actual
  12.        
  13.         set_adc_channel(1)
  14.         Ik = read_adc();
  15.  
  16.         dV = Vk - V;                // V e I son el valor anterior     
  17.         dI = I - I;
  18.  
  19.         if(dV == 0)
  20.                 {
  21.                
  22.                 if(dI != 0)
  23.                         {
  24.                        
  25.                         if(dI > 0)
  26.                                 {
  27.                                
  28.                                 D = D + dx;
  29.                         //      V = Vk;      No se si hace falta repetir esto,
  30.                         //      I = Ik;      o se puede poner solo una vez al
  31.                                              final del algoritmo       
  32.                                 }
  33.                         else
  34.                                 {
  35.                                
  36.                                 D = D - dx;
  37.                         //      V = Vk;
  38.                         //      I = Ik;
  39.                                
  40.                                 }
  41.                        
  42.                         }
  43.                 else
  44.                         {
  45.  
  46.                         V = Vk;
  47.                         I = Ik;
  48.  
  49.                         }
  50.                
  51.         else
  52.                 {
  53.  
  54.                 if(dI/dV != -(Ik/Vk))
  55.                         {
  56.  
  57.                         if(dI/dV > -(Ik/Vk))
  58.                                 {
  59.                        
  60.                                 D = D + dx;
  61.                         //      V = Vk;
  62.                         //      I = Ik;
  63.                        
  64.                                 }
  65.                         else   
  66.                                 {
  67.  
  68.                                 D = D + dx;
  69.                         //      V = Vk;
  70.                         //      I = Ik;
  71.  
  72.                                 }
  73.  
  74.                         }
  75.                 else
  76.                         {
  77.  
  78.                         V = Vk;
  79.                         I = Ik;
  80.  
  81.                         }
  82.  
  83.                 }
  84.  
  85.         }
  86.  
  87. }
Título: Re: Diagrama de flujo CCS
Publicado por: Modulay en 07 de Mayo de 2008, 15:59:30
Te corrijo un despiste que tuviste.
La renovación del valor anterior basta con que la hagas una vez al final,ya que no atiende a condiciones...se hace siempre.

(http://img353.imageshack.us/img353/2610/dfmy7.th.jpg) (http://img353.imageshack.us/my.php?image=dfmy7.jpg)

Código: C++
  1. void algoritmo()
  2.   {
  3.  
  4.   // COMIENZO
  5.   // Lecturas
  6.  
  7.   while(TRUE)
  8.     {
  9.     set_adc_channel(0);    
  10.     Vk = read_adc();            // Vk e Ik son el valor actual
  11.     set_adc_channel(1)
  12.     Ik = read_adc();
  13.     dV = Vk - V;    // V e I son el valor anterior
  14.     dI = I - I;
  15.     if(dV == 0)
  16.       {
  17.       if(dI != 0)
  18.         {
  19.           if(dI > 0)
  20.           {
  21.             D = D + dx;
  22.           }
  23.           else
  24.           {
  25.             D = D - dx;
  26.           }
  27.         }
  28.       else
  29.       {
  30.         if(dI/dV != -(Ik/Vk))
  31.         {
  32.           if(dI/dV > -(Ik/Vk))
  33.           {
  34.             D = D - dx;  // Tenías puesto D = D + dx
  35.            }
  36.           else
  37.           {
  38.             D = D + dx;        
  39.            }
  40.          }
  41.        }
  42.        V = Vk;
  43.        I = Ik;
  44.      }
  45.   }

Si no recuerdo mal,cuando se cambia de canal para proceder a la lectura, antes de efectuar la lectura hay que introducir un retardo para que la lectura se haga de forma correcta.Compruébalo en el datasheet o busca por el foro, que ya se trató el tema con anterioridad.
Por el resto,lo veo bien.
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 08 de Mayo de 2008, 16:12:27
Saludos!  :-)
Lo del retardo es del todo cierto... generalmente se usa entre 20us y 50us... yo uso 50us para estar seguro de que las condiciones están dadas para la siguiente conversión...
Entonces puedes agregar un delay_us(50) después de la primera conversión y justo antes de cambiarte de canal.
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 09 de Mayo de 2008, 04:57:28
la pregunta va referente al PWM interno de mi pic, en el algoritmo de control envio cada ciclo el Duty a un convertidor, yo tengo puesto D=D+dx, pero se que no se escribe así, como hago para poner la instrucción de enviar (de salida) en CCS el Duty??

El "dx" me sale en el diagrama de flujo del metodo IncCond, no se si es una constante, supongo que si, que ahi marco la resolución, el mínimo cambio de estado, puede ser??

Gracias por explicarme lo del tiempo de retardo.

Saludos cordiales a todos.
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 09 de Mayo de 2008, 10:43:06
Saludos!  :-)
Lo que tienes que hacer es que dentro del main, pero antes del while, escribes:

setup_ccp1(CCP_PWM);                    //Esto le dice al modulo ccp que lo vas a usar como generador de PWM.
setup_timer_2(T2_DIV_BY_1,255,1);  //Aquí estableces el período mediante configurar el timer2 (pre-escala, postcala...)

y cuando quieras cambiar el duty, ya dentro del while, lo haces con la siguiente instrucción:

set_pwm1_duty(duty);

Donde duty es la variable que estás usando que reprenta la variación del ancho de pulso.
Y no más, es todo!  :)

Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 20 de Mayo de 2008, 11:59:18
hola a todos, he intentado compilar mi programa, y no funcionó, me dice que tengo que declarar las variables, las declaro o defino y nada, me pueden ayudar, gracias

Código: C#
  1. #include <16f877.h>         //pic a utilizar
  2. #fuses XT,NOWDT,NOPROTECT,PUT      //ordenes para el programador
  3. #use delay (clock=20000000)
  4.  
  5. int dx;
  6. static Vk,Ik,dV,dI,V,I;
  7. static D;
  8.  
  9. dx = 10;
  10.  
  11. void algoritmo()
  12. {
  13.  
  14. setup_ccp1(CCP_PWM);                    
  15. setup_timer_2(T2_DIV_BY_1,255,1);
  16.  
  17. // COMIENZO
  18. // Lecturas
  19.  
  20. while(TRUE)
  21.    {
  22. ...
  23.    set_adc_channel(0);
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 20 de Mayo de 2008, 12:02:17
el codigo completo:

Código: C#
  1. #include <16f877.h>         //pic a utilizar
  2. #fuses XT,NOWDT,NOPROTECT,PUT      //ordenes para el programador
  3. #use delay (clock=20000000)
  4.  
  5. int dx;
  6. static Vk,Ik,dV,dI,V,I;
  7. static D;
  8.  
  9. dx = 10;
  10.  
  11. void algoritmo()
  12. {
  13.  
  14. setup_ccp1(CCP_PWM);                    
  15. setup_timer_2(T2_DIV_BY_1,255,1);
  16.  
  17. // COMIENZO
  18. // Lecturas
  19.  
  20. while(TRUE)
  21.    {
  22.    set_adc_channel(0);
  23.    Vk = read_adc();            // Vk e Ik son el valor actual
  24.    
  25.    delay_us(50);  
  26.  
  27.    set_adc_channel(1);
  28.    Ik = read_adc();
  29.  
  30.    dV = Vk - V;          // V e I son el valor anterior  
  31.    dI = Ik - I;
  32.  
  33.    if(dV == 0)
  34.       {
  35.      
  36.       if(dI != 0)
  37.          {
  38.          
  39.          if(dI > 0)
  40.             {
  41.            
  42.             D = D + dx;
  43.            
  44.             }
  45.          else
  46.             {
  47.            
  48.             D = D - dx;
  49.            
  50.             }
  51.          
  52.          }
  53.      
  54.    else
  55.       {
  56.  
  57.       if(dI/dV != -(Ik/Vk))
  58.          {
  59.  
  60.          if(dI/dV > -(Ik/Vk))
  61.             {
  62.          
  63.             D = D - dx;
  64.          
  65.             }
  66.          else  
  67.             {
  68.  
  69.             D = D + dx;
  70.  
  71.             }
  72.  
  73.          }
  74.      
  75.       }
  76.    V = Vk;
  77.    I = Ik;
  78.    set_pwm1_duty(D);
  79.  
  80.    }
  81.  
  82. }
  83. }
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 20 de Mayo de 2008, 12:05:14
Saludos mue!
Mira allí en las líneas 6 y 7 estás diciendo que las variables son estáticas, pero no las estás declarando, es decir, tienes que colocar el tipo de variable apropiada.
Por ejemplo:
Código: [Seleccionar]
static [u]int[/u] Vk,Ik,dV,dI,V,I;

Bueno eso es si fuese de tipo int; si es otro tipo lo colocas allí y listo.
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 20 de Mayo de 2008, 13:56:28
hola

Duda existencial, en el algoritmo de contro, Vk y Ik, les debo asignar una patilla analogica???

A la hora del esquema físico, a la misma patilla o diferente,

He mirado por manuales y por ejemplo AN0 (del pic) dicen que es una salida analogica...

Saludos cordiales.
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 20 de Mayo de 2008, 14:06:36
Según veo en tu código, Vk e Ik son los valores que estás leyendo de tensión y corriente... claro que ambos son tensiones, que estás colocando en los canales analógicos 0 y 1 (AN0 y AN1), respectivamente.
Lo que tienes que hacer es ver en la datasheet del pic que estás usando en qué pines están ubicados esos canales (AN0 y AN1) y allí conectar lo que correspondería a los valores analógicos de Vk e Ik.

He mirado por manuales y por ejemplo AN0 (del pic) dicen que es una salida analogica...
Me imagino que quieres decir "entrada analógica".

Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 20 de Mayo de 2008, 19:46:45
gracias, si que son una entrada,

tengo un problemilla, el setup_timer_2(t2_div_1,255,1), que valores tengo que poner de t2_div,etc... para conseguir 5KHz de PWM en vez de 20KHz?? lo he provado de todas las maneras... t2_div_16,64,1.....

gracias, he mirado el funcionamiento del PWm y lo entiendo pero poder escalar la frecuencia....

un saludo.
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 21 de Mayo de 2008, 09:56:17
Ya lo he encontrado, para una frecuencia de pwm de 5 KHz , con un cristal de 20 MHz, el timer se configura asi:

setup_timer_2(T2_DIV_By_4, 249, 1),  ahora bien lo he encontrado sin explicación, alguien me podria decir por que coge 249 y el periodo dividido entre 4??

gracias
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 21 de Mayo de 2008, 13:20:38
Saludos!

T2_DIV_BY_4: Indica que la pre-escala del timer es de 4. Es decir, por cada 4 ciclos del timer el contador (registro tmr2) incrementará en 1.
249: Indica el período. Es decir, el timer comienza a contar de 0 y termina cuando llega a 249 (Y otra vez vuelve a 0).
1: es la post -escala. En este caso cuando el timer llegue a 249 se activará la bandera de interrupción por timer2. Si por ejemplo, en vez de 1 fuera 3, el timer contaría 3 veces de 0 a 249 antes de hacer set la bandera.

Así que tenemos: (20E6)^-1*4*249=0.1992ms
(este es el período. El 4 es porque el reloj fuente para el tmr2 es la frecuencia de oscilación del cristal dividida entre 4, es decir el período es 4 veces más grande).
Entonces: Freq=1/P=1/(0.1992E^-3)=5.020Hz=5,02KHz.

Amigo mue, si en vez de 249 usas 250 te da exactamente 5KHz.
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: kcire en 23 de Mayo de 2008, 17:04:29
Hola mue la verdad hasta ahora no entendi bien que es lo que quieres hacer, pero bueno aqui
dejo la simulación del codigo que propuso el maestro Modulay hice las correciones que dijo
firepic, bueno puedo decir que simula en Proteus pero no garantizo sea la solución.

Espero sirva de algo, adjunto la simulación y espero sus comentarios.
Título: Re: Diagrama de flujo CCS
Publicado por: Gonzalo_BlackHawk en 23 de Mayo de 2008, 23:48:42
Hola a todos. Firepic, en realidad el valor de PR2 de 249 es correcto, da una frecuencia de PWM de 5KHz exacta. Repasemos la formula de calculo de la frecuencia del PWM:

fPWM = 1/ ((PR2 + 1). 4 . (1/fosc). Prescalador)

donde fPWM es la frecuencia de salida del PWM, fosc es la frecuencia del cristal, y Prescalador y PR2 son los valores que configuramos mediante setup_timer_2 asi:

Código: [Seleccionar]
setup_timer_2(Prescalador, PR2, Postescalador);
Como pueden darse cuenta el postescalador no tiene influencia en el PWM y puede colocarse en un valor arbitrario cualquiera (dentro de los valores permitidos de mas esta decir).

Nos estamos escribiendo.
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 26 de Mayo de 2008, 12:46:51
Gracias Gonzalo!
Tienes razón, había olvidado lo del PR2+1...  :?
Entonces en realidad 249 son 250 iteraciones.
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 26 de Mayo de 2008, 12:54:46
Hola amiguetes,

tengo problemas con mi algoritmo, estoy convirtiendo de analogico a digital bien??? device=8??? Float.........no se que es, y si el algoritmo esta bien como puedo saber si esta haciendo la conversion...

Código: C#
  1. #include <16f877.h>         //pic a utilizar
  2. #device adc=8   //????    
  3. #fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, WRT //ordenes. para el programador
  4. #use delay (clock=20000000)
  5.  
  6. const int dx=10;
  7. static int Vk,Ik,dV,dI,V,I;
  8. int D;
  9.  
  10. //setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
  11.  
  12. void main()
  13. {
  14.  
  15. setup_ccp1(CCP_PWM);                    
  16. setup_timer_2(T2_DIV_BY_4,249,1);
  17.  
  18. // COMIENZO
  19. // Lecturas
  20.  
  21. setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
  22. setup_adc(ADC_CLOCK_DIV_2); //antigua setup_adc(ADC_CLOCK_DIV_32);
  23.  
  24.  //set_tris_a(0xff);
  25.  
  26. while(TRUE)
  27.    {
  28.    set_adc_channel(0);
  29.    delay_us(20);
  30.    Vk = (float)read_adc();            // Vk e Ik son el valor actual
  31.    
  32.    delay_us(50);  
  33.  
  34.    set_adc_channel(1);
  35.    delay_us(20);
  36.    Ik = (float)read_adc();


Habia pensado que para hacer la conversion meto la variable Vk en un puerto entero de 8 bits y miro bit por bit, que me da, como hago eso???

muchas gracias
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 26 de Mayo de 2008, 13:13:49
Bueno con device adc=8 me parece que estás desaprovechando precisión en la medición... pues el pic 16f877 permite conversión a 10 bits...
Entonces mejor sería device adc=10.
Lo que no estoy seguro es lo que estás haciendo:
Código: [Seleccionar]
  Vk = (float)read_adc();            // Vk e Ik son el valor actual
Bueno ya algún experto nos explicará, pero no sé si es recomendable hacer la conversión A/D y la conversión de entero a float en una misma instrucción...
Pero dices que no sabes si está haciendo la conversión... lo has probado en proteus?
Pues así como lo tienes debería funcionar...
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 26 de Mayo de 2008, 13:23:39
Bueno mue si lo que quieres es probar la conversión, puedes dejarlo tal como está, a 8 bits, pero insertando estas líneas:

Código: C
  1. set_adc_channel(0);
  2.   delay_us(20);
  3.   lectura_vk=read_adc();
  4.   output_X(lectura);
  5. //  Vk = (float)read_adc();            // Vk e Ik son el valor actual

Deberías declarar lectura_vk como int, y podrías declararte también una lectura_ik y hacer el código similar para ik.
Y en la instrucción output_x en lugar de la x coloca el puerto al que vas a mandar el dato (por ejemplo si lo vas a mandar al puerto C: output_C)
Lo que te recomiendo es que montes en proteus la cuestión y simules la entrada analógica con un potenciómetro (tensión variable) y 8 leds con cátodo a tierra en el puerto al que vas a mandar el dato, asi puedes ver fácilmente si está haciendo la conversión correctamente.

Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: Gonzalo_BlackHawk en 26 de Mayo de 2008, 14:02:45
Hola mue, hay algunas cositas que no esta bien en tu programa, ya firepic hizo hincapié en una:

Código: [Seleccionar]
Vk = (float)read_adc();
y tambien

Código: [Seleccionar]
Ik = (float)read_adc();
La función read_adc() devuelve un valor entero de acuerdo al preprocesador #device adc=x, que en tu caso sera 1 byte.  Luego estas haciendo un casting a un numero con coma flotante para luego guardarla en una variable del tipo entero de 1 byte de longitud (Mira en las declaraciones, tanto Vk como IK son del tipo int). En limpio, estas convirtiendo una variable entera de 1 byte en un numero con coma flotante para luego volver a convertirlo en un numero entero de 1 byte, lo cual es un desperdicio de tiempo de procesador. Para que el codigo sea correcto coloca en reemplazo de las instrucciones anteriores lo siguiente:

Código: [Seleccionar]
Vk = read_adc();
y tambien

Código: [Seleccionar]
Ik = read_adc();
Con respecto a la instruccion setup_adc, estas configurando el reloj del ADC en forma incorrecta, una frecuencia de la mitad del reloj principal solo es valida para frecuencias de cristal menores o iguales a 1.25 MHz. Para tu caso, 20 MHz y un PIC 16F877 recomiendo que reemplazes la instrucción setup_adc por esta otra:

Código: [Seleccionar]
setup_adc(ADC_CLOCK_DIV_32);
Para informarte mas sobre la configuracion del tiempo de conversion del ADC lee este post, aqui se ha debatido sobre ello:

Seguimiento a los voltajes de I/O de un trafo (http://www.todopic.com.ar/foros/index.php?topic=21209.0)

Con respecto a la instrucción delay_us(50) esta no es necesaria pues una vez que read_adc() termina y devuelve el valor convertido pues cambiar el canal de entrada sin esperar. Es más, transcurridos 100 ns luego de comenzar read_adc() el capacitor del sample & hold se desconecta y ya se puede cambiar el canal de entrada, pero bueno, eso es orejón de otro tarro y no voy a entrar en detalles.

Veo que declaraste algunas variables globales como estaticas, nunca he tenido la oportunidad de probar que efectos tiene este tipo de declaracion en la memoria, pero por definicion, una variable global es estatica por si misma y declararla como static o no   es indiferente, salvo que tengas varias unidades de compilacion en tu proyecto.

Por ultimo supongo que falta algo de código en el programa, pues faltan los corchetes que cierran el main y el bucle while, sin eso no iras a ninguna parte, no podras ni compilar tu programa. Perdona por haberte dejado tanto trabajo :mrgreen:, esperamos con ansias tus logros.

Un saludo desde Argentina.


Título: Re: Diagrama de flujo CCS
Publicado por: mue en 26 de Mayo de 2008, 14:18:50
gracias por vuestra ayuda de momento mi progranma es este, para quien lo quiera leer y opinar:

Código: C#
  1. #include <16f877.h>         //pic a utilizar
  2. #device adc=8      
  3. #fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, WRT //ordenes. para el programador
  4. #use delay (clock=20000000)
  5.  
  6. const int dx=10;
  7. static int Vk,Ik,dV,dI,V,I;
  8. int D;
  9.  
  10. //setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
  11.  
  12. void main()
  13. {
  14.  
  15. setup_ccp1(CCP_PWM);                    
  16. setup_timer_2(T2_DIV_BY_4,249,1);
  17.  
  18. // COMIENZO
  19. // Lecturas
  20.  
  21. setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
  22. //setup_adc(ADC_CLOCK_DIV_2); //antigua setup_adc(ADC_CLOCK_DIV_32);
  23.    set_tris_a(0xff);
  24.    set_tris_b(0);
  25.  
  26.    SETUP_ADC(ADC_CLOCK_INTERNAL);      // configuras esto para que el a/d funcione con un reloj interno del micro
  27.    //SETUP_ADC_PORTS(AN0);                       // aca determianr que el puerto RA0 será analógico
  28.    //SET_ADC_CHANNEL(0);                          
  29.  
  30.    
  31.  
  32.  
  33.  //set_tris_a(0xff);
  34.  
  35. while(TRUE)
  36.    {
  37.    set_adc_channel(0);
  38.    delay_us(20);
  39.    Vk = (int)read_adc();            // Vk e Ik son el valor actual
  40.    
  41.    delay_us(50);  
  42.    
  43.    output_b(Vk);               // lee el canal analogico seleccionado anteriormente, y lo uestra el en puerto b
  44.    delay_us(20);
  45.    
  46.    set_adc_channel(1);
  47.    delay_us(20);
  48.    Ik = (int)read_adc();
  49.  
  50.    delay_us(50);
  51.  
  52.    dV = Vk - V;          // V e I son el valor anterior  
  53.    dI = Ik - I;
  54.  
  55.    if(dV == 0)
  56.       {
  57.      
  58.       if(dI != 0)
  59.          {
  60.          
  61.          if(dI > 0)
  62.             {
  63.            
  64.             D = D + dx;
  65.            
  66.             }
  67.          else
  68.             {
  69.            
  70.             D = D - dx;
  71.            
  72.             }
  73.          
  74.          }
  75.      
  76.    else
  77.       {
  78.  
  79.       if(dI/dV != -(Ik/Vk))
  80.          {
  81.  
  82.          if(dI/dV > -(Ik/Vk))
  83.             {
  84.          
  85.             D = D + dx;
  86.          
  87.             }
  88.          else  
  89.             {
  90.  
  91.             D = D - dx;
  92.  
  93.             }
  94.  
  95.          }
  96.      
  97.       }
  98.    V = Vk;
  99.    I = Ik;
  100.  
  101.    set_pwm1_duty(D);
  102.    delay_ms(1);
  103.    }
  104.  
  105.    }
  106. }

Saludos muy cordiales desde Barcelona.
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 26 de Mayo de 2008, 14:36:36
otra duda como puedo saber respecto el algoritmo anterior cuanto aumento "dx"??
dx es un valor constante que hace variar el duty "D",

como puedo saber la resolucion, creo que mi duty va de 0 a 1000 siendo el 1000 el 100%.

gracias
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 26 de Mayo de 2008, 15:35:26
Pues no has corregido las observaciones que te ha hecho el Dr. Gonzalo.
A ver pues, a trabajar!  :D
Bueno con respecto a lo de que el duty D va de 0 a 1000... entonces tienes que cambiar la definición de la variable, en vez de colocarla como la tienes (int), debes colocarla como int16.
En cuanto a esto:
otra duda como puedo saber respecto el algoritmo anterior cuanto aumento "dx"??
dx es un valor constante que hace variar el duty "D",
Ahí si me dejaste frito viejo... porque si dices que es un valor constante, cómo es que va a aumentar?  :shock:
Bueno tal vez no capté tu pregunta, trata de explicarte mejor a ver....
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: mue en 26 de Mayo de 2008, 15:46:02
Que cantidad aumento cada vez el duty (en este caso D), donde D viene de D = D - dx; o D = D + dx;

por que eso del int16???
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 26 de Mayo de 2008, 15:53:59
Bueno si dices que el valor del duty varía entre 0 y 1000, entonces la variable que tienes definida D se queda corta... porque está definida como entero de ocho bits (int) y ya sabrás que 8 bits permite valores solo de 0-255.... entonces si tienes un int16 permite de 0-65535.... claro que tu vas a usar no más 0-1000.
En cuanto a esto:
Que cantidad aumento cada vez el duty (en este caso D), donde D viene de D = D - dx; o D = D + dx;
Todavía no te capto bien. A ver, tú quieres saber cuánto ha variado D por cada medición? Entonces lo que debes hacer es guardar D en una variable, digamos D_anterior... y luego otra variable (tendría que ser float, por si el cambio es negativo, o sea ahora D es menor) que podrías llamar variacion o delta... seria:
Código: [Seleccionar]
delta=D-D_anterior;
D_anterior=D;
Y vuelves a cargar D_anterior con el valor actual para que la próxima lectura tenga el valor anterior...
Espero haberme explicado.
Ok nos leemos!  :mrgreen:
Título: Re: Diagrama de flujo CCS
Publicado por: Gonzalo_BlackHawk en 26 de Mayo de 2008, 21:07:40
Hola mue, el duty del PWM se define por un valor de 10 bits, es decir que puede tomar valores entre 0 a 1024. Tal como lo ha dicho firepic, D debe ser del tipo long o int16 o de 2 bytes de longitud para poder contener todo el espectro de duty que necesitas. El PWM solo toma como duty valores enteros, por lo tanto dx no puede ser menor que 1 y debe ser entero.  Sin embargo, la variación en el ciclo de trabajo real de la onda de salida con respecto al valor que tu seteas varia de acuerdo a la resolución del PWM, la cual esta en función de la frecuencia del mismo.

No me voy a explayar mas en este tema, creo que primero debes solucionar tus otros inconvenientes que ya hemos expuesto en post anteriores. Tal como ha dicho firepic, A ver pues, a trabajar!   :-/ :-/

Saludos desde Argentina.


Título: Re: Diagrama de flujo CCS
Publicado por: mue en 02 de Junio de 2008, 07:01:50
Tengo la mejor pregunta de este post y la mas ambigua:

Cuando controlo mi proceso, basandome en el algoritmo, voy mirando la tension y la intensidad mediante el CAD del pic y segun lo que de, aumento o disminuyo el duty cycle para modificar el trabajo del convertidor. La pregunta es esta: No deja de aumentar el duty!!! o disminuir!!!! no se queda en ningun punto , no llega ni a oscilar en un intervalo!

Alguna idea??? (Me quedan 3 dias para entregar el proyecto, se nota mi estres??jejeje)

un saludo cordial,
Título: Re: Diagrama de flujo CCS
Publicado por: firepic en 02 de Junio de 2008, 12:14:52
Saludos mue! Tal vez puede ser porque la tensión y corriente que estás midiendo están cambiando muy rápido... prueba hacer una pausa entre una medición y la otra... bueno es sólo una hipótesis... pero sería bueno que colocaras alguna simulación en proteus para ver qué es lo que está haciendo tu circuito y cuál podría ser la falla.
Andale pues, que si lo puedes lograr!  :P
Nos leemos!  :mrgreen: