Help using SHIFTOUT with 14m2 (to drive a WS2803 chip)

Hi all.
I am working on an RGB led project and I am trying to get a picaxe talking to a WS2803 chip.
I know on this forum there is a lot of information and code for the WS2801 chip, but I haven't had any success learning or transferring any of that knowledge to this.
I am very new at understanding communicating between chips and things such as spi and i2c.


I got this chip working with an arduino which uses a shiftout command: shiftOut(ws2803_dataPin, ws2803_clockPin, MSBFIRST, "value from 0-255");
With this code, I am able to pwm individual leds on each output pin.

So I went ahead and bought some 14m2 chips thinking they supported the SHIFTOUT command, however I just found out they don't :(

Doing a bit of research, I found that you can achieve spi if you do it manually (like in code examples 2 and 3 on the SHIFTOUT command page), however the several lines of code that it takes to achieve the same as the shiftout command (which I only understand because it is relatively similar to the arduino's) look gibberish to me.


Here is my arduino code that I am trying to convert to the picaxe. All it is is a simple led chaser that goes through each pin over and over again: View attachment arduino led chaser WS2803.txt


And at the bottom is my attempt at converting the code to picaxe. Obviously it doesn't work because the 14m2 doesnt support shiftout.



So if someone could please help me out with this I would really appreciate it. All I need is to get some very basic led control and I should be fine figuring out the rest (i.e. pwm for rgb to achieve colors etc...)

also just as a side note, I don't understand what LSB and MSB mean, so if someone has a good quick explination or a useful link that will make sense to a beginner like me, it would be really appreciated as well.

Cheers
 

Attachments

westaust55

Moderator
I has posted a "getting started with the WS2801" which has the code you need. There are also other threads for the WS 2801 and I recall at least one thread using my code as a starting point for the WS 2803 that was working.

Try a forum search for my information.
 
I know, I feel bad because I have tried all of it but can't get it working with the ws2803. Seriously I tried like all the versions of your code on the 14m2 and the 08m2 and got nothing.
And i know everything is connected properly because it works perfectly with the arduino. (i.e. all the grounds are connected, clock and data pins are correct etc..)
Any advice?

I'm sure there are easy and obvious changes from your ws2801 code to what i need, but I just don't have the knowledge on how to do that at this point.
In the meantime, I am trying my best to figure it out, but a nudge in the right direction would save me a lot of time.
 

westaust55

Moderator
I am not home to work through in detail but your code is far from complete compared to my WS2801 code.

Commands such as SHIFTOUT are only available on X1 and X2 parts. For the M2 parts you need subroutines.
You are only sending 1 byte = 8 bits but you need to rapidly send 18 bits for full control.
From memory you will also need to increase the clock speed (to 8 or 16 MHz) for the data transfer rate to match the WS280x series chips.

Suggest read this thread:
http://www.picaxeforum.co.uk/showthread.php?23145-WS2803&highlight=Ws2803
Where a WS2803 was working with minor mods to my WS2801 code example.
 
Last edited:

Bill.b

Senior Member
This is a test code I used to send data to two ws2803 chips

It is a modified version of westaust55's code for the ws2801.

Code:
'Robot RGB LED and Piezo Control.
#PICAXE 18M2
SETFREQ M32

; -----[ I/O Definitions ]-------------------------------------------------- 

; - - - DIGITAL INPUT PINS  - - -
; pinsc - digital address from main processor
; - - - DIGITAL OUTPUT PINS - - - 

SYMBOL SData	= pinc.0 ; SDI Pin on WS2801 - used to transfer 1 bit of data to a pin
SYMBOL S_Data	= c.0 ; SDI Pin	- also defined this way to use with the LOW command in Init:
SYMBOL SClock	= c.1 ; CKI Pin on WS2801


; -----[ Constants ]-------------------------------------------------------

SYMBOL TotalMods	= 12   
SYMBOL Data_Sets	= 4
SYMBOL SeqStep_Delay = 500 ; 
SYMBOL DataBaseAddr = $80

; -----[ Variables ]-------------------------------------------------------

SYMBOL LED_Data	= b0 ; NOTE: - this must be b0 for SendData sub routine to work
SYMBOL DataTransf	= b1
SYMBOL No_LEDs	= b2
SYMBOL CycleLen	= b3
SYMBOL MemAddr 	= b4
SYMBOL Cntr		= b5
SYMBOL AllSent 	= b6
symbol data3	= b7
symbol Datain	= b8
symbol Piezodata	= b9



	Low S_Data		; by using LOW command we automatically  also set the pin as an output
	Low Sclock		; by using LOW command we automatically  also set the pin as an output
	MemAddr = 0		; set the EEPROM data pointer to the first location
	No_LEDs = 3 * TotalMods	      ; calculate the total number of individual LED channels
	AllSent = DataBaseAddr + No_LEDs  ; the upper RAM location for M2 RAM "scratchpad" area
	CycleLen = No_LEDs * Data_Sets      ; calculate the number of bytes of EEPROM data in the cycle
;
; -----[ Program Code ]----------------------------------------------------
b7 =0

  FetchColour:
B14=0
  	bptr = DataBaseAddr
  	high b.0
  DO
  '
  	lookup b14,($ff,$ff,$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$00,$ff,$ff,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$ff,$ff,$ff,$00),led_data
	; Fetch the Red component of the specified colour
	@bPtrInc = LED_Data

	B14=B14+1
	LOOP UNTIL B14 > 36
	GOSUB SendData

	PAUSE SeqStep_Delay
	B14=0
	
	low b.0
	  	bptr = DataBaseAddr
  	high b.1
  DO
  '
  	lookup b14,($00,$00,$00,$FF,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$00,$00,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00),led_data
	; Fetch the Red component of the specified colour
	@bPtrInc = LED_Data

	B14=B14+1
	LOOP UNTIL B14 > 36
	GOSUB SendData

	PAUSE SeqStep_Delay
	B14=0
	
	low b.1

	goto FetchColour
; -----[ Subroutines ]----------------------------------------------------- 
;


;
; Subroutine to serially clock out the data through the SW2801 chips for the RGB LEDs

SendData:	
	bptr = DataBaseAddr			; set the RAM start location for RGB LED string data
	DO
		LED_Data = @bptrinc		; load the data into b0 so we can extract each bit quickly
		SData = bit7 : PulsOut SClock, 1	; msb first to the data pin and clock out
		SData = bit6 : PulsOut SClock, 1
		SData = bit5 : PulsOut SClock, 1
		SData = bit4 : PulsOut SClock, 1
		SData = bit3 : PulsOut SClock, 1
		SData = bit2 : PulsOut SClock, 1
		SData = bit1 : PulsOut SClock, 1
		SData = bit0 : PulsOut SClock, 1	; lsb of the current data byte to be clocked out
	LOOP UNTIL bptr = AllSent
'	pause 100		; continue until all data is sent for all RGB LEDs in string
	RETURN
Bill
 

hippy

Technical Support
Staff member
The key feature for WS2801 and WS2803 is that the data must be clocked out such that there is never a long time between data clocks. If this time exceed 500us or so then the WS2801 or WS2803 will timeout and reset, the next data will be taken as data for the first LED of the strip.

In getting things to work with a WS2801 or WS2803, the best starting place is code which will just control the first LED, or to take code which is known to work which fades or switches LED's of its own accord. There should be a number of examples of those in the forum, and a few of those are cited and linked to in this thread.

If those programs do not work then the question must be "why not" ? That should be investigated because it will likely be no better creating any other code which does similar as that would almost certainly suffer the same fate of not working.

My plan would be; get code for controlling the first LED working, extend that to controlling multiple LED's, ensure that can control first and last LED's, use that as the basis of the control you want to have.

Also; if someone can say what the differences are between WS2803 and WS2801 that would help people who are only familiar with one or the other, or neither but are willing to try and help.
 
Top