|
|
View previous topic :: View next topic |
Author |
Message |
acidice333
Joined: 14 Oct 2006 Posts: 33
|
ws2801 driver? |
Posted: Thu Jan 26, 2012 9:29 pm |
|
|
Does anybody have a driver?
I'm trying to get my ws2801 to work but I don't know if its my hardware or attempt at a driver.
http://www.sparkfun.com/products/10504 |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Jan 27, 2012 9:05 am |
|
|
Hi,
Did you look at the example code on the Sparkfun website? It's written for the Arduino, but it looks easy enough to convert to CCS 'C'. It appears like that example code is just 'bit banging' the data into the chip, so it's just some simple digital I/O.
I've done a lot of work with the 'ShiftBrite' RGB LED's, but not this one.
John |
|
|
acidice333
Joined: 14 Oct 2006 Posts: 33
|
|
Posted: Fri Jan 27, 2012 4:39 pm |
|
|
Yeah I looked at that one and the one from adafruit.
I converted the LPD8806 (bitbang) from adafruit and that worked but I can't seem to get the ws2801 working.
Looking at both drivers from adafruit, they look pretty similar so I just jolted it down and I cant get it to work. Altho I only have one to work with right now, ordered another from sparkfun just incase this one was a dud.
adafruit's drivers are both similar.. particularly the show()
https://github.com/adafruit/LPD8806/blob/master/LPD8806.cpp
https://github.com/adafruit/WS2801-Library/blob/master/WS2801.cpp
Here's what I got..
Code: |
#define WS2801_DATA PIN_c1 // da
#define WS2801_CLOCK PIN_c2 // cl
#define WS2801_LEDS 1 //
int8 numLEDs = WS2801_LEDS;
#INCLUDE <stdlibm.h> // needed for malloc
void WS2801_Init(void);
void show(void);
int8 *pixels;
void WS2801_Init(void) {
pixels=malloc(numLEDs*3); // allocates 3bytes per pixel
memset(pixels,0x80,numLEDs*3); // init to RGB 'off' state
}
void show(void) {
int16 i;
int16 nl3 = numLEDs * 3; // 3 bytes per LED
int8 bit=0x80;
for (i=0; i<nl3; i++) {
for (bit=0x80; bit; bit>>=1 ) {
if (pixels[i] & bit) output_high(WS2801_DATA);
else output_low(WS2801_DATA);
output_high(WS2801_CLOCK);
output_low(WS2801_CLOCK);
}
}
delay_ms(1);
}
// Convert R,G,B to combined 32-bit color
int32 color(int8 r, int8 g, int8 b) {
// take the lowest 7 bits of each alue and append them end to end
// we have the top bit set high (its a 'parity-like' bit in the protocol
// and must be set!)
return 0x808080 | ((int32)g<<16) | ((int32)r<<8) | ((int32)b);
}
// store the rgb component in our array
void setPixelColor(int16 n, int8 r, int8 g, int8 b) {
if (n<numLEDs) { //arrays are 0-indexed, thus not '<='
int8 *p = &pixels[n*3];
*p++ = r;
*p++ = g;
*p++ = b;
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Mar 13, 2013 2:39 pm |
|
|
Just to update this thread...
I've managed to talk to them using SPI now I need some 'real' reason to use them.
Neat, cheap 'RGB pixels'. |
|
|
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Sun Aug 11, 2013 7:07 pm |
|
|
hey temtronic, may you share your library?
bye |
|
|
thefloyd
Joined: 02 Sep 2009 Posts: 46
|
WS2801 code |
Posted: Thu Aug 15, 2013 8:57 pm |
|
|
I use standard SPI to write to my WS2801 strips. A 4mhz SPI clock works fine.
There isn't much to these, you just need to spi_write() your rgb values times number of pixels on the strip, then pause for at least 500us when you're done to latch the data. Something like:
Code: |
for(i=0;i<160;i++) {
spi_write(0xFF);
spi_write(0x00);
spi_write(0x00);
}
delay_us(500);
|
.. would light up 160 pixels (a standard 5M roll of 32 LED/m WS2801 strip) all red.
An ugly/first-hack example that does a bit more is at: http://www.insomnialighting.com/code/ws2801.c - note this example worked with a strip that accepted data in a funky order (BGR instead of RGB).
If I find time tomorrow or this weekend I'll try and write a clean program and post it here. |
|
|
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Fri Aug 16, 2013 3:03 am |
|
|
Thanks thefloyd for all the info.
I will taka a look at the above link.
bye |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Aug 16, 2013 6:22 am |
|
|
here's a version I cut long time ago...
not pretty but it did work...
Code: | //46k22_ws2801_2.c
//46k22 ws2801 8 LED test code
// working blu-grn-red-yel-vio-tel-bnk-wht
#include <18f46k22.h>
#include "46k22_fuses.h"
#include "46k22_pins.h"
#use delay(clock=16000000)
#use rs232(baud=9600,xmit=SIO_TX1,rcv=SIO_RX1,errors,stream=SIOport)
#use rs232(baud=9600,xmit=SIO_TX2,rcv=SIO_RX2,errors,stream=USBport)
#include "46k22_LCD.c"
#include "jay_DS1307.c"
#USE SPI (MASTER, SPI1, MODE=0, BITS=8, STREAM=SPI_1, MSB_FIRST)
#define LED_STRIP_LEN 8 // number of LEDs on the strip
#define RAND_MAX 255
unsigned int32 led_strip_colors[LED_STRIP_LEN];
void send_frame() {
unsigned int16 i;
unsigned int8 red,green,blue;
for(i=0;i<LED_STRIP_LEN;i++) {
blue = led_strip_colors[i] & 0xFF;
green = (led_strip_colors[i] >> 8) & 0xFF;
red = (led_strip_colors[i] >> 16) & 0xFF;
spi_write(red);
spi_write(green);
spi_write(blue);
}
delay_us(500); // delay 500us to latch the IC
}
void main()
{
unsigned int16 i;
unsigned int16 x;
lcd_init();
delay_ms(500);
printf(lcd_putc,"WS2801 test 1");
delay_ms(500);
while(true){
for(i = 0 ; i < LED_STRIP_LEN ; i++) {led_strip_colors[i] = 0;}
led_strip_colors[0] = 0xFF0000; // red
led_strip_colors[1] = 0x00FF00; // green
led_strip_colors[2] = 0x0000FF; // blue
led_strip_colors[3] = 0x00FFFF; // green + blue
led_strip_colors[4] = 0xFF00FF; // red + blue (purple)
led_strip_colors[5] = 0xFFFF00; // red + green (org)
led_strip_colors[6] = 0x000000; // off + off + off
led_strip_colors[7] = 0xFFFFFF; // red + green + blue (white)
send_frame();
delay_ms(500);
lcd_gotoxy(2,2);
printf(lcd_putc,"%lu pass",x);
x=x+1;
}// forever while loop
}// end of main
|
jay |
|
|
matheuslps
Joined: 29 Sep 2010 Posts: 73 Location: Brazil
|
|
Posted: Fri Aug 16, 2013 9:38 am |
|
|
temtronic and thefloyd
How did you discover that hex codes for the colors?
bye |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Aug 16, 2013 1:00 pm |
|
|
'Somewhere' I downloaded the ws2801 datasheet..giving me the order of the data ( R,G,B) in this case.
0x00 is off
0xFF is full on
of the colour chosen
You can download an RGB color wheel of the web...to see what combinations give which colour.
I know R+B make Purple( Violet), and R+G+B make white.
The 'shade' or intensity is determined by the values selected.
There's probably a few 'RGB LED color selection' programs on the web, I just never bothered to look..
I do remember planning on using 4 bytes for 'pixel data'. One byte the address of the pixel, then the next 3 for the RGB data.I allows very effcient use of code space as well as using the CCS SPI function for tight code ! It was a 'work-in-progress' then other things came up.....
hth
jay |
|
|
ali 2020
Joined: 18 Apr 2013 Posts: 2
|
driver for ws2801 |
Posted: Mon Nov 19, 2018 6:56 am |
|
|
hi
I need to run 15 ws2801 in serial mode.
My program work with 1 and 2 and 3 ws2801
but more than 3 ws2801 not work correct.
I use spi mode for running this ic.
My code is that
Code: | #include <18f66k80.h>
#USE SPI (MASTER, CLK=PIN_C3, Do=PIN_C5, MODE=3, BITS=24, STREAM=coin , LSB_FIRST)
#define leng 15
unsigned int i=0,j=0;
void main()
{ port_c_pullups(0xFF);
while (1)
{
for (i=0;i<leng;i++){
SPI_XFER(coin,0xFFFFFFFF);
}
output_d(0xf0);
delay_ms(1500);
for (i=0;i<leng;i++){
SPI_XFER(coin, 0xFFFFFF00 );
}
output_d(0x0f);
delay_ms(1500);
for (i=0;i<leng;i++){
SPI_XFER(coin, 0xFFFF00FF );
}
output_d(0b10101010);
delay_ms(1500);
for (i=0;i<leng;i++){
SPI_XFER(coin, 0xFF00FFFF );
}
output_d(0b01010101);
delay_ms(1500);
}} |
anybody can help me? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Nov 19, 2018 7:59 am |
|
|
OK...some points..
1) you setup ( # USE SPI) for 24 bits..that's 3 bytes BUT you send 4 bytes ( 32 bits). ALso I used mode 0 not mode 3...
2) since 3 modules work, try 4, confirm if it works NOT 15 modules.
3) you should use names for the colors, as I have done, otherwise it's very difficult to KNOW which LED is supposed to be what color. It also make troubleshooting for us a lot easier !
I suspect your datastream of bits is incorrect however I don't see a PIC clock speed ! Either you didn't post your complete program or the PIC is running at some 'failsafe' speed. I've never used that PIC but some newer ones do have a failsafe oscillator.
It's been 5 years since I last posted my working code in this thread,so I'm a bit rusty when it comes to this device. I do KNOW my code worked back then. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Nov 19, 2018 8:03 am |
|
|
He is also sending LSB first. Again different from the working driver... |
|
|
ali 2020
Joined: 18 Apr 2013 Posts: 2
|
driver for ws2801 |
Posted: Mon Nov 19, 2018 9:28 am |
|
|
thanks for your answer
1/ in this case : Quote: | you setup ( # USE SPI) for 24 bits..that's 3 bytes BUT you send 4 bytes ( 32 bits). ALso I used mode 0 not mode 3... |
only transmitted 24 bit and 8 bit not transmitted so can i use this code even
Code: | SPI_XFER(coin, 0xFFFF00 ); |
and in mode 0 my circuit not work but in mode 3 is work
Code: |
#include <18F66K80.h>
#device ADC=16
#FUSES VREGSLEEP_SW //Ultra low-power regulator is enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES BORV30 //Brownout reset at 3.0V
#FUSES PROTECT //Code protected from reads
#FUSES CPB //Boot Block Code Protected
#FUSES WRT //Program Memory Write Protected
#FUSES WRTC //Configuration registers write protected
#FUSES WRTB //Boot block write protected
#FUSES EBTR //Memory protected from table reads
#FUSES EBTRB //Boot block protected from table reads
#use delay(clock=16MHz,crystal=16MHz)
#use rs232(baud=9600,parity=N,xmit=PIN_G3,rcv=PIN_G0,bits=8,stream=PORT1)
#use rs232(baud=9600,parity=N,xmit=PIN_E7,rcv=PIN_E6,bits=8,stream=PORT2) |
2/ in this case
Quote: | 2) since 3 modules work, try 4, confirm if it works NOT 15 modules. |
my code work in 3 ws2801 properly , but more than 3 not work even i chose leng=4
3/ this code is simple and that is for test and not complicated
ever 8 bit is for one color for sample :
Code: | 0xffffff //! means all color is off
0xffff00 //! that means 2 color off and 1 color on |
4/ Quote: | He is also sending LSB first. Again different from the working driver... |
this is not problem because in this case color be changed and not matter
excuse me for my bad English writing |
|
|
|
|
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
|