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));
}
}
}
}