[Aporte] Mezclador de luz RGB

Yo quiero hacer algunas preguntas sobre este tema no se si ya está agotado,si es así consultare por mail



Va la pregunta ejemplo cargo el fuente .c PWM con POTS en un 18F4550 por medio de un bootloader y no funciona, cambie de salidas,etc, bueno dejo el programa que cargo.
Código:
//////////////////////////////////////////////////////////////////////////
////Control de 3 canales PWM por software                               //
////se utiliza para mesclar el brillo de tres leds;rojo,verde,azul      //
////utilizando potenciometro conectados a puerto AN0,AN1 y AN2          //
////recuerde que la libreria PWM.h debe estar en la misma carpeta       //
////donde se encuentre su codigo fuente                                 //
//////////////////////////////////////////////////////////////////////////
#include <18F4550.h>       
#device ADC=8  
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#include "usb_bootloader.h"
#use delay(clock = 48000000)   
#Define CH0 PIN_D0             //led ROJO conectado a rb5, cambie de pin si desea
#Define CH1 PIN_D1             //led VERDE conectado a rb6, cambie de pin si desea
#Define CH2 PIN_D3             //led AZUL conectado a rb7, cambie de pin si desea
#include <PWM.h>           //libreria para generar PWM de 8 bit por software 
#use fast_io(d)
//#use fast_io(a)
void main (void) 
{  
unsigned byte value;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN2);      //A0,A1,A2 entradas analogicas
set_tris_d(0xF0);
output_d(0); 
//output_a(0);
delay_ms(20);
PWM_init(150);                    //Inicia MACRO para generar PWM por software, RTCC_DIV_2       
while(true)    
    { 
    
    set_adc_channel(0);
    delay_us(50);
    value=read_adc();  //lee canal AN0
    write_duty0(value);//escribe canal PWM0
    output_high(CH0);

    set_adc_channel(1);
    delay_ms(150);  
    value=read_adc();  //lee canal AN1
    write_duty1(value);//escribe canal PWM1
    output_low(CH0);
    output_high(CH1);
    
    set_adc_channel(2);
    delay_ms(150);
    value =read_adc(); //lee canal AN2
    output_low(CH1);
    write_duty2(value);//escribe canal PWM2
    }
}
este es el PWM_init

Código:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////      
////libreria PWM.h, version 8Bit                                                                           //                    
////author: dinoelectro                                                                                    //
////www.forosdeelectronica.com                                                                             //
////dino_barreto@hotmail.com                                                                               //
////Con esta libreria podra generar ondas PWM con una resolucion de 8bit.                                  //
////Por defecto las ondas generadas salen por los pines B0, B1 y B2, pero cualquier otro PIN puede ser     //
////configurado como salida PWM; Por ejemplo: para generar las ondas en los pines A0,A1 y A2 usted deberia //     
////hacer la definicion de los canales como sigue:                                                         //
////                    #define CH0 PIN_A0                                                                 //
////                    #define CH1 PIN_A1                                                                 //
////                    #define CH2 PIN_A2                                                                 //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef CH0 #define CH0 PIN_D0 #endif //si no ha definido, PIN_B0 sera canal0 PWM por defecto
#ifndef CH1 #define CH1 PIN_D1 #endif //si no ha definido, PIN_B1 sera canal1 PWM por defecto
#ifndef CH2 #define CH2 PIN_D3 #endif //si no ha definido, PIN_B2 sera canal2 PWM por defecto
unsigned byte intcount =0;
unsigned byte dutycycle0=0;
unsigned byte dutycycle1=0;
unsigned byte dutycycle2=0;
unsigned byte Reload;
///////////////////////////////////////////////////////////////////////////////////////////////////////
////Funcion PWM_init(load)                                                                         //
////USO:                                                                                             //
////      Esta funcion inicia y habilita interrupcion por timer0                                     //
////      el timer0 es necesario para generar la onda PWM cuya                                       //
////      frecuencia esta directamente realacionada con el cristal                                   //     
////      que haya elejido y con el valor que carga en el timer0                                     //
////Parametros:                                                                                      //
////      load: puede tomar un valor de 0... 255                                                   // 
////      mientras mayor sea el valor de load, mayor sera la frecuencia de la onda PWM             //                              //
////VALOR DE RETORNO:                                                                                //
////      ninguno                                                                                    //
///////////////////////////////////////////////////////////////////////////////////////////////////////
void PWM_init(load)                                                                                    
{
    if (load >240) load=240;
    Reload = load;
    setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT); 
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
////Funciones Write_Duty0, Write_Duty1, Write_Duty2                                                  //
////USO:                                                                                             //
////      Estas funciones escriben el valor del ciclo util en los canales 0, 1 y 2; respectivamente  //
////PARAMETROS:                                                                                      //
////      value, es el ciclo util, puede tomar un valor entre 0 y 255                                //
////VALOR DE RETORNO:                                                                                //
////      ninguno                                                                                    //
///////////////////////////////////////////////////////////////////////////////////////////////////////
void write_duty0(value) {dutycycle0=value;}
void write_duty1(value) {dutycycle1=value;}
void write_duty2(value) {dutycycle2=value;}
///////////////////////////////////////////////////////////////////////////////////////////////////////
#int_timer0
void timer0_isr() 
{   set_timer0(Reload);
      if (intcount--==0)
   {
   output_high(CH0); 
    output_high(CH1); 
    output_high(CH2);  
   }
   if (intcount==dutycycle0)output_low(CH0); 
   if (intcount==dutycycle1)output_low(CH1); 
   if (intcount==dutycycle2)output_low(CH2); 
}
Alguien podría dar una mano. Muchas gracias
 
