Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

RGB LED Strip Controller(problem in using pwm signals)

Status
Not open for further replies.

vinay bs

Member level 3
Joined
May 22, 2012
Messages
65
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,751
hi guys, i am using pic16f883 micro controller to generate pwm signals to control rgb led, pic has two built in pwm channels,
but i need channels to control all three....
please help me how to generate third channel(any options using timers or can i make use of two ccp channels to generate third one....
below is my code using mikro c compiler..

Code:
#define red PORTC.F1
#define green PORTC.F2
#define blue PORTC.F3
#define sw1 PORTC.F6
#define sw2 PORTC.F5
#define sw3 PORTC.F4
unsigned char press;
unsigned char i,j,k;
void main() 
{
C1ON_bit=0;
C2ON_bit=0;
ANSEL=0x00;
ANSELH=0x00;
TRISC=0b11111000;
PORTC=0x00;
PWM1_Init(5000);
PWM2_Init(5000);
PWM1_Start();
PWM2_Start();
press=0;
     while(1)
     {
       if(sw1==0)
       {
               press=press+1;
               if(press=1)
               {
               red=1;
               blue=0;
               green=0;
               }
               else if(press=2)
               {
               red=0;
               blue=1;
               green=0;
               }
               else if(press=3)
               {
               press=0;
               red=0;
               blue=0;
               green=1;
               }

       }
       if(sw2==0)
       {
               for(i=0;i<255;i++)
               {
                PWM2_Set_Duty(i);
                Delay_ms(10);
               }
               for(j=255;j<0;j--)
               {
                PWM1_Set_Duty(j);
                Delay_ms(10);
               }
               for(k=0;k<255;k++)
               {
                blue=0;
                Delay_ms(2);
                Delay_us(500);
                blue=1;
                Delay_ms(7);
                Delay_us(500);
               }
        }
      if(sw3==0)
      {
       red=1;
       green=1;
       blue=1;
      }

     }
}
 

Is this a simulation or actual real hardware? If sim, why not select a microcontroller with 3 PWM channels?
If real hardware, you could implement your own PWM routine for all three channels, based on a single timer.
For example, have a timer executing 100 times per sec. At each tick, decide (for each LED) whether to turn on a port pin, or
to turn it off, or to do nothing.. The decision would effectively be your PWM routine in software.
 

Hi Vinay
In my point of view, hear ccp1 and ccp2 mode are activated for 8MHZ crystal, and in the ccp register
1. PWM resolution is 10 bits
2. don't use last 2 less significant bits CCPxCON,
3. so only CCPRxL have to be used for change the duty cycle

Code:
unsigned char   dc ;

        TRISC = 0 ;                     // set PORTC as output
        PORTC = 0 ;                     // clear PORTC

        
         //configure CCP module as 4000 Hz PWM output
   
        PR2 = 0b01111100 ;
        T2CON = 0b00000101 ;
        CCP1CON = 0b00001100 ;
        CCP2CON = 0b00111100 ;
 

Run a timer, when the timer overflows then in the ISR give the reload value according to the PWM required or desired, again after the interrupt reload the value. This would repeat itself and thus acting as a PWM output.
Consider it using a GPIO pin as a PWM output pin.
 

can anyone put example prog for this, just like fading led from 0% duty cycle to 100%....
so that i can easily implement... please...
 

C source code example : How to smoothly blink two LEDs
target : PIC16F877A, 8 Mhz crystal, HS clock, no watchdog.
Code:
void main()
        {
        unsigned char   dc ;

        TRISC = 0 ;                     // set PORTC as output
        PORTC = 0 ;                     // clear PORTC

        /*
         * configure CCP module as 4000 Hz PWM output
         */
        PR2 = 0b01111100 ;
        T2CON = 0b00000101 ;
        CCP1CON = 0b00001100 ;
        CCP2CON = 0b00111100 ;

        for(;;)                         // forever
                {
                /*
                 * PWM resolution is 10 bits
                 * don't use last 2 less significant bits CCPxCON,
                 * so only CCPRxL have to be touched to change duty cycle
                 */
                for(dc = 0 ; dc < 128 ; dc++)
                        {
                        CCPR1L = dc ;
                        CCPR2L = 128 - dc ;
                        Delay_ms(10) ;
                        }
                for(dc = 127 ; dc > 0 ; dc--)
                        {
                        CCPR1L = dc ;
                        CCPR2L = 128 - dc ;
                        Delay_ms(10) ;
                        }
                }
        }
 

thanks avinesh....
but i need to generate pwm without using ccp module....
is this possible by using timers.... ????
if so give some examples....
 

You can use timer. I will show pseudo code:
1. configure a GPIO Pin as output pin. Set initial value high.
2. Load the counter with equivalent value.
3. in the ISR, complement the GPIO Pin. Reload the counter with value.

This would generate the PWM output with desired duty cycle.
 

hi fellows i am not able to get those codes.....
please give example codes to generate pwm signals to fade rgb light using timers....
 

thanks dean_winchester.....
it goes like this....
i am using rgb strip to test....

if sw1 pressed, red color should glow at full intensity
again if sw1 pressed 2nd time, green color should glow like that blue color if sw1 pressed 3rd time....

if sw2 pressed rgb all should fade continuously one by one from 0% to 100%...

if sw3 pressed all rgb colors should glow, so that i can get white light...

thanks...
 

Hi vinay
1) for creating the pwm signal to third channel, we can use timer concept, for creating timer delay, the rise and fall time of the signal is calculated, and also we need to consider the oscillator frequency

