TODOPIC

Microcontroladores PIC => RTOS => Mensaje iniciado por: john_freddy en 19 de Abril de 2012, 16:00:19

Título: control de potencia trifasico
Publicado por: john_freddy en 19 de Abril de 2012, 16:00:19
Buenas tardes compañeros del foro, soy nuevo en esta cuestión de programas en micros, actualmente estoy desarrollando un proyecto el cual por medio de dos pulsadores debo aumentar o disminuir el angulo de disparo que se va a producir para disparar 3 scr que van conectados a una red trifásica, cuando presiono el pulsador de incremento este angulo de disparo se debe ver en la fase de 0°, en la de 120° y en la de 240° y debe incrementarse igualmente a medida que presiono nuevamente el pulsador y así mismo debe suceder cuando disminuyo por medio del otro pulsador. Lo he intentado por interrupciones y por rtos peor no he logrado tener control de los pulsos de disparo. Adjunto los dos programas realizados si es posible alguien me ayude se lo agradezco de antemano.

Este programa es por interrupciones: el problema aquí son los tiempos que se emplean para producir los disparos ya que no hay simetría y el pulso no permanece estático.

#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)
#priority RB,EXT

float ret = 0;
float ret1 = 5.55;
//float disp = 0.231;

#int_EXT
void EXT_isr(){
delay_ms(ret);
output_D (0b0000000001);
delay_ms(1);
output_D (0b0000000000);
delay_ms(ret1);
output_D (0b0000000010);
delay_ms(1);
output_D (0b0000000000);
}

#int_RB
void RB_isr(void){
if (input(pin_B6)==0){
ret += 0.231;
ret1 += 0.231;
}
}

void main(void)
{
port_b_pullups(true);
setup_adc_ports(no_analogs);
set_tris_B(0b11111111);
set_tris_D(0b00000000);
enable_interrupts(global);
enable_interrupts(INT_EXT);
ext_int_edge(L_to_H);
enable_interrupts(INT_RB);
ext_int_edge(H_to_L);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
while(TRUE);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
}


Por medio de RTOS: en este segundo caso se generan los pulsos pero no puedo incluir los pulsadores ya que cuando lo hago y coloco la variable ret se detiene la generación de pulsos y no hay ningún control sobre esto, pero si cambio la variable ret y ret1 a numeros por ejemplo 1ms o algo por el estilo se produce un tren de pulsos.


#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)
#use rtos(timer=0,minor_cycle=1us)//8330us)                  //8330us

float ret = 0;
float ret1 = 5.55;
float disp = 0.231;


#task(rate=16ms,max=1us)

void incremento(){

delay_ms(ret);
output_D (0b0000000001);
delay_ms(0.1);
output_low(PIN_D0);
delay_ms(ret1);
output_D (0b0000000010);
delay_ms(0.1);
output_low(PIN_D1);

}

//#task(rate=2ms,max=1us)

//void decremento();



void main(void)
{
port_b_pullups(true);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_adc_ports(no_analogs);
set_tris_B(0b11111111);
set_tris_D(0b00000000);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);

rtos_run();
}

les pido disculpas por el mensaje tan largo y de nuevo muchas gracias a quien me pueda orientar
Título: Re: control de potencia trifasico
Publicado por: Picuino en 19 de Abril de 2012, 17:02:39
¿Cuál es el problema?

Saludos
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 19 de Abril de 2012, 17:17:50
Gracias Picuino, el asunto es: en el código que manejo por interrupciones cuando doy a los pulsadores los tiempo no los puedo medir en la simulación por tal motivo no se si se están produciendo a los intervalo deseados. en el código que maneja RTOs cuando coloco condicionales para manejar a los pulsadores ya no se producen los pulsos pero si no coloco estos condicionales si hay un tren de pulsos. Y por ultimo no estoy totalmente seguro si el código como esta escrito este bien encaminado para la solución del problema. Gracias
Título: Re: control de potencia trifasico
Publicado por: Picuino en 19 de Abril de 2012, 17:44:02
No estoy seguro de entender el problema.

¿Qué hace este código que has posteado?

Código: [Seleccionar]
#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)
#priority RB,EXT
  
float ret = 0;
float ret1 = 5.55;
  
