-
ESP32 同时启动 AP 模式 + UDP 服务 + Web 服务器
-
Web 服务器提供 HTML 控制页面
-
网页通过 JavaScript 发送 UDP 指令到 ESP32 的 UDP 端口
-
ESP32 的 UDP 服务接收指令并控制 LED import socket
import network
import machine
import time
from machine import Pin
全局变量
led = Pin(2, Pin.OUT) # 初始化GPIO2为输出模式
led.value(0) # 默认熄灭LED
def start_ap():
"""启动ESP32的AP模式"""
ap = network.WLAN(network.AP_IF)
ap.active(False)
time.sleep(0.5)
ap.active(True)
AP配置
ssid = 'ESP32_APTest'
password = '12345678'
ap.config(
essid=ssid,
password=password,
authmode=3, # WPA2-PSK
max_clients=10
)
等待AP启动完成
while not ap.active():
time.sleep(0.1)
print('='*20)
print('AP模式已启动')
print('SSID:', ssid)
print('密码:', password)
ip = ap.ifconfig()[0]
print('IP地址:', ip) # 通常是192.168.4.1
print('='*20)
return ip
def udp_server():
"""启动UDP服务,监听指令控制LED(修复超时日志)"""
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(("0.0.0.0", 7788))
udp_socket.settimeout(1) # 超时1秒,避免阻塞
while True:
try:
接收UDP数据
recv_data, sender_info = udp_socket.recvfrom(1024)
cmd = recv_data.decode("utf-8").strip()
执行指令
if cmd == "light on":
led.value(1)
print(f"来自{sender_info}的指令:点亮LED")
udp_socket.sendto(b"success: LED ON", sender_info)
elif cmd == "light off":
led.value(0)
print(f"来自{sender_info}的指令:熄灭LED")
udp_socket.sendto(b"success: LED OFF", sender_info)
else:
udp_socket.sendto(b"error: unknown command", sender_info)
关键修复:兼容110和116两种超时错误码,不打印正常超时
except OSError as e:
err_code = e.args[0]
110/116都是超时错误,忽略不打印
if err_code in (110, 116):
continue
其他OSError才打印错误
else:
print(f"UDP服务异常: {e}")
continue
其他非超时异常才打印
except Exception as e:
print(f"UDP服务其他错误: {e}")
continue
def get_html_page():
"""单独定义HTML页面,避免格式化冲突"""
html = """
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 LED控制</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 400px;
margin: 50px auto;
text-align: center;
}
.control-btn {
width: 150px;
height: 60px;
font-size: 20px;
margin: 10px;
border: none;
border-radius: 8px;
cursor: pointer;
color: white;
}
#onBtn {
background-color: #4CAF50;
}
#offBtn {
background-color: #f44336;
}
#status {
margin-top: 20px;
font-size: 18px;
color: #333;
}
</style>
</head>
<body>
<h1>ESP32 LED控制器</h1>
<button id="onBtn" class="control-btn">点亮LED</button>
<button id="offBtn" class="control-btn">熄灭LED</button>
<div id="status">等待操作...</div>
<script>
// 使用HTTP请求控制LED,兼容所有浏览器
async function sendCommand(cmd) {
try {
const response = await fetch(`/light/${cmd}`);
const result = await response.text();
document.getElementById('status').textContent = `操作结果: ${result}`;
} catch (err) {
document.getElementById('status').textContent = `操作失败: ${err}`;
}
}
// 绑定按钮事件
document.getElementById('onBtn').addEventListener('click', () => {
sendCommand("on");
});
document.getElementById('offBtn').addEventListener('click', () => {
sendCommand("off");
});
</script>
</body>
</html>
在嵌入式设备(ESP32)上构建一套 “局域网内可视化、跨设备兼容” 的硬件控制方案,
weixin_462901972026-03-20 11:24
相关推荐
疯狂成瘾者1 小时前
语义分块提升RAG检索精度小陈工3 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“A__tao7 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)研究点啥好呢7 小时前
Github热门项目推荐 | 创建你的像素风格!迷藏4947 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障明日清晨8 小时前
python扫码登录dybazhange8 小时前
python如何像matlab一样使用向量化替代for循环人工干智能8 小时前
科普:python中你写的模块找不到了——`ModuleNotFoundError`unicrom_深圳市由你创科技8 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?小敬爱吃饭8 小时前
Ragflow Docker部署及问题解决方案(界面为Welcome to nginx,ragflow上传文件失败,Docker中的ragflow-cpu-1一直重启)