Skip to content

Week 15 - Interface and application programming

Assignments of the Week

Group Assignment

  • Write an application that interfaces a user with an input &/or output device that you made

Individual Assignment:

  • Compare as many tool options as possible

Group Working

My group work is attached here: https://fabacademy.org/2025/labs/unnc/assignments/week15/week15.html

Individual Working

This week I will implement the interaction between the processing side and the esp32 side. First, I will use the xiao esp32 c3 to control the ws2812 light strip. By inputting different numbers, I can control the different colors of the ws2812 light strip. Next, I will use processing to make an interface and interact with esp32 through the processing side interface.

Introduction to WS2812

WS2812 is an intelligent control LED light source that integrates a control circuit and an RGB chip into a single 5050 package component. Technical Specifications:

Integrated Design: The control circuit and RGB chip are integrated into the same package.

Signal Reshaping Circuit: Built-in signal reshaping circuit ensures that the waveform does not accumulate distortion when transmitted to the next driver.

Power Loss Reset Circuit: Built-in power loss reset circuit ensures the light resets correctly in case of power failure.

Color and Brightness: Each pixel can achieve 256 levels of brightness control in three primary colors, displaying a total of 16,777,216 colors, with a scanning frequency of no less than 400Hz/s.

Serial Signal Transmission: Signals are transmitted through a single-wire serial port. When the distance between any two points exceeds 5 meters, no additional circuitry is required for signal transmission.

Refresh Rate: At a refresh rate of 30fps, the number of LEDs in series is no less than 512 in low-speed mode and no less than 1024 in high-speed mode.

Data Transmission Rate: Data is transmitted at a rate of 800Kbps.

Electrical Characteristics: The power supply voltage is 6.0~7.0V. The red, green, and blue LEDs operate at voltages of 1.8-2.2V, 3.0-3.2V, and 3.2-3.4V, respectively.

Communication Method: Uses a single NZR (Non-Return-to-Zero) communication mode.

Below are the mechanical dimensions, pin configuration, and pin functions of the WS2812:

To light up a WS2812 LED strip using the ESP32, you would typically choose between the FastLED library or the Adafruit_NeoPixel library. I chose to use the FastLED library and will briefly explain how to use it.

Color Representation

The FastLED library supports three color representation methods: RGB, HSV, and Color Palette. Below is an introduction to how each of these methods can be used.

RGB
  1. This function uses RGB values ​​to represent colors, where rVal, gVal, and bVal correspond to the brightness values ​​of red, green, and blue, respectively.
c
CRGB RGBcolorName(rVal, gVal, bVal);

We can get the RGB value of the desired color through a color picker website, which provides the RGB value corresponding to each color. It is recommended to use the following website for color selection: https://htmlcolorcodes.com/zh/yanse-xuanze-qi/

  1. In addition, FastLED also supports the use of RGB color names to represent colors. The following are examples of how to use them and some of the color names that can be selected.
c
CRGB::Red
  • RGB color value table:
CRGB::AliceBlue
CRGB::Amethyst
CRGB::AntiqueWhite
CRGB::Aqua
CRGB::Aquamarine
CRGB::Azure
CRGB::Beige
CRGB::Bisque
CRGB::Black
CRGB::BlanchedAlmond
CRGB::Blue
CRGB::BlueViolet
CRGB::Brown
CRGB::BurlyWood
HSV

When using HSV to represent colors, you can set it using the following method. It includes three parameters: Hue, Saturation, and Value (Brightness):

the LED strip is completely off.

c
CHSV HSVcolorName(hVal, sVal, vVal)
  • Hue (H): The range of hue values is 0~255.

  • Saturation (S): Saturation represents how close the color is to a spectral color. The higher the value, the more saturated the color (closer to its true color). The lower the value, the closer the color is to white. When the value is zero, the color is white.

  • Brightness (V): Brightness represents the intensity of the color. The higher the value, the brighter the LED strip. The lower the value, the dimmer the LED strip. When the value is zero,

Color Palette

The FastLED library provides 8 preset color palettes that can be used to achieve a variety of lighting effects. The specific usage will be described in detail when introducing the relevant function functions.

c
CloudColors_p          
LavaColors_p            
OceanColors_p          
ForestColors_p          
RainbowColors_p         
RainbowStripeColors_p
PartyColors_p         
HeatColors_p

Introduction to the FastLED Library

The following content includes function introduction and usage examples. The comments in the function introduction section explain the function functions and the meaning of each parameter in detail; the usage examples demonstrate the specific call of the function. Simply cancel the comments of the corresponding function to realize the control and display of different colors of the WS2812 light strip.

c
FastLED.show();   // Update the LED display.

FastLED.clear();  // Turn off all LEDs.

FastLED.setBrightness(30);   // Set the brightness of the LED strip, with a maximum value of 255.