#int_EXT
void EXT_isr(){
   delay_ms(ret);
   output_D (0b0000000001);
   delay_ms(1);
   output_D (0b0000000000);
   delay_ms(ret1);
   output_D (0b0000000010);
   delay_ms(1);
   output_D (0b0000000000);
}
  
#int_RB
void RB_isr(void){
   if (input(pin_B6)==0){
      ret += 0.231;
      ret1 += 0.231;
   }
}
  

void main(void)  {
   port_b_pullups(true);
   setup_adc_ports(no_analogs);
   set_tris_B(0b11111111);
   set_tris_D(0b00000000);
   enable_interrupts(global);
   enable_interrupts(INT_EXT);
   ext_int_edge(L_to_H);
   enable_interrupts(INT_RB);
   ext_int_edge(H_to_L);
   output_low(PIN_D0);
   output_low(PIN_D1);
   output_low(PIN_D2);
   while(TRUE);
   output_low(PIN_D0);
   output_low(PIN_D1);
   output_low(PIN_D2);
}

Si lo comentas un poco se entenderá mejor.

Me llama la atención la instrucción  while(TRUE); que detiene la ejecución del programa.

Saludos
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 19 de Abril de 2012, 17:53:23
Gracias por responder. No soy muy hábil en lo de la programación pero voy a tratar de explicarlo lo mejor posible y efectivamente faltaron los comentarios y me disculpo por eso. el montaje físico esta compuesto por un circuito de cruce por cero y un pic18f4550 para manejar tres SCR conectados a una red trifasica.  cuando presiono el pulsador conectado el pin B6 se habilita la interrupción por cambio de flanco y realiza el incremento del tiempo de disparo el cual es manejado por ret(fase a 0°) y ret1(fase a 120°), cuando el ckto de cruce por cero hace el cambio de bajo a alto se habilita la interrupción ext y saca al puerto D los pulsos en los tiempos establecidos por ret y ret1. En la simulación  lo que se debe ver es un tren de pulsos al cual logro desplazar a medida que incremento o decremento el tiempo de disparo y estos pulsos se deben ver reflejados en las ondas a 0°, 120° y 240°. La instrucción while(true) lo que hace es un ciclo infinito para que el programa corra infinitamente.
Título: Re: control de potencia trifasico
Publicado por: Picuino en 19 de Abril de 2012, 18:19:50
¿Qué frecuencia de red utilizas?

La variable ret ya desplaza el primer pulso. No hace falta ret1, porque estás desplazando el segundo pulso dos veces.

Ret1 debería valer siempre el tiempo de 0º a 120º

Otra cosa es que los delay creo que no aceptan valores reales.

Saludos.
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 20 de Abril de 2012, 00:14:21
La frecuencia de red es 60hz, pero el ret retarda la fase a cero grados y ret1 retrasa el disparo para la de 120 grados, aun así no seria necesario y solo con uno bastara?
Título: Re: control de potencia trifasico
Publicado por: Picuino en 20 de Abril de 2012, 10:12:46
Sólo uno bastaría.

El retardo máximo debería ser de 1/(2*60) = 8'333ms

El retardo entre el primer disparo y el segundo debe ser exactamente 8.333ms

Los retardos debes aumentarles poco a poco. En tu código se aumenta el retardo continuamente con la pulsación de la tecla. Se debería aumentar con el flanco para ir paso a paso.

Saludos.
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 20 de Abril de 2012, 11:52:21
Picuino, muchas gracias por sus respuestas pero me surgen dos dudas, primero los disparos que menciona a 8.33ms esos serian para la onda a 0°, pero y para las ondas a 120° y a 240° no debería realizar una especia de desfase de tiempo por ejemplo la onda a 120° su desfase seria de 5.55ms, y la segunda que esto no se sinceramente como hacerlo es como incrementar con los flancos de subida y esta segunda es la que mas me interesa. De nuevo muchas gracias por su ayuda.
Título: Re: control de potencia trifasico
Publicado por: Picuino en 20 de Abril de 2012, 13:16:42
1. Cruce por cero de onda 0º
2. Desfase de x ms
3. Disparo de onda de 0º
4. Desfase de 8.33ms
3. Disparo de onda de 120º
4. Desfase de 8.33ms
3. Disparo de onda de 240º

