在这段保持社交距离的时期,很难找到更积极和四处走动的方法。与我上学时相比,在线课程几乎不需要在建筑物中走动和在储物柜中交换学习材料。在社区外散步是保持活跃和每天锻炼的好方法,但是,有些日子可能风太大而不能在外面散步,或者可能会下雨。此外,在持续的 COVID-19 期间,留在室内以降低传播或感染病毒的风险变得越来越重要。
这就是为什么我们有动力开发一种有趣的方式来让人们在室内保持活跃和健康!MuSticks 结合了音乐和棍子的理念,让室内锻炼变得实用而有趣。在这些困难时期保持健康并保持活跃很重要,我们希望 MuSticks 能够以这种小方式帮助人们。
该项目使用 Raspberry Pi Zero W、Adafruit Stereo Speaker Bonnet 和 Surface Bone Conductive Transducer 扬声器。我们决定使用换能器,因为它具有在硬表面上转换音频波信号的有趣特性。我们决定使用塑料瓶,但您可以尝试不同的材料。

我们决定把木棍分成三部分。

为了制作完整的棍子,您需要打印两个扬声器支架和两个瓶架。扬声器支架紧贴瓶架,如下所示:

然后使用螺钉/螺母将板/电池连接到瓶架上,如下所示

边框/电池座有两个版本;“Battery and Board Holder.stl ”文件比BBH3.stl文件的比例略小。这种差异允许两个持有人一起抢夺并滚动以关闭并保护内容物。

将硬件放在一起

为了发布我们的 Web 界面,我们需要在我们的 RPi Zero W 中安装 LDAP。您可以找到几个网页来指导您在 Raspberry Pi Zero W 中安装 LDAP。
我们还使用以下命令安装 mp3 实用程序 MPG123:
$ sudo apt-get install mpg123
然后按照此处的 Adafruit Speaker Bonnet for Raspberry Pi 轻松安装中的说明进行操作。
感谢 Adafruit 的说明,我们能够找到 SomaFM
超过 30 个独特的收听者支持的、无商业广告的、地下/替代无线电广播频道向世界传播。
轻松测试扬声器并提供多种选择是理想之选。但是,从 Web 服务运行它并不容易。
现在我们准备好创建我们的界面了。
安装服务器和扬声器后,我们使用“Bootstrap Studio”创建了一个简单的 Web 界面。我们不确定是否可以上传自动生成模板,但我们可以显示我们对代码所做的手动更改。
下图是界面截图:

每个按钮图像都会向服务器的主页提交一个代码,以指示所选电台。代码看起来像
="action" value="selEighties">
src="assets/img/scenery/u80s-120.png" alt="DLS">
="action" value="selDeepSpace">
src="assets/img/scenery/DeepSpaceOne.gif" alt="DLS">
="action" value="selPoptron">
src="assets/img/scenery/poptron120.png" alt="DLS">
="action" value="selMissionC">
src="assets/img/scenery/missioncontrol120.jpg" alt="DLS">
="action" value="selXmas">
src="assets/img/scenery/xmasrocks120.png" alt="DLS">
="action" value="selStop">
src="assets/img/scenery/image1.jpg" alt="DLS">
请注意,value 属性具有在 GET 命令名称操作中发送回服务器的值。
最初的想法是接收选台,然后批处理一个进程在后台运行MPG123,但不可能。对于初学者,除非我们使用 sudo 命令运行 shell 进程,否则程序不会启动。
我们尝试执行以下命令,其中 exec 是生成进程的 PHP 函数:
exec("nohup mpg123 http://ice1.somafm.com/u80s-128-mp3 > /dev/null 2>&1 echo $!");
但它一开始进程就崩溃了 mpg123 程序。
然后我们在命令行中使用 sudo 权限尝试了 shell_exec,例如:
shell_exec('sudo mpg123 http://ice1.somafm.com/u80s-128-mp3 > /dev/null 2>&1 echo $!');
这有效,但需要注意的是该进程永远不会返回到服务器,因此客户端被卡住了,不允许它做出不同的选择。
我们最终决定打破 Web 服务器和 MPG123 程序之间的依赖关系。
我们创建了一个循环运行的 bash 脚本,读取文本命令文件的内容并在主进程级别提交批处理作业以运行 MPG123 程序。该脚本将在下一节中解释。
Web 服务器的工作是获取所选站并将相应的命令代码写入命令文件,以便 bash 脚本可以读取选择并执行该过程。
一个问题是文件访问的并发性,我们是否可以打开它以写入并同时读取以执行命令。是的,我们可以!!!
这是服务器 PHP 程序的一部分,它从客户端获取选择并将命令代码写入命令文件:
//Check if there is a command
if (isset($_GET["action"]))
{
//Open file to write
$myfile = fopen("runSelection.txt", "w");
//Set command to stop current streaming
fwrite($myfile, "4\n");
//Make sure to flush buffer to file
fclose($myfile);
//Wait, maybe not that necessary
sleep(1);
//Select the next stream station
if ($_GET["action"] == "selEighties")
{
$myfile = fopen("runSelection.txt", "w");
fwrite($myfile, "3\n");
fclose($myfile);
}
.
.
.
注意,我们首先检查客户端是否通过action属性发送了一个选择,然后我们用PHP函数fopen打开文件进行写入,然后编写命令代码4,即停止当前的MPG123作业,然后我们关闭文件刷新缓冲区并允许 bash 脚本读取和执行此命令有一个小的延迟(可能不需要)。
接下来,如果选择了一个站,则再次打开命令文件(fopen),写入相应的命令,关闭文件(刷新缓冲区)并等待下一次客户端选择。
这个过程保证了客户端/服务器执行的流畅,并且没有通过允许服务器访问内核进程命令而暴露任何可能的安全性。
bash 脚本具有让项目在 Web 界面上蓬勃发展的魔力。
该脚本扫描命令文件 runSelection.txt。当客户端请求站点时,PHP 服务器服务正在写入此文件。
脚本循环运行,直到选择退出命令 (2)
while [ $selection -ne 2 ]
do
.
.
.
done
该脚本通过以下循环命令读取文件的每一行(仅一行)
while read line
do
selection="$line"
.
.
.
done < runSelection.txt
然后脚本检查选择,如果它与之前的选择不同,它会提交批处理文件以执行,例如
# if current selection is not the last read then execute
if [[ $selection -eq 3 ]] && [[ $lastSel -ne $selection ]]; then
# Prepare command to execute in the background
cmd="mpg123 http://ice1.somafm.com/u80s-128-mp3"
# Execute command and assign process id to variable.
nohup $cmd > /dev/null & PID=$!
echo "$PID"
# Remember last selection so it does not execute again.
lastSel=selection
exec4=0
fi
注意脚本保留了进程id,所以当停止命令(4)进入命令文件时,它可以杀死它,如下所示:
cmd="kill $PID"
echo "$cmd"
# Kill last submitted process
nohup $cmd > /dev/null
就是这样,bash 文件可以愉快地创建和删除进程,并且 Web 服务可以不间断地工作。
我们花了一些心思才想出解决方法,但如果您有一个想要批处理的过程,这可能是一个可能的解决方案。
最后,请注意我们选择使用 SomaFM 播放音乐,但您可以添加 MP3 歌曲库并享受乐趣。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !