Micro Python HTTP服务器和Web页面示例
前言:
本示例展示了如何使用MicroPython在一个嵌入式开发板CanMV-K230上创建一个简单的Web服务器,该服务器可以用来通过Web浏览器控制一个LED灯的状态(开/关)。此外,还提供了一个简单的网页,允许用户通过点击按钮来改变LED的状态 实现人机交互,并实时查看当前状态。
通过这示例你可以了解到:
- 连接WiFi网络;
- 使用MicroPython创建一个基本的HTTP服务器;
- 通过Web界面远程控制硬件设备。
源码:
'''
实验名称:HTTP网页控制LED
实验平台:01Studio CanMV-K230
日期:2024-9-15
教程:wiki.01studio.cc
作者:杀破狼
版本:v1.0
'''
import usocket
import network, socket, time, os, sys, utime
from machine import Pin
from media.sensor import * # 导入sensor模块,使用摄像头相关接口
from media.display import * # 导入display模块,使用display相关接口
from media.media import * # 导入media模块,使用media相关接口
# LED初始化
LED = Pin(52, Pin.OUT) # 初始化为输出模式,默认高电平点亮
time.sleep(2) # 等待WiFi模块初始化
SSID = ''
PASSWORD = ''
# 初始化媒体管理器
MediaManager.init()
# WIFI连接函数
def WIFI_Connect():
WIFI_LED = Pin(52, Pin.OUT) # 使用相同的LED引脚作为WIFI指示灯
wlan = network.WLAN(network.STA_IF) # STA模式
wlan.active(True) # 激活WIFI接口
if not wlan.isconnected():
print('正在连接...')
# 输入WIFI账号密码(仅支持2.4G信号)
wlan.connect(SSID, PASSWORD)
if wlan.isconnected(): # 连接成功
# LED蓝灯点亮
WIFI_LED.value(1)
# 串口打印信息
print('IP:', wlan.ifconfig())
return wlan.ifconfig()[0]
else: # 连接失败
# LED闪烁3次提示
for i in range(3):
WIFI_LED.value(1)
utime.sleep_ms(300)
WIFI_LED.value(0)
utime.sleep_ms(300)
wlan.active(False)
return None
# HTTP服务
def handle_client(cl, addr, request_str):
# 获取请求行
request_line = request_str.split('\r\n')[0]
method, path, _ = request_line.split()
if path == '/':
# 返回主页
response = web_page()
elif path == '/led':
# 处理LED控制请求
content_length = int(request_str.split('Content-Length: ')[1].split('\r\n')[0])
post_data = request_str.split('\r\n\r\n')[1][:content_length]
if 'state=on' in post_data:
LED.value(1) # 点亮
print('LED ON')
response = 'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nLED ON'
elif 'state=off' in post_data:
LED.value(0) # 熄灭
print('LED OFF')
response = 'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nLED OFF'
elif path == '/status':
# 返回LED状态
led_status = "ON" if LED.value() == 1 else "OFF"
response = f'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n{led_status}'
else:
# 资源未找到
response = 'HTTP/1.1 404 NOT FOUND\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nResource not found.'
cl.send(response.encode())
cl.close()
utime.sleep(0.3) # 确保所有数据都已发送完毕
def web_page():
led_value = LED.value()
# 设置按钮的颜色
button_color = "#4CAF50" if led_value == 0 else "#D32F2F" # LED熄灭时按钮绿色,点亮时按钮红色
html = f"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CanMV K230 LED Control</title>
<style>
body {{
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
padding: 1rem;
margin: 0;
box-sizing: border-box;
}}
.container {{
width: 100%;
max-width: 600px;
text-align: center;
}}
h1, p {{
margin: 0.5rem 0;
}}
.button {{
display: inline-block;
border: none;
border-radius: 4px;
color: white;
padding: 12px 24px;
text-decoration: none;
font-size: 16px;
margin: 0.5rem 0;
cursor: pointer;
width: 100%;
max-width: 300px;
}}
@media screen and (max-width: 600px) {{
.button {{
width: 100%;
}}
}}
</style>
<script>
function toggleLED() {{
var xhr = new XMLHttpRequest();
xhr.open("POST", "/led", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("state=" + (document.querySelector('.button').innerText === 'ON' ? 'off' : 'on'));
updateStatus(); // 更新状态
}}
function updateStatus() {{
var xhr = new XMLHttpRequest();
xhr.open("GET", "/status", true);
xhr.onload = function() {{
if (this.status === 200) {{
document.querySelector('.button').style.backgroundColor = this.responseText === 'ON' ? '#D32F2F' : '#4CAF50';
document.querySelector('.button').innerText = this.responseText === 'ON' ? 'ON' : 'OFF';
}}
}};
xhr.send();
}}
</script>
</head>
<body onload="updateStatus()">
<div class="container">
<h1>CanMV K230 LED Control</h1>
<button class="button" style="background-color: {button_color};"
onclick="toggleLED()">{"ON" if led_value == 1 else "OFF"}</button>
</div>
</body>
</html>"""
return f'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n{html}'
try:
ip_address = WIFI_Connect()
if ip_address is not None:
addr = socket.getaddrinfo(ip_address, 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print(f'服务器监听 {ip_address}:80')
while True:
os.exitpoint() # 检测IDE中断
cl, addr = s.accept()
print('客户端从', addr, '连接')
request = cl.recv(1024)
request_str = request.decode()
if 'HTTP' in request_str: # 判断是否为HTTP请求
handle_client(cl, addr, request_str)
except KeyboardInterrupt:
print("用户停止程序")
except Exception as e:
print(f"发生异常: {e}")
finally:
MediaManager.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
使用方法: 运行此代码之后在终端查看服务器监听得IP和端口,列如: 192.168.1.101:80
然后在浏览器得地址栏输入对应IP与端口: