Hi! Wow...this thread is still active?? Haha.
Unfortunately, I had some more trouble with the Netduino chip and ultimately wound up switching to a different device for control.
BUT!
I still have my last working code. Here you go-it was written in C# for a WS8201.
Good luck!
using System; using System.IO; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.NetduinoMini; namespace NetduinoMiniApplication1 { public class Program { static UInt16 numLEDs; static SPI.Configuration xSPIConfig; static SPI xspi; static byte[] colors; static byte[] zeroes; static byte[] attentionSequence = new byte[] { 0, 0, 0, 0 }; static int numChannelsPerPixel = 3; static void writeColors() { xspi.Write(colors); } static void writezeros(int n) { while (n>0) { xspi.Write(zeroes); n--; } } //Order is R (0), G (1), B (2). static byte[] getRGBChannelsFromColor(UInt32 color) { byte[] buffer = new byte[numChannelsPerPixel]; buffer[0]=(byte)((color >> 16) | 0x80);//g buffer[1]=(byte)((color >> 8) | 0x80);//r buffer[2] = (byte)(color | 0x80);//b return buffer; } static void setPixelColor(UInt16 n, UInt32 c) { if (n >= numLEDs) return; // '>=' because arrays are 0-indexed colors[n*numChannelsPerPixel] = (byte)((c >> 16) | 0x80);//g colors[n * numChannelsPerPixel + 1] = (byte)((c >> 8) | 0x80);//r colors[n * numChannelsPerPixel + 2] = (byte) (c | 0x80);//b } static void setPixelColor(UInt16 n, byte r, byte g, byte b) { if (n >= numLEDs) return; // '>=' because arrays are 0-indexed colors[n * numChannelsPerPixel] = (byte)(g | 0x80); colors[n * numChannelsPerPixel + 1] = (byte)(r | 0x80); colors[n * numChannelsPerPixel + 2] = (byte)(b | 0x80); } //Used to send command to change color. static void latch() { //writezeros(1); xspi.Write(zeroes); } static void clearColorArrayValues() { for (UInt16 i = 0; i < colors.Length; ++i) { colors[i] = (byte)0x80 | 0; //Debug.Print("colors[i]=" + colors[i]); } writeColors(); latch(); } static void doPulseTransition(UInt32[] pulse_colors) { clearColorArrayValues(); for (byte j = 0; j < pulse_colors.Length; j++) { for (byte i = 0; i < numLEDs; ++i) { setPixelColor(i, pulse_colors[j]); //j } writeColors(); //Send latch so can write. latch(); //writezeros(numLEDs); //Thread.Sleep(5000 / numLEDs); } } //Algorithm: break each color down into RGB components, then decrement/increment each channel value until it matches the destination RGB value. static void doPulseTransition(UInt32 initial_color, UInt32 final_color, int refresh) { clearColorArrayValues(); UInt32 a, b, i, tmp_color; a = initial_color; b = final_color; byte[] initial_rgb = getRGBChannelsFromColor(initial_color); byte[] final_rgb = getRGBChannelsFromColor(final_color); for (i=0; i<numChannelsPerPixel; i++) { while (initial_rgb[i] != final_rgb[i]) { if (initial_rgb[i] < final_rgb[i]) { initial_rgb[i]++; } else if (initial_rgb[i] > final_rgb[i]) { initial_rgb[i]--; } tmp_color = RgbToColor(initial_rgb[1], initial_rgb[0], initial_rgb[2]); setColor(tmp_color,refresh); } } } static void setColor(UInt32 col) { for (byte i = 0; i < numLEDs; ++i) { setPixelColor(i, col); } writeColors(); Refresh(); } static void setColor(UInt32 col, int refreshInMS) { for (byte i = 0; i < numLEDs; ++i) { setPixelColor(i, col); } writeColors(); Refresh(refreshInMS); } static void initializeZeroArray() { for (byte j = 0; j < zeroes.Length; j++) { zeroes[j] = 0x00; } } static void reset() { for (byte j = 0; j < colors.Length; j++) { colors[j] = 0x00; } } static void clearALLLEDs() { clearColorArrayValues(); Refresh(); } static UInt32 RgbToColor(byte r, byte g, byte b) { // Take the lowest 7 bits of each value 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! UInt32 color; color = (UInt32)(g | 0x80); color <<= 8; color |= (UInt32)(r | 0x80); color <<= 8; color |= (UInt32)(b | 0x80); return color; } static void Refresh() { xspi.Write(attentionSequence); xspi.Write(colors); var ledLatchCount = numLEDs * 2; for (var i = 0; i < ledLatchCount; i++) { latch(); } //Need to wait a little after setting to allow values to go all the way down. //TODO: consider adding a value to function that accepts how long to wait. If it is not specified, use a default value. 500-1000ms work. Try to find 30<x<500 such that change is //not too quick Thread.Sleep(500);// } static void Refresh(int waitInMS) { xspi.Write(attentionSequence); xspi.Write(colors); var ledLatchCount = numLEDs * 2; for (var i = 0; i < ledLatchCount; i++) { latch(); } //Need to wait a little after setting to allow values to go all the way down. //TODO: consider adding a value to function that accepts how long to wait. If it is not specified, use a default value. 500-1000ms work. Try to find 30<x<500 such that change is //not too quick Thread.Sleep(waitInMS);// } public static void Main() { numLEDs = 32; xSPIConfig = new SPI.Configuration(Cpu.Pin.GPIO_NONE, false, 0, 0, false, true, 20000, SPI.SPI_module.SPI1); /* * public SPI.Configuration ( Pin ChipSelect_Port, bool ChipSelect_ActiveState, UInt16 ChipSelect_SetupTime, UInt16 ChipSelect_HoldTime, bool Clock_IdleState, bool Clock_Edge, UInt16 Clock_Rate, SPI_module SPI_mod )*/ xspi = new SPI(xSPIConfig); zeroes = new byte[numChannelsPerPixel * ((numLEDs + 63) / 64)]; colors = new byte[numChannelsPerPixel * numLEDs]; //0x00FF0000=Green, 0x000000FF=Blue, 0x0000FF00=Red UInt32[] pulse_cols = { 0x000000FF, 0x0000FF00, 0x00FF0000 }; Debug.Print("Zeroes length=" + zeroes.Length); reset(); initializeZeroArray(); while (true) { doPulseTransition(RgbToColor(0, 0, 255), RgbToColor(0, 255, 0),2); doPulseTransition(RgbToColor(0, 255, 0),RgbToColor(255, 0, 0),2); setColor(RgbToColor(255, 0, 0)); setColor(RgbToColor(0, 255, 0)); setColor(RgbToColor(0, 0, 255)); } } } }