CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

RGB Led Duty Cycle

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

RGB Led Duty Cycle
PostPosted: Wed Nov 22, 2017 6:03 am     Reply with quote

Hello,

I am trying to use the CJMCU 2812 rgb led module. My module has a CD shape.

What i am trying to do is, make the first led to give color i want. The problem is, the value does have a weird effect. Sometimes it increases the brightness sometimes it does not. For example, blue = 1. it is brighter than blue = 200 but lesser than blue = 255.

I checked the datasheet and tutorial video
https://blog.adafruit.com/2014/07/21/tutorial-on-programming-the-neopixel-ws2812-rgb-leds-using-a-pic-microcontroller-and-c-language/

The datasheet says, for 1 i should give 0.9s high and for 0 i should give 0.35s high voltage to modules data pin.

this is the datasheet
http://www.seeedstudio.com/document/pdf/WS2812B%20Datasheet.pdf

Here is my code
Code:

#include <18F2550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,NOMCLR,PROTECT,NOLVP,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

#define RGBPIN PIN_B0
#define LEDNUM 8

void neobit(int);
void led_on();

int red = 0;
int green = 0;
int blue = 200;


void main()
{
   delay_ms(100);   
   led_on();
}

void neobit(int bit)
{
   if(bit==1)
   {
      output_high(RGBPIN);
      delay_cycles(6);
      output_low(RGBPIN);

   }
   else
   {
      output_high(RGBPIN);
      delay_cycles(3);
      output_low(RGBPIN);
   }
}

void led_on()
{
   int i=0;

      for(i=0;i<8;i++)
      {
         neobit(bit_test(green,i));
      }
      for(i=0;i<8;i++)
      {
         neobit(bit_test(red,i));
      }
      for(i=0;i<8;i++)
      {
         neobit(bit_test(blue,i));
      }
   output_low(RGBPIN);
   delay_us(100);
}
 
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

Re: RGB Led Duty Cycle
PostPosted: Wed Nov 22, 2017 6:13 am     Reply with quote

I edited code to this

Code:

#include <18F2550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,NOMCLR,PROTECT,NOLVP,NODEBUG,NOBROWNOUT,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)

#define RGBPIN PIN_B0
#define LEDNUM 8

void neobit(int);
void led_on();

int red = 0;
int green = 0;
int blue = 200;
int color[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1};

void main()
{
   delay_ms(100);
   int i=0;
   for(i=0;i<24;i++)
   {
      if(color[i]==1)
      {
      output_high(RGBPIN);
      delay_cycles(6);
      output_low(RGBPIN);
      }
      else
      {
         output_high(RGBPIN);
         delay_cycles(3);
         output_low(RGBPIN);
      }
   }
}



The datasheet says i should give a 24 bit number(8bit G 8bit R 8 Bit B ). I can see a linear change when i play with numbers in array color. So i am assuming i did something wrong on bit_test command but i could not see the mistake. Any ideas?

Thank you very much!
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 6:25 am     Reply with quote

It looks like your 'neobit' timing code is incorrect.
I remember playing with these a few years ago and the timing has to be spot on.
A neobit '1' has to be .9us hi then .35ns low
a neobit '0' has to be .35ns hi then .9ns low.

You don't have a fixed delay after the 2nd state of the neobit.
I haven't done the math but an oscillioscope would show the timing.

Start with a simple loop for a neobit '1' and a 100ms delay, observe the data on the scope. The required delay_cycles(xxx) has to include the setting or clearing of the bit.

This basic 'neobit' timing HAS to be accurate as the LED requires a stream of 24 'neobits' + reset to decode into an LED color. If the neobit timing is say 10ns short, in 24 bits (1 pixel) it's now 240ns short.

I'll see if I can find my code...it may be on the old Eng PC.
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 6:33 am     Reply with quote

temtronic wrote:
It looks like your 'neobit' timing code is incorrect.
I remember playing with these a few years ago and the timing has to be spot on.
a neobit '1' has to be .9us hi then .35ns low
a neobit '0' has to be .35ns hi then .9ns low.