fill_solid(leds, 30, CRGB::Red);   // Set the LED strip to a single color.
// leds: LED object.
// 30: Number of LEDs to fill (starting from the beginning).
// CRGB::Red: Set the color value to red.

fill_rainbow(leds, 30, beginHue, deltaHue);  // Set the LED strip to a rainbow gradient.
// leds: LED object.
// 30: Number of LEDs.
// beginHue: Starting hue value for the rainbow, maximum is 255.
// deltaHue: Hue difference between adjacent LEDs, maximum is 255.

fill_gradient_RGB(leds, 0, CRGB::Red, 30, CRGB::Blue);   // Set the LED strip to a gradient color.
// leds: LED object.
// 0: Starting LED index.
// CRGB::Red: Starting color.
// 30: Ending LED index.
// CRGB::Blue: Ending color.

fill_palette(leds, 30, 0, 8, OceanColors_p, 255, LINEARBLEND);   // Fill the LED strip using a color palette.
// leds: LED object.
// 30: Number of LEDs to fill.
// 0: Starting color index in the palette.
// 8: Color index difference between adjacent LEDs.
// OceanColors_p: Preset color palette.
// 255: Maximum brightness.
// LINEARBLEND: Linear blending effect.

fill_gradient(leds, 0, CHSV(50, 255, 255), 29, CHSV(150, 255, 255), SHORTEST_HUES/LONGEST_HUES);   // Set the LED strip to a gradient using HSV colors.
// CHSV(50, 255, 255): Starting color in HSV format.
// CHSV(150, 255, 255): Ending color in HSV format.
// SHORTEST_HUES: Shortest hue transition between two colors.
// LONGEST_HUES: Longest hue transition between two colors.
// Note: When using SHORTEST_HUES or LONGEST_HUES, the CHSV format must be used.

ColorFromPalette(RainbowColors_p, 0, 128, LINEARBLEND);   // Get a specific color from a palette.
// RainbowColors_p: Color palette to use.
// 0: Color index in the palette.
// 128: Brightness.
// LINEARBLEND: Linear blending effect.

fadeToBlackBy(leds, 30, 10);  // Gradually fade out the LED strip.
// leds: LED object.
// 30: Number of LEDs.
// 10: Fade intensity.

Function use cases

c
#include "FastLED.h"           

#define NUM_LEDS 18            // Number of LEDs
#define LED_DT 8               // Signal pin
#define LED_TYPE WS2812B       // LED strip model
#define COLOR_ORDER GRB        // Color order

int startIndex = 0;  // Starting offset

uint8_t max_bright = 50;       // LED brightness, range 0~255
CRGB leds[NUM_LEDS];           // Establish LED strip leds

// fill_solid
// CRGB myColor = CRGB::BlanchedAlmond;   // Color
CRGB myColor(50,0,50);   // Red green blue values

// fill_rainbow parameters (rainbow gradient)
uint8_t beginHue = 0;         // Starting hue
uint8_t deltaHue = 5;        // Hue difference between adjacent LEDs

// fill_gradient_RGB parameters (RGB gradient)
int gradientStart = 0;        // Gradient start LED number
CRGB startColor = CRGB::Blue;  // Gradient starting color
int gradientEnd = 17;    // Gradient end LED number
CRGB endColor = CRGB::Green;   // Gradient ending color

// fill_palette parameters (palette filling)
uint8_t paletteStartIndex = 0;      // Palette starting index
uint8_t paletteColorDiff = 5;        // Index difference of adjacent LEDs in palette
CRGBPalette16 myPalette = HeatColors_p;  // Use preset palette
  /*
    8 preset palettes:
    CloudColors_p           // Clouds
    LavaColors_p            // Lava
    OceanColors_p           // Ocean
    ForestColors_p          // Forest
    RainbowColors_p         // Rainbow
    RainbowStripeColors_p
    PartyColors_p           // Party
    HeatColors_p            // Heat
  */
uint8_t paletteBrightness = 128;    // Brightness
TBlendType paletteBlending = LINEARBLEND; // Linear change NOBLEND: abrupt color change

// fill_gradient parameters (HSV)
int hsvGradientStart = 0;           // HSV gradient start LED number
CHSV hsvStartColor = CHSV(50, 255, 255); // HSV starting color
int hsvGradientEnd = 17;      // HSV gradient end LED number
CHSV hsvEndColor = CHSV(150, 255, 255); // HSV ending color
TGradientDirectionCode gradientDirection = SHORTEST_HUES; // Color transition direction (SHORTEST_HUES or LONGEST_HUES)

// ColorFromPalette parameters
uint8_t paletteIndex = 15;       // Palette color index to retrieve
uint8_t colorBrightness = 128;  // Brightness when retrieving color
TBlendType colorBlendType = LINEARBLEND;  // Blending mode when retrieving color

void setup() { 
  LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(max_bright);
  FastLED.clear();
}

