打印

FastLED可以实现二维点阵LED的显示效果

[复制链接]
801|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2025-5-13 22:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

FastLED 完全可以实现二维点阵(矩阵)LED的显示效果!虽然 FastLED 原生设计主要用于一维 LED 灯带控制,但通过合理的 坐标映射逻辑处理,可以轻松将一维灯带数据转换为二维矩阵的显示效果。以下是具体实现方法和示例:


1. 硬件连接与布局

二维点阵的 LED 通常以网格形式排列(如 8x8、16x16 等),常见连接方式有两种:

  • 蛇形排列(Snake Layout): LED 灯带在行间交替方向(例如,第一行从左到右,第二行从右到左),以缩短走线。
  • 逐行排列(Row-by-Row): 每行 LED 独立连接,方向一致。

需要根据实际硬件布局编写 坐标映射函数


2. 核心步骤

(1) 定义二维矩阵参数

#define MATRIX_WIDTH  16  // 矩阵宽度(列数)
#define MATRIX_HEIGHT 8   // 矩阵高度(行数)
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT) // LED总数
CRGB leds[NUM_LEDS];

(2) 坐标映射函数

将二维坐标 (x, y) 转换为一维 LED 索引。 示例代码(蛇形排列)

cpp

复制

下载

uint16_t XY(uint8_t x, uint8_t y) {
  if (y % 2 == 0) {
    // 偶数行:从左到右
    return y * MATRIX_WIDTH + x;
  } else {
    // 奇数行:从右到左
    return y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x);
  }
}

(3) 控制二维点阵

通过 XY(x, y) 函数直接操作指定坐标的 LED:

// 在坐标 (3, 5) 显示红色
leds[XY(3, 5)] = CRGB::Red;

// 在坐标 (0, 0) 到 (4, 4) 绘制绿色方块
for (int x = 0; x < 5; x++) {
  for (int y = 0; y < 5; y++) {
    leds[XY(x, y)] = CRGB::Green;
  }
}

3. 示例效果实现

(1) 滚动文字/图案

通过偏移坐标实现水平或垂直滚动:

void loop() {
  static int offset = 0;
  for (int x = 0; x < MATRIX_WIDTH; x++) {
    for (int y = 0; y < MATRIX_HEIGHT; y++) {
      // 计算滚动后的坐标(水平滚动)
      int shiftedX = (x + offset) % MATRIX_WIDTH;
      // 根据图案显示颜色(示例:间隔点亮)
      leds[XY(shiftedX, y)] = (x % 2 == 0) ? CRGB::Blue : CRGB::Black;
    }
  }
  FastLED.show();
  offset++;
  delay(100);
}

(2) 动态波纹效果

结合二维坐标计算动态亮度:

void loop() {
  static uint8_t wave = 0;
  for (int x = 0; x < MATRIX_WIDTH; x++) {
    for (int y = 0; y < MATRIX_HEIGHT; y++) {
      // 计算距离中心的波纹强度
      float dx = x - MATRIX_WIDTH/2;
      float dy = y - MATRIX_HEIGHT/2;
      uint8_t brightness = 255 * (sin8(sqrt(dx*dx + dy*dy) + wave) / 255;
      leds[XY(x, y)] = CHSV(128, 255, brightness);
    }
  }
  FastLED.show();
  wave += 5;
  delay(30);
}

4. 高级技巧

(1) 使用二维数组缓存

为简化逻辑,可先将颜色数据存储在二维数组,再批量写入 LED:

CRGB buffer[MATRIX_WIDTH][MATRIX_HEIGHT];

// 更新缓冲区
buffer[3][2] = CRGB::Purple;

// 将缓冲区写入实际 LED
for (int x = 0; x < MATRIX_WIDTH; x++) {
  for (int y = 0; y < MATRIX_HEIGHT; y++) {
    leds[XY(x, y)] = buffer[x][y];
  }
}
FastLED.show();

(2) 优化性能

  • 并行刷新:如果使用多个 LED 控制器(如多个 WS2812B 灯带),可分割矩阵并并行驱动。
  • 颜色预计算:对动态效果预先计算颜色值,减少实时计算量。

5. 完整示例:8x8 矩阵显示彩虹波浪

#include <FastLED.h>
#define MATRIX_WIDTH  8
#define MATRIX_HEIGHT 8
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
CRGB leds[NUM_LEDS];

// 坐标映射(蛇形排列)
uint16_t XY(uint8_t x, uint8_t y) {
  return (y % 2 == 0) ? (y * MATRIX_WIDTH + x) : (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x));
}

void setup() {
  FastLED.addLeds<WS2812B, 6>(leds, NUM_LEDS);
}

void loop() {
  static uint8_t hue = 0;
  for (int x = 0; x < MATRIX_WIDTH; x++) {
    for (int y = 0; y < MATRIX_HEIGHT; y++) {
      // 根据坐标生成色相和明度波浪
      uint8_t ledHue = hue + x * 10 + y * 5;
      uint8_t brightness = sin8(x * 20 + y * 20 + hue);
      leds[XY(x, y)] = CHSV(ledHue, 255, brightness);
    }
  }
  FastLED.show();
  hue += 2;
  delay(20);
}

注意事项

  • 硬件布局:务必确认 LED 的物理排列方式(蛇形/逐行),否则坐标会错乱。
  • 性能限制:大型矩阵(如 32x32)可能因刷新率不足导致卡顿,需优化代码或使用更高性能控制器(如 ESP32)。

通过 FastLED 的灵活性和二维坐标映射,你可以轻松实现复杂的动态图案、游戏甚至低分辨率动画!

使用特权

评论回复

相关帖子

沙发
keer_zu|  楼主 | 2025-5-19 21:56 | 只看该作者
static uint8_t wave = 0;
  for (int x = 0; x < MATRIX_WIDTH; x++) {
    for (int y = 0; y < MATRIX_HEIGHT; y++) {
      // 计算距离中心的波纹强度
      float dx = x - MATRIX_WIDTH/2;
      float dy = y - MATRIX_HEIGHT/2;
      uint8_t brightness = 255 * (sin8(sqrt(dx*dx + dy*dy) + wave) / 255);
      leds[XY(x, y)] = CHSV(128, 255, brightness);
    }
  }
  FastLED.show();
  wave += 5;
  delay(300);


使用特权

评论回复
板凳
keer_zu|  楼主 | 2025-5-20 11:07 | 只看该作者
彩红效果:

static uint8_t hue = 0;
  for (int x = 0; x < MATRIX_WIDTH; x++) {
    for (int y = 0; y < MATRIX_HEIGHT; y++) {
      // 根据坐标生成色相和明度波浪
      uint8_t ledHue = hue + x * 10 + y * 5;
      uint8_t brightness = sin8(x * 20 + y * 20 + hue);
      leds[XY(x, y)] = CHSV(ledHue, 255, brightness);
    }
  }
  FastLED.show();
  hue += 2;
  delay(20);


使用特权

评论回复
地板
keer_zu|  楼主 | 2025-5-20 14:41 | 只看该作者
#include <BluetoothSerial.h>
#include <FastLED.h>
#include <math.h>
struct Polar { float radius; float angle_radians; };

Polar cartesianToPolar(float x, float y) {
    return {
        sqrt(x*x + y*y),
        atan2(y, x)
    };
}

#define MATRIX_WIDTH  30  // 矩阵宽度(列数)
#define MATRIX_HEIGHT 15   // 矩阵高度(行数)
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT) // LED总数

#define LED_PIN     15   // 数据线连接的GPIO引脚
//#define NUM_LEDS    450  // LED数量
#define BRIGHTNESS 100  // 亮度(0-255)
CRGB leds[NUM_LEDS];
CRGB red_c   = CRGB(255, 0, 0);    // 红色
CRGB green_c   = CRGB(0, 255, 0);    // 绿色
CRGB blue_c   = CRGB(0, 0, 255);    // 蓝色
CRGB black_c   = CRGB(0, 0, 0);      // 黑色(关闭LED)
CRGB white_c   = CRGB(255, 255, 255);// 白色(全亮度)