2) So a PWM wave is just a signal that changes between 0 volts & 5 volts (digital logic 0 and 1). for increase the wave timing and voltage variation, we can use timer delay.

based on the crystal frequency the timer isr gets called and the timer overflows on the limit
based on that (for 20 MHz)

Code:
for(count=0;count<50;count++) //50 * 0.020 Seconds = 1 Second
{
     PORTB = 0x01;     //PortB Pin 0 = 5v (logic 1)
     Delay_ms(7);       //Delay 1.5mS
     Delay_us(5);
     PORTB = 0x00;    //PortB Pin 0 = 0v (logic 0)
     Delay_ms(92);//Delay 18.5mS
     Delay_us(5);
}
 

Hi vinay
1) for creating the pwm signal to third channel, we can use timer concept, for creating timer delay, the rise and fall time of the signal is calculated, and also we need to consider the oscillator frequency

2) So a PWM wave is just a signal that changes between 0 volts & 5 volts (digital logic 0 and 1). for increase the wave timing and voltage variation, we can use timer delay.

based on the crystal frequency the timer isr gets called and the timer overflows on the limit
based on that (for 20 MHz)

Code:
for(count=0;count<50;count++) //50 * 0.020 Seconds = 1 Second
{
     PORTB = 0x01;     //PortB Pin 0 = 5v (logic 1)
     Delay_ms(7);       //Delay 1.5mS
     Delay_us(5);
     PORTB = 0x00;    //PortB Pin 0 = 0v (logic 0)
     Delay_ms(92);//Delay 18.5mS
     Delay_us(5);
}

In this case the PWM will not be Increasing, for that you need to increase the width of the Wave. .i.e with every loop just increment the time for which the port remains high.
 

but we have problem in incrementing time delay(i.e delay routine should be constant).....
 

the corresponding increment should also reflect decrement in other bit field. i.e. if time for a bit for high is increased, then time for bit to stay low should decrease by same factor. Else the frequency of wave would change.
So, i would suggest that use a timer and simple complement the Port in the ISR. Moreover you can match the 0 to 100% PWM with the 0x0000 to 0xFFFF value of Timer and correspondingly increase the value of Timer. All this needs to be carried out in the ISR of the timer.
 

could u please help me... if u can put the above description into codes....
 

1. -> Configure the timer in 16 bit mode. Enable interrupt for timer. initially put timer value =0xFFFF and port condition initially be 0. Now Run the timer.
2. -> In the Interrupt Routine for timer, complement the Port value and decrement the timer value by 0x28F and again start the timer. Also, dont forget to place the check on timer value ( it should be between 0x0000 and 0xFFFF).
You will have a PWM waveform on the Port.
 

please somebody give sample code.... my mind is not working.....blocked....:sad:
 

find attachment for proteus design file...
here i used three seperate leds(RGB), but in real time i am using rgb strip instead.....
 

Attachments

  • rgb con.rar
    7.9 KB · Views: 51

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top