Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

Previously, we introduced the basics of .NET nanoFramework. In this article, we continue with the example of the Microweather ESP32-S2-Pico to discuss development with .NET nanoFramework: controlling the onboard RGB lights and external RGB lights. The content includes the significance of status lights, WS2812, HSV, PWM, and related knowledge.

1. Background

The first step in ESP32 development is basically to light up the lights, right? Lighting, lighting, lighting… I didn’t expect that this lighting would take me 2 weeks. One reason is that I was quite busy with work, and I only had spare time to work on this. Moreover, it also required searching for and learning various materials because the onboard lights are not that easy to control, and I made some mistakes along the way.

2. The Significance of Status Lights

I am not sure if there is a saying that the first step in ESP32 development is to light up the lights, but the role of the device’s status indicator light is indeed significant. It can provide users with information about the device’s working status. The device status light usually indicates different working states of the device using different colors or flashing frequencies. For example:

Green: The device is working normally.Red: The device has a fault.Yellow: The device is performing an operation, such as upgrading.Flashing: The device is performing an operation, such as data transmission.

The device status light is a very simple and understandable human-computer interaction method, allowing users to quickly understand the working status of the device and take timely action.

Typically, the device status light is located on the outside or front of the device, making it easy for users to view. For example, a router has a red-green light; the green light indicates that the network is normal, while the red light indicates a network issue. Similarly, in some simple small appliances, a red light indicates charging, while the light being off indicates that charging is complete.

3. Onboard LED

The onboard LED hardware of the ESP32-S2-Pico has undergone version modifications, and simply pulling up the GPIO does not light it up.

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

Hardware Changes

By checking the schematic, we can find that the LED is connected to GPIO9, and the circuit for the LED is WS2812B-0807. The schematic for this part is shown below, with only one LED:

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

WS2812B

4. WS2812

4.1 Introduction

WS2812 is a high-performance, low-cost full-color LED strip. It is a series-controlled light, allowing multiple LED lights to be connected together and controlled by serial signals to manage each LED’s color and brightness.

The main features of WS2812 include rich colors, high brightness, high dynamic range, and high precision in color temperature adjustment, enabling 256 levels of gray adjustment.

The control method of WS2812 is through a technique called single-wire control. This control method allows all LED lights to be controlled through a single wire, with each LED light having a built-in controller that can receive and decode the single-wire signal. This allows the controller to control the color and brightness of all LED lights by sending signals through a single wire.

WS2812 has a wide range of applications in many fields, such as LED light strips, LED dot matrix screens, LED tubes, LED rings, etc.

4.2 Control Principle

Each WS2812 LED light has a built-in controller that can receive and decode the single-wire signal. The controller distinguishes different data bits by the timing of high and low levels.

Usually, the color of each LED light consists of three data bits (red, green, blue), with each data bit representing 8 levels of brightness.

When the controller receives the single-wire signal, it first detects a high-level pulse, which is used to synchronize the data. Following this is 24 bits of data, consisting of 8 bits of red data, 8 bits of green data, and 8 bits of blue data. The controller decodes the signal according to this data format and sets the color and brightness of the LED light.

Since the focus of the article varies, here we only provide a simple introduction. Once you understand the principle, you can write your own driver, of course, you need to refer to the relevant hardware manual for a more detailed understanding of the data transmission methods, as the specific timing requirements for different LED communication may vary. Interested readers can look for information and try it themselves.

Principle introduction: https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf

Here we only need to use the already written driver, such as the neopixel library in MicroPython. Of course, .NET nanoFramework also has related libraries: Ws28xx.Esp32.

5. Onboard RGB Control

Here we use the ESP32 WS2812 Driver, code repository: https://github.com/nanoframework/nf-Community-Contributions/tree/master/drivers/ESP32-WS2812, which provides a PixelController helper class to easily implement WS2812 control. You can also understand the implementation of the driver through the source code.

5.1 Simple Color Test

The constructor of PixelController provides three parameters: GPIO, pixel count, and an optional parameter for RGBW light strip control, defaulting to false.

PixelController controller = new PixelController(9, 1);// Simple color testcontroller.SetColor(0,255,0,0);// Redcontroller.UpdatePixels();Thread.Sleep(1000);controller.SetColor(0, 0, 255, 0);// Greenccontroller.UpdatePixels();Thread.Sleep(1000);controller.SetColor(0, 0, 0, 255);// Bluecontroller.UpdatePixels();Thread.Sleep(1000);controller.SetColor(0, 255, 255, 255);// Whitecontroller.UpdatePixels();Thread.Sleep(1000);

Effect:

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

Color Change

5.2 HSV Color Model

The previous section simply tested the red, green, blue, and white colors of the light using SetColor. Another way to set the color is to use SetHSVColor, which utilizes the HSV color model.

HSV (Hue, Saturation, Value) and RGB (Red, Green, Blue) are two different color spaces. In the HSV color model:

Hue (H) represents the type of color, such as red, yellow, blue, etc. The value of hue is measured in degrees, ranging from 0° to 360°, starting from red and calculated counterclockwise. Red is 0°, green is 120°, and blue is 240°. Their complementary colors are yellow at 60°, cyan at 180°, and purple at 300°;Saturation (S) indicates how close the color is to the spectral color. The higher the value, the more saturated the color; the lower the value, the grayer the color. The saturation value ranges from 0 to 1.Value (V) indicates the brightness of the color. The higher the value, the brighter the color; the lower the value, the darker the color. The value of V ranges from 0 to 1.

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