CRGB yellow_c   = CRGB(255, 255, 0);  // 黄色
CRGB qing_c   = CRGB(0, 255, 255);  // 青色
CRGB pin_c   = CRGB(255, 0, 255);  // 品红
CRGB cheng_c   = CRGB(255, 165, 0);  // 橙色
CRGB zi_c   = CRGB(128, 0, 128);  // 紫色
CRGB fen_c   = CRGB(255, 192, 203);// 粉色
int flag=0;

//===================================================
// 定义主色和辅助色的HSV范围(H:0-255对应0-360度)
const uint8_t MAIN_HUE = 0;     // 主色Hue(例如红色)
const uint8_t ACCENT_HUE = 32;  // 辅助色Hue(例如橙色)
const uint8_t HUE_RANGE = 16;   // 主辅色之间的过渡范围

// 动态参数
uint8_t baseBrightness = 128;   // 基础亮度
uint8_t brightnessJitter = 50;  // 亮度波动范围
uint8_t saturation = 200;       // 饱和度(0-255)
uint8_t spreadRatio = 50;       // 主色占比(%)

//===================================================

#define FILL_LEDS(value) do { \
    for (size_t i = 0; i < NUM_LEDS; ++i) { \
        (leds)[i] = (value); \
    } \
} while(0)

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

uint16_t XY(uint8_t x, uint8_t y) {
  return (y % 2 == 0) ? (y * MATRIX_WIDTH + x) : (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x));
}

BluetoothSerial SerialBT;
#define BUFFER_SIZE 1024
uint8_t buffer[BUFFER_SIZE];
int write_idx = 0;
int read_idx = 0;
unsigned long total_bytes = 0;
unsigned long last_time = 0;

#define BT_DISCOVER_TIME 10000

static bool btScanAsync = true;
static bool btScanSync = true;

void btAdvertisedDeviceFound(BTAdvertisedDevice *pDevice) {
  Serial.printf("Found a device asynchronously: %s\n", pDevice->toString().c_str());
}

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  randomSeed(analogRead(0));    // 初始化随机种子
  
  Serial.begin(115200);
  SerialBT.begin("ESP32-liuyan");  //Bluetooth device name
  Serial.println("The device started, now you can pair it with bluetooth!");
  // SerialBT.setMTU(1024);

  if (btScanAsync) {
    Serial.print("Starting asynchronous discovery... ");
    if (SerialBT.discoverAsync(btAdvertisedDeviceFound)) {
      Serial.println("Findings will be reported in \"btAdvertisedDeviceFound\"");
      delay(10000);
      Serial.print("Stopping discoverAsync... ");
      SerialBT.discoverAsyncStop();
      Serial.println("stopped");
    } else {
      Serial.println("Error on discoverAsync f.e. not working after a \"connect\"");
    }
  }

  if (btScanSync) {
    Serial.println("Starting synchronous discovery... ");
    BTScanResults *pResults = SerialBT.discover(BT_DISCOVER_TIME);
    if (pResults) {
      pResults->dump(&Serial);
    } else {
      Serial.println("Error on BT Scan, no result!");
    }
  }
}

void fill_shape( struct CRGB * targetArray, int numToFill,
                  uint8_t initialhue,
                  uint8_t deltahue )
{
    CHSV hsv;
    hsv.hue = initialhue;
    hsv.val = 255;
    hsv.sat = 240;
    for( int i = 0; i < numToFill; ++i) {
        targetArray[i] = hsv;
        hsv.hue += deltahue;
    }
}

void breath_light()
{
static uint8_t brightness = 0;
  // 使用正弦波生成明度值(0-255)
  brightness = beatsin8(10, 50, 255); // 参数:频率(Hz), 最小值, 最大值
  fill_solid(leds, NUM_LEDS, CHSV(96, 255, brightness)); // 固定色相(如绿色)
  FastLED.show();
}

