esp32,ws2812b,正方形灯板,16*16 256 颗灯珠,光影效果。下载,安装,点亮。附源代码

esp32,ws2812b,正方形灯板,16*16 256

esp32,ws2812b,正方形灯板,16*16 256

esp32,ws2812b,正方形灯板,16*16 256

esp32,ws2812b,正方形灯板,16*16 256

esp32,ws2812b,正方形灯板,16*16 256

某宝链接

https://item.taobao.com/item.htm?ft=t&id=711485540266&spm=pc_detail.29232929.202205.12.519d7dd6zAjLib


  • 以下是下载、安装、点亮步骤
  • arduino IDE 集成开发编辑器,下载地址

https://support.arduino.cc/hc/en-us/articles/360019833020-Download-and-install-Arduino-IDE

  • arduino IDE,这样就装好了

  • arduino IDE 集成开发编辑器,安装好之后
  • 需要在 IDE 中配置 esp32 相关的核心支持包

  • 导航至 文件 (File) > 首选项 (Preferences)
  • 在弹出的对话框中,找到“附加开发板管理器网址 (Additional Boards Manager URLs)” 这个输入框
  • 将下面这个至关重要的地址,精确无误地复制进去
  • https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  • 这个网址是 anduino IDE ESP32 的核心支持包
  • 如果更新碰到网络问题,下载极其缓慢,可以参考以下博客,手动下载核心支持包
  • https://blog.csdn.net/penguinyao/article/details/147632696

  • 导航至 工具 (Tools) > 开发板 (Board) > 开发板管理器 (Boards Manager…)。
  • 开发板管理器会加载一会

  • 下载中

  • 下载完成

  • 将 ESP32 开发板通过 USB 线连接到电脑

  • 接下来通过库管理器安装 FastLED 库
  • 在 Arduino IDE 中,导航至 项目 (Sketch) > 导入库 (Include Library) > 管理库 (Manage Libraries…)

  • 在库管理器窗口的搜索框中,输入 FastLED
  • 点击“安装”
  • IDE 会自动下载并放置到正确的位置


  • 接线

gnd -> gnd

3.3v -> vcc

io16 -> din


  • 工具 (Tools) > 开发板 (Board) 中,选择一款通用的板型,例如 ESP32 Dev Module。

  • 工具 (Tools) > 端口 (Port) 中,选择刚才在设备管理器中看到的那个 COM 端口。


假设以下:

  • 使用的 esp32 引脚,io16
  • 灯板:16*16,256 颗灯珠,ws2812b
  • 将下面的代码复制到 arduino IDE 的编辑区
#include <WiFi.h>
#include <WebServer.h>
#include <FastLED.h>

// WiFi配置
const char* ssid = "HUAWEI-10HP4H";
const char* password = "123456789";

// LED配置
#define LED_PIN     16
#define NUM_LEDS    256
#define BRIGHTNESS  80

CRGB leds[NUM_LEDS];
WebServer server(80);

// 效果控制变量
uint8_t currentEffect = 0;
bool effectRunning = true;
uint8_t ledBrightness = 80;
uint8_t effectSpeed = 50;

// 效果状态变量
uint8_t breathingHue = 0;
int breathingBrightness = 0;
int breathingDirection = 1;
uint8_t timeCounter = 0;
float spiralAngle = 0;
uint8_t pulseRadius = 0;
uint8_t pulseHue = 0;
uint8_t rainbowStart = 0;

void setup() {
  Serial.begin(115200);
  
  // 初始化LED
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(ledBrightness);
  FastLED.clear();
  FastLED.show();
  
  // 连接WiFi
  WiFi.begin(ssid, password);
  Serial.print("连接WiFi");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.print("WiFi已连接! IP地址: ");
  Serial.println(WiFi.localIP());
  
  // 设置Web路由
  server.on("/", handleRoot);
  server.on("/effect", handleEffect);
  server.on("/brightness", handleBrightness);
  server.on("/speed", handleSpeed);
  server.on("/power", handlePower);
  
  server.begin();
  Serial.println("Web服务器已启动!");
}

void loop() {
  server.handleClient();
  
  if (effectRunning) {
    runCurrentEffect();
  } else {
    FastLED.clear();
    FastLED.show();
  }
  
  delay(map(effectSpeed, 0, 100, 100, 10)); // 速度控制
}