Edito:
Tienes razón con el desfase. Debe ser de 5.55 ms, no de 8.33ms
1. Cruce por cero de onda 0º
2. Desfase de x ms
3. Disparo de onda de 0º
4. Desfase de 5.55 ms
3. Disparo de onda de 120º
4. Desfase de 5.55 ms
3. Disparo de onda de 240º

  
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 20 de Abril de 2012, 16:01:57
lo modifique de la siguiente forma:

#int_EXT                                                  //esta interrupción es la del cruce por cero, cuando cambia de bajo a alto ejecuta el proceso
void EXT_isr(){                                        // no estoy muy seguro a los 8.33ms que seria el equivalente a 180°, creo que deberia ser 5.55ms que seria
delay_ms(ret);                                        //desface a 120° que es el desface de las otras dos ondas.
output_D (0b0000000001);                       
delay_ms(0.1);
output_D (0b0000000000);
delay_ms(8.33);
output_D (0b0000000010);
delay_ms(0.1);
output_D (0b0000000000);
delay_ms(8.33);
output_D (0b0000000100);
delay_ms(0.1);
output_D (0b0000000000);
}

#int_RB                                                                   //esta interrupcion es por cambio de estado en el puerto B4 a B7 en este caso el pulsador de incremento
void RB_isr(void){                                                    //esta conectado al pin B6, cuando ocurre el cambio de estado de alto a bajo y el contador de retardo (ret)
if (input(pin_B6)==0 && ret <= 8.33){                       //es menor de 8.33, incrementa ret en 0.231 que seria el equivalente a 5°
ret += 0.231;
}
}

cuando simulo con proteus me aparecen los pulsos pero si doy click en el pulsador de incremento los pulsos desaparecen. De nuevo agradezco la ayuda brindada.
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 20 de Abril de 2012, 16:48:12
Picuino como podría hacer sin el uso de la interrupción ext que los tiempos sean manejados con el flanco de subida. Gracias
Título: Re: control de potencia trifasico
Publicado por: Picuino en 20 de Abril de 2012, 17:02:22
ufff...

Te cuento el método más sencillo (sin rtos):


Código: [Seleccionar]
main() {
   char keyb1;



   while(1) {
      if (input(pin_B6)==0  &&  keyb1==1)  {
         keyb1 == 0;
         ret += 0.231;
      }
      if (input(pin_B6)==1  and keyb1==0)  {
         keyb1 = 1;
      }
   }
}

         
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 20 de Abril de 2012, 17:29:31
pero me surgió una duda mayor y quien es keyb1, es algún teclado externo o algo así?, lo he estado manejando con RTOs ya tengo las tareas pero no logro cuadrar los tiempo, le adjunto el código por RTOs:


#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)
#use rtos(timer=0,minor_cycle=1us)

float ret = 0;


#task(rate=16ms,max=1us)                                                //tarea para los pulsadores
void pulsadores(){
for (; ;){
delay_ms(500);
if(input(pin_B6)==0){// && ret <=8.33){
output_D(0b00001000);                                                      //esta salida es para un led que coloque para rastrear en donde esta ejecutandose el programa,
ret += 0.231;                                                                    //es decir si el programa entro a la condición. esta condición es para incrementar el tiempo de disparo
}
else
if(input(pin_B7)==0){// && ret > 0){                                  //esta condición es para disminuir el tiempo de disparo, si ret es menor que cero el pulso pasaría a
output_D(0b00000000);                                                     //tiempos anteriores al del origen de la señal seno de 0°
ret -= 0.231;
}
}
}

#task(rate=16ms,max=1us)

void fases(){                                                                   //maneja las fases a 0 y 120°, coloque un retardo de 500ms para que tome un solo pulso
delay_ms(500);
delay_ms(1);
output_high(PIN_D0);
delay_ms(0.1);
output_low(PIN_D0);
}


Gracias



void main(void)
{
port_b_pullups(true);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_adc_ports(no_analogs);
set_tris_B(0b11111111);
set_tris_D(0b00000000);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);

rtos_run();
}









Título: Re: control de potencia trifasico
Publicado por: Picuino en 20 de Abril de 2012, 17:54:44
keyb1 es sólo una variable auxiliar de tipo char.