void loop() {
#if 0
  int index;
  static uint8_t hue = 0;
    // 非阻塞读取蓝牙数据
  while (SerialBT.available()) {
    int bytes_to_read = SerialBT.available();
    bytes_to_read = min(bytes_to_read, BUFFER_SIZE - write_idx);

    // 写入缓冲区
    if (bytes_to_read > 0) {
      flag = 1;
      SerialBT.readBytes(&buffer[write_idx], bytes_to_read);
      if(buffer[write_idx] == 'r' || buffer[write_idx] == 'R'){
        FILL_LEDS(red_c);
      } else if(buffer[write_idx] == 'g' || buffer[write_idx] == 'G'){
        FILL_LEDS(green_c);
      } else if(buffer[write_idx] == 'b' || buffer[write_idx] == 'B'){
        FILL_LEDS(blue_c);
      } else if(buffer[write_idx] == 'w' || buffer[write_idx] == 'W'){
        FILL_LEDS(white_c);
      } else if(buffer[write_idx] == 'y' || buffer[write_idx] == 'Y'){
        FILL_LEDS(yellow_c);
      } else if(buffer[write_idx] == 's' || buffer[write_idx] == 'S'){
        FILL_LEDS(black_c);
        flag = 0;
      } else if(buffer[write_idx] == 'q' || buffer[write_idx] == 'Q'){
        FILL_LEDS(qing_c);
      } else if(buffer[write_idx] == 'p' || buffer[write_idx] == 'P'){
        FILL_LEDS(pin_c);
      } else if(buffer[write_idx] == 'c' || buffer[write_idx] == 'C'){
        FILL_LEDS(cheng_c);
      } else if(buffer[write_idx] == 'z' || buffer[write_idx] == 'Z'){
        FILL_LEDS(zi_c);
      } else if(buffer[write_idx] == 'f' || buffer[write_idx] == 'F'){
        FILL_LEDS(fen_c);
      } else if(buffer[write_idx] == 'v' || buffer[write_idx] == 'V'){
        FILL_LEDS(fen_c);
      }
      
      FastLED.show();
        
      for(index = 0;index < bytes_to_read;index ++)
      Serial.printf("%c",buffer[write_idx + index]);
      write_idx = (write_idx + bytes_to_read) % BUFFER_SIZE;
      total_bytes += bytes_to_read;
    } else {
      
    }

    // 缓冲区切换检查(防止覆盖未读数据)
    if (write_idx >= BUFFER_SIZE / 2 && read_idx < BUFFER_SIZE / 2) {
      read_idx = BUFFER_SIZE / 2;  // 切换到后半缓冲区
    }
  }

  // 计算实时带宽
  unsigned long current_time = millis();
  if (current_time - last_time >= 1000) {
    float rate = (total_bytes * 8) / 1000.0;  // 转换为Kbps
    //Serial.printf("当前接收速率: %.2f Kbps\n", rate);
    total_bytes = 0;
    last_time = current_time;
  }
  
  //if(!flag) {
    fill_shape(leds, NUM_LEDS, hue++, 10);
    FastLED.show();
    //Serial.printf("%d\n",hue);
    //delay(1000);
    //FILL_LEDS(black_c);
    //FastLED.show();
    //delay(1000);
    //delay(10);
    //flag = !flag;
  //}
#else
static uint8_t hue = 0;
  for (int x = 0; x < MATRIX_WIDTH; x++) {
    for (int y = 0; y < MATRIX_HEIGHT; y++) {
      // 根据坐标生成色相和明度波浪
      uint8_t ledHue = hue + x * 10 + y * 5;
      uint8_t brightness = sin8(x * 20 + y * 20 + hue);
      leds[XY(x, y)] = CHSV(ledHue, 255, brightness);
    }
  }
  FastLED.show();
  hue += 2;
  delay(20);
//breath_light();
#endif
}

使用特权

