Autor Tema: Problema en PWM por software.  (Leído 4737 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Cossworth

  • PIC12
  • **
  • Mensajes: 56
Problema en PWM por software.
« en: 13 de Septiembre de 2010, 21:48:20 »
Problema solucionado y proyecto completo funcionando acá: http://www.todopic.com.ar/foros/index.php?topic=33151.0

***************************************************************************************

Hola, antes que nada quiero aclarar que le busqué la vuelta por todos lados a este problema antes de decidirme a pedir ayuda acá, estoy realizando una lámpara de led's RGB los cuales controlo por PWM, el programa funciona perfectamente cuando se desea mantener un color fijo, pero al intentar realizar una transición aparecen destellos esporádicos como se puede ver en el siguiente video:


Para el código me basé en un ejemplo de Nocturno, que al ver en detenimiento, genera el mismo destello aleatorio:


El código que estoy usando es el siguiente, tiene varias partes comentadas de todas los cambios que le hice para intentar eliminar el maldito destello (cambiar el tipo de variables, evitar llegar a valores como 0 y 255, etc):

Código: [Seleccionar]
#include <12F675.h>

#fuses NOWDT,NOPROTECT,NOMCLR,INTRC_IO

#use delay (clock=4000000)



#byte puerto=0x05

#bit R=puerto.0

#bit G=puerto.1

#bit B=puerto.2



#define delay 10

#define reloj 220



int azul=0;

int rojo=0;

int verde=0;

int azul1=0;

int rojo1=0;

int verde1=0;

int pulso=0;

int estado=0;





//Secuencia de transición



void fade(){

rojo=253;

azul=5;

verde=5;

while(1){

for(verde=5;verde<253;verde+=5){

delay_ms(delay);

};



// while(verde<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=253;rojo>5;rojo-=5){

delay_ms(delay);

};



// while(rojo>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(azul=5;azul<253;azul+=5){

delay_ms(delay);

};



// while(azul<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// azul++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(verde=253;verde>5;verde-=5){

delay_ms(delay);

};



// while(verde>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=5;rojo<253;rojo+=5){

delay_ms(delay);

};



// while(rojo<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(verde=5;verde<253;verde+=5){

delay_ms(delay);

};



// while(verde<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=253;rojo>5;rojo-=5){

delay_ms(delay);

};



// while(rojo>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(azul=253;azul>5;azul-=5){

delay_ms(delay);

};



// while(azul>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// azul--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=5;rojo<253;rojo+=5){

delay_ms(delay);

};



// while(rojo<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(verde=253;verde>5;verde-=5){

delay_ms(delay);

};



// while(verde>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



}; //Termina el while



}



//Generar un color fijo



void color(int8 red, int8 green, int8 blue){

rojo=red;

verde=green;

azul=blue;

}



//Interrupcion para detectar cuando se presiona un botón.



//Secuencia del timer, es el que genera los colores



#int_RTCC

void timer0(void){

if (pulso==254) pulso=0; else pulso++;

if(rojo1!=rojo) rojo1=rojo;

if(verde1!=verde) verde1=verde;

if(azul1!=azul) azul1=azul;

if (pulso==0){

R=1;

G=1;

B=1;

};

if (pulso==rojo1)

R=0;

if (pulso==verde1)

G=0;

if (pulso==azul1)

B=0;

set_timer0(reloj);

}



//Programa principal



void main(){

setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_1);

setup_adc(ADC_OFF);

setup_adc_ports(NO_ANALOGS);

enable_interrupts(INT_RTCC);

enable_interrupts(GLOBAL);

set_tris_a(0b111000);

estado=0;

set_timer0(reloj);