Última edición por un moderador:
no encuentro ningún error en el código,.. lo único que te puedo sugerir es asegurarte de estar trabajando con un cristal de 20Mhz en la librería PWM.h no es necesario hacer ningún cambio (al menos que desees ampliarla)

otra duda que tengo es ¿El bootloader funciona, es decir te deja descargar el programa?
 
Gracias por contestar dinoelectro,creo que funciona bien por que des cargue dos programas para titilar un led uno compilado en c18 y el otro en ccs y los dos funcionaron, inclusive si miras el codigo yo agregue output_high(CH0); anule los write_duty;PWM_init(150);#include <PWM.h> modifique tiempos en delay_ms(150);y demas camdios en otro delay,y el programa se cargo ,se ven los led prenderse y apagarce.
Creo que esto cofirma que se carga.
Puede haber algun problema con las interrupciones al hacerlo con el booloader, el remapeo.
Por ahora no se me ocurre nada.



Te comento que estoy trabajando con cristal de 20 mhz.
Tambien esta reforma que yo ise para que titilaran dos led (las comente anteriormente)las cargue con #use delay(clock = 48000000)
20000000 y 4000000, y funcionaron todas en el pic y se variaba la frecuencia de titilar los led
 
Última edición:
tienes razon, el remapeo de interrupciones a las direcciones 0x8 y 0x16 puede ser la solucion habria que probrar...

si utilizas el bootloader de CCS tambien existe la opcion de colocar el bootloader en las ultimas direcciones de memoria, evitandote eso del remapeo
 
Cuando tenga un tiempo le pongo mano si lo descubro lo comento,lo tengo funcionando en est momento con un pic16f877A.
Muchas gracias



Estoy usando el hid bootloader en c18.
 
Última edición:
Encontré la solución a mi caso, y porque digo esto, porque no todas las versiones de los compiladores ccs funcionan exactamente igual (referencia http://www.todopic.com.ar/foros/index.php?topic=23135.80).
Allí se discutio bien a fondo este tema y al navegar por alli encontre esta solucion a mi caso. (Soy reiterativo,todo depende de la version del ccs con el que compilemos el archivo fuente de aplicacion que en mi caso es PWM y aclaro que yo uso un bootloader compilado en c18 y el PWM esta compilado en ccs OK)
Este es el código y funciona

Código:
//////////////////////////////////////////////////////////////////////////
////Control de 3 canales PWM por software                               //
////se utiliza para mesclar el brillo de tres leds;rojo,verde,azul      //
////utilizando potenciometro conectados a puerto AN0,AN1 y AN2          //
////recuerde que la libreria PWM.h debe estar en la misma carpeta       //
////donde se encuentre su codigo fuente                                 //
//////////////////////////////////////////////////////////////////////////
#include <18F4550.h>       
#device ADC=8  
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 48000000)   
#define CH0 PIN_B5             //led ROJO conectado a rb5, cambie de pin si desea
#define CH1 PIN_B6             //led VERDE conectado a rb6, cambie de pin si desea
#define CH2 PIN_B7             //led AZUL conectado a rb7, cambie de pin si desea
#include <PWM.h>           //libreria para generar PWM de 8 bit por software 

#build(reset=0x1000,interrupt=0x1008)  //ACA ESTA EL TRUCO QUE NO ES 
#org 0x0000,0x0FFF {}                      //MIO, SOLO LO BUSQUE.Esta es una forma de remapear el 
                                                     // reset y las interrupciones para mi caso.


void main (void) 
{  
unsigned byte value;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN2);        //A0,A1,A2 entradas analogicas
set_tris_b(0x00);
//set_tris_d(0x03);
PWM_init(225);                    //Inicia MACRO para generar PWM por software, RTCC_DIV_2       
while(true)    
    {   
    set_adc_channel(0);
    delay_us(50);
    value=read_adc();  //lee canal AN0
    write_duty0(value);//escribe canal PWM0

    set_adc_channel(1);
    delay_us(50);  
    value=read_adc();  //lee canal AN1
    write_duty1(value);//escribe canal PWM1  
    
    set_adc_channel(2);
    delay_us(50);
    value =read_adc(); //lee canal AN2
    write_duty2(value);//escribe canal PWM2
    
    
   // output_toggle(PIN_D3); 
   // delay_ms(140); 
     }
}