void loop () {       
  // Set LED strip to a single color
  // fill_solid(leds, NUM_LEDS, myColor);  // Fill with blue

  // Rainbow gradient
  // fill_rainbow(leds, NUM_LEDS, beginHue, deltaHue);
  // leds: LED object
  // NUM_LEDS: LED count
  // beginHue: starting hue value of rainbow color, maximum 255
  // deltaHue: hue difference between adjacent LEDs, maximum 255

  // RGB gradient
  // fill_gradient_RGB(leds, gradientStart, startColor, gradientEnd, endColor);
  // leds: LED object
  // gradientStart: starting LED number
  // startColor: starting color
  // gradientEnd: last LED number
  // endColor: ending color

  // Palette filling
  // fill_palette(leds, NUM_LEDS, paletteStartIndex, paletteColorDiff, myPalette, paletteBrightness, paletteBlending);
  // NUM_LEDS: LED count
  // paletteStartIndex: first LED's palette color sequence number
  // paletteColorDiff: color difference between adjacent LEDs
  // myPalette: preset palette
  // paletteBrightness: brightness (0~255)
  // LINEARBLEND: linear transition

  // HSV gradient
  // fill_gradient(leds, 0, hsvStartColor, 18, hsvEndColor, gradientDirection);
  // fill_gradient(leds, 0, CHSV(50, 255,255) , 29, CHSV(150,255,255), LONGEST_HUES);
  // hsvStartColor: starting color, HSV format
  // hsvEndColor: ending color
  // SHORTEST_HUES: short hue transition, shortest color transition between two color values
  // LONGEST_HUES: long hue transition, longest color transition between two color values
  // Note: When using SHORTEST_HUES and LONGEST_HUES, CHVS method must be used for coloring

  // Retrieve color from palette individually
  // CRGB myColor = ColorFromPalette(RainbowColors_p, paletteIndex, colorBrightness, colorBlendType);
  // fill_solid(leds, NUM_LEDS, myColor);
  // RainbowColors_p: use palette
  // paletteIndex: color sequence number
  // colorBrightness: brightness
  // LINEARBLEND: linear gradient
  
  // Running light effect
  //  for (int i = 0; i < NUM_LEDS; i++) {
  //   leds[i] = CRGB::Red;    // Light up as red
  //   FastLED.show();
  //   delay(100);             // Delay between each light, can adjust faster or slower
  //   leds[i] = CRGB::Black;  // Turn off current light
  // }

  // Shift one color overall every time
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[(i + startIndex) % NUM_LEDS] = CHSV((i * 10) % 255, 255, 255); 
  }
  
  FastLED.show();
  delay(100); // Control flow speed (smaller means faster)

  // Clear current light status for the next refresh
  fill_solid(leds, NUM_LEDS, CRGB::Black);

  // Move the starting point to create a flowing effect
  startIndex = (startIndex + 1) % NUM_LEDS;

  // FastLED.show();
  // delay(25); 
}

Processing to WS2812

Communication between Processing and the XIAO ESP32 is established via a serial interface. Processing runs on the PC and handles tasks such as data visualization, input, processing, and output. The XIAO ESP32 connects to the PC through USB and executes control operations according to the data it receives.

Case

I created a simple interface using Processing that prompts the user to press keys 1, 2, 3, or 4. When a corresponding key is pressed, a command is sent via serial communication to control a WS2812 LED strip, which lights up in different colors based on the input.

c
#include <FastLED.h>

#define LED_PIN     8
#define NUM_LEDS    18
#define BRIGHTNESS  128

CRGB leds[NUM_LEDS];
char command = 0;

void setup() {
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  FastLED.clear();
  FastLED.show();
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    command = Serial.read();
    applyEffect(command);
  }
}

void applyEffect(char cmd) {
  switch (cmd) {
    case '1':
      fill_solid(leds, NUM_LEDS, CRGB::Red);
      break;
    case '2':
      fill_rainbow(leds, NUM_LEDS, 0, 7);
      break;
    case '3':
      fill_gradient_RGB(leds, 0, CRGB::Red, NUM_LEDS - 1, CRGB::Blue);
      break;
    case '4':
      fill_palette(leds, NUM_LEDS, 0, 8, OceanColors_p, 255, LINEARBLEND);
      break;
    default:
      FastLED.clear();
      break;
  }
  FastLED.show();
}

processing:

c
import processing.serial.*;

Serial myPort;

void setup() {
  size(400, 200);
  printArray(Serial.list());  // 查看串口
  myPort = new Serial(this, Serial.list()[0], 9600); // 自动选择第一个串口
}

void draw() {
  background(0);
  fill(255);
  textSize(20);
  textAlign(CENTER, CENTER);
  text("Press 1~4 to control LED effects", width / 2, height / 2);
}

void keyPressed() {
  if (key >= '1' && key <= '4') {
    myPort.write(key + "\n");
  }
}

The demonstration effect is as follows: