- 2025-01-08
-
回复了主题帖:
【Follow me第二季第4期】基于 Edge Impulse 的语音识别
lugl4313820 发表于 2024-12-30 22:25
咱们这个语音识别,是要联网?还是把算法下载到本地就可以识别了?
把算法下载到了单片机上
- 2024-12-30
-
回复了主题帖:
【Follow me第二季第4期】任务汇总
【Follow me第二季第4期】代码-嵌入式开发相关资料下载-EEWORLD下载中心
- 2024-12-29
-
上传了资料:
【Follow me第二季第4期】代码
-
加入了学习《任务提交》,观看 任务提交
-
加入了学习《fm4任务展示》,观看 fm4任务展示
-
回复了主题帖:
【Follow me第二季第4期】任务二 学习IMU基础知识,通过串口打印六轴原始数据
补充一下演示视频
[localvideo]9de5480931303ec0416d695adf902631[/localvideo]
-
加入了学习《Follow me第二季第4期 Arduino? Nano RP2040 Connect活动项目总结》,观看 Follow me第二季第4期项目总结
-
回复了主题帖:
【Follow me第二季第4期】任务汇总
【Follow me第二季第4期】基于 Edge Impulse 的语音识别 https://bbs.eeworld.com.cn/thread-1302947-1-1.html
-
发表了主题帖:
【Follow me第二季第4期】基于 Edge Impulse 的语音识别
本帖最后由 eew_uscYT9 于 2024-12-28 23:23 编辑
本项目教你如何做出自己的语音识别
本项目的大体流程 我的语音识别是识别开灯和关灯两个声音,听到对应的声音就对板子上的灯进行开和关
https://studio.edgeimpulse.com/ 先去这个网站注册好账号
然后创建一个新的项目
输入项目名字,其他保存不动
接着到了数据的采集,我通过对Edge Impulse的文档查阅,发现可以用Arduino Nano主板进行数据的采集,其他的数据采集方式有手机、Edge Impulse CLI(该方式比较复杂)
先下载Edge Impulse准备好的固件
然后把该固件下载到nano板子上
接着点左边的data acquisition
点击下面所指的图标就能进行数据的采集,数据分为训练数据集和测试数据集,一般是8、2开,
数据采集完之后点击creat impulse进行训练的设置,如下面所示,设置完之后点击save impulse
点击mfcc进行参数的设置,直接默认设置,然后保存参数
然后点击上方的generate features进行生成特征 ,根据feature explorer能够看出我的数据区分度还是挺高的
接着点击classifier 进行训练,参数都可以用默认设置
点击model testing进行模型测试 我的模型训练还是可以的 接下来进行模型的部署,我们现在arduino,然后进行build,把生成的文件下载下来,打开arduino ide进行添加
我的代码如下
/* Edge Impulse ingestion SDK
* Copyright (c) 2022 EdgeImpulse Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// If your target is limited in memory remove this macro to save 10K RAM
#define EIDSP_QUANTIZE_FILTERBANK 0
/*
** NOTE: If you run into TFLite arena allocation issue.
**
** This may be due to may dynamic memory fragmentation.
** Try defining "-DEI_CLASSIFIER_ALLOCATION_STATIC" in boards.local.txt (create
** if it doesn't exist) and copy this file to
** `<ARDUINO_CORE_INSTALL_PATH>/arduino/hardware/<mbed_core>/<core_version>/`.
**
** See
** (https://support.arduino.cc/hc/en-us/articles/360012076960-Where-are-the-installed-cores-located-)
** to find where Arduino installs cores on your machine.
**
** If the problem persists then there's not enough memory for this model and application.
*/
/* Includes ---------------------------------------------------------------- */
#include <rp2040_inferencing.h>
#include <PDM.h>
#include "WiFiNINA.h"
#define led1 LEDB
#define led2 LEDG
#define led3 LEDR
/** Audio buffers, pointers and selectors */
typedef struct {
int16_t *buffer;
uint8_t buf_ready;
uint32_t buf_count;
uint32_t n_samples;
} inference_t;
static inference_t inference;
static signed short sampleBuffer[2048];
static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal
static volatile bool record_ready = false;
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Arduino setup function
*/
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(led3, OUTPUT);
pinMode(led2, OUTPUT);
// comment out the below line to cancel the wait for USB connection (needed for native USB)
while (!Serial);
Serial.println("Edge Impulse Inferencing Demo");
// summary of inferencing settings (from model_metadata.h)
ei_printf("Inferencing settings:\n");
ei_printf("\tInterval: ");
ei_printf_float((float)EI_CLASSIFIER_INTERVAL_MS);
ei_printf(" ms.\n");
ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16);
ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0]));
if (microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT) == false) {
ei_printf("ERR: Could not allocate audio buffer (size %d), this could be due to the window length of your model\r\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT);
return;
}
}
/**
* @brief Arduino main function. Runs the inferencing loop.
*/
void loop()
{
ei_printf("Starting inferencing in 2 seconds...\n");
delay(2000);
ei_printf("Recording...\n");
bool m = microphone_inference_record();
if (!m) {
ei_printf("ERR: Failed to record audio...\n");
return;
}
ei_printf("Recording done\n");
signal_t signal;
signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
signal.get_data = µphone_audio_signal_get_data;
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR res = run_classifier_continuous(&signal, &result, debug_nn);
if (res != EI_IMPULSE_OK) {
ei_printf("ERR: Failed to run classifier (%d)\n", res);
return;
}
// print inference return code
ei_printf("run_classifier returned: %d\r\n", res);
print_inference_result(result);
//ei_printf(" %s: ", ei_classifier_inferencing_categories[i]);
}
/**
* @brief PDM buffer full callback
* Copy audio data to app buffers
*/
static void pdm_data_ready_inference_callback(void)
{
int bytesAvailable = PDM.available();
// read into the sample buffer
int bytesRead = PDM.read((char *)&sampleBuffer[0], bytesAvailable);
if ((inference.buf_ready == 0) && (record_ready == true)) {
for(int i = 0; i < bytesRead>>1; i++) {
inference.buffer[inference.buf_count++] = sampleBuffer[i];
if(inference.buf_count >= inference.n_samples) {
inference.buf_count = 0;
inference.buf_ready = 1;
break;
}
}
}
}
/**
* @brief Init inferencing struct and setup/start PDM
*
* @param[in] n_samples The n samples
*
* [url=home.php?mod=space&uid=784970]@return[/url] { description_of_the_return_value }
*/
static bool microphone_inference_start(uint32_t n_samples)
{
inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t));
if(inference.buffer == NULL) {
return false;
}
inference.buf_count = 0;
inference.n_samples = n_samples;
inference.buf_ready = 0;
// configure the data receive callback
PDM.onReceive(pdm_data_ready_inference_callback);
PDM.setBufferSize(2048);
delay(250);
// initialize PDM with:
// - one channel (mono mode)
if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) {
ei_printf("ERR: Failed to start PDM!");
microphone_inference_end();
return false;
}
// optionally set the gain, defaults to 24
// Note: values >=52 not supported
//PDM.setGain(40);
return true;
}
/**
* @brief Wait on new data
*
* @return True when finished
*/
static bool microphone_inference_record(void)
{
bool ret = true;
record_ready = true;
while (inference.buf_ready == 0) {
delay(10);
}
inference.buf_ready = 0;
record_ready = false;
return ret;
}
/**
* Get raw audio signal data
*/
static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr)
{
numpy::int16_to_float(&inference.buffer[offset], out_ptr, length);
return 0;
}
/**
* @brief Stop PDM and release buffers
*/
static void microphone_inference_end(void)
{
PDM.end();
ei_free(inference.buffer);
}
void print_inference_result(ei_impulse_result_t result) {
// Print how long it took to perform inference
ei_printf("Timing: DSP %d ms, inference %d ms, anomaly %d ms\r\n",
result.timing.dsp,
result.timing.classification,
result.timing.anomaly);
ei_printf("Predictions:\r\n");
for (uint16_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
if(result.classification[i].value>0.7)
{
switch (i) {
case 0: digitalWrite(led3, LOW); break;
case 1: digitalWrite(led3, HIGH); break;
default: digitalWrite(led2, LOW);
}
}
ei_printf(" %s: ", ei_classifier_inferencing_categories[i]);
ei_printf("%.5f\r\n", result.classification[i].value);
}
// Print anomaly result (if it exists)
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf("Anomaly prediction: %.3f\r\n", result.anomaly);
#endif
}
#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE
#error "Invalid model for current sensor."
#endif
演示视频
[localvideo]d8177a49fca202d9ad2e38951857c1aa[/localvideo]
- 2024-12-28
-
回复了主题帖:
【Follow me第二季第4期】任务三 学调试PDM麦克风,通过串口打印收音数据和音频波形
本帖最后由 eew_uscYT9 于 2024-12-29 23:27 编辑
[localvideo]2d950ac4b69a1ed58dc86b1ceae90a16[/localvideo]
对应的视频展示
还有一个和pico2联动,通过打响指能控制nano板子和pico2板子的灯进行变化
[localvideo]2d51811098e155c28760aee1191550e6[/localvideo]
- 2024-12-26
-
加入了学习《【Follow me第二季第4期】ARDUINO NANO RP2040 CONNECT》,观看 Arduino NANO RP2040演示合集
-
回复了主题帖:
【Follow me第二季第4期】任务三 学调试PDM麦克风,通过串口打印收音数据和音频波形
Jacktang 发表于 2024-12-24 07:45
结果输出的曲线为什么是下降的
截的是做完之后的数据
- 2024-12-23
-
加入了学习《Arduino? Nano RP2040 Connect 任务视频》,观看 PDM 数据打印及音频波形
-
发表了主题帖:
【Follow me第二季第4期】任务汇总
本帖最后由 eew_uscYT9 于 2025-1-11 21:43 编辑
视频
【Follow me第二季第4期】-EEWORLD大学堂
必做任务一:搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!;
【Follow me第二季第4期】任务一Blink、串口打印 https://bbs.eeworld.com.cn/thread-1301039-1-1.html
必做任务二:学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据;
【Follow me第二季第4期】任务二 学习IMU基础知识,通过串口打印六轴原始数据 https://bbs.eeworld.com.cn/thread-1301142-1-1.html
必做任务三:学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。
通过打响指进行灯的控制,也控制pico2的灯的亮灭
具体流程如下
【Follow me第二季第4期】任务三 学调试PDM麦克风,通过串口打印收音数据和音频波形 https://bbs.eeworld.com.cn/thread-1301144-1-1.html
发挥任务:
【Follow me第二季第4期】基于 Edge Impulse 的语音识别 https://bbs.eeworld.com.cn/thread-1302947-1-1.html
心得体会
通过这次我学习到了IMU的使用、麦克风的使用、了解到了音频的波形,也学习到了怎么样进行机器学习,并且自己也部署了一个可以识别命令的进行开关灯的小demo
最后非常感谢EEWorld和得捷电子举办的活动,这次活动让我收获了许多知识,希望能多出一点有关ai方向,让我们了解前沿,与前沿接轨
代码
https://download.eeworld.com.cn/detail/eew_uscYT9/635471
-
发表了主题帖:
【Follow me第二季第4期】任务三 学调试PDM麦克风,通过串口打印收音数据和音频波形
本帖最后由 eew_uscYT9 于 2024-12-23 17:26 编辑
硬件部分
ST MP34DT06JTR MEMS麦克风
▪ AOP = 122.5 dBSPL
▪ 64 dB信噪比
▪ 全向灵敏度
▪ -26 dBFS ± 1 dB灵敏度
硬件连接
代码部分
先安装PDM库
#include <WiFiNINA.h>
#include <PDM.h>
bool LED_SWITCH = false;
// default number of output channels
static const char channels = 1;
// default PCM output frequency
static const int frequency = 20000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[512];
// Number of audio samples read
volatile int samplesRead;
void setup() {
Serial.begin(115200);
pinMode(LEDB, OUTPUT);
while (!Serial);
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and -10 on the Portenta Vision Shields
// PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shields
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop() {
// Wait for samples to be read
if (samplesRead) {
// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if (channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
i++;
}
Serial.println(sampleBuffer[i]);
if (sampleBuffer[i] > 10000 || sampleBuffer[i] <= -10000) {
LED_SWITCH = !LED_SWITCH;
if (LED_SWITCH) {
Serial.println();
digitalWrite(LEDR, HIGH);
Serial.println("ON!");
Serial.println();
delay(1000);
}
else {
Serial.println();
digitalWrite(LEDR, LOW);
Serial.println("OFF!");
Serial.println();
delay(1000);
}
}
}
// Clear the read count
samplesRead = 0;
}
}
/**
Callback function to process the data from the PDM microphone.
NOTE: This callback is executed as part of an ISR.
Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
现象是打一个响指就会让红灯亮,再打一个就会关闭红灯
输出的数据如下
-
加入了学习《直播回放: DigiKey FollowMe 第二季 第4期 Arduino Nano RP2040 Connect 任务讲解》,观看 Arduino Nano RP2040 Connect 任务讲解
- 2024-12-06
-
发表了主题帖:
【Follow me第二季第4期】任务二 学习IMU基础知识,通过串口打印六轴原始数据
本帖最后由 eew_uscYT9 于 2024-12-6 20:00 编辑
Nano RP2040 Connect Cheat Sheet | Arduino Documentation 板子的arduino教程
ST LSM6DSOXTR 6轴惯性测量单元(IMU)
▪ 3D陀螺仪
• ±2/±4/±8/±16 g全量程
▪ 3D加速度计
• ±125/±250/±500/±1000/±2000 dps全量程
▪ 高级计步器、步态检测器和步数计数器
▪ 运动检测、倾斜检测
▪ 标准中断:自由落体、唤醒、6D/4D方向、单击和双击
▪ 可编程有限状态机:加速度计、陀螺仪和外部传感器
▪ 机器学习核心
▪ 嵌入式温度传感器
加速度的各个方向
陀螺仪的各个方向
实现步骤
1先在arduino上安装Arduino_LSM6DSOX库
相关的api
代码如下
#include <Arduino_LSM6DSOX.h>
float Ax, Ay, Az;
float Gx, Gy, Gz;
void setup() {
Serial.begin(9600);
while(!Serial);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println("Hz");
Serial.println();
Serial.print("Gyroscope sample rate = ");
Serial.print(IMU.gyroscopeSampleRate());
Serial.println("Hz");
Serial.println();
}
void loop() {
if (IMU.accelerationAvailable()) {
if (IMU.gyroscopeAvailable())
{
IMU.readAcceleration(Ax, Ay, Az);
IMU.readGyroscope(Gx, Gy, Gz);
Serial.println("data: ");
Serial.print(Ax);
Serial.print('\t');
Serial.print(Ay);
Serial.print('\t');
Serial.println(Az);
Serial.print(Gx);
Serial.print('\t');
Serial.print(Gy);
Serial.print('\t');
Serial.println(Gz);
Serial.println();
}
}
delay(250);
}
串口数据输出如下
想解算姿态,但是不知道该怎么做,求教
-
回复了主题帖:
【Follow me第二季第4期】任务一Blink、串口打印
Jacktang 发表于 2024-12-6 07:29
就是控制一下三个灯的亮和灭
对的
-
发表了主题帖:
【Follow me第二季第4期】任务一Blink、串口打印
本帖最后由 eew_uscYT9 于 2024-12-6 23:40 编辑
点灯启动
RGB连接方式
有原理图可以看出,低电平点亮
代码如下
#include "WiFiNINA.h"
#define led1 LEDB
#define led2 LEDG
#define led3 LEDR
void setup() {
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
}
void loop() {
Serial.println("Hello DigiKey & EEWorld!");
// Red
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
delay(500);
// Green
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
delay(500);
// Blue
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
delay(500);
}
顺带打印了"Hello DigiKey & EEWorld!"
- 2024-09-21
-
加入了学习《FollowMe 第二季:2 - Arduino UNO R4 Wi-Fi 及任务讲解》,观看 Arduino UNO R4 Wi-Fi 及任务讲解