感谢活动主办方给的试用机会,收到快递后,里面一大堆配件,先来个开箱。
把两块板子叠在一起,因为我们需要用到网线来做首次无头登录。另外由于项目中需要用到语音交互,因此需要用拓展板上的3.5mm接口,拓展板在本次项目中不可缺少,必须得加上。
我会在接下来一个月的评测期内,配置好开发环境,逐个实现各个功能模块,最终完成整个项目。评测的进程会更新在本篇的评论区中,敬请期待。
首先我们安装一下固件,配置好开发环境。
去官网下载最新的Debian镜像,最新的镜像链接可以在官方wiki上找到,我选择用github方式下载server版的镜像。因为板载内存仅有1个H,如果带有图形环境的话再进行项目开发会比较吃力。
选择图里的V2.4_07-12_server_WalnutPi-1b_6.1.31_debian12.img.rar就可以。
接下来,我们需要一个烧录工具,我推荐使用便携版的balenaEtcher。虽然这个工具文件较大,但操作非常简单,一键即可完成烧录。而且便携版不需要安装,使用起来也很方便。
随后,找一张容量在16G以上的内存卡,插入电脑,打开balenaEtcher,选择相应的镜像和内存卡,点击烧录,等待过程完成即可。
完成烧录后,把内存卡插入开发板,开发板上电,这样系统就算完成了烧录工作。
由于我没有HDMI显示器和键盘,因此无法按照官方WIKI那样使用桌面系统。因此,在首次启动时,我需要采用无头方式来配置无线网络。好在核桃派的接口非常齐全,不但有串口接口可以实现无头登录,拓展板上更集合了网线接口,可以直接使用有线网来ssh登录,非常方便。这里我们就使用有线网的方式来进行配置。
把板子插上网线后,可以通过登录路由器管理界页面来找到核桃派的IP地址。但是考虑到每个人的路由器不一样,或许有些路由器并不支持此功能,因此我们可以使用一个简单的小软件Advanced IP Scanner来扫描整个网段的设备,用来找到核桃派的ip
找到ip后,在电脑上打开cmd,在里面输入以下ssh命令,就可以连接到核桃派。我们使用pi用户登录,密码同样为pi。
接下来连接无线wifi。网上大多教程使用的都是nmcli这个工具,但其实有个更加方便地工具可以使用,nmtui,它还可以自动连接已连接的网络。
sudo nmtui
选择第二个选项激活网络连接,找到自己家的WiFi按回车输入密码即可完成连接。
这时候我们就可以用sudo ifconfig
查看到无线网卡的ip,就可以拔掉网线,使用wifi登录ssh了。
整个项目是在python下进行开发的。为了不污染系统环境,我们会使用虚拟环境来进行开发。有linux python开发经验的小伙伴一定会知道,linux平台中很多python包并不是通过pip的方式进行安装的,而是通过apt包管理器安装在系统环境中的,这是为了有权限对硬件或是内核进行操作。因此,创建虚拟环境时需要导入系统环境包。
由于一部分包需要用到apt安装,另一部分需要用到sudo安装,而有一些包之间还会存在冲突和兼容问题,因此我把所有需要安装的包和创建虚拟环境的命令都写在了一个bash中,只需要一键运行这个bash,就可以自动完成环境配置工作。
#!/bin/bash
sudo apt update
sudo apt full-upgrade -y
sudo apt autoremove -y
cd ~
mkdir jarvis_walnutpi
cd jarvis_walnutpi
sudo apt install gcc python3-dev -y
sudo apt install python3.11-venv -y
python -m venv venv --system-site-packages
source venv/bin/activate
pip install -U "fastapi[standard]"
sudo apt install python3-pyaudio -y
pip install -U SpeechRecognition
sudo apt install flac -y
pip install -U opencv-python
pip install -U torchvision==0.15.2
pip install -U ultralytics
pip install -U "g4f[all]"
pip install -U edge-tts
pip install -U pydub
sudo apt install ffmpeg libavcodec-extra -y
这些包安装是需要一些时间1的,通过ssh安装会存在一个风险,一旦出现ssh掉线,安装也会被终止。为了避免这种情况,我们可以使用screen
工具来新建一个窗口,在这个窗口内执行安装程序,这样即使我们关闭窗口,安装也不会中止。
sudo apt install screen
screen -R setup
接下来运行上面的sh文件,我用了半个小时左右,完成后我们就完成了全部环境配置工作。
由于核桃派上的3.5mm接口仅可以做音频输出使用,不能输入,因此这个项目我计划使用电脑来进行音频输入,输入完成后将录音的bytes数据通过FastAPI发送到核桃派,接着核桃派进行语音识别,图像视频,大语言模型调用,TTS合成音频,播放。大预言返回的文本结果可以作为返回值返回给PC。相当于将PC仅作为一个网络麦克风使用。
那首先我们先把PC这块语音输入的问题给解决了。我们在pc上使用的库同样也是pyaudio,用pydub来进行测试。先安装所需的库:
pip install pyaudio
pip install pydub
pip install numpy
然后我写了下面代码用来获取声音。
import time
import pyaudio
import pydub
import numpy as np
import io
def listen(_min_db=200, _end_delay=1.0, _timeout=60):
_CHANNELS = 1
_RATE = 16000
_CHUNK = 1024
_FORMAT = pyaudio.paInt16
_p = pyaudio.PyAudio()
_stream = _p.open(
format=_FORMAT,
channels=_CHANNELS,
rate=_RATE,
input=True,
frames_per_buffer=_CHUNK,
)
print("开始计时")
_buffer = io.BytesIO()
_flag_record = True # 判断是否继续录音
_flag_start = False # 开始录音节点
_flag_end = False # 判断声音小了
_time_wait = time.time()
_time_start = 0
_time_end = 0
while _flag_record:
_data = _stream.read(_CHUNK, exception_on_overflow=False)
_buffer.write(_data)
_db = np.max(np.frombuffer(_data, dtype=np.short))
print(_db)
if _flag_start == False and _db > _min_db:
_flag_start = True
print("开始录音")
_time_start = time.time()
if _flag_start:
if _flag_end == False and _db < _min_db:
_flag_end = True
_time_end = time.time()
print(f"间隔{_end_delay}s后开始检测是否还是小声")
continue
if _flag_end == True and _db > _min_db:
_flag_end = False
print("大声,继续录音")
continue
if _flag_end == True and time.time() - _time_end > _end_delay:
_flag_record = False
print("结束录音")
continue
if time.time() - _time_wait > _timeout: # 超时直接退出
_flag_record = False
print("超时")
continue
_stream.stop_stream()
_stream.close()
_p.terminate()
_buffer.seek(0)
_audio = pydub.AudioSegment.from_file(
_buffer,
format="raw",
frame_rate=_RATE,
channels=_CHANNELS,
sample_width=_p.get_sample_size(_FORMAT),
)
_audio = _audio.set_frame_rate(16000)
_wav = io.BytesIO()
_audio.export(_wav, format="wav")
return _wav
if __name__ == "__main__":
import pydub.playback as playback
save = False
result = listen()
sound = pydub.AudioSegment.from_file(result, format="wav")
playback.play(sound)
if save:
with open("audio.wav", "wb") as file:
file.write(result.getbuffer())
代码运行起来后程序会循环检测麦克风的声压,当升压超过阈值后,也就是定义的_min_db=200
,则开始录音;当超过一段时间音量小于阈值后,则认为说话结束,停止录音。
录音仅用到pyaudio,pydub是用来把声音数据和数据头组装起来形成wav文件的。在下面的测试运行代码中使用了pydub的播放功能来把录到的音频再播放出来,可以用作测试。
如果电脑的录音和播放功能正常,运行这段代码,就可以完成上述功能测试。如果把save改成1,还可以得到保存好的wav录音文件。
更多回帖