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 support@ccsinfo.com

WS2812b and Pic18f46k22

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



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

WS2812b and Pic18f46k22
PostPosted: Mon Dec 09, 2019 3:43 pm     Reply with quote

With this code, the WS2812b can emit any number of lights in any color.

WS2812B.h
Code:

#define DATA_PIN PIN_B0 // Write the pin you want to use.

#define LED_NUMBER 8 // How many leds do you have

#define CONTRAST 1 // [1-254] bright

#define COLOR_SELECT 1
//1 Red - Green - Blue 
//2 Yellow - Cyan - Purple
//3 White
//4 ALL


#define WS_ONE(pinPtr) {\
   output_high(pinPtr); delay_cycles(1); delay_cycles(1); \
   delay_cycles(1); delay_cycles(1); delay_cycles(1); delay_cycles(1); \
   delay_cycles(1); delay_cycles(1); output_low(pinPtr);\
}

#define WS_ZERO(pinPtr) {\
   output_high(pinPtr); delay_cycles(1); delay_cycles(1); \
   output_low(pinPtr); delay_cycles(1); delay_cycles(1); \
   delay_cycles(1); delay_cycles(1); delay_cycles(1);\
}

#define WS_RESET(pinPtr) output_low(pinPtr); delay_us(1);


WS2812B.c

Code:

#include "WS2812B.h"

//About Blink leds i don't understand exactly

void data_stream(unsigned int8 temp) {
   
   if(temp & 0x80) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x40) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x20) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x10) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x08) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x04) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x02) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}
   if(temp & 0x01) {WS_ONE(DATA_PIN);} else {WS_ZERO(DATA_PIN);}

}

//How many leds do you have

void RGB_color(char red, char green, char blue) {
  for(int i=0;i<LED_NUMBER;i++){
  data_stream(red);
  data_stream(green);
  data_stream(blue);
  }
 // delay_ms(1);
}
// Color Select
void prove_driver(void) {
   static unsigned int8 temp = 0;
   if(COLOR_SELECT==1)//B,R,G ranking why this way?
   {
    switch(temp) {
     case 0: RGB_color(0x00, 0x00, CONTRAST); temp += 1; break;
     case 1: RGB_color(0x00, CONTRAST, 0x00); temp += 1; break;
     case 2: RGB_color(CONTRAST, 0x00, 0x00); temp = 0;  break;
   }
    }
   else if(COLOR_SELECT==2)//P,Y,C ranking why this way?
   {
    switch(temp) {
     case 0: RGB_color(0x00, CONTRAST, CONTRAST); temp += 1; break;
     case 1: RGB_color(CONTRAST, CONTRAST, 0x00); temp += 1; break;
     case 2: RGB_color(CONTRAST, 0x00, CONTRAST); temp = 0;  break;
   }
    }
   else if(COLOR_SELECT==3)//White
   {
      RGB_color(0xFF, 0xFF, 0xFF);
   }
   else if(COLOR_SELECT==4)//All COLOR
   {
     switch(temp) {
     case 0: RGB_color(0x00, 0x00, CONTRAST); temp += 1; break;
     case 1: RGB_color(0x00, CONTRAST, 0x00); temp += 1; break;
     case 2: RGB_color(CONTRAST, 0x00, 0x00); temp += 1;  break;
     case 3: RGB_color(0x00, CONTRAST, CONTRAST); temp += 1; break;
     case 4: RGB_color(CONTRAST, CONTRAST, 0x00); temp += 1; break;
     case 5: RGB_color(CONTRAST, 0x00, CONTRAST); temp += 1;  break;
    case 6: RGB_color(0xFF, 0xFF, 0xFF); temp = 0; break;
   
   }
    }




      WS_RESET(DATA_PIN);
      delay_ms(1000);
}   



Code

Code:

#include "18f46k22.h"             
#device adc = 10                     
                                     
#define OSC 32000000                 
#use delay (internal = OSC)    //internal oscillator and pll. Frekans not divison 4     

                               //configuration setting     