HSV

Compared to traditional RGB, HSV allows for smoother brightness changes by adjusting the brightness.

5.3 Breathing Light Effect

To achieve the breathing light effect, we simply need to use SetHSVColor to set different brightness colors to smoothly implement the brightness change effect of the breathing light.

// Breathing light effectPixelController controller = new PixelController(9, 1);var ts = 0;for (; ; ){    var add = true;    var v = 0f;    for (; ; )    {        controller.SetHSVColor(0, 240, 50, v);        controller.UpdatePixels();        if (add)        {            v += 0.05f;        }        else        {            v -= 0.05f;        }        if (v >= 1) add = false;        if (v <= 0) break;        Thread.Sleep(50);    }    if (ts > 5) break;    ts++;}

Effect:

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

Breathing Light

5.4 Overall Color Test

For RGB colors, we can generate random colors by using three random numbers within 255. After understanding HSV, we can also directly sample colors evenly in a circular range based on the value of hue.

// Generate how many colors or the number of LED beadsuint ledCount = 25;PixelController controller = new PixelController(9, ledCount);// Add colors set at the beginningint step = (int)(360 / ledCount);var hue = 0;for (uint i = 0; i < ledCount; i++){    // HSV    // Hue H ranges from 0° to 360°    // Saturation S ranges from 0% to 100%, the higher the value, the more saturated the color    // Value V indicates the brightness of the color, usually ranges from 0% (black) to 100% (white)    // V is well set to 1, which is very bright    controller.SetHSVColor((short)i, (short)hue, 1, 0.05f);    hue = hue + step;    controller.UpdatePixels();}// Loop to change colorfor (; ; ){    controller.MovePixelsByStep(1);    controller.UpdatePixels();    Thread.Sleep(500);}

This code is more suitable for light strips, as the Microweather ESP32-S2-Pico has only one LED bead; using MovePixelsByStep after changing the position with UpdatePixels can also show color changes.

Many players enjoy RGB light effects, which can be considered “light pollution”. Using this to control light strips can be quite fun.

6. Official Driver Library Ws28xx.Esp32

Of course, it is best to use the official nanoFramework.Iot.Device.Ws28xx.Esp32 package, which can be installed via Nuget. It is important to choose the correct version, as the other nanoFramework packages it depends on must correspond to the firmware you are flashing.

The usage is also simple; here is a simple example of RGB color control:

// 1 LED, 1 pixelconst int Count = 1;// LED Pin for Microweather ESP32-S2-Picoconst int Pin = 9;public static void Main(){    Ws28xx neo = new Ws2812c(Pin, Count);    BitmapImage img = neo.Image;    for (; ; )    {        img.SetPixel(0, 0, Color.Red);        neo.Update();        Thread.Sleep(500);        img.SetPixel(0, 0, 0, 255, 0);        neo.Update();        Thread.Sleep(500);        img.SetPixel(0, 0, 0, 0, 255);        neo.Update();        Thread.Sleep(500);    }}

However, it is important to note that Ws28xx needs to use Ws2812c for instantiation; otherwise, the color control will not be correct.

7. Full-Color RGB

This section demonstrates controlling full-color red, green, and blue LED lights through PWM ports.

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

LED

You can see that the module has 4 pins, with a voltage of 5V, connected to the VBUS pin; the other three pins are RBG control pins connected to GP2-4.

Mastering RGB Lighting with .NET nanoFramework on ESP32-S2-Pico

Wiring

After connecting the device, the next step is to write code. First, we write the initialization function, defining R_Pin, B_Pin, and G_Pin, corresponding to GPIO that need to be set up for PWM. We use Configuration.SetPinFunction to configure the corresponding pins. Then we create PWM channels from the three pins using PwmChannel.CreateFromPin, and then start the control.

/// <summary>/// Define the PWM channels for RBG/// </summary>private static PwmChannel R_Pin, B_Pin, G_Pin;/// <summary>/// Initialize and configure PWM information/// </summary>public static void Init() {    // Set the pins first, RBG connected to GP2-4    Configuration.SetPinFunction(2, DeviceFunction.PWM2);    Configuration.SetPinFunction(3, DeviceFunction.PWM3);    Configuration.SetPinFunction(4, DeviceFunction.PWM4);    // Create PWM channels from the three pins    R_Pin = PwmChannel.CreateFromPin(2, 40000, 0);    B_Pin = PwmChannel.CreateFromPin(3, 40000, 0);    G_Pin = PwmChannel.CreateFromPin(4, 40000, 0);    // Start PWM    R_Pin.Start();    B_Pin.Start();    G_Pin.Start();}

The core control code is also simple; here we randomly generate numbers within 255 and map them to percentages. The duty cycle of PwmChannel is a percentage, of type double, ranging from 0 to 1.

public static void Main(){    Init();    Random random = new Random();    while (true)    {        R_Pin.DutyCycle = random.Next(255) / 255.0;        B_Pin.DutyCycle = random.Next(255) / 255.0;        G_Pin.DutyCycle = random.Next(255) / 255.0;        Thread.Sleep(500);    }}

8. Conclusion

All related codes in this article, as well as those from previous related series articles, have been open-sourced on GitHub. Interested readers can check it out: https://github.com/sangyuxiaowu/ESP32_S2_PICO.

If there are any errors or omissions, please feel free to point them out.

Leave a Comment