Skip to content

Commit cf3887b

Browse files
authored
Added support for WS2815B (dotnet#1800)
* Introduced color mode, added support for WS2815B * Revamped the sample * Changed sample * Fixed namespace * Updated Readme * Removed YouTube-Link * Added copyright headers * Removed color mode, added derivation of BitmapImageNeo3 for RGB-format * Added new commented line that shows that the initialization of Ws2815b is identical to the other strips * Broken up the menu output for better readability * Moved properties (back) to protected const fields
1 parent 3ded70b commit cf3887b

File tree

13 files changed

+766
-359
lines changed

13 files changed

+766
-359
lines changed

src/devices/Ws28xx/BitmapImageNeo3.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77
namespace Iot.Device.Ws28xx
88
{
99
/// <summary>
10-
/// Special 24bit RGB format for Neo pixel LEDs where each bit is converted to 3 bits.
10+
/// Special 24bit GRB format for Neo pixel LEDs where each bit is converted to 3 bits.
1111
/// A one is converted to 110, a zero is converted to 100.
1212
/// </summary>
1313
internal class BitmapImageNeo3 : BitmapImage
1414
{
15-
private const int BytesPerComponent = 3;
16-
private const int BytesPerPixel = BytesPerComponent * 3;
1715
// The Neo Pixels require a 50us delay (all zeros) after. Since Spi freq is not exactly
1816
// as requested 100us is used here with good practical results. 100us @ 2.4Mbps and 8bit
1917
// data means we have to add 30 bytes of zero padding.
2018
private const int ResetDelayInBytes = 30;
2119

20+
protected const int BytesPerComponent = 3;
21+
protected const int BytesPerPixel = BytesPerComponent * 3;
22+
2223
public BitmapImageNeo3(int width, int height)
2324
: base(new byte[width * height * BytesPerPixel + ResetDelayInBytes], width, height, width * BytesPerPixel)
2425
{
@@ -38,7 +39,8 @@ public override void SetPixel(int x, int y, Color c)
3839
Data[offset++] = _lookup[c.B * BytesPerComponent + 2];
3940
}
4041

41-
private static readonly byte[] _lookup = new byte[256 * BytesPerComponent];
42+
protected static readonly byte[] _lookup = new byte[256 * BytesPerComponent];
43+
4244
static BitmapImageNeo3()
4345
{
4446
for (int i = 0; i < 256; i++)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Drawing;
5+
6+
namespace Iot.Device.Ws28xx
7+
{
8+
/// <summary>
9+
/// Special 24bit RGB format for Neo pixel LEDs where each bit is converted to 3 bits.
10+
/// A one is converted to 110, a zero is converted to 100.
11+
/// </summary>
12+
/// <seealso cref="Iot.Device.Ws28xx.BitmapImageNeo3" />
13+
internal class BitmapImageNeo3Rgb : BitmapImageNeo3
14+
{
15+
public BitmapImageNeo3Rgb(int width, int height)
16+
: base(width, height)
17+
{
18+
}
19+
20+
public override void SetPixel(int x, int y, Color c)
21+
{
22+
var offset = y * Stride + x * BytesPerPixel;
23+
Data[offset++] = _lookup[c.R * BytesPerComponent + 0];
24+
Data[offset++] = _lookup[c.R * BytesPerComponent + 1];
25+
Data[offset++] = _lookup[c.R * BytesPerComponent + 2];
26+
Data[offset++] = _lookup[c.G * BytesPerComponent + 0];
27+
Data[offset++] = _lookup[c.G * BytesPerComponent + 1];
28+
Data[offset++] = _lookup[c.G * BytesPerComponent + 2];
29+
Data[offset++] = _lookup[c.B * BytesPerComponent + 0];
30+
Data[offset++] = _lookup[c.B * BytesPerComponent + 1];
31+
Data[offset++] = _lookup[c.B * BytesPerComponent + 2];
32+
}
33+
}
34+
}

src/devices/Ws28xx/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
This binding allows you to update the RGB LEDs on Ws28xx / SK6812 and based strips and matrices.
44

5-
To see how to use the binding in code, see the [sample](samples/Ws28xx_Samples/Program.cs).
5+
To see how to use the binding in code, see the [sample](samples/LEDStripSample/Program.cs).
66

77
## Documentation
88

99
* WS2812B: [Datasheet](https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf)
10+
* WS2815B: [Datasheet](http://www.world-semi.com/DownLoadFile/138)
1011
* WS2808: [Datasheet](https://datasheetspdf.com/pdf-file/806051/Worldsemi/WS2801/1)
1112
* SK6812: [Datasheet](https://cdn-shop.adafruit.com/product-files/2757/p2757_SK6812RGBW_REV01.pdf)
1213
* [Neo pixels guide](https://learn.adafruit.com/adafruit-neopixel-uberguide)
@@ -46,6 +47,7 @@ using SpiDevice spi = SpiDevice.Create(settings);
4647

4748
Ws28xx neo = new Ws2808(spi, count);
4849
// Ws28xx neo = new Ws2812b(spi, Count);
50+
// Ws2815b neo = new Ws2815b(spi, ledCount);
4951
5052
while (true)
5153
{

src/devices/Ws28xx/Ws2815B.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Device.Spi;
5+
6+
namespace Iot.Device.Ws28xx
7+
{
8+
/// <summary>
9+
/// Represents WS2815B LED driver
10+
/// </summary>
11+
public class Ws2815b : Ws28xx
12+
{
13+
/// <summary>
14+
/// Constructs Ws2815b instance
15+
/// </summary>
16+
/// <remarks>In contrast to <see cref="Ws2812b"/> this constructor changes the order of the color values.</remarks>
17+
/// <param name="spiDevice">SPI device used for communication with the LED driver</param>
18+
/// <param name="width">Width of the screen or LED strip</param>
19+
/// <param name="height">Height of the screen or LED strip. Defaults to 1 (LED strip).</param>
20+
public Ws2815b(SpiDevice spiDevice, int width, int height = 1)
21+
: base(spiDevice, new BitmapImageNeo3Rgb(width, height))
22+
{
23+
}
24+
}
25+
}

src/devices/Ws28xx/Ws28xx.sln

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 16
4-
VisualStudioVersion = 16.0.31729.503
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.32112.339
55
MinimumVisualStudioVersion = 15.0.26124.0
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B2C3D1C3-4F59-4544-982C-E205F522DF27}"
77
EndProject
8-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ws28xx.Samples", "samples\Ws28xx_Samples\Ws28xx.Samples.csproj", "{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}"
9-
EndProject
108
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ws28xx", "Ws28xx.csproj", "{D909238E-13C4-45C4-B044-CCBB08B51647}"
119
EndProject
12-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sk6812.Samples", "samples\Sk6812_Samples\Sk6812.Samples.csproj", "{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}"
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LEDStripSample", "samples\LEDStripSample\LEDStripSample.csproj", "{C76432A3-D59A-44FF-B138-298E7B988615}"
1311
EndProject
1412
Global
1513
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,18 +19,6 @@ Global
2119
Release|x86 = Release|x86
2220
EndGlobalSection
2321
GlobalSection(ProjectConfigurationPlatforms) = postSolution
24-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
25-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
26-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Debug|x64.ActiveCfg = Debug|Any CPU
27-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Debug|x64.Build.0 = Debug|Any CPU
28-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Debug|x86.ActiveCfg = Debug|Any CPU
29-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Debug|x86.Build.0 = Debug|Any CPU
30-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
31-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Release|Any CPU.Build.0 = Release|Any CPU
32-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Release|x64.ActiveCfg = Release|Any CPU
33-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Release|x64.Build.0 = Release|Any CPU
34-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Release|x86.ActiveCfg = Release|Any CPU
35-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED}.Release|x86.Build.0 = Release|Any CPU
3622
{D909238E-13C4-45C4-B044-CCBB08B51647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3723
{D909238E-13C4-45C4-B044-CCBB08B51647}.Debug|Any CPU.Build.0 = Debug|Any CPU
3824
{D909238E-13C4-45C4-B044-CCBB08B51647}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -45,25 +31,24 @@ Global
4531
{D909238E-13C4-45C4-B044-CCBB08B51647}.Release|x64.Build.0 = Release|Any CPU
4632
{D909238E-13C4-45C4-B044-CCBB08B51647}.Release|x86.ActiveCfg = Release|Any CPU
4733
{D909238E-13C4-45C4-B044-CCBB08B51647}.Release|x86.Build.0 = Release|Any CPU
48-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Debug|Any CPU.Build.0 = Debug|Any CPU
50-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Debug|x64.ActiveCfg = Debug|Any CPU
51-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Debug|x64.Build.0 = Debug|Any CPU
52-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Debug|x86.ActiveCfg = Debug|Any CPU
53-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Debug|x86.Build.0 = Debug|Any CPU
54-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Release|Any CPU.ActiveCfg = Release|Any CPU
55-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Release|Any CPU.Build.0 = Release|Any CPU
56-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Release|x64.ActiveCfg = Release|Any CPU
57-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Release|x64.Build.0 = Release|Any CPU
58-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Release|x86.ActiveCfg = Release|Any CPU
59-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192}.Release|x86.Build.0 = Release|Any CPU
34+
{C76432A3-D59A-44FF-B138-298E7B988615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{C76432A3-D59A-44FF-B138-298E7B988615}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{C76432A3-D59A-44FF-B138-298E7B988615}.Debug|x64.ActiveCfg = Debug|Any CPU
37+
{C76432A3-D59A-44FF-B138-298E7B988615}.Debug|x64.Build.0 = Debug|Any CPU
38+
{C76432A3-D59A-44FF-B138-298E7B988615}.Debug|x86.ActiveCfg = Debug|Any CPU
39+
{C76432A3-D59A-44FF-B138-298E7B988615}.Debug|x86.Build.0 = Debug|Any CPU
40+
{C76432A3-D59A-44FF-B138-298E7B988615}.Release|Any CPU.ActiveCfg = Release|Any CPU
41+
{C76432A3-D59A-44FF-B138-298E7B988615}.Release|Any CPU.Build.0 = Release|Any CPU
42+
{C76432A3-D59A-44FF-B138-298E7B988615}.Release|x64.ActiveCfg = Release|Any CPU
43+
{C76432A3-D59A-44FF-B138-298E7B988615}.Release|x64.Build.0 = Release|Any CPU
44+
{C76432A3-D59A-44FF-B138-298E7B988615}.Release|x86.ActiveCfg = Release|Any CPU
45+
{C76432A3-D59A-44FF-B138-298E7B988615}.Release|x86.Build.0 = Release|Any CPU
6046
EndGlobalSection
6147
GlobalSection(SolutionProperties) = preSolution
6248
HideSolutionNode = FALSE
6349
EndGlobalSection
6450
GlobalSection(NestedProjects) = preSolution
65-
{D97F0DC4-777E-4F1A-BF18-A63DA22707ED} = {B2C3D1C3-4F59-4544-982C-E205F522DF27}
66-
{76D2B9B1-CBDE-445C-BE6D-B5C5C1754192} = {B2C3D1C3-4F59-4544-982C-E205F522DF27}
51+
{C76432A3-D59A-44FF-B138-298E7B988615} = {B2C3D1C3-4F59-4544-982C-E205F522DF27}
6752
EndGlobalSection
6853
GlobalSection(ExtensibilityGlobals) = postSolution
6954
SolutionGuid = {F452F127-C7D8-4D14-9484-B23E8F0C3468}

0 commit comments

Comments
 (0)