回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【FireBeetle 2 ESP32-C5】WS2812 彩灯的网页控制 简单

头像 无垠的广袤 2025.10.04 7 0

【FireBeetle 2 ESP32-C5】WS2812 彩灯的网页控制

本文介绍了 FireBeetle 2 ESP32-C5 开发套件实现 WS2812 小彩灯颜色和亮度的 HTTP 网页远程控制的项目设计。

 

项目介绍

准备工作:包括开发板固件烧录、Thonny IDE 安装等;

流程图:包括开发板代码和网页服务器代码对应的流程图;

工程代码:包括开发板板端执行代码、网页服务器端代码等;

工程测试:包括程序运行、网页界面、颜色和亮度控制、效果检验等;

 

准备工作

开发板烧录 MicroPython 固件;

电脑安装 Thonny IDE 软件,用以调试板端程序;

详见:【FireBeetle 2 ESP32-C5】 介绍、固件上传、工程测试 DF创客社区 .

 

硬件连接

开发板与 WS2812 模块的接线方式如下

ESP32-C5WS2812Note
Pin 2DINSignal
3.3VVCCPower
GNDGNDGround

实物连接

ws2812_board_connect.jpg

 

流程图

 

flowchart_ws2812_http.jpg

 

 

工程代码

包括 ESP32-C5 代码、HTML 网页代码两部分。

 

ESP32-C5 代码

打开 Thonny IDE 软件,新建 ws2812_http_color_control.py 工程文件,并添加如下代码

 

# WS2812 Color Controller using HTTP
# Upload index.html first
import network
import socket
import time
from machine import Pin
import neopixel
import json
import os
import sys

# WS2812配置
NUM_LEDS = 16  # LED数量
PIN_NUM = 2    # 数据引脚
np = neopixel.NeoPixel(Pin(PIN_NUM), NUM_LEDS)

# WiFi配置
SSID = "D106-108"
PASSWORD = "kobe2016"

# 全局变量存储当前颜色和亮度
current_color = (255, 255, 255)  # 默认白色
current_brightness = 100  # 默认亮度百分比

def cleanup():
    """清理函数,关闭所有灯光"""
    print("\n正在关闭所有灯光...")
    for i in range(NUM_LEDS):
        np[i] = (0, 0, 0)
    np.write()
    print("所有灯光已关闭")
    sys.exit()
    
def connect_wifi():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    
    if not wlan.isconnected():
        print('Connecting to WiFi...')
        wlan.connect(SSID, PASSWORD)
        
        for i in range(10):
            if wlan.isconnected():
                break
            time.sleep(1)
    
    if wlan.isconnected():
        print('WiFi connected!')
        print('Network config:', wlan.ifconfig())
        return wlan.ifconfig()[0]
    else:
        print('WiFi connection failed')
        return None

def apply_brightness(color, brightness):
    """应用亮度到颜色值"""
    r, g, b = color
    brightness_factor = brightness / 100.0
    r = int(r * brightness_factor)
    g = int(g * brightness_factor)
    b = int(b * brightness_factor)
    return (r, g, b)

def update_leds():
    """更新所有LED显示"""
    color_with_brightness = apply_brightness(current_color, current_brightness)
    print(f"Updating LEDs to RGB: {color_with_brightness}")
    for i in range(NUM_LEDS):
        np[i] = color_with_brightness
    np.write()

def handle_request(client_socket):
    """处理HTTP请求"""
    try:
        request = client_socket.recv(1024).decode('utf-8')
        
        if not request:
            client_socket.close()
            return
            
        lines = request.split('\r\n')
        if len(lines) > 0:
            request_line = lines[0]
            parts = request_line.split(' ')
            if len(parts) >= 2:
                method = parts[0]
                path = parts[1]
                
                print(f"Processing: {method} {path}")
                
                if path == '/':
                    send_html_response(client_socket)
                elif path.startswith('/set_color'):
                    handle_set_color(path, client_socket)
                elif path.startswith('/set_brightness'):
                    handle_set_brightness(path, client_socket)
                elif path == '/get_status':
                    handle_get_status(client_socket)
                else:
                    send_404_response(client_socket)
    
    except Exception as e:
        print('Error handling request:', e)
    finally:
        client_socket.close()

def send_html_response(client_socket):
    """发送HTML页面"""
    try:
        with open('index_ws2812.html', 'r') as f:
            html_content = f.read()
        
        response = f"""HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

{html_content}"""
        client_socket.send(response.encode('utf-8'))
        print("HTML response sent")
    except Exception as e:
        print("Error sending HTML:", e)
        send_404_response(client_socket)