Saludos.
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 20 de Abril de 2012, 18:11:28
este fue el codigo que monte para la instruccion que me indico pero no funciono, si es posible mírelo a ver si esta bien o esta mal en algún lugar. Gracias


#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)

char keyb1;
float ret;

void main(void)
{
port_b_pullups(true);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_adc_ports(no_analogs);
set_tris_B(0b11111111);
set_tris_D(0b00000000);
while(1) {
      if (input(pin_B6)==0  &&  keyb1==1)  {
         keyb1 == 0;
         delay_ms(500);
         ret += 0.231;
         delay_ms(ret);
         output_D (0b0000000001);
         delay_ms(0.1);
         output_D (0b0000000000);
      }
      if (input(pin_B6)==1  && keyb1==0)  {
         keyb1 = 1;
      }
}
}
Título: Re: control de potencia trifasico
Publicado por: Picuino en 20 de Abril de 2012, 20:38:51
#int_EXT                                                  //esta interrupción es la del cruce por cero, cuando cambia de bajo a alto ejecuta el proceso
void EXT_isr(){                                        // no estoy muy seguro a los 8.33ms que seria el equivalente a 180°, creo que deberia ser 5.55ms que seria
delay_ms(ret);                                        //desface a 120° que es el desface de las otras dos ondas.
output_D (0b0000000001);                       
delay_ms(0.1);
output_D (0b0000000000);
delay_ms(5.45);
output_D (0b0000000010);
delay_ms(0.1);
output_D (0b0000000000);
delay_ms(5.45);
output_D (0b0000000100);
delay_ms(0.1);
output_D (0b0000000000);
}

#int_RB                                                                   //esta interrupcion es por cambio de estado en el puerto B4 a B7 en este caso el pulsador de incremento
void RB_isr(void){                                                    //esta conectado al pin B6, cuando ocurre el cambio de estado de alto a bajo y el contador de retardo (ret)
   if (input(pin_B6)==0 && ret <= 5.55) {                   //es menor de 8.33, incrementa ret en 0.231 que seria el equivalente a 5°
      ret += 0.231;
      RBIF = 0;
   }
}


He copiado tu código con algún cambio.
Si RB_isr se llama por flanco, no hace falta añadir el código que te copié.
Tienes razón en el desfase de 5.55ms

No entiendo por qué al pulsar B6 deja de dar pulsos. ¿Y si desactivas el bit de interrupción RBIF?
¿Puedes comprobar si funciona ahora?

Saludos
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 21 de Abril de 2012, 12:45:56
Lo he estado analizando y no encuentro como desactivar el bit del RBIF, me podría ilustrar la instrucción de como deshabilitarla.
Título: Re: control de potencia trifasico
Publicado por: Picuino en 21 de Abril de 2012, 13:27:37
No conozco el compilador CSS. En el compilador C18 es:

INTCONbits.RBIF = 0;


Saludos.
Título: Re: control de potencia trifasico
Publicado por: MLO__ en 21 de Abril de 2012, 13:50:07
Código: [Seleccionar]
disable_interrupt(INT_RB)  ;-)
Título: Re: control de potencia trifasico
Publicado por: Picuino en 21 de Abril de 2012, 16:25:27
Hola MLO, el problema creo que está en que hay que borrar el bit de interrupción (RBIF) para que no vuelva a saltar la rutina de interrupción otra vez al retornar.

Creo que tu código desactiva la interrupción (RBIE) de manera que no saltaría nunca más. ¿Cómo se borra RBIE en CSS?


Saludos.
Título: Re: control de potencia trifasico
Publicado por: jeremylf en 22 de Abril de 2012, 11:44:56
No se debe poner valores float en los delay_xx, pues no tienen el efecto deseado. Miren el Help, solo admite variables o constantes de 16 bits, es decir, de 0 a 65535.

Para 5.5ms deberia ser: delay_us(5500);
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 22 de Abril de 2012, 20:36:38
compañeros muchas gracias, con los cambios realizados el programa ha evolucionado satisfactoriamente, pero aun tengo un pequeño problema:

Inicialmente cuando corro el programa aparecen los pulsos desfasados, aunque no he verificado los tiempos de desface pero el problema es que cuando presiono el pulsador de incremento no me realiza ningún desface, si entra en esa parte del código pero no hace nada, luego si presiono varias veces el pulsador me desaparecen todos los pulsos, igualmente si presiono el de decremento no pasa nada ni los desfasa ni aparecen.

