Some quick dirt code in 2 hours to demonstrate using SPI
Works well. The following code moves a purple light arround a 4 meters 240 RGB light string I got from Adafruit. Nothing fancy here, but I’ll clean up the code, add some comments and put it to the CodeShare later. G31VL6hlbgE
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
namespace WS2811_test
{
public class Program
{
public static void Main()
{
WS2811 MyWS2811Strip = new WS2811(240,SPI.SPI_module.SPI2);
Thread.Sleep(2000);
while (true)
{
for (int i = 0; i < 240; i++)
{
if (i > 0) MyWS2811Strip.Set(i - 1, 0, 0, 0, false);
MyWS2811Strip.Set(i, 255, 0, 255);
}
for (int i = 238; i >= 0; i--)
{
MyWS2811Strip.Set(i + 1, 0, 0, 0, false);
MyWS2811Strip.Set(i, 255, 0, 255);
}
}
}
}
public class WS2811 : IDisposable
{
private byte[] _WS2811Table;
private byte[] _WS2811Buffer;
private SPI.Configuration _WS2811SPIConfig;
private SPI _WS2811SPI;
private int _StripLength;
public WS2811(int striplength, SPI.SPI_module SPImodule)
{
_StripLength = striplength;
// Initialize SPI
_WS2811SPIConfig = new SPI.Configuration(Cpu.Pin.GPIO_NONE, false, 0, 0, false, true, 3200, SPImodule);
_WS2811SPI = new SPI(_WS2811SPIConfig);
// SPI Transmit buffer = 4 output byte per color, 3 colors per light
_WS2811Buffer = new byte[4 * 3 * striplength];
// Compute fast byte to SPI lookup table
_WS2811Table = new byte[1024];
for (int i = 0, ptr = 0; i <= 255; i++)
{
for (int j = 6; j >= 0; j -= 2)
{
switch (i >> j & 3)
{
case 0: _WS2811Table[ptr++] = 0x88; break;
case 1: _WS2811Table[ptr++] = 0x8C; break;
case 2: _WS2811Table[ptr++] = 0xC8; break;
case 3: _WS2811Table[ptr++] = 0xCC; break;
}
}
}
//Clear all leds
Clear();
}
public void Dispose()
{
_WS2811Buffer = null;
_WS2811Table = null;
_WS2811SPI.Dispose();
Debug.GC(true);
}
public void SetAll(byte[] BGRBuffer, bool transmit=true)
{
// Transcode
for (int i = 0; i < _StripLength * 3; i++) Array.Copy(_WS2811Table, BGRBuffer[i] << 2, _WS2811Buffer,i << 2, 4);
// Send
if (transmit) _WS2811SPI.Write(_WS2811Buffer);
}
public void Clear (bool transmit=true)
{
// Transcode
for (int i = 0; i < _StripLength * 3; i++) Array.Copy(_WS2811Table, 0, _WS2811Buffer, i << 2, 4);
// Send
if (transmit) _WS2811SPI.Write(_WS2811Buffer);
}
public void Set(int index, byte r, byte g, byte b, bool transmit=true)
{
// Transcode
Array.Copy(_WS2811Table, g << 2, _WS2811Buffer, index * 12, 4);
Array.Copy(_WS2811Table, r << 2, _WS2811Buffer, index * 12 + 4, 4);
Array.Copy(_WS2811Table, b << 2, _WS2811Buffer, index * 12 + 8, 4);
// Send
if (transmit) _WS2811SPI.Write(_WS2811Buffer);
}
public void Transmit()
{
_WS2811SPI.Write(_WS2811Buffer);
}
}
}