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

ws2801 driver?

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



Joined: 14 Oct 2006
Posts: 33

View user's profile Send private message

ws2801 driver?
PostPosted: Thu Jan 26, 2012 9:29 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 27, 2012 9:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jan 27, 2012 4:39 pm     Reply with quote

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: 9099
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Mar 13, 2013 2:39 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Sun Aug 11, 2013 7:07 pm     Reply with quote

hey temtronic, may you share your library?

bye
thefloyd



Joined: 02 Sep 2009
Posts: 46

View user's profile Send private message

WS2801 code
PostPosted: Thu Aug 15, 2013 8:57 pm     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Fri Aug 16, 2013 3:03 am     Reply with quote

Thanks thefloyd for all the info.

I will taka a look at the above link.

bye
temtronic



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

View user's profile Send private message

PostPosted: Fri Aug 16, 2013 6:22 am     Reply with quote

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

View user's profile Send private message MSN Messenger

PostPosted: Fri Aug 16, 2013 9:38 am     Reply with quote

temtronic and thefloyd

How did you discover that hex codes for the colors?

bye
temtronic



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

View user's profile Send private message

PostPosted: Fri Aug 16, 2013 1:00 pm     Reply with quote

'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

View user's profile Send private message

driver for ws2801
PostPosted: Mon Nov 19, 2018 6:56 am     Reply with quote

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: 9099
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Nov 19, 2018 7:59 am     Reply with quote

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: 19216

View user's profile Send private message

PostPosted: Mon Nov 19, 2018 8:03 am     Reply with quote

He is also sending LSB first. Again different from the working driver...
ali 2020



Joined: 18 Apr 2013
Posts: 2

View user's profile Send private message

driver for ws2801
PostPosted: Mon Nov 19, 2018 9:28 am     Reply with quote

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
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