评论回复
5
keer_zu|  楼主 | 2025-5-20 19:12 | 只看该作者
#if 1
void optim_vision()
{
float global_brightness = breathe(20.0);  // 20秒呼吸周期
  rotation_angle += ROTATION_SPEED * (millis() % 20) / 1000.0;
  
  for(int i=0; i<NUM_LEDS; i++) {
    float r = led_r[i];
    float theta = led_theta[i] + rotation_angle;
   
    // 添加角度扰动
    theta += randomGaussian();
   
    CRGB color;
    if(r < 0.15) {  // 核心层
      float layerBrightness = 0.8 + 0.2 * sin(millis()/500.0);  // 动态亮度
      color = colorBlend(coreColor1, coreColor2, layerBrightness);
    }
    else if(r < 0.4) {  // 过渡层
      color = colorBlend(mainColor, coreColor2, 0.3);
    }
    else {  // 背景层
      color = bgColor;
    }
   
    // 应用全局亮度
    color.fadeToBlackBy(255 * (1 - global_brightness));
    leds[i] = color;
  }
  
  FastLED.show();
  FastLED.delay(20);  // 控制刷新率
}
#endif

使用特权

评论回复
6
keer_zu|  楼主 | 2025-5-20 19:14 | 只看该作者
#include "led_functions.h"

#define NOISE_STRENGTH 0.3   // 扰动强度

CRGB leds[NUM_LEDS]; // 实际定义LED数组

// 极坐标系统
float led_r[NUM_LEDS];      // 半径(归一化 0-1)
float led_theta[NUM_LEDS];  // 初始角度(弧度)
float rotation_angle = 0;   // 当前旋转角度


// 高斯噪声生成
float randomGaussian() {
  // 使用Box-Muller转换生成高斯分布
  static float z0, z1;
  static bool generate = false;
  generate = !generate;
  
  if (!generate) return z1 * NOISE_STRENGTH;
  
  float u1, u2;
  do {
    u1 = random(1, 1000) / 1000.0;
    u2 = random(1, 1000) / 1000.0;
  } while (u1 <= 0.0001);
  
  z0 = sqrt(-2.0 * log(u1)) * cos(TWO_PI * u2);
  z1 = sqrt(-2.0 * log(u1)) * sin(TWO_PI * u2);
  return z0 * NOISE_STRENGTH;
}

// 呼吸效果生成器
float breathe(float periodSeconds) {
  static unsigned long lastUpdate;
  float cycle = (millis() - lastUpdate) / (periodSeconds * 1000);
  return (sin(cycle * TWO_PI) * 0.5 + 0.5);  // 输出0-1
}

// 极坐标初始化
void initPolarCoords() {
  // 假设LED排列在圆形区域(需要根据实际布局调整)
  for(int i=0; i<NUM_LEDS; i++) {
    // 转换为虚拟坐标(示例用圆形布局)
    float x = (i % MATRIX_WIDTH) / MATRIX_WIDTH - 0.5;  // 假设50x10的布局
    float y = (i / MATRIX_WIDTH) / MATRIX_HEIGHT - 0.5;
   
    led_r[i] = sqrt(x*x + y*y) * 2;    // 归一化半径
    led_theta[i] = atan2(y, x);        // 初始角度
  }
}

// 颜色混合函数
CRGB colorBlend(CRGB color1, CRGB color2, float weight) {
  return CRGB(
    color1.r * (1-weight) + color2.r * weight,
    color1.g * (1-weight) + color2.g * weight,
    color1.b * (1-weight) + color2.b * weight
  );
}

uint16_t XY(uint8_t x, uint8_t y)
{
  return (y % 2 == 0) ? (y * MATRIX_WIDTH + x) : (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x));
}


void leds_setup()
{
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
  initPolarCoords();
}

使用特权

评论回复
7
keer_zu|  楼主 | 2025-5-24 00:48 | 只看该作者
显示“祝你生日快乐”

#include <FastLED.h>

#define LED_PIN     15
#define COLOR_ORDER GRB
#define CHIPSET     WS2815
#define NUM_LEDS    450
CRGB leds[NUM_LEDS];

#define MATRIX_WIDTH  30
#define MATRIX_HEIGHT 15

#define BITMAP_WIDTH 96

#define BITMAP_INDEX(x,y) ((14-y)*12 + (x/8) - 1)
#define BITMMAP_POSITION(x) (x%8)