#fuses INTRC_IO, NOWDT, PUT, NOMCLR         
#fuses NOBROWNOUT, NOLVP, NOCPD, NODEBUG,   
#fuses NOPROTECT,           
#fuses NOFCMEN, NOWRT, STVREN               

#use FAST_IO(ALL)                           
                       

#include "WS2812B.c"


   void main(void) {
       delay_ms(1000);

       output_drive(DATA_PIN);

       While(True){
   
          prove_driver();

      }
   }
Very Happy
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Mon Dec 09, 2019 3:46 pm     Reply with quote

Quote:

Thank you for question PCM Programmer.
1) My code is running.
2) Can give eight led light at the same time.
3) LEDs give different or same color light at the same time.
So I think the 'WS_ONE' or 'ws_zero' functions are correct.

My problems are;
1)
Kod:

data_stream (red);
data_stream (green);
data_stream (blue);

I wrote this function eight times for eight leds.
r, g, b --> g, r, b
r, b, g --> g, b, r
g, b, r --> b, g, r
g, r, b --> r, g, b
b, r, g --> r, b, g
b, g, r --> b, r, g
If I change the rankings, the luminous order of the leds changes.
I couldn't understand the how of that.
2) When changing the LED colors in order, I want one of them to remain the same color. But I couldn't.
Actually, the same two questions.
data_stream (red);
data_stream (green);
data_stream (blue);
How this function works. Question
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Mon Dec 09, 2019 4:01 pm     Reply with quote

I have one more question;
When I select 4 as Color Select;
Code:

   else if(COLOR_SELECT==4)//All COLOR
   {
     switch(temp) {
     case 0: RGB_color(0x00, 0x00, CONTRAST); temp += 1; break;
     case 1: RGB_color(0x00, CONTRAST, 0x00); temp += 1; break;
     case 2: RGB_color(CONTRAST, 0x00, 0x00); temp += 1;  break;
     case 3: RGB_color(0x00, CONTRAST, CONTRAST); temp += 1; break;
     case 4: RGB_color(CONTRAST, CONTRAST, 0x00); temp += 1; break;
     case 5: RGB_color(CONTRAST, 0x00, CONTRAST); temp += 1;  break;
    case 6: RGB_color(CONTRAST, CONTRAST, CONTRAST); temp = 0; break;
   
   }



LEDs light in this order;

Blue - Red - Yellow - Purple - Yellow - Cyan - White

WHY?
Thankyou for answers.
Question
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 09, 2019 4:44 pm     Reply with quote

Did you write this code ? Your questions imply that someone else wrote
this code. If so, post a link to the website where you found this code.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 1:19 am     Reply with quote

The code is for 'stinky's on this page: http://www.ccsinfo.com/forum/viewtopic.php?t=52446&start=0&postdays=0&postorder=asc&highlight=

I just made minor changes.
Please contribute with your help
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 5:34 am     Reply with quote

You removed his comments, which explained why he did things.
That's why its hard for you to understand.

This is his original routine with his comments:
Quote:
/*WS2812 accepts colors in order of green-red-blue.
I do not, so these assign as red-green-blue which
is more comfortable to me.*/

void RGB_color(unsigned int8 red, unsigned int8 green, unsigned int8 blue) {
data_stream(green);
data_stream(red);
data_stream(blue);
}


Look at the diagram in the WS2812B data sheet titled:
Quote:
Composition of 24bit data

It shows the hardware design of the LED strip requires data to be
sent in this order: Green, Red, Blue. (ie., GRB).

But Stinky doesn't like to think or write in that order. So he created a
"wrapper" function called RGB_color(). It accepts the function parameters
in the order that he likes: RGB_color(red, green, blue).
But inside the function when it sends the data, it is put into the correct
order of transmission that the LED strip requires: green, red, blue

It's simply a wrapper function for his mental convenience. He thinks of
colors as R, G, B (not G, R, B).

Here is your function. You have messed up the order of the transmitted
data. You have changed the contents of the function to send it in RGB
order, and that is incorrect:
Quote:
void RGB_color(char red, char green, char blue) {
for(int i=0;i<LED_NUMBER;i++){
data_stream(red);
data_stream(green);
data_stream(blue);
}
// delay_ms(1);
}


Try this:
Code:
void RGB_color(char red, char green, char blue) {
  for(int i=0;i<LED_NUMBER;i++){
  data_stream(green);
  data_stream(red);
  data_stream(blue);
  }

}

----------------------------
I have a question about this line that you wrote:
Quote:
#define CONTRAST 1 // [1-254] bright

The WS2812B data sheet says it supports 256 levels, so why do you
think it only supports 254 levels ? It should be 0 to 255.
Also, why do you set the brightness to 1 ? That's a very low level.
In Stinky's code, he sets it to 0xFF (255), for full brightness.
I would guess that you could hardly see a brightness level of 1.
temtronic



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

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 7:29 am     Reply with quote

re: CONTRAST

To me that's a bad choice of word. Brightness or level would be better to 'self describe' what the varaible is used for. When I started 'computers' variables only had 2 letters so naming a variable 'RED_LED_brightness' still seems 'odd' to me. Doesn't help I can't type (missing finger) and dyslexic either !

I understand it might just be a 'translation to English' point as PICs are used Worldwide.

Jay
temtronic



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

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 8:57 am     Reply with quote

Still a couple of timing problems.
I downloaded the datasheet, twice, and got two DIFFERENT timing charts....

1) Both say ws_reset must be > 50us, but you'v only got 1us...