you don't have a fixed delay after the 2nd state of the neobit.
I haven't done the math but an oscillioscope would show the timing.

start with a simple loop for a neobit '1' and a 100ms delay, observe the data on the scope. The required delay_cycles(xxx) has to include the setting or clearing of the bit.

This basic 'neobit' timing HAS to be accurate as the LED requires a stream of 24 'neobits' + reset to decode into an LED color. If the neobit timing is say 10ns short, in 24 bits (1 pixel) it's now 240ns short.

I'll see if I can find my code...it may be on the old Eng PC.


Thank you temtronic

I took the values for cycles from the tutorial video. I dont know how to make a delay time for periods smaller than us. What is the calculation method?
On the video he used 18f4550 and used crystal. I used the same configuration with him.

I will check the signal with oscillioscope and find the correct values for cycles
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 7:10 am     Reply with quote

delay_cycles(1) will give a delay of one cycle.
A 'cycle' is clock speed/4, so 48MHz/4 = 12 MHz. 1/12,000,000 is 8.333 x 10e-8.

For a neobit '1' you need T1H of .9us, T0L 0f .35us
or 900 ns ..350ns.

The 900ns 'high' time has to include the setting the pin high.
setting or clearing a bit for PICs is fast, only one cycle according to the datasheet. So to create a neobit 1 you need.

Set bit, delay 899 ns, clear bit, delay 349ns.
...
I leave you to do the math.... hint...think in nanaseconds.....

Also since 1/12 is NOT an integer, there is a small amount you have to account for. ie .333 * 24 = 8... this value is constant, based on the crystal frequency. When you 'do the math' you'll see how it changes the numbers.

Since this is a serial stream of data it is important that you get the timing as close as possible to what the LED requires.

Edit: Looked for programs, none. Found some 2801 code, so I didn't buy the 2812s as it was easier to code for the 2801s. Mr. T's comments about the SSP and nibbles rings very familar......and I did see code 'somewhere' on the net using that technique, sigh, years ago....

edit #2:

OK if your 2812 is the same as the ws2812, search in the code library !! there is code there that should work. Mr. T's nibbles tweaked my grey cells and I googled it... I'll do anything to stay inside today as it's 0*C here, dull,overcast, snowy....sigh..Old Man Winter is here.
Jay Sad


Last edited by temtronic on Wed Nov 22, 2017 8:01 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 7:32 am     Reply with quote

The classic way of cheating these, is to use the SSP.
You set this up to give a bit time for the shortest interval needed. About 3MHz works.
You need to be running off a processor clock that allows something very close to this to be generated.
Then you send nibbles on this to give the required timings. So a 2bit pattern of 00, needs 0b10001000. 01 needs 0b10000001 11 needs 0b00010001 and 10 needs 0b00011000. A '0' is a 1000 nibble and a 1 is a 0001 nibble. If I remember correctly, this just works on the times.
There is no way the processor is fast enough to generate the patterns using software.
Using 3Mhz, the bit time is 0.33uSec. The nibble takes 1.33uSec, which is then inside the 1.25+/-0.15uSec specified time. The three 0's gives 1uSec (which is within the 0.9+/- 0.15 required for this pulse, and the '1' is 0.33uSec, with the same comment.
You have to set the SSP up to run off timer2/2.
Timer 2 needs to be set to use a divisor of 2 (PR2=1), and prescaler of 1. This then gives a clock at 6Mhz.
You also need to choose an SSP mode that idles high (to avoid sending reset patterns when idle).
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Wed Nov 22, 2017 9:18 am     Reply with quote

Well done Jay.
I remembered this having been described before. However the timings seem to be a factor of two too slow, for the data sheet figures. The bits would be using 48000000/(16*8) sec as shown. 2.666uSec.
doguhanpala



Joined: 05 Oct 2016
Posts: 120

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 6:41 am     Reply with quote

Thank you for your answers.

I think i found the problem. First of all i used unsigned int instead of integer for duty cycles. Also, the datasheet says, rgb waits for MSB first so i edited the code according to it (changed the "for loop" parameters).

It works fine with the same delay cycles but i will calculate them anyways.

Thank you so much!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group