【FireBeetle 2 ESP32-C5】WS2812 彩灯的网页控制
本文介绍了 FireBeetle 2 ESP32-C5 开发套件实现 WS2812 小彩灯颜色和亮度的 HTTP 网页远程控制的项目设计。
项目介绍
准备工作:包括开发板固件烧录、Thonny IDE 安装等;
流程图:包括开发板代码和网页服务器代码对应的流程图;
工程代码:包括开发板板端执行代码、网页服务器端代码等;
工程测试:包括程序运行、网页界面、颜色和亮度控制、效果检验等;
准备工作
开发板烧录 MicroPython 固件;
电脑安装 Thonny IDE 软件,用以调试板端程序;
详见:【FireBeetle 2 ESP32-C5】 介绍、固件上传、工程测试 DF创客社区 .
硬件连接
开发板与 WS2812 模块的接线方式如下
ESP32-C5 | WS2812 | Note |
---|---|---|
Pin 2 | DIN | Signal |
3.3V | VCC | Power |
GND | GND | Ground |
实物连接

流程图

工程代码
包括 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 控制器
色环选择器
颜色预览
亮度控制
预设颜色
保存代码,并上传至 ESP32-C5 开发板根目录。
工程测试
包括程序运行和效果演示、颜色和亮度控制等。
运行程序
运行 Thonny IDE 并连接开发板;
运行 ws2812_http_color_control.py 程序,终端输出 WiFi 连接和网页服务器地址;
效果
浏览器打开终端提示的网址 http://192.168.31.101/ ,显示界面如下

颜色控制

亮度控制

单色显示

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