Funpack3-5:基于BeagleBone® Black的网页LED控制
该项目使用了BeagleBone® Black,实现了网页LED控制的设计,它的主要功能为:基于BeagleBone上的AM3358,运行Linux在其中部署网页,控制板载LED。
标签
嵌入式系统
Funpack活动
开发板
振青666
更新2025-01-14
贵州大学
43

1 项目简介

本项目使用BeagleBone Black开发板(以下简称:BBB开发板)控制板载LED。通过Web界面,用户可以控制每个LED的开关状态,实现全开和全关操作。项目使用Node.js作为服务器端技术栈,Express.js作为Web服务器框架,Socket.IO实现前后端实时通信,EJS作为模板引擎渲染页面。

2 环境准备

2.1 下载并烧录最新的官方镜像

在路由器后台查询开发板ip,使用ssh登录到开发板,或者使用cloud9

2.2 安装node

sudo apt update && sudo apt full-upgrade
sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y build-essential nodejs

执行上述命令,安装Node.js 18 LTS

安装完成后,执行

node -v
npm -v

返回如下图所示,表示安装成功

image.png

2.3 安装pm2用于管理node项目

注意使用管理员权限,不然不能全局安装

sudo npm install pm2@latest -g

3 工程介绍

工程中主要代码为后端server.js、前端index.html

后端流程图如下

前端流程图如下

3.1 设计思路

想要控制BBB开发板控制LED开关,只需要通过命令行控制,下面这行代码即可打开LED0

echo 1 > /sys/class/leds/beaglebone:green:usr0/brightness

BBB开发板有四个led分别对应usr0、usr1、usr2、usr3通过控制他们的brightness控制位为0或1点亮或关闭led

设计网页,点击对应按钮后,执行响应操作即可实现对led的控制

由于BBB开发板系统内对led有占用,会导致usr0和usr2不规律闪烁,因此在程序执行前需要关闭其他触发器对led的占用

for led in /sys/class/leds/beaglebone:green:usr*/; do
echo none > $led/trigger
done

3.2 核心代码

3.2.1 初始化LED

后端启动时,关闭其他触发器对led的占用,并使全部led为关闭状态

function initializeLEDs() {
  const command = 'for led in /sys/class/leds/beaglebone:green:usr*/; do echo none > $led/trigger; done';
  childProcess.exec(command, (error, stdout, stderr) => {
    if (error) {
      console.error(`exec error: ${error}`);
      return;
    }
    // 可以在这里打印输出或错误信息
    console.log(`stdout: ${stdout}`);
    console.error(`stderr: ${stderr}`);
  });
}

3.2.2 LED状态广播

为了确保每个网页客户端打开后,led状态统一,在客户端链接时,向客户端发送当前led状态,

io.on('connection', (socket) => {
  console.log('A user connected');

  for (let i = 0; i < 4; i++) {
    exec(`cat /sys/class/leds/beaglebone:green:usr${i}/brightness`, (error, stdout, stderr) => {
      if (error) {
        console.error(`exec error: ${error}`);
        return;
      }
      const state = parseInt(stdout) === 1;
      ledStates[i] = state;
      socket.emit('ledStatus', i, state);
    });
  }

3.2.3 LED操作命令执行

执行对应led的开关命令

function execCommands(turnOn) {
  for (let i = 0; i < 4; i++) {
    const ledPath = `/sys/class/leds/beaglebone:green:usr${i}/`;
    exec(`echo none > ${ledPath}trigger`, (error) => {
      if (error) console.error(`exec error: ${error}`);
    });
    exec(`echo ${turnOn ? 1 : 0} > ${ledPath}brightness`, (error) => {
      if (error) console.error(`exec error: ${error}`);
      io.emit('ledStatus', i, turnOn);
    });
  }
}

3.2.4 前端程序

index.html 文件通常是一个网页的入口点,包含 HTML、CSS 和 JavaScript 代码,用于定义网页的结构、样式和行为。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Funpack3-5 LED Control</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      padding-top: 50px;
    }
    .led-container {
      display: inline-block;
      margin: 0 10px;
    }
    .led {
      width: 50px;
      height: 50px;
      border-radius: 50%;
      background-color: #ccc;
      border: 2px solid #000;
      cursor: pointer;
      display: inline-block;
    }
    button {
      margin: 10px;
      padding: 10px 20px;
      font-size: 16px;
    }
    .buttons-row {
      text-align: center;
      margin-top: 20px;
    }
  </style>
</head>
<body>
  <h1>Funpack3-5 LED Control</h1>
  <!-- LED circles with onclick event listeners -->
  <div class="led-container"><div class="led" id="led0" onclick="toggleLED(0)"></div></div>
  <div class="led-container"><div class="led" id="led1" onclick="toggleLED(1)"></div></div>
  <div class="led-container"><div class="led" id="led2" onclick="toggleLED(2)"></div></div>
  <div class="led-container"><div class="led" id="led3" onclick="toggleLED(3)"></div></div>
  <!-- Buttons row -->
  <div class="buttons-row">
    <button onclick="turnOnLEDs()">全开</button>
    <button onclick="turnOffLEDs()">全关</button>
  </div>


  <script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
  <script>
    const socket = io();
    let ledStates = {0: false, 1: false, 2: false, 3: false};


    function turnOnLEDs() {
      socket.emit('turnOnLEDs');
    }


    function turnOffLEDs() {
      socket.emit('turnOffLEDs');
    }


    function toggleLED(ledNumber) {
      const newState = !ledStates[ledNumber];
      socket.emit('toggleLED', ledNumber, newState);
      ledStates[ledNumber] = newState;
      updateLEDStatus(ledNumber, newState);
    }


    function updateLEDStatus(ledNumber, isOn) {
      const ledElement = document.getElementById('led' + ledNumber);
      ledElement.style.backgroundColor = isOn ? 'red' : '#ccc';
    }


    // 监听服务器发送的LED状态更新事件
    socket.on('ledStatus', (ledNumber, isOn) => {
      ledStates[ledNumber] = isOn;
      updateLEDStatus(ledNumber, isOn);
    });
  </script>
</body>
</html>

4 部署流程与效果

4.1 部署完成nodejs后,打开下载的工程文件

在项目文件夹中,运行下面的命令安装依赖

npm install express socket.io ejs

4.2 启动工程

在项目文件夹中,运行下面的命令启动项目

node server.js

返回如下条目即运行成功

image.png

打开 http://<BeagleBone-IP>:9000 ,即可访问网页客户端,点击按钮点亮对应的LED,效果如下:

image.png

image.png

4.3 部署工程并开机启动(可选)

4.3.1 输入下面的代码,使用pm2部署服务

pm2 start server.js --name funpack3
或以下命令指定运行的端口,默认监听9000
​pm2 start server.js --name funpack3 --port=9000

4.3.2 查询pm2运行状态

pm2 status​

image.png

可以看到已经成功运行

4.3.3 保存配置

pm2 save

image.png

4.3.4 开机启动

pm2 startup

这个命令会检测你的操作系统,并提供一个命令,让你复制并执行。这个命令会安装一个系统服务,用于管理PM2的启动。

image.png
比如这里这个指令是

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u debian --hp /home/debian

执行即可开机启动

4.4 防火墙配置(或许需要)

使用iptables 管理防火墙,开放9000端口

sudo iptables -A INPUT -p tcp --dport 9000 -j ACCEPT

5 总结

本项目展示了如何使用BeagleBone Black开发板和Node.js技术栈来控制硬件LED。通过Web界面,用户可以直观地控制LED的状态,实现全开和全关操作。




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