2) The ws_one and ws_zero aren't the same. At 32Mhz clock, tcy is 125ns.
my problem is WHICH datasheet to use. I like the one where '1' vs '0' is the mirror image of high vs low. 3 cycle high, 7 low, 7 high, 3 low. the timing as shown may work for short runs......??

If I get time I may see if I have the LEDs here, at least the 46K22 is my goto PIC !

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 12:08 pm     Reply with quote

Get the latest version 5 datasheet directly from the manufacturer's website.
Ignore all other ones. Do a Google search for this:
Quote:
WS2812B datasheet pdf site:www.world-semi.com

Google will return this result at the top of the list:
Quote:
[PDF]WS2812B Ver. No.: V5 - Worldsemi
temtronic



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

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 12:51 pm     Reply with quote

yeesh.. I just downloaded it, even MORE confused !

According to their chart...

t0h=220ns, t0l=580ns
t1h=580ns, t1l=580ns

and

t0h+t0l = t1h+t1l
....

If we assume the "0" and the "1" have the same width( makes sense to me )
then their t1l spec is wrong and should be 220ns(same as t0h ).

Sigh , I now have 4 of their datasheets with various numbers...

Jay

I'm using the minimum times
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 1:37 pm     Reply with quote

I agree it looks like they made a mistake in the vs. 5 datasheet.

The version 4 datasheet does it the way you want:
https://www.parallax.com/sites/default/files/downloads/28085-WS2812B-V4_v1.0-RGB-LED-Datasheet.pdf
Ttelmah



Joined: 11 Mar 2010
Posts: 19256

View user's profile Send private message

PostPosted: Tue Dec 10, 2019 1:49 pm     Reply with quote

I'd always aim for the middle time. Gives the most margin for error
on the clock. The datasheet is silly. I have used these in the past, using
SPI to generate the bits. Setup SPI at 6.4MHz. Then sending 2 1's for
a '0', and 4 for a '1', works merrily. This gives 312.5nSec for the T0H and
625 for T1H. 625 for T1L, and 937.5 for T0L. All inside the V5 data sheet
figures. Total bit time is 1.25uSec.
Having different times in different data sheet versions is designed to drive
us all nutty (not hard...), but doesn't help. I think internally the chip
doesn't actually care much about the 'frame' time, just about the two
different pulse lengths for 1 and 0. So anything with about 300nSec high
is a '0', and double this high is a '1'.
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