def handle_set_color(path, client_socket):
    """处理设置颜色请求"""
    global current_color
    
    try:
        if '?' in path:
            query_string = path.split('?')[1]
            params = query_string.split('&')
            
            r, g, b = 255, 255, 255
            
            for param in params:
                if '=' in param:
                    key, value = param.split('=')
                    if key == 'r':
                        r = int(value)
                    elif key == 'g':
                        g = int(value)
                    elif key == 'b':
                        b = int(value)
            
            current_color = (r, g, b)
            update_leds()
            
            response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n"
            response += json.dumps({"status": "success", "color": current_color})
            client_socket.send(response.encode('utf-8'))
            print(f"Color set to: {current_color}")
        else:
            send_400_response(client_socket)
    except Exception as e:
        print("Error setting color:", e)
        send_500_response(client_socket)

def handle_set_brightness(path, client_socket):
    """处理设置亮度请求"""
    global current_brightness
    
    try:
        if '?' in path:
            query_string = path.split('?')[1]
            params = query_string.split('&')
            
            for param in params:
                if '=' in param:
                    key, value = param.split('=')
                    if key == 'value':
                        current_brightness = max(0, min(100, int(value)))
                        update_leds()
                        
                        response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n"
                        response += json.dumps({"status": "success", "brightness": current_brightness})
                        client_socket.send(response.encode('utf-8'))
                        print(f"Brightness set to: {current_brightness}%")
                        return
            
            send_400_response(client_socket)
        else:
            send_400_response(client_socket)
    except Exception as e:
        print("Error setting brightness:", e)
        send_500_response(client_socket)

def handle_get_status(client_socket):
    """处理获取当前状态请求"""
    status = {
        "color": current_color,
        "brightness": current_brightness
    }
    
    response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n\r\n"
    response += json.dumps(status)
    client_socket.send(response.encode('utf-8'))

def send_400_response(client_socket):
    response = "HTTP/1.1 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nInvalid request"
    client_socket.send(response.encode('utf-8'))

def send_404_response(client_socket):
    response = "HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\n\r\nPage not found"
    client_socket.send(response.encode('utf-8'))

def send_500_response(client_socket):
    response = "HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain\r\n\r\nServer error"
    client_socket.send(response.encode('utf-8'))

def check_files():
    """检查必要的文件是否存在"""
    try:
        files = os.listdir()
        print("Files on ESP32:", files)
        if 'index_ws2812.html' in files:
            print("index_ws2812.html found!")
            with open('index_ws2812.html', 'r') as f:
                content = f.read()
                print(f"HTML file size: {len(content)} bytes")
            return True
        else:
            print("ERROR: index_ws2812.html not found!")
            print("Please upload index_ws2812.html file to ESP32")
            return False
    except Exception as e:
        print("Error checking files:", e)
        return False

def start_web_server():
    """启动Web服务器"""
    # 检查文件是否存在
    if not check_files():
        return
    
    ip_address = connect_wifi()
    if ip_address is None:
        return
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('', 80))
    server_socket.listen(5)
    
    print(f'Web server started at http://{ip_address}')
    
    # 初始化LED
    update_leds()
    
    try:
        while True:
            try:
                client_socket, addr = server_socket.accept()
                handle_request(client_socket)
            except Exception as e:
                print('Error in main loop:', e)
                time.sleep(1)
    except KeyboardInterrupt:
        print("\nKeyboard interrupt received")
    finally:
        # 确保在退出前关闭所有灯光
        cleanup()

# 启动Web服务器
start_web_server()

保存代码;

 

HTML 网页代码

新建 index_ws2812.html 网页文件,并添加如下代码

 




    
    
    ESP32-C5 WS2812 Controller
    


    


        

🎨 ESP32-C5 WS2812 控制器


        
        

            

色环选择器


            

                
                

            

            

                

                    色调 (Hue)
                    
                

                
            

        


        

            

颜色预览


            

            

                
RGB: 255, 255, 255

                
HEX: #FFFFFF

            

        


        

            

亮度控制


            

                

                    亮度
                    100%
                

                
            

        


        

            

预设颜色


            

                

                

                

                

                

                

                

                

            

        

        
        

        
        
    


    

 

保存代码,并上传至 ESP32-C5 开发板根目录。

 

工程测试

包括程序运行和效果演示、颜色和亮度控制等。

 

运行程序

运行 Thonny IDE 并连接开发板;

运行 ws2812_http_color_control.py 程序,终端输出 WiFi 连接和网页服务器地址;

ws2812_http_print.JPG

效果

浏览器打开终端提示的网址 http://192.168.31.101/ ,显示界面如下

ws2812_http_server.jpg

颜色控制

color_control.gif

亮度控制

brightness_control.gif

单色显示

color_single.gif

 

总结

本文介绍了 FireBeetle 2 ESP32-C5 开发套件实现 WS2812 小彩灯颜色和亮度的 HTTP 网页远程控制的项目设计。包括网页服务器工程代码、板端执行代码、工程测试流程、控制效果演示等,为相关产品的开发设计和快速应用提供了参考。

评论

user-avatar