1. 项目需求
目标是通过网页实现对BeagleBone上LED灯的控制,并能够启动和停止效果。通过Flask框架实现网页的创建和与硬件的交互。
2. 处理思路
使用Flask作为服务端框架,在网页端点击按钮触发服务器的控制脚本,进而控制BeagleBone的LED灯状态。按下按钮时,通过Python脚本控制GPIO设备上的LED灯亮灭。
3.流程图
4. 实现步骤
4.1 使用Flask创建网页
Flask是一个轻量级的Web框架,非常适合小型项目,它通过路由(route)来接收HTTP请求,并与后端的逻辑交互。在本项目中,Flask用于接收前端请求,控制LED灯的开关,并将状态返回给前端显示。
主要特点:
- 轻量级:没有太多的内置功能,开发者可以根据需要添加库和插件。
- 灵活性:开发者可以自由配置应用结构,选择自己喜欢的工具和库。
- 简单易用:API 简单直观,适合快速开发。
- 扩展性:通过扩展可以轻松加入更多功能,如数据库、认证、表单处理等。
基本功能:
- 路由系统:将 URL 与视图函数绑定。
- 模板引擎:通过 Jinja2 渲染动态 HTML 页面。
- 静态文件支持:可以处理 CSS、JS、图片等静态资源。
Flask 的简洁性使得它特别适合用来构建小型应用、API 或快速原型,但对于大型复杂应用,可能需要更多的手动配置。
4.2 LED控制功能实现
LED的控制功能使用了Python脚本seqLED.py
,该脚本会让LED灯闪烁。这个脚本会通过subprocess
模块在Flask应用中启动或停止。
seqLED.py
脚本示例:
import time
import os
LEDs = 4
LEDPATH = '/sys/class/leds/beaglebone:green:usr'
# 关闭触发器
for i in range(LEDs):
with open(LEDPATH + str(i) + "/trigger", "w") as f:
f.write("none")
# 打开每个LED的亮度文件
f = [open(LEDPATH + str(i) + "/brightness", "w") for i in range(LEDs)]
# 流水灯效果
while True:
for i in range(LEDs):
f[i].seek(0)
f[i].write("1")
time.sleep(0.25)
for i in range(LEDs):
f[i].seek(0)
f[i].write("0")
time.sleep(0.25)
在Flask中,我们通过subprocess.Popen
来启动这个脚本,并且通过terminate()
方法停止它,从而控制流水灯的启停。
4.3 Flask后端代码
在后端,我们创建了一个简单的路由/<action>
来处理LED的开关。根据请求的action
(开启、关闭、闪烁),调用相应的函数控制LED。
后端代码示例:
import time
from flask import Flask, render_template
import os
import threading # 引入多线程
app = Flask(__name__)
LEDs = 4 # 要控制的LED数量
LEDPATH = '/sys/class/leds/beaglebone:green:usr'
flashing = False # 控制闪烁的标志位
led_thread = None # 用于存储闪烁线程
# 关闭所有LED的触发器,防止它们根据其他条件自动改变状态
for i in range(LEDs):
try:
with open(os.path.join(LEDPATH + str(i), "trigger"), "w") as f:
f.write("none")
except IOError as e:
print(f"错误:无法关闭LED {i} 的触发器: {e}")
# 为每个LED的亮度控制打开文件
brightness_files = []
for i in range(LEDs):
try:
brightness_files.append(open(os.path.join(LEDPATH + str(i), "brightness"), "w"))
except IOError as e:
print(f"错误:无法打开LED {i} 的亮度文件: {e}")
# 控制LED开启的函数
def turn_on_leds():
brightness_files[1].seek(0)
brightness_files[1].write("1") # 打开LED
# 控制LED关闭的函数
def turn_off_leds():
brightness_files[1].seek(0)
brightness_files[1].write("0") # 关闭LED
# 控制LED闪烁的函数
def turn_shan_leds():
global flashing
while flashing: # 闪烁开启时一直运行
brightness_files[1].seek(0)
brightness_files[1].write("1") # 打开LED
time.sleep(1) # 闪烁间隔
brightness_files[1].seek(0)
brightness_files[1].write("0") # 关闭LED
time.sleep(1) # 闪烁间隔
# 启动闪烁的线程
def start_blinking():
global led_thread, flashing
if led_thread is None or not led_thread.is_alive(): # 如果闪烁线程没有启动,或者已经停止
flashing = True
led_thread = threading.Thread(target=turn_shan_leds) # 启动新线程
led_thread.start()
# 停止闪烁的线程
def stop_blinking():
global flashing
flashing = False
if led_thread is not None:
led_thread.join() # 等待线程结束
turn_off_leds() # 关闭LED
@app.route("/")
def index():
state = 0 # 默认页面,显示当前LED的状态
templateData = {
"title": "GPIO output Status",
"led": state,
}
return render_template("index.html", **templateData)
@app.route("/<action>")
def action(action):
global flashing
if action == "on":
turn_on_leds() # 打开LED
state = 1 # 更新状态为开启
elif action == "off":
stop_blinking() # 停止闪烁并关闭LED
state = 0 # 更新状态为关闭
elif action == "shan":
start_blinking() # 启动闪烁
state = 2 # 更新状态为闪烁中
# 返回更新后的页面
templateData = {
"led": state,
}
return render_template("index.html", **templateData)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=3082, debug=True)
4.4 前端网页
在前端,根据LED的状态(开启或关闭)显示不同的按钮文本。
前端代码示例:
<!DOCTYPE html>
<head>
<title>GPIO Control</title>
<link rel="stylesheet" href='../static/style.css' />
</head>
<body>
<h2>网页控制LED BBB</h2>
<h3> Status </h3>
LED ==> {{ led }}
<br>
<h3> Commands </h3>
LED Ctrl ==>
<a href="/on">ON</a>
<a href="/off">OFF</a>
<a href="/shan">闪烁</a>
</body>
</html>
4.5 按钮逻辑
- On: 当LED为关闭状态时,点击按钮后会开小灯,LED灯亮起。
- Off: 当LED为开启状态时,点击按钮后会关闭小灯,LED灯熄灭。
- 闪烁: 当LED为闪烁状态时,点击按钮后会以1s闪烁小灯。
5 效果展示
网页点击ON的时候,板卡上的LED灯亮起
网页点击OFF的时候,板卡上的LED灯灭掉
网页点击闪烁的时候,板卡上的LED灯以1s的周期进行闪烁
项目总结
本项目的目标是通过Flask框架创建一个网页,实现对BeagleBone上LED灯的控制,并能够启动和停止流水灯效果。以下是本项目的概括总结:
1. 技术栈
- Flask:用于搭建Web应用,接收前端请求并与硬件进行交互。
- Python:用于编写控制LED灯状态的逻辑,启动和停止效果。
- HTML + CSS:构建前端界面,实现LED灯的状态显示和控制按钮。
2. 功能实现
- Flask路由:通过Flask定义了多个路由,其中
/
用于渲染首页,/control_led
用于接收控制命令(如开启、关闭LED)。 - LED控制:通过Python脚本控制BeagleBone上的LED灯,使用
subprocess
模块启动或停止流水灯脚本。 - 前端交互:前端页面展示LED的当前状态,用户可以通过按钮控制LED的开关,按钮文本会根据状态动态变化。
3. 工作流程
- 用户通过网页点击“Turn On”或“Turn Off”按钮,触发Flask后端的路由。
- 后端接收到请求后,根据按钮的状态,启动或停止LED流水灯的脚本。
- LED的状态会实时反馈到前端页面,按钮文本和LED的显示颜色会随之变化。
4. 代码概述
main.py
:负责控制LED灯以流水灯的效果闪烁。- Flask后端:使用Flask创建Web服务,管理LED的状态,启动和停止流水灯脚本。
- 前端页面:展示LED的状态,并提供控制按钮,按钮根据LED状态切换文本。
5. 优化方向
- 可以扩展为多盏LED的控制,支持个性化配置。
- 增强界面交互效果,例如实时显示LED灯的状态。
- 在Flask中引入异步处理,以支持更复杂的控制逻辑。
6.遇到的问题
因为我在学校,在校园网因为想连接校园网需要验证,但是板卡不能验证身份,也想通过无线网卡连接WiFi,确发现配置的时候老是出现问题,突然想到,我们电脑自带网口,为何不让电脑的WiFi连接到板卡上呢,这样我们直接连接到我们的电脑上的WiFi,连接上WiFi才能下载我们的包文件进行更新,这样才能添加我们的包。
这里我选择共享WiFi。
这里是主要将我们的WiFi连接到我们的网口上,需要将网口的网段配置相同,才能实现网络连接,然后记住一点的就是,每次重启的时候,我们都需要重新共享网络
通过这个项目,我们实现了从网页控制硬件设备(LED灯)的功能,掌握了Flask与硬件交互的基本方法,为更多嵌入式设备控制提供了基础框架。