【发布时间】:2022-07-14 03:30:50
【问题描述】:
我正在做一个需要从 Arduino NANO 33 BLE 保存音频文件的项目,以使用 EdgeImpulse 创建数据集,首先,我不能使用集成的 webUSB 直接在 EdgeImpulse 上保存音频,因为我需要关联它音频文件到本地保存的视频,然后我分析视频以将音频与基于视频的特定类相关联。
我的第一次尝试是使用示例文件(PDMSerialPlotter)来保存采样,但是如果我使用这个python函数保存终端接收到的采样:
def serial_import_from_arduino(time_str,serial_port_name):
ser = serial.Serial(serial_port_name, 115200) # Create Serial link
prefisso = "audio/"
file_name = prefisso + time_str + ".json"
file = open(file_name,"w")
for x in range(sample): # sample = # of samples to save
cc=str(ser.readline())
print(cc)
file.write(cc[2:][:-5])
file.write(",")
file.close()
要运行这个脚本,它应该持续 5 秒,因为麦克风采样是 16khz 并且样本变量是 16k * 5 但脚本运行了大约 22 秒(这次我从 1 计数到 22),用于上传我在 EdgeImpulse 上将采样率设置为 16khz,音频长度为 5 秒,但音频加快了。
所以我认为 Serial.print() 速度不够快,无法保存 16khz 采样(16 位)
在网上搜索发现,函数Serial.print()将数据转换成ASCII码发送,这个过程会浪费一些时间,所以我做了一个简单的Arduino代码,用Serial.write( ) 函数(不应该转换数据,但可以只打磨 1 个字节)这段代码:
void setup() {
Serial.begin(115200);
while(!Serial);
}
byte value = 255;
void loop() {
Serial.write(value);
}
我使用读取 2 个字节(16 位)的 Python 脚本分析了 Serial 并将其保存在文件中,并计算一秒钟内保存了多少样本: 导入序列号 进口时间
ser = serial.Serial("COM3", 115200) # Create Serial link
value = 0
file = open("audio/file.txt","w")
start_time = time.time()
print(start_time)
while(time.time()-start_time < 1 ):
value = value + 1
file.write(str(ser.read(1)))
file.write(",")
file.close()
print(value)
如果我在 1 秒内占用 2 个字节,则可以节省 [5700-5800] 个样本,但我需要 16000 个。
我的第二次尝试是在 Arduino 上本地保存样本,然后一次全部传输,问题是我无法保存长度超过 6 秒的音频,因为我填满了 Arduino 内存,而我的项目需要更长的音频超过 6 秒,可能我想连续录制音频或至少 30-60 分钟
请帮帮我!
【问题讨论】:
-
1) 您需要提高您的串行通信速度,115200bps 最多是 115200/10 = 11520 字节数据/秒。 2)如果您将数据作为原始二进制文件发送,为什么要将其转换为 str 以保存它?只需使用
open("audio/file.txt","wb"将其保存为原始二进制数据即可。 3)您可能还想考虑将数据读入字节数组,仅在字节数组填满时才将其写入文件。 -
我尝试使用一些不同的波特率,但这不会影响我一秒钟可以记录的样本数量,我现在用 2000000 进行了测试(在 Arduino 和 Python 脚本上进行了更改)我设置了
open("audio/file.txt","wb"),所以在保存文件之前没有转换为str,结果与[5700-5900]样本之前的几秒钟相同。我认为 Python 脚本足够快,因为如果我在不等待串行通信的情况下打印文件,我可以在几秒钟内编写 650000 个样本,因此限制速度的串行通信也是如此。
标签: python arduino sampling arduino-nano