El código es:

#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)
#priority RB,EXT

float ret;
//float ret1 = 5.55;
//float disp = 0.231;

#int_EXT
void EXT_isr(){
delay_ms(ret);
output_D (0b0000000001);
delay_us(100);
output_D (0b0000000000);
delay_us(5450);
output_D (0b0000000010);
delay_us(100);
output_D (0b0000000000);
delay_us(5450);
output_D (0b0000000100);
delay_us(100);
output_D (0b0000000000);
}

#int_RB
void RB_isr(void){
delay_ms(125);
if (input(PIN_B6)==0 && ret <= 5550){
delay_ms(125);
output_high(PIN_C0);
ret += 231/10;
output_low(PIN_C0);
disable_interrupts(INT_RB);

}
else
if(input(PIN_B7)==0 && ret > 0){
delay_ms(125);
output_high(PIN_C1);
ret -= 0.231;
output_low(PIN_C1);
disable_interrupts(INT_RB);

}
}

void main(void)
{
port_b_pullups(true);
setup_adc_ports(no_analogs);
set_tris_B(0b11111111);
set_tris_C(0b00000000);
set_tris_D(0b00000000);
enable_interrupts(global);
enable_interrupts(INT_EXT);
ext_int_edge(L_to_H);
enable_interrupts(INT_RB);
ext_int_edge(H_to_L);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
while(TRUE);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
}

Hice las correcciones que sugirió  jeremylf para valores enteros en los delay y la sugerencia de Picuino de desactivar el RBIF con la instrucción que sugirio MLO, pero la variable ret como esta si cambia y necesito que sea así en valores de 0.231ms la coloque como una fracción porque no se como colocarle algún modificador para que me la tome en milisegundos o microsegundos.

Adjunto el archivo de la simulación.

Muchas gracias por ayudarme en esto.
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 22 de Abril de 2012, 21:12:25
estoy haciendo el código por RTOs porque quiero aprovechar la oportunidad para aprender el manejo de las mismas, adjunto el código pero en este el problema es que no se generan los pulsos.


#include <18f4550.h>
#fuses  HS, NOWDT, NOBROWNOUT, NOMCLR, NOPROTECT, NOWRT
#use fast_io(B)
#use delay(clock=20000000)
#use rtos(timer=0,minor_cycle=1us)//8330us)                  //8330us

float ret = 0;



#task(rate=16666us,max=1us)
void pulsadores(){
//for (; ;){
delay_ms(125);
if(input(pin_B6)==0 && ret <=8.33){
output_high(PIN_C0);
ret += 0.231;
}
if(input(pin_B7)==0 && ret > 0){
output_low(PIN_C0);
ret -= 0.231;
}
//rtos_yield();
}
//}


#task(rate=16666us,max=1us)
void fase0(){                //maneja la fase a 0
delay_us(100);
if(input(pin_B0)==0){        //cruce por cero
   if(input(pin_B0)==1){
output_high(PIN_C1);
delay_ms(ret);
output_high(PIN_D0);
delay_us(100);
output_low(PIN_D0);
   }
}
}

void main(void)
{
port_b_pullups(true);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_adc_ports(no_analogs);
set_tris_B(0b11111111);
set_tris_C(0b00000000);
set_tris_D(0b00000000);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
output_low(PIN_C0);
output_low(PIN_C1);
rtos_run();
;
}










Título: Re: control de potencia trifasico
Publicado por: MLO__ en 22 de Abril de 2012, 21:26:00
 :shock: :shock:

que despiste!!! es:

Código: [Seleccionar]
clear_interrupt(INT_RB)
Saludos
Título: Re: control de potencia trifasico
Publicado por: john_freddy en 22 de Abril de 2012, 22:16:03
Muchisimas gracias a todos los que participaron: Picuino, Jeremylf, MLO. sin su ayuda no habría podido lograrlo. Aun falta ajustar los ángulos de disparo ya que la prueba la hice con un angulo de casi 30° y pues así no habría suficiente control, así que hay que reducirlo a 5° mas o menos pero se genera el problema de la coma flotante pero eso ya es carpintería para el final. De nuevo compañeros muchisimas gracias por el apoyo en este proyecto.