Funpack3-5 BeagleBone® Black入门指南与网页点灯
该项目使用了BeagleBone® Black,实现了网页控制板载LED的设计,它的主要功能为:搭建网络环境,实现网页上的开关控制板载LED的开关。
标签
Funpack活动
网页
BeagleBone® Black
henry
更新2025-01-15
7

Funpack3-5 BeagleBone® Black入门指南与网页点灯

所要完成的项目是funpack活动板卡2的任务2:
任务2:在系统中建立一个网页,并且与LED联动,使用网线连接到设备上时,可以从网页中控制LED的开关与闪烁

开发任务主要在板子上linux环境的搭建,连接网络,搭建板卡的开发环境。


开始之前的介绍,很详细,建议通读。

开发环境搭建

连接模式

板卡的连接模式有很多种,本身就可以当作一个小主机(SBC单板计算机)

桌面模式:microHDMI,vnc

命令行:ssh(网络连接),virtual serial port(usb连接的虚拟串口),3.3v的FTDI线缆(串口)


网络

网络连接方式

  • 千兆以太网:RJ45 Port
  • usb共享网络
  • wifi适配器(链接中为官方推荐的wifi适配器)


连接网络

只要通过usb与主机连接,两者就连通了网络

对于主机端的ip:

BBB:

iperf带宽测试小实验

BBB作为主机,默认tcp连接

iperf3 -s

电脑作为主机

iperf3 -c 192.168.7.2

连接公网

上述主机与BBB建立了网络连接,但BBB还未与外网连接

通过usb共享网络可以很方便的实现网络连接

在linux中setting up IP masquerading

在主机上执行ipMasquerade.sh便可以共享主机网络,主要是允许了ipv4的转发,通过iptables添加流量转发规则

在主机上执行setDNS.sh,为BBB添加网关,以及dns,脚本中需要用root用户ssh登录,而默认镜像中是没有root密码的,需要在BBB上执行sudo passwd root设置密码,且默认root是不给ssh登录的,需要更改/etc/ssh/sshd_config中的#PermitRootLogin prohibit-passwordPermitRootLogin yes以允许root的密码模式进行ssh连接(设置后sudo systemctl restart sshd让配置生效)
或直接在开发板更新/etc/resolv.conf与主机相同的dns地址,并添加主机ip为默认网关,与脚本一样

至此已经完成联网


开发环境

在将开发板升级为较新的镜像后(t卡烧录好自动升级板卡mmc的镜像后插入电脑,重启会自动进入tf卡中的系统并执行升级)

镜像

在开发板中执行sudo systemctl start bb-code-server.service启动code-server

在浏览器中打开 http://192.168.7.2:3000 即可进入板子上的vscode开发环境~首次体验这种开发环境,流畅的同时十分高效


任务

网页与LED联动

目标:

在系统中建立一个网页,并且与LED联动,使用网线连接到设备上时,可以从网页中控制LED的开关与闪烁

教程:

flask网页点灯

完整的copy仿照里面的app3.py其实就以及完成这个任务了

但默认的文字的界面实在不好看,且板子上有四个led,我们将他们统统控制起来,调整样式,最终效果如下(功能展示及说明):以及闪烁开关:

与实物的照片:


部分关键代码解析:

通过python搭建网页后台

使用库Flask搭建后台

from flask import Flask, render_template, jsonify

linux开发环境中将板子上的四个led注册到了文件系统中,

路径在:/sys/class/leds/beaglebone:green:usr0/为usr0到usr3

注册html中的事件回调来控制led的开关

@app.route('/toggle_led/<int:led_index>')
def toggle_led(led_index):
    current_state = get_led_state(led_index)
    new_state = 'off' if current_state == 'on' else 'on'
    set_led_state(led_index, new_state)
    return jsonify({"status": new_state})

再优化下界面,通过图片切换控制并表示led状态


闪烁也是同样的控制逻辑


基本流程,分为网页与后台:


完整代码(服务端):

from flask import Flask, render_template, jsonify
import threading
import time


app = Flask(__name__)


# LED 控制路径
LED_PATHS = [
    "/sys/class/leds/beaglebone:green:usr0/",
    "/sys/class/leds/beaglebone:green:usr1/",
    "/sys/class/leds/beaglebone:green:usr2/",
    "/sys/class/leds/beaglebone:green:usr3/"
]


# LED 状态管理
led_states = [{'state': 'off', 'blink': False, 'last_toggle': 0} for _ in LED_PATHS]
blink_interval = 0.5  # 闪烁间隔(秒)



def write_led_brightness(led_index, value):
    """直接操作 LED 文件写入亮度值"""
    try:
        with open(LED_PATHS[led_index] + 'brightness', 'w') as f:
            f.write(str(value))
    except Exception as e:
        print(f"Error writing LED {led_index} brightness: {e}")



@app.route('/')
def index():
    """主页显示当前 LED 状态"""
    # 初始化时关闭 triggers
    for i in range(len(LED_PATHS)):
        try:
            with open(LED_PATHS[i] + 'trigger', 'w') as f:
                f.write('none')
        except Exception as e:
            print(f"Error setting LED {i} trigger: {e}")
    # 显示所有 LED 状态
    led_states_display = [led['state'] for led in led_states]
    return render_template('index.html', led_states=led_states_display)



@app.route('/toggle_led/<int:led_index>')
def toggle_led(led_index):
    """切换 LED 开关状态"""
    if led_index < 0 or led_index >= len(LED_PATHS):
        return jsonify({'error': 'Invalid LED index'}), 400


    led = led_states[led_index]
    if led['blink']:
        # 如果正在闪烁,停止闪烁
        led['blink'] = False


    # 切换开关状态
    new_state = 'off' if led['state'] == 'on' else 'on'
    led['state'] = new_state
    write_led_brightness(led_index, 1 if new_state == 'on' else 0)


    return jsonify({'status': new_state})



@app.route('/blink_led/<int:led_index>')
def blink_led(led_index):
    """启动或停止 LED 闪烁"""
    if led_index < 0 or led_index >= len(LED_PATHS):
        return jsonify({'error': 'Invalid LED index'}), 400


    led = led_states[led_index]
    if led['blink']:
        # 停止闪烁
        led['blink'] = False
        led['state'] = 'off'
        write_led_brightness(led_index, 0)
        return jsonify({'status': 'off'})
    else:
        # 开始闪烁
        led['blink'] = True
        print("start blink")
        led['last_toggle'] = time.time()
        return jsonify({'status': 'blinking'})



def update_leds():
    """后台线程定期更新 LED 闪烁状态"""
    while True:
        current_time = time.time()
        for i, led in enumerate(led_states):
            if led['blink']:
                # 检查是否需要切换状态
                print("blinking");
                if current_time - led['last_toggle'] >= blink_interval:
                    led['state'] = 'off' if led['state'] == 'on' else 'on'
                    led['last_toggle'] = current_time
                    write_led_brightness(i, 1 if led['state'] == 'on' else 0)
        time.sleep(0.1)  # 减少 CPU 占用


if __name__ == '__main__':
    threading.Thread(target=update_leds, daemon=True).start()
    app.run(host='0.0.0.0', port=5000, debug=True)


对本活动的心得体会:

linux开发板玩起来很有趣,能学到很多东西,选择的板卡也很优秀,有着很多社区支持,有一本入门的cookbook和一个pru的cookbook,指导很详细。希望能多多参加这样的活动,多多学习多多总结与分享。

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