Funpack3-5 基于BeagleBone Black的控制LED网页制作
该项目使用了BeagleBone Black开发板,实现了通过网页控制LED的设计,它的主要功能为:访问部署在BeagleBone Black的Web服务,控制板子上LED的亮灭。。
标签
Funpack活动
开发板
magmadimsum
更新2025-01-14
北京邮电大学
4

项目描述:基于 BeagleBone Black 的网页 LED 控制系统

一、项目背景

随着物联网技术的发展,智能家居逐渐成为现代生活的重要组成部分。通过网络控制家庭设备,不仅可以提升生活的便利性,还能实现能源的高效管理。本项目旨在利用 BeagleBone Black(BBB)开发一个基于网页的 LED 控制系统,使用户能够通过互联网轻松控制 LED 灯的状态。该项目不仅具有实用价值,还能帮助用户深入理解嵌入式系统和网络编程的基本原理。

二、项目目标

本项目的主要目标包括:

  1. 搭建一个稳定的网页服务器,能够接收用户请求并控制 LED 灯。
  2. 实现 LED 灯的开关控制和闪烁功能,提供简单直观的用户界面。

三、设计思路

本项目的设计思路是通过 BeagleBone Black 的 GPIO 接口控制 LED 灯,同时通过 Flask 框架搭建一个简易的网页服务器。用户可以通过网页发送请求,服务器接收到请求后,通过处理请求中的数据来控制 LED 的状态。

具体设计流程如下:

  1. 硬件连接:将多个 LED 灯连接到 BBB 的 GPIO 引脚,确保每个 LED 的状态都可以独立控制。
  2. 网页服务器搭建:使用 Flask 框架搭建网页服务器,处理用户的 GET 和 POST 请求。
  3. 控制逻辑实现:编写控制 LED 的逻辑,包括开、关和闪烁功能。
  4. 用户界面设计:设计简洁易用的网页界面,用户可以通过点击按钮轻松控制 LED。

四、硬件组成

  1. BeagleBone Black(BBB):作为项目的核心控制器,提供强大的处理能力和丰富的接口。
  2. LED 灯:多个 LED 灯用于显示状态,连接到 BBB 的 GPIO 引脚。
  3. 电阻:用于限制 LED 的电流,保护 LED 不被烧毁。
  4. 面包板和跳线:用于连接 LED 和 BBB,方便搭建电路。

五、软件组件

  1. 操作系统:使用 Debian 等 Linux 发行版作为 BBB 的操作系统,提供稳定的运行环境。
  2. Flask:轻量级的 Python Web 框架,用于搭建网页服务器。
  3. HTML:用于设计用户界面,实现与服务器的交互。
  4. Python:用于编写控制逻辑和处理用户请求。

六、软件流图
image.png

七、实物演示

image.png
image.png

image.png


八、代码

Python代码:(说明在注释中)

# Flask app
app = Flask(__name__)


@app.route('/', methods=['GET'])
def home(): # 更改所有的LED为可控制状态
os.system(
'echo none > /sys/devices/platform/leds/leds/beaglebone:green:usr0/trigger')
os.system(
'echo none > /sys/devices/platform/leds/leds/beaglebone:green:usr1/trigger')
os.system(
'echo none > /sys/devices/platform/leds/leds/beaglebone:green:usr2/trigger')
os.system(
'echo none > /sys/devices/platform/leds/leds/beaglebone:green:usr3/trigger')
set_states(linesLED, [0, 0, 0, 0])
set_states(linesGPIO, [0, 0])
return redirect('/led')


@app.route('/led', methods=['GET', 'POST'])
def LED(): # 控制 LED 的主函数
try:
if request.method == 'POST': # 处理 POST 请求
data = request.get_json() # 获取请求中的 JSON 数据
LEDstates = get_states(['LED0', 'LED1', 'LED2', 'LED3'], data) # 获取当前 LED 状态

if "default" in data: # 如果请求数据中包含 "default"
resetLED() # 重置所有 LED 到默认状态
else:
if 'blink' in data: # 如果请求数据中包含 "blink"
times = int(data.get('times', 0)) # 获取闪烁次数
gap_time = float(data.get('gap_time', 0.5)) # 获取闪烁间隔时间
blink(times, gap_time, linesLED, LEDstates) # 调用闪烁函数
else:
set_states(linesLED, LEDstates) # 设置 LED 状态

return jsonify({"status": "success"}) # 返回成功响应

else: # 处理 GET 请求
set_states(linesLED, [0, 0, 0, 0]) # 将所有 LED 状态设置为关闭
return render_template('led.html') # 渲染 LED 控制的 HTML 页面

except Exception as e: # 捕获异常
print(f"An error occurred: {e}") # 打印错误信息
return jsonify({"status": "error", "message": str(e)}), 500 # 返回错误响应


@app.route('/gpio', methods=['GET', 'POST'])
def GPIO(): # 控制 GPIO 的主函数
# 此处与LED控制部分同理,省略


if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001) # 广播到所有5001端口

HTML代码:

//led.html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <title>BBB LED Controller</title>
    <meta charset="utf-8" />
    <style>
      body {
        font-family: Arial, sans-serif;
      }
      form {
        margin: 20px;
      }
      label {
        margin-right: 10px;
      }
      input[type="submit"],
      input[type="reset"] {
        margin-right: 10px;
        margin-top: 10px;
      }
    </style>
  </head>


  <body>
    <header>
      <h1>BeagleBone Black LED Controller</h1>
    </header>


    <main>
      <form id="ledForm" action="" method="post">
        <p>
          <label for="LED0">LED0</label>
          亮
          <input type="radio" id="LED0" value="1" name="LED0" />
        </p>


        <p>
          <label for="LED1">LED1</label>
          亮
          <input type="radio" id="LED1" value="1" name="LED1" />
        </p>


        <p>
          <label for="LED2">LED2</label>
          亮
          <input type="radio" id="LED2" value="1" name="LED2" />
        </p>


        <p>
          <label for="LED3">LED3</label>
          亮
          <input type="radio" id="LED3" value="1" name="LED3" />
        </p>


        <p>
          <label for="blink">闪烁</label>
          <input type="checkbox" id="blink" value="1" name="blink" />
        </p>


        <p>
          <label for="times">闪烁次数</label>
          <input type="number" id="times" value="5" name="times" min="1" />
        </p>


        <p>
          <label for="gap_time">闪烁间隔</label>
          <input
            type="number"
            id="gap_time"
            value="1"
            name="gap_time"
            min="0.1"
            step="0.1"
          />
        </p>


        <p>
          <label for="default">默认</label>
          <input type="checkbox" id="default" value="1" name="default" />
        </p>


        <input type="submit" id="submitBtn" value="提交" />
        <input type="reset" value="重置" />
      </form>


      <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="gpio">GPIO</a></p>
    </main>


    <footer></footer>
    <script>
      document
        .getElementById("submitBtn")
        .addEventListener("click", function (event) {
          event.preventDefault(); // Prevent form from submitting the default way


          const formData = new FormData(document.getElementById("ledForm"));


          // Convert FormData to JSON
          const data = {};
          formData.forEach((value, key) => {
            data[key] = value;
          });


          // Fetch API to handle the asynchronous request
          fetch("/led", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify(data),
          })
            .then((response) => response.json()) // Process the server response as JSON
            .then((data) => {
              if (data.status === "success") {
                alert("Form submitted successfully!");
              } else {
                alert("Form submission failed.");
              }
            })
            .catch((error) => {
              // Handle error
              alert("An error occurred while submitting the form.");
              console.error("Error:", error);
            });
        });
    </script>
  </body>
</html>
//gpiod.html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <title>BBB GPIO Controller</title>
    <meta charset="utf-8" />
    <style>
      body {
        font-family: Arial, sans-serif;
      }


      form {
        margin: 20px;
      }


      label {
        margin-right: 10px;
      }


      input[type="submit"],
      input[type="reset"] {
        margin-right: 10px;
        margin-top: 10px;
      }
    </style>
  </head>


  <body>
    <header>
      <h1>BeagleBone Black GPIO Controller</h1>
    </header>


    <main>
      <form id="gpioForm" action="" method="post">
        <p>
          <label for="GPIO18">GPIO18</label>
          亮
          <input type="radio" id="GPIO18" value="1" name="GPIO18" />
        </p>


        <p>
          <label for="GPIO19">GPIO19</label>
          亮
          <input type="radio" id="GPIO19" value="1" name="GPIO19" />
        </p>


        <p>
          <label for="blink">闪烁</label>
          <input type="checkbox" id="blink" value="1" name="blink" />
        </p>


        <p>
          <label for="times">闪烁次数</label>
          <input type="number" id="times" value="5" name="times" min="1" />
        </p>


        <p>
          <label for="gap_time">闪烁间隔</label>
          <input
            type="number"
            id="gap_time"
            value="1"
            name="gap_time"
            min="0.1"
            step="0.1"
          />
        </p>


        <input type="submit" id="submitBtn" value="提交" />
        <input type="reset" value="重置" />
      </form>


      <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="led">LED</a></p>
    </main>


    <footer></footer>
    <script>
      document
        .getElementById("submitBtn")
        .addEventListener("click", function (event) {
          event.preventDefault(); // Prevent form from submitting the default way


          const formData = new FormData(document.getElementById("gpioForm"));


          // Convert FormData to JSON
          const data = {};
          formData.forEach((value, key) => {
            data[key] = value;
          });


          // Fetch API to handle the asynchronous request
          fetch("/gpio", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify(data),
          })
            .then((response) => response.json()) // Process the server response as JSON
            .then((data) => {
              if (data.status === "success") {
                alert("Form submitted successfully!");
              } else {
                alert("Form submission failed.");
              }
            })
            .catch((error) => {
              // Handle error
              alert("An error occurred while submitting the form.");
              console.error("Error:", error);
            });
        });
    </script>
  </body>
</html>


附件下载
code.zip
代码
团队介绍
北京邮电大学
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号