while(1){



//Switch



switch(estado){

case 0: {

color(253,0,0);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 1: {

color(0,253,0);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 2: {

color(0,0,253);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 3: {

color(253,253,253);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 4: {

color(253,0,253);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 5: {

while(1){

color(0,0,0);

delay_ms(5);

color(253,253,253);

delay_ms(5);

if(input(PIN_A5)) {

estado++;

break;

};

};

break;

};

case 6: {

fade();

break;

};



}; //Termina el Switch



}; //Termina el While



} //Termina el Main

Alguien sabe como solucionar este problema?

Quisiera lograr un efecto parejo y progresivo como este:


Desde ya muchas gracias :)
« Última modificación: 10 de Diciembre de 2010, 23:10:18 por Cossworth »

Desconectado Cossworth

  • PIC12
  • **
  • Mensajes: 56
Re: Problema en PWM por software.
« Respuesta #1 en: 21 de Septiembre de 2010, 20:26:59 »
Nadie tiene idea? me está volviendo loco el destello ese, ya escribí el código de cero usando distintos ciclos, cambiando el seteo del timer y no hay caso  :5]

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema en PWM por software.
« Respuesta #2 en: 21 de Septiembre de 2010, 20:58:00 »
Que frecuencia de PWM estás usando?
No contesto mensajes privados, las consultas en el foro

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema en PWM por software.
« Respuesta #3 en: 21 de Septiembre de 2010, 21:13:55 »
Hola.

Estas trabajando a 4MHz .... por lo que el PWM que generas es muy lento y por eso me imagino que es el destello ....

Saludos
El papel lo aguanta todo

Desconectado Cossworth

  • PIC12
  • **
  • Mensajes: 56
Re: Problema en PWM por software.
« Respuesta #4 en: 05 de Octubre de 2010, 20:02:11 »
Antes que nada disculpen que desaparecí, no me llegaron las notificaciones al correo :5]

Que frecuencia de PWM estás usando?

El Timer0 desborda cada 220 ciclos, a 4mhz serían algo así como 4.5KHz, estoy en lo cierto?

Hola.

Estas trabajando a 4MHz .... por lo que el PWM que generas es muy lento y por eso me imagino que es el destello ....

Saludos

El problema de la baja velocidad es que titila, eso lo puedo ir corrigiendo modificando la frecuencia del PWM, pero lo que no logro explicarme es que, por ejemplo, cuando está haciendo una transición de azul a verde, aparece un destello rojo luego sigue normalmente el ciclo.
Deduzco que es un problema de código ya que este problema se ve en el ejemplo de Nocturno y yo utilicé la misma técnica para lograr el PWM por software.

Otra cosa que me olvidaba, este efecto se hace mas o menos notorio cuando cambio los valores de Delay en la transición :shock:, el comando delay_ms() afecta a las interrupciones de Timer?


Desde ya muchas gracias por responder, en la semana les subo unas fotos para mostrar el progreso de la lámpara, ya tiene 5 leds de 3W y una fuente de 5A :-/

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema en PWM por software.
« Respuesta #5 en: 05 de Octubre de 2010, 21:48:36 »
Hola.

No vi el destello que dices  :shock: (será que ya me esta fallando la vista  :D )

Yo he usado esto para la interrupción y no me dan esos destellos.

Código: C#
  1. #int_Timer0
  2. void ActivaLed(void)
  3. {
  4.         Ticks++;
  5.  
  6.         if (Ticks==0)
  7.         {
  8.                 on(BLUE);
  9.                 on(RED);
  10.                 on(GREEN);
  11.         }
  12.         if(Ticks>=Rojo)
  13.                 off(RED);
  14.         if(Ticks>=Verde)
  15.                 off(GREEN);
  16.         if(Ticks>=Azul)
  17.                 off(BLUE);
  18.         set_timer0(230);
  19. }

Saludos
El papel lo aguanta todo

Desconectado Cossworth

  • PIC12
  • **
  • Mensajes: 56
Re: Problema en PWM por software.
« Respuesta #6 en: 05 de Octubre de 2010, 21:58:23 »
Hola.

No vi el destello que dices  :shock: (será que ya me esta fallando la vista  :D )

Yo he usado esto para la interrupción y no me dan esos destellos.

Código: C#
  1. #int_Timer0
  2. void ActivaLed(void)
  3. {
  4.         Ticks++;
  5.  
  6.         if (Ticks==0)
  7.         {
  8.                 on(BLUE);
  9.                 on(RED);
  10.                 on(GREEN);
  11.         }
  12.         if(Ticks>=Rojo)
  13.                 off(RED);
  14.         if(Ticks>=Verde)
  15.                 off(GREEN);
  16.         if(Ticks>=Azul)
  17.                 off(BLUE);
  18.         set_timer0(230);
  19. }

Saludos

Gracias por la respuesta, en el segundo video se ve el destello entre 0:04 y 0:06 cuando cambia de verde a azul (aparece un destello amarillo). En la filmación de mi lámpara no se distingue muy bien, voy a probar con el código ese pero parecería ser similar al que estoy usando.

Un dato extra, este problema me pasó utilizando el led de 3W, tambien con leds individuales de 5mm, con un 16f628a y con el actual 12f675, por eso es que pienso en un error de código.

Que opinas acerca de que los comandos delay_ms() afecten las interrupciones?

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema en PWM por software.
« Respuesta #7 en: 05 de Octubre de 2010, 22:25:34 »
Hola.

Los delay_ms() afectan las interrupciones cuando se ponen dentro de las interrupciones, pero no veo ninguna así en tu código.

Saludos
El papel lo aguanta todo

Desconectado Cossworth

  • PIC12
  • **
  • Mensajes: 56
Re: Problema en PWM por software.
« Respuesta #8 en: 12 de Octubre de 2010, 13:24:44 »
Pude eliminar los destellos!  :-/

El problema era que al hacer los cambios de color en la transición, no verificaba que la secuencia de PWM se encuentre en 0, por lo que, al cambiar el valor en el medio de la secuencia, se encendía el led fuera de tiempo.

Solo agregué la verificacion esa antes de cambiar cada color y listo :D

Muchas gracias a todos por la ayuda!

Desconectado cordobe

  • PIC10
  • *
  • Mensajes: 3
Re: Problema en PWM por software.
« Respuesta #9 en: 10 de Diciembre de 2010, 16:43:32 »


Hola Gente!! Soy bastante nuevo en el Foro y sobretodo con los PICs!! Espero poder aprender bastante!!

Cossworth podrias publicar todo este proyecto??

Me interesa muchisimo el tema de las interrupciones y PWM, pero hasta ahora no logro comprenderlas del todo!! Creo que en este proyecto que has puesto aca es bastante completo con respecto a lo que estoy queriendo aprender!!

Desde ya muchas Gracias!!

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema en PWM por software.
« Respuesta #10 en: 10 de Diciembre de 2010, 16:59:27 »
 :? Si te estas iniciando y quieres aprender, hay otros proyectos más sencillos (buscar en el foro). Otra cosa es implementar el proyecto directamente :D y en ese caso lee bien el primer post.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado cordobe

  • PIC10
  • *
  • Mensajes: 3
Re: Problema en PWM por software.
« Respuesta #11 en: 10 de Diciembre de 2010, 17:13:48 »

Hola Suky!! 

Cuando te refieres al primer post, haces referencia a este:


Hola, antes que nada quiero aclarar que le busqué la vuelta por todos lados a este problema antes de decidirme a pedir ayuda acá, estoy realizando una lámpara de led's RGB los cuales controlo por PWM, el programa funciona perfectamente cuando se desea mantener un color fijo, pero al intentar realizar una transición aparecen destellos esporádicos como se puede ver en el siguiente video:


Para el código me basé en un ejemplo de Nocturno, que al ver en detenimiento, genera el mismo destello aleatorio:


El código que estoy usando es el siguiente, tiene varias partes comentadas de todas los cambios que le hice para intentar eliminar el maldito destello (cambiar el tipo de variables, evitar llegar a valores como 0 y 255, etc):

Código: [Seleccionar]
#include <12F675.h>

#fuses NOWDT,NOPROTECT,NOMCLR,INTRC_IO

#use delay (clock=4000000)



#byte puerto=0x05

#bit R=puerto.0

#bit G=puerto.1

#bit B=puerto.2



#define delay 10

#define reloj 220



int azul=0;

int rojo=0;

int verde=0;

int azul1=0;

int rojo1=0;

int verde1=0;

int pulso=0;

int estado=0;





//Secuencia de transición



void fade(){

rojo=253;

azul=5;

verde=5;

while(1){

for(verde=5;verde<253;verde+=5){

delay_ms(delay);

};



// while(verde<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=253;rojo>5;rojo-=5){

delay_ms(delay);

};



// while(rojo>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(azul=5;azul<253;azul+=5){

delay_ms(delay);

};



// while(azul<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// azul++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(verde=253;verde>5;verde-=5){

delay_ms(delay);

};



// while(verde>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=5;rojo<253;rojo+=5){

delay_ms(delay);

};



// while(rojo<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(verde=5;verde<253;verde+=5){

delay_ms(delay);

};



// while(verde<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=253;rojo>5;rojo-=5){

delay_ms(delay);

};



// while(rojo>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(azul=253;azul>5;azul-=5){

delay_ms(delay);

};



// while(azul>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// azul--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(rojo=5;rojo<253;rojo+=5){

delay_ms(delay);

};



// while(rojo<253){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// rojo++;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



for(verde=253;verde>5;verde-=5){

delay_ms(delay);

};



// while(verde>0){

// disable_interrupts(INT_RTCC);

// disable_interrupts(GLOBAL);

// delay_cycles(250);

// verde--;

// enable_interrupts(INT_RTCC);

// enable_interrupts(GLOBAL);

// delay_ms(delay);

// };



}; //Termina el while



}



//Generar un color fijo



void color(int8 red, int8 green, int8 blue){

rojo=red;

verde=green;

azul=blue;

}



//Interrupcion para detectar cuando se presiona un botón.



//Secuencia del timer, es el que genera los colores



#int_RTCC

void timer0(void){

if (pulso==254) pulso=0; else pulso++;

if(rojo1!=rojo) rojo1=rojo;

if(verde1!=verde) verde1=verde;

if(azul1!=azul) azul1=azul;

if (pulso==0){

R=1;

G=1;

B=1;

};

if (pulso==rojo1)

R=0;

if (pulso==verde1)

G=0;

if (pulso==azul1)

B=0;

set_timer0(reloj);

}