// 颜色定义
const CRGB BACKGROUND_COLOR = CRGB(0x0, 0x0, 0x100); //
const CRGB TEXT_COLOR = CRGB(0xFF, 0x0, 0x00);       //

// 点阵数据(已转换格式)
/*96 x 15*/
static const unsigned char textBitmap[] = {
    0x33, 0xfc, 0x08, 0x80, 0x11, 0x00, 0x1f, 0xf0, 0x10, 0x40, 0x00, 0xf0,
    0x13, 0xfc, 0x08, 0x80, 0x11, 0x00, 0x1f, 0xf0, 0x10, 0x40, 0x1f, 0xf0,
    0xfa, 0x04, 0x19, 0xfe, 0x11, 0x00, 0x10, 0x10, 0x13, 0xf8, 0x1f, 0x00,
    0xfa, 0x04, 0x11, 0xfe, 0x3f, 0xfc, 0x10, 0x10, 0x1b, 0xf8, 0x11, 0x00,
    0x1a, 0x04, 0x33, 0x06, 0x3f, 0xfc, 0x10, 0x10, 0x5c, 0x48, 0x31, 0x00,
    0x13, 0xfc, 0x36, 0x24, 0x61, 0x00, 0x10, 0x10, 0x54, 0x48, 0x21, 0x00,
    0x3b, 0xfc, 0x74, 0x20, 0xc1, 0x00, 0x1f, 0xf0, 0x50, 0x48, 0x3f, 0xfc,
    0x7c, 0x90, 0xd1, 0x28, 0x81, 0x00, 0x1f, 0xf0, 0xd7, 0xfe, 0x3f, 0xfc,
    0xd4, 0x90, 0x91, 0x2c, 0x3f, 0xf8, 0x10, 0x10, 0x97, 0xfe, 0x09, 0x20,
    0x94, 0x90, 0x13, 0x24, 0x3f, 0xf8, 0x10, 0x10, 0x10, 0xe0, 0x09, 0x30,
    0x11, 0x92, 0x12, 0x26, 0x01, 0x00, 0x10, 0x10, 0x10, 0xa0, 0x19, 0x18,
    0x11, 0x12, 0x16, 0x22, 0x01, 0x00, 0x10, 0x10, 0x11, 0xb0, 0x31, 0x0c,
    0x13, 0x12, 0x14, 0x22, 0x01, 0x00, 0x10, 0x10, 0x11, 0x10, 0x61, 0x04,
    0x16, 0x1e, 0x10, 0xa0, 0xff, 0xfe, 0x1f, 0xf0, 0x13, 0x18, 0x45, 0x04,
    0x1c, 0x0e, 0x10, 0xe0, 0xff, 0xfe, 0x1f, 0xf0, 0x16, 0x0e, 0x07, 0x00
};

int scrollOffset = 0;

// 蛇形布局坐标转换
int getLedIndex(int x, int y) {
  if (x < 0 || x >= MATRIX_WIDTH || y < 0 || y >= MATRIX_HEIGHT) return -1;
  if (y % 2 == 0) return y * MATRIX_WIDTH + x;
  else return y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x);
}

void setup() {
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  FastLED.setBrightness(50);
}

void loop() {
  static unsigned long lastUpdate = 0;
  if (millis() - lastUpdate > 100) {
    lastUpdate = millis();
   
    fill_solid(leds, NUM_LEDS, BACKGROUND_COLOR);

    for (int x = 0; x < MATRIX_WIDTH; x++) {
      int bitmapX = (scrollOffset + x) % BITMAP_WIDTH;
      for (int y = 0; y < MATRIX_HEIGHT; y++) {
        if ((textBitmap[BITMAP_INDEX(bitmapX,y)] << BITMMAP_POSITION(bitmapX)) &0x80) {
          int ledIndex = getLedIndex(x, y);
          if (ledIndex != -1) leds[ledIndex] = TEXT_COLOR;
        }
      }
    }

    FastLED.show();
    scrollOffset = (scrollOffset + 1) % BITMAP_WIDTH;
  }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1445

主题

12781

帖子

53

粉丝