// Web页面HTML
void handleRoot() {
  String html = R"(
<!DOCTYPE html>
<html lang='zh-CN'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>WS2812B 光影控制台</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        
        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
            font-size: 2.5em;
            background: linear-gradient(45deg, #667eea, #764ba2);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        
        .status {
            text-align: center;
            margin-bottom: 30px;
            padding: 15px;
            background: linear-gradient(45deg, #4CAF50, #45a049);
            color: white;
            border-radius: 10px;
            font-size: 1.2em;
        }
        
        .control-section {
            margin-bottom: 30px;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 15px;
            border-left: 5px solid #667eea;
        }
        
        .section-title {
            font-size: 1.3em;
            color: #333;
            margin-bottom: 15px;
            font-weight: bold;
        }
        
        .effect-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
        }
        
        .effect-btn {
            padding: 15px 20px;
            border: none;
            border-radius: 10px;
            cursor: pointer;
            font-size: 1em;
            font-weight: bold;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }
        
        .effect-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 20px rgba(0,0,0,0.2);
        }
        
        .effect-btn.active {
            transform: scale(0.95);
            box-shadow: inset 0 4px 8px rgba(0,0,0,0.2);
        }
        
        .btn-breathing { background: linear-gradient(45deg, #ff9a9e, #fecfef); color: #333; }
        .btn-ripple { background: linear-gradient(45deg, #a8edea, #fed6e3); color: #333; }
        .btn-rainbow { background: linear-gradient(45deg, #ffecd2, #fcb69f); color: #333; }
        .btn-spiral { background: linear-gradient(45deg, #667eea, #764ba2); color: white; }
        .btn-matrix { background: linear-gradient(45deg, #0f3460, #0e4b99); color: #00ff00; }
        .btn-pulse { background: linear-gradient(45deg, #fa709a, #fee140); color: #333; }
        
        .slider-container {
            margin: 15px 0;
        }
        
        .slider {
            width: 100%;
            height: 8px;
            border-radius: 5px;
            background: #ddd;
            outline: none;
            -webkit-appearance: none;
        }
        
        .slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: #667eea;
            cursor: pointer;
        }
        
        .power-btn {
            width: 100%;
            padding: 20px;
            font-size: 1.2em;
            font-weight: bold;
            border: none;
            border-radius: 15px;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-top: 20px;
        }
        
        .power-on {
            background: linear-gradient(45deg, #4CAF50, #45a049);
            color: white;
        }
        
        .power-off {
            background: linear-gradient(45deg, #f44336, #da190b);
            color: white;
        }
        
        .value-display {
            display: inline-block;
            background: #667eea;
            color: white;
            padding: 5px 10px;
            border-radius: 20px;
            font-weight: bold;
            margin-left: 10px;
        }
        
        @keyframes pulse {
            0% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.7); }
            70% { box-shadow: 0 0 0 10px rgba(102, 126, 234, 0); }
            100% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0); }
        }
        
        .active-effect {
            animation: pulse 2s infinite;
        }
    </style>
</head>
<body>
    <div class='container'>
        <h1>🌈 WS2812B 光影控制台</h1>
        <a href='https://item.taobao.com/item.htm?ft=t&id=711485540266&spm=pc_detail.29232929.202205.12.519d7dd6zAjLib' target="_blank">淘宝店铺</a>
        <div class='status' id='status'>
            ✨ 系统就绪 - 256颗LED等待您的指挥
        </div>
        
        <div class='control-section'>
            <div class='section-title'>🎨 光影效果选择</div>
            <div class='effect-grid'>
                <button class='effect-btn btn-breathing' onclick='setEffect(0)'>🫁 呼吸灯</button>
                <button class='effect-btn btn-ripple' onclick='setEffect(1)'>🌊 水波纹</button>
                <button class='effect-btn btn-rainbow' onclick='setEffect(2)'>🌈 彩虹瀑布</button>
                <button class='effect-btn btn-spiral' onclick='setEffect(3)'>🌌 螺旋星云</button>
                <button class='effect-btn btn-matrix' onclick='setEffect(4)'>💚 数字雨</button>
                <button class='effect-btn btn-pulse' onclick='setEffect(5)'>⚡ 能量脉冲</button>
            </div>
        </div>
        
        <div class='control-section'>
            <div class='section-title'>🔆 亮度控制</div>
            <div class='slider-container'>
                <input type='range' min='10' max='255' value='80' class='slider' id='brightnessSlider' oninput='setBrightness(this.value)'>
                <span class='value-display' id='brightnessValue'>80</span>
            </div>
        </div>
        
        <div class='control-section'>
            <div class='section-title'>⚡ 速度控制</div>
            <div class='slider-container'>
                <input type='range' min='10' max='100' value='50' class='slider' id='speedSlider' oninput='setSpeed(this.value)'>
                <span class='value-display' id='speedValue'>50</span>
            </div>
        </div>
        
        <button class='power-btn power-on' id='powerBtn' onclick='togglePower()'>
            🔌 关闭灯光
        </button>
    </div>

    <script>
        let currentEffect = 0;
        let isOn = true;
        
        // 设置效果
        function setEffect(effect) {
            currentEffect = effect;
            fetch(`/effect?value=${effect}`)
                .then(() => {
                    updateEffectButtons();
                    updateStatus();
                });
        }
        
        // 设置亮度
        function setBrightness(value) {
            document.getElementById('brightnessValue').textContent = value;
            fetch(`/brightness?value=${value}`);
        }
        
        // 设置速度
        function setSpeed(value) {
            document.getElementById('speedValue').textContent = value;
            fetch(`/speed?value=${value}`);
        }
        
        // 电源控制
        function togglePower() {
            isOn = !isOn;
            const btn = document.getElementById('powerBtn');
            if (isOn) {
                btn.textContent = '🔌 关闭灯光';
                btn.className = 'power-btn power-on';
            } else {
                btn.textContent = '🔌 开启灯光';
                btn.className = 'power-btn power-off';
            }
            fetch(`/power?value=${isOn ? '1' : '0'}`);
        }
        
        // 更新效果按钮状态
        function updateEffectButtons() {
            const buttons = document.querySelectorAll('.effect-btn');
            buttons.forEach((btn, index) => {
                if (index === currentEffect) {
                    btn.classList.add('active', 'active-effect');
                } else {
                    btn.classList.remove('active', 'active-effect');
                }
            });
        }
        
        // 更新状态显示
        function updateStatus() {
            const effects = ['呼吸灯', '水波纹', '彩虹瀑布', '螺旋星云', '数字雨', '能量脉冲'];
            document.getElementById('status').textContent = 
                `✨ 当前效果: ${effects[currentEffect]} | 256颗LED正在闪耀`;
        }
        
        // 初始化
        updateEffectButtons();
        updateStatus();
    </script>
</body>
</html>
)";
  
  server.send(200, "text/html", html);
}

// 处理效果切换
void handleEffect() {
  if (server.hasArg("value")) {
    currentEffect = server.arg("value").toInt();
    Serial.println("切换到效果: " + String(currentEffect));
  }
  server.send(200, "text/plain", "OK");
}

// 处理亮度调节
void handleBrightness() {
  if (server.hasArg("value")) {
    ledBrightness = server.arg("value").toInt();
    FastLED.setBrightness(ledBrightness);
    Serial.println("亮度设置为: " + String(ledBrightness));
  }
  server.send(200, "text/plain", "OK");
}

// 处理速度调节
void handleSpeed() {
  if (server.hasArg("value")) {
    effectSpeed = server.arg("value").toInt();
    Serial.println("速度设置为: " + String(effectSpeed));
  }
  server.send(200, "text/plain", "OK");
}

// 处理电源控制
void handlePower() {
  if (server.hasArg("value")) {
    effectRunning = (server.arg("value") == "1");
    Serial.println("电源状态: " + String(effectRunning ? "开启" : "关闭"));
  }
  server.send(200, "text/plain", "OK");
}

// 运行当前效果
void runCurrentEffect() {
  switch (currentEffect) {
    case 0: breathingLight(); break;
    case 1: waterRipple(); break;
    case 2: rainbowWaterfall(); break;
    case 3: spiralNebula(); break;
    case 4: digitalRain(); break;
    case 5: energyPulse(); break;
  }
}

// 效果函数实现(简化版,与之前相同但去掉了delay)
void breathingLight() {
  breathingBrightness += breathingDirection * 3;
  if (breathingBrightness >= 255 || breathingBrightness <= 0) {
    breathingDirection = -breathingDirection;
    breathingHue += 10;
  }
  
  CHSV color(breathingHue, 200, breathingBrightness);
  fill_solid(leds, NUM_LEDS, color);
  FastLED.show();
}

void waterRipple() {
  for (int x = 0; x < 16; x++) {
    for (int y = 0; y < 16; y++) {
      float distance = sqrt(pow(x - 7.5, 2) + pow(y - 7.5, 2));
      uint8_t brightness = sin8(distance * 20 - timeCounter * 8);
      CHSV color(160 + sin8(distance * 10) / 4, 255, brightness);
      leds[y * 16 + x] = color;
    }
  }
  timeCounter++;
  FastLED.show();
}

void rainbowWaterfall() {
  for (int y = 0; y < 16; y++) {
    uint8_t hue = rainbowStart + (y * 16);
    for (int x = 0; x < 16; x++) {
      leds[y * 16 + x] = CHSV(hue, 255, 255);
    }
  }
  rainbowStart += 2;
  FastLED.show();
}

void spiralNebula() {
  fadeToBlackBy(leds, NUM_LEDS, 20);
  
  for (int i = 0; i < 8; i++) {
    float spiral_angle = spiralAngle + i * PI / 4;
    float radius = 3 + 4 * sin(spiralAngle / 10 + i);
    
    int x = 8 + radius * cos(spiral_angle);
    int y = 8 + radius * sin(spiral_angle);
    
    if (x >= 0 && x < 16 && y >= 0 && y < 16) {
      leds[y * 16 + x] = CHSV(spiralAngle * 4 + i * 32, 255, 255);
    }
  }
  
  spiralAngle += 0.1;
  FastLED.show();
}

// 数字雨效果的完整实现
void digitalRain() {
  fadeToBlackBy(leds, NUM_LEDS, 64);
  
  for (int x = 0; x < 16; x++) {
    if (random8() < 20) {
      for (int y = 0; y < 16; y++) {
        if (leds[y * 16 + x] == CRGB::Black) {
          leds[y * 16 + x] = CHSV(96, 255, 255);
          break;
        }
      }
    }
  }
  
  for (int y = 15; y > 0; y--) {
    for (int x = 0; x < 16; x++) {
      if (leds[(y-1) * 16 + x] != CRGB::Black && leds[y * 16 + x] == CRGB::Black) {
        leds[y * 16 + x] = leds[(y-1) * 16 + x];
        leds[(y-1) * 16 + x].fadeToBlackBy(100);
      }
    }
  }
  FastLED.show();
}

void energyPulse() {
  static uint8_t center_x = 8, center_y = 8;
  
  fadeToBlackBy(leds, NUM_LEDS, 50);
  
  for (int x = 0; x < 16; x++) {
    for (int y = 0; y < 16; y++) {
      float distance = sqrt(pow(x - center_x, 2) + pow(y - center_y, 2));
      
      if (abs(distance - pulseRadius) < 1.5) {
        uint8_t brightness = 255 - abs(distance - pulseRadius) * 100;
        leds[y * 16 + x] = CHSV(pulseHue, 255, brightness);
      }
    }
  }
  
  pulseRadius++;
  if (pulseRadius > 12) {
    pulseRadius = 0;
    pulseHue += 30;
    center_x = random(4, 12);
    center_y = random(4, 12);
  }
  
  FastLED.show();
}
  • 将以上代码复制后
  • 按住 esp32 开发板 BOOT 键,然后按一下 EN 键,最后松开,进入烧录模式
  • 接下来,点击 IDE 左上角的 “向右箭头” 按钮(上传)

  • IDE 会开始编译代码。首次编译 ESP32 代码会稍慢
  • 编译完成后,它会尝试上传。观察下方的输出窗口。如果显示 Connecting…_____…,有时需要按住 ESP32 板上的 “BOOT” 按钮,直到上传开始。

  • 如果上传失败,尝试以下操作。
    1. 拔掉开发板所有负载
    2. 将 flash mode 设为 DIO

  • 接下来,打开串口工具
  • 查看开发板的网络 ip 是多少

  • 断电,接上负载
  • gnd -> gnd
  • 3.3v -> vcc
  • io16 -> din
  • 上电启动,等一下,灯板就会亮
  • 在浏览器打开刚刚查看的开发板网络 ip,192.168.1.239
  • 现在就可以通过网页,选择预设好的光影效果了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值