项目描述
项目简介
本项目实现了在Beaglebone Black板子上面,使用Rust编程语言编写web服务器,并且在Beaglebone Black中部署web服务器。通过web服务器的网页实现控制板子上的四个LED的功能。
硬件介绍
BeagleBone Black 是一款基于开放源代码的单板计算机 (SBC),由 BeagleBoard 开发。它采用TI的处理器AM3359 Cortex-A8处理器并且配备了很多接口和外设,比如HDMI,USB等等。BeagleBone Black 拥有强大的社区支持,并且有大量的教程和库,是特别适合初学者的一款SBC。
设计思路
本次项目的设计思路非常简单,就是在Beaglebone Black中启动一个网页,并且监听对应的端口。然后在手机浏览器上访问Beaglebone Black上对应的端口,实现控制Beaglebone Black上LED的效果
软件流程图
本项目的核心流程图如下:
其实非常简单,就是在Beaglebone Black里面host一个webserver,然后监听一个端口,并且在网页后端控制LED。然后使用手机访问对应的端口,触发对应的LED。
我也借此机会,学习了Rust的web服务器开发,并且使用了salvo库,成功地在Beaglebone里面使用Rust实现了一个后端服务器并且控制板子上的LED,Rust的核心代码如下:
use salvo::prelude::*;
use std::fs::OpenOptions;
use std::io::Write;
use std::path::Path;
static LEDPATH: &str = "/sys/class/leds/beaglebone:green:usr";
#[handler]
async fn control_led(req: &mut Request, res: &mut Response) {
let led_number = req.param::<usize>("led_number").unwrap_or(1);
let action = req.param::<String>("action").unwrap_or("off".to_string());
// Adjust the led_number to zero-based indexing
let led_path = format!("{}{}/brightness", Path::new(LEDPATH).display(), (led_number - 1).to_string());
println!("led path: {}", led_path);
// Open the brightness file and write to it based on the action
let mut file = OpenOptions::new().write(true).open(led_path).unwrap();
if action == "on" {
file.write_all(b"1").unwrap();
} else {
file.write_all(b"0").unwrap();
}
res.render("LED action executed");
}
#[handler]
async fn index(res: &mut Response) {
res.render(Text::Html(INDEX_HTML.to_string()));
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt().init();
let router = Router::new()
.get(index)
.push(Router::with_path("control_led/<led_number>/<action>").get(control_led));
let acceptor = TcpListener::new("127.0.0.1:5800").bind().await;
Server::new(acceptor).serve(router).await;
}
static INDEX_HTML: &str = r#"<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LED Control</title>
<script>
// 通过 fetch API 向服务器发送控制命令
async function controlLED(ledNumber, action) {
try {
const response = await fetch(`/control_led/${ledNumber}/${action}`);
const data = await response.json();
document.getElementById('statusDisplay').innerText = `LED${ledNumber} is now ${data.status}`;
} catch (error) {
console.error('Error controlling LED:', error);
}
}
</script>
</head>
<body>
<h1>Control LEDs</h1>
<!-- LED 控制按钮 -->
<button onclick="controlLED(1, 'on')">Turn LED1 ON</button>
<button onclick="controlLED(1, 'off')">Turn LED1 OFF</button>
<br>
<button onclick="controlLED(2, 'on')">Turn LED2 ON</button>
<button onclick="controlLED(2, 'off')">Turn LED2 OFF</button>
<br>
<button onclick="controlLED(3, 'on')">Turn LED3 ON</button>
<button onclick="controlLED(3, 'off')">Turn LED3 OFF</button>
<br>
<button onclick="controlLED(4, 'on')">Turn LED4 ON</button>
<button onclick="controlLED(4, 'off')">Turn LED4 OFF</button>
<!-- 显示状态 -->
<p id="statusDisplay"></p>
</body>
</html>
"#;
代码也非常简单:主函数中,路由器设置了首页和控制LED的路径,然后在对应的handler中,实现了根据不同按钮的参数来控制不同的LED
功能展示以及说明
首先在手机上打开网页:
可以看到网页上我写了8个按键,分别对应4个LED的控制功能,点击Turn LED ON,就可以打开对应的LED,这里可以看到,左边的LED已经打开了。
打开全部4个LED:
然后点击右边的关闭:
关闭全部4个LED:
心得体会
通过本次在 Beaglebone Black 上使用 Rust 编程语言实现 Web 服务器来控制硬件 LED,我对嵌入式系统、Web 开发以及 Rust 编程有了更加深入的理解。感谢FunPack活动能够给我机会让我玩到好玩的板子并且实现自己的想法🫶