|
|
View previous topic :: View next topic |
Author |
Message |
ressas
Joined: 15 Nov 2019 Posts: 135
|
WS2812b and Pic18f46k22 |
Posted: Mon Dec 09, 2019 3:43 pm |
|
|
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();
}
}
| |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Mon Dec 09, 2019 3:46 pm |
|
|
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
|
|
Posted: Mon Dec 09, 2019 4:01 pm |
|
|
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.
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 09, 2019 4:44 pm |
|
|
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
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 10, 2019 5:34 am |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Tue Dec 10, 2019 7:29 am |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Tue Dec 10, 2019 8:57 am |
|
|
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
|
|
Posted: Tue Dec 10, 2019 12:08 pm |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Tue Dec 10, 2019 12:51 pm |
|
|
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
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Dec 10, 2019 1:49 pm |
|
|
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'. |
|
|
|
|
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
|