Seguiré probando con otros códigos para ver si funciona
 
Última edición por un moderador:
Aca les dejo el programa fuente para el pic12F629 que yo arme con ayuda de varios programas ajenos.
El pulsador es para buscar un color y al soltarlo quedara el color elejido por el usuario,tambien se puede
lo puede reemplazar por un interruptor y si esta accionado se genera la secuencia de colores prefijada
en la tabla longitud SINE_WAVE [210].
Creo que con este pic12F629 es con el mas pequeño que podemos trabajar .



Enlace pic12F629 https://www.forosdeelectronica.com/f11/programa-pic-12f629-86129/index2.html
 

Adjuntos

  • RGB12F629.rar
    25.7 KB · Visitas: 126
Última edición:
realice con pic un mezclador de color automático con diodos de colores RGB se colocaron dos macros uno que cambia de rojo hasta azul, y otro que cambia de azul hasta rojo los dos macros están sincronizados y se colocaron en el puerto A de un pic 16f877 desde A0 hasta A5. espero les guste
 

Adjuntos

  • RGB.rar
    23.7 KB · Visitas: 104
Última edición:
cordial saludo estimados, he probado el código de alberto0265 y funciona a las mil maravillas, podrían por favor indicarme como lo traslado para un pic 16f628a? he tratado de hacerlo modificando el programa pero siempre me bota error, gracias de antemano :=)
 
Hola estuve mirando tu post y quisiera hacerte un par de preguntas tu nueva libreria pwm.h funciona con pic16f628a? y con esta puedo hacer que genere colores aleatorios ?
Gracias por tu gran aporte y por la ayuda que me puedas brindar
 
Claro que se puede sin ningún problema.
Debes utilizar PINA o PINB, nunca PINC. Recuerda que el PIC16F628 no tiene puerto C.
 
Última edición por un moderador:
he buscado información para la genereaciòn de pwm para controlar rgb gracias me sirvio los programas que encontre en el foro ahora no se si me puedes ayudar necesito que en vez de un pulsador o potenciometro se cambia el pwm con una orden que llegue mediante comunicacion serial por ejempli si es 1 subir pwm si es 2 bajar pwm tiene alguna idea?
 
Hola no se si este tema este obsoleto o ya nadie resuelva preguntas pero me gustaría saber si con ese código es posible obtener frecuencias mayores y de no ser así ¿creen que sea posible?
 
Hola, hay alguien atendiendo en este post? Quería hacer este mismo mezclador RGB pero con mi pic 16F690. Al momento de implementar el código me tira errores en varios fuses y no funciona...ayuda!
 
Gracias por la respuesta DOSMETROS!

Ya no me salen esos errores con los #FUSES y me funciona. Sin embargo el problema que tengo es que después de ajustar los 3 dutys, no sale de la función nunca. Además me sale que hay excesiva carga de CPU, no se si a la hora de implementarlo me dará problema. Te adjunto el código y el diseño de proteus para ver si me puedes ayudar. Gracias!

NOTA: lo que quiero es poder enviarle desde un pc los 3 datos de RGB (de 0 a 255), y después que ajuste mediante PWM cada uno de los leds (tengo un módulo RGB) y que después salga de la función para volver a pedir otro dato.
 

Adjuntos

  • Proyecto.rar
    16.1 KB · Visitas: 17
  • Funcionando.jpg
    Funcionando.jpg
    96.5 KB · Visitas: 14
Hola ya hace mucho tiempo que he dejado de programar en PIC... sin embargo aquí te dejo un ejemplo que hace exactamente lo que tu deseas pero con ARDUINO:

http://dinoelectro.blogspot.com/2017/06/dimmer-rgb-con-arduino.html?m=1

Espero te sirva, Saludos!



Hola ya hace mucho que no programo PIC; sin embargo tengo un ejemplo que hace justamente lo que tu deseas, lamentablemente es para ARDUINO utilizando el puerto serie y processing

Te dejo el enlace por si te sirve;

http://dinoelectro.blogspot.com/2017/06/dimmer-rgb-con-arduino.html?m=1
 
Última edición:
Gracias dinoelectro, creo que tu eres el que creaste la libreria PWM.h para PIC C, revisaste el código que envié para ver por qué el programa nunca sale de la función cambiar_color?
Vi la página del proyecto en arduino y la verdad te agradezco el aporte pero no me sirve de mucho...no conozco nada de arduino y el lenguaje que usa, parece más sencillo pero recién estoy empezando con picc y no entiendo nada...

Saludos y ojalá alguien pueda ayudarme.
 
Atrás
Arriba