//Programa principal



void main(){

setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_1);

setup_adc(ADC_OFF);

setup_adc_ports(NO_ANALOGS);

enable_interrupts(INT_RTCC);

enable_interrupts(GLOBAL);

set_tris_a(0b111000);

estado=0;

set_timer0(reloj);



while(1){



//Switch



switch(estado){

case 0: {

color(253,0,0);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 1: {

color(0,253,0);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 2: {

color(0,0,253);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 3: {

color(253,253,253);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 4: {

color(253,0,253);

if(input(PIN_A5)) {

delay_ms(50);

if(!input(PIN_A5)) estado++;

};

break;

};

case 5: {

while(1){

color(0,0,0);

delay_ms(5);

color(253,253,253);

delay_ms(5);

if(input(PIN_A5)) {

estado++;

break;

};

};

break;

};

case 6: {

fade();

break;

};



}; //Termina el Switch



}; //Termina el While



} //Termina el Main

Alguien sabe como solucionar este problema?

Quisiera lograr un efecto parejo y progresivo como este:


Desde ya muchas gracias :)


Creo entender bastante de lo que ha publicado el amigo Cossworth, salvo que no entiendo del todo cuando dice:

"El problema era que al hacer los cambios de color en la transición, no verificaba que la secuencia de PWM se encuentre en 0, por lo que, al cambiar el valor en el medio de la secuencia, se encendía el led fuera de tiempo."

Donde verifica este hecho?? en que parte del Codigo??

Desconectado Cossworth

  • PIC12
  • **
  • Mensajes: 56
Re: Problema en PWM por software.
« Respuesta #12 en: 10 de Diciembre de 2010, 21:26:00 »

Creo entender bastante de lo que ha publicado el amigo Cossworth, salvo que no entiendo del todo cuando dice:

"El problema era que al hacer los cambios de color en la transición, no verificaba que la secuencia de PWM se encuentre en 0, por lo que, al cambiar el valor en el medio de la secuencia, se encendía el led fuera de tiempo."

Donde verifica este hecho?? en que parte del Codigo??

En ese código no estaba implementada la verificación a la que hago referencia, te adjunto el último código que funciona muy bien (baje la resolución de 8 a 7 bits para no hilar tan fino jaja)

El código se puede simplificar y agilizar mucho, no es una versión final pero cumple con su propósito.

Código: [Seleccionar]
#include <12F675.h>

#fuses NOWDT,NOPROTECT,NOMCLR,INTRC_IO

#use delay (clock=4000000)



#byte puerto=0x05

#bit R=puerto.0

#bit G=puerto.1

#bit B=puerto.2



#define delay 2

#define reloj 220



int azul=0;

int rojo=0;

int verde=0;

int azul1=0;

int rojo1=0;

int verde1=0;

int pulso=0;

int estado=0;

int i=0;





//Secuencia de transición



void fade(){

rojo=251;

azul=5;

verde=5;

while(1){

for(i=5;i<251;i+=2){

while(1){

if(pulso==0){

verde=i;

break;

};

};

delay_ms(delay);

};



for(i=251;i>5;i-=2){

while(1){

if(pulso==0){

rojo=i;

break;

};

};

delay_ms(delay);

};



for(i=5;i<251;i+=2){

while(1){

if(pulso==0){

azul=i;

break;

};

};

delay_ms(delay);

};



for(i=251;i>5;i-=2){

while(1){

if(pulso==0){

verde=i;

break;

};

};

delay_ms(delay);

};



for(i=5;i<251;i+=2){

while(1){

if(pulso==0){

rojo=i;

break;

};

};

delay_ms(delay);

};



for(i=5;i<251;i+=2){

while(1){

if(pulso==0){

verde=i;

break;

};

};

delay_ms(delay);

};



for(i=251;i>5;i-=2){

while(1){

if(pulso==0){

rojo=i;

break;

};

};

delay_ms(delay);

};



for(i=251;i>5;i-=2){

while(1){

if(pulso==0){

azul=i;

break;

};

};

delay_ms(delay);

};



for(i=5;i<251;i+=2){

while(1){

if(pulso==0){

rojo=i;

break;

};

};

delay_ms(delay);

};



for(i=251;i>5;i-=2){

while(1){

if(pulso==0){

verde=i;

break;

};

};

delay_ms(delay);

};



}; //Termina el while



}



//Generar un color fijo



void color(int8 red, int8 green, int8 blue){

while(1){

if(pulso==0){

rojo=red;

verde=green;

azul=blue;

break;

};

};

}



//Interrupcion para detectar cuando se presiona un botón.



//Secuencia del timer, es el que genera los colores



#int_RTCC

void timer0(void){

if (pulso==254) pulso=0; else pulso+=2;

if(rojo1!=rojo) rojo1=rojo;

if(verde1!=verde) verde1=verde;

if(azul1!=azul) azul1=azul;

if (pulso==0){

R=1;

G=1;

B=1;

};

if (pulso>rojo1)

R=0;

if (pulso>verde1)

G=0;

if (pulso>azul1)

B=0;

set_timer0(reloj);

}



//Programa principal



void main(){

setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_1);

setup_adc(ADC_OFF);

setup_adc_ports(NO_ANALOGS);

enable_interrupts(INT_RTCC);

enable_interrupts(GLOBAL);

set_tris_a(0b111000);

estado=0;

set_timer0(reloj);



while(1){



//Switch



switch(estado){

case 0: {

color(253,0,0);

if(input(PIN_A4)) {

delay_ms(50);

if(!input(PIN_A4)) estado++;

};

break;

};

case 1: {

color(0,253,0);

if(input(PIN_A4)) {

delay_ms(50);

if(!input(PIN_A4)) estado++;

};

break;

};

case 2: {

color(0,0,253);

if(input(PIN_A4)) {

delay_ms(50);

if(!input(PIN_A4)) estado++;

};

break;

};

case 3: {

color(253,253,253);

if(input(PIN_A4)) {

delay_ms(50);

if(!input(PIN_A4)) estado++;

};

break;

};

case 4: {

color(253,0,253);

if(input(PIN_A4)) {

delay_ms(50);

if(!input(PIN_A4)) estado++;

};

break;

};

case 5: {

while(1){

color(0,0,0);

delay_ms(5);

color(253,253,253);

delay_ms(5);

if(input(PIN_A4)) {

estado++;

break;

};

};

break;

};

case 6: {

fade();

break;

};



}; //Termina el Switch



}; //Termina el While



} //Termina el Main

La comprobación que agregué es esta:

Código: [Seleccionar]
for(i=251;i>5;i-=2){

while(1){

if(pulso==0){

verde=i;

break;

};

};

En la que compruebo que el ciclo de PWM se encuentre en 0 antes de aumentar la variable del color.

Ahora voy a armar bien el primer post con un PCB y algunas imágenes en caso de que alguien lo quiera implementar ;)

Desconectado cordobe

  • PIC10
  • *
  • Mensajes: 3
Re: Problema en PWM por software.
« Respuesta #13 en: 11 de Diciembre de 2010, 10:54:38 »


Muchisimas gracias por responder Cossworth!!

lo voy a tratar de armar y despues te comento como me fue!!

muy interesante tu post y la verdad que me esta superando esto de la programacion, porque no termino de definirme por cual lenguaje usar, estoy bastante mareado... porque todos los tutoriales que encuentro publican cosas basicas y a la hora de implementar algo un poco mas complejo (como tu publicacion) te dejen con muchas dudas!!


De ante mano, te agradezco infinitamente tu predisposicion!!