添加对门铃的连接

使用简单的 AI 检测门铃声音

项目介绍

本教程的目标是为未连接的门铃添加功能。例如,我们将检测门铃何时响起以发送消息。

我们将以完全非侵入性的方式进行,这意味着我们将只使用门铃发出的声音。我们不会拆卸任何东西。我们将使用 NanoEdge AI Studio(免费工具)自动创建一个 AI 模型,该模型能够对门铃是否响起或只是背景噪音进行分类。

别担心,您不需要 AI 知识即可遵循本教程:)

计划如下:

  1. 设置
  2. 收集麦克风数据
  3. 创建分类模型
  4. 在我们的Arduino代码中添加模型

设置:

首先,我们需要将麦克风连接到Arduino板。

使用跳线连接:

  1. OUT(麦克风)到 A0(板)
  2. GND 到板上的一个 GND
  3. VCC 至 3.3v

确保您有一根 USB 数据线将主板连接到 PC。

然后我们需要将麦克风靠近门铃发出声音的部分!

在Arduino IDE中:

确保您选择了正确的 COM 端口:工具>端口,然后选择正确的端口。

选择正确的电路板:

  1. Arduino Renesas UNO R4 > 开发板的工具>板 > Arduino UNO R4 WIFI
  2. 如果没有找到它,请单击“Tools > Boards > Boards Manager…”,查找 UNO R4 并安装软件包

收集麦克风数据

我们使用具有非常高数据速率的数字麦克风。

我们将通过从麦克风收集值的缓冲区来收集音乐的卡盘,并通过每收集 1 个值仅保留 32 个值来降低数据速率。

我们收集音乐的缓冲区并记录单个音符以对其进行分类。即使对于人类来说,也无法通过从歌曲中随机提取一个音符来识别歌曲。

为此,请执行以下操作:

  1. 定义 A0 的AMP_PIN,因为我们的麦克风使用 A0 引脚发送数据
  2. 我们定义了一个名为 neai_buffer 的缓冲区来储存收集的值
  3. 在我们的例子中,缓冲区的大小为 1024 (SENSOR_SAMPLE)
  4. 我们在 setup() 中初始化串行
  5. 我们创建一个 get_microphone_data() 来收集来自麦克风的数据缓冲区。我们只得到 1/32 的值
  6. 我们仅在检测到声音 400 时才调用该函数>以避免任何不可能是门铃声音的随机噪声。根据您的设备,您可能需要降低它。
  7. 我们打印缓冲区以通过串行发送。

代码:

/* Defines ----------------------------------------------------------*/ #define SENSOR_SAMPLES 1024 //buffer size #define AXIS 1 //microphone is 1 axis #define DOWNSAMPLE 32 //microphone as a very high data rate, we downsample it /* Prototypes ----------------------------------------------------------*/ void get_microphone_data(); //function to collect buffer of sound /* Global variables ----------------------------------------------------------*/ static uint16_t neai_ptr = 0; //pointers to fill for sound buffer static float neai_buffer[SENSOR_SAMPLES * AXIS] = {0.0}; //souhnd buffer int const AMP_PIN = A0; // Preamp output pin connected to A0 /* Setup function ----------------------------------------------------------*/ void setup() { Serial.begin(115200); delay(10); } /* Infinite loop ----------------------------------------------------------*/ void loop() { if (analogRead(A0)> 400){ get_microphone_data(); } } /* Functions declaration ----------------------------------------------------------*/ void get_microphone_data() { static uint16_t temp = 0; //stock values int sub = 0; //increment to downsample //while the buffer is not full while (neai_ptr < SENSOR_SAMPLES) { //we only get a value every DOWNSAMPLE (32 in this case) if (sub > DOWNSAMPLE) { /* Fill neai buffer with new accel data */ neai_buffer[neai_ptr] = analogRead(AMP_PIN); /* Increment neai pointer */ neai_ptr++; sub = 0; //reset increment } else { //we read the sample even if we don't use it //else it is instantaneous and we don't downsample temp = analogRead(AMP_PIN); } sub ++; } //print the buffer values to send them via serial for (uint16_t i = 0; i < SENSOR_SAMPLES; i++) { Serial.print(neai_buffer[i]); Serial.print(" "); } Serial.print("\n"); neai_ptr = 0; //reset the beginning position }

NanoEdge AI 工作室

以前下一个

这里的目标是使用 NanoEdge 创建一个异常检测项目。我们希望将门铃检测为“标称”,而将其他所有内容检测为“异常”行为。为此,请执行以下操作:

  1. 打开 NanoEdge
  2. 创建异常检测项目
  3. 选择Arduino R4 WIFI板作为目标(其他板兼容)
  4. 选择麦克风 1 轴作为传感器
  5. 单击“下一步”

然后,我们将收集每首音乐的数据。在名义步骤中:

  1. 单击 ADD SIGNAL
  2. 然后从串行 (USB)
  3. 然后单击 START/STOP 收集数据(确保选择了正确的 COM 端口)
  4. 多次记录门铃响起 (x100)。避免空缓冲区(如果需要,请暂停)
  5. 单击“继续”,然后单击“导入”
  6. 如果需要,请重命名文件

对于异常步骤,您想收集您家中可能发生的所有其他声音(孩子们玩耍的声音、狗的声音、钢琴声、作品声、吸尘声等)。例如,您可以记录每分钟发生的事情(在 get_microphone_data() 函数之后的数据记录代码中添加延迟)。

我所做的是,我使用了Youtube上的多个“房屋背景噪音”视频。

一旦你拥有了你想要的一切,就去基准测试步骤。

你拥有的歌曲越多,它就会变得越难,所以从简单开始。

  1. 点击 NEW BENCHMARK
  2. 选择所有歌曲,然后单击“开始”

基准测试将寻找最佳模型并对数据进行预处理,以找到能够对歌曲进行分类的模型。

我得到了一个很好的基准分数,它在模拟器中按预期工作。

在仿真器中,当被要求提供新的学习信号时,这意味着播放标称声音(门铃),以便可以重新训练模型。

然后进入编译步骤:

  1. 选中页面底部的“包括基准测试中的知识”框
  2. 单击编译,填写小表格并保存您的 AI 库 (.zip)。

在这里,我们使用在基准测试中学到的知识。您可以选择不包含这些知识,而是直接在微控制器上重新训练模型。更多信息请见:

$ https://wiki.st.com/stm32mcu/wiki/AI:NanoEdge_AI_Library_for_anomaly_detection_(AD)$ 

将 NanoEdge 模型集成到我们的代码中

现在我们有了异常检测库,我们需要将其添加到Arduino代码中:

  1. 打开得到的.zip,有一个Arduino文件夹,里面有另一个zip
  2. 在Arduino IDE中导入库:Sketch > Include library > Add .ZIP library…,然后选择Arduino文件夹中的.zip

如果您已经在ARDUINO IDE中使用了NANOEDGE AI库:

转到 Document/Arduino/Library 并删除 NanoEdge 的。然后按照上面的说明导入新库。

重要:

如果由于RAM而出现错误,则可能是由于NanoEdge中的库。回到 NanoEdge 中的 VALIDATION STEP,选择一个较小的库(单击右侧的表冠),然后在 Arduino IDE 中编译并替换它。

要使用 NanoEdge,非常简单:

  1. 使用 neai_anomalydetection_init() 检查是否一切正常
  2. 包括要“训练”的模型的知识
  3. 使用 neai_anomalydetection_detect 进行运行检测

如果相似度为 100,则表示我们的信号与标称数据(门铃声)有 100% 相似,如果为 0,则我们有 0% 的机会成为标称数据。

因此,我们将阈值设置为 90,以打印我们正在检测到门铃声。

/* Setup function ———————————————————-*/

void setup() {

Serial.begin(115200);

delay(10);

/* Initialize NanoEdgeAI AI */

neai_code = neai_anomalydetection_init();

if (neai_code != NEAI_OK) {

Serial.print(“Not supported board.\n”);

} else {

neai_anomalydetection_knowledge(knowledge);

}

}

/* Infinite loop ———————————————————-*/

void loop() {

if (analogRead(A0) > 400) {

get_microphone_data();

neai_anomalydetection_detect(neai_buffer, &similarity);

Serial.println(similarity);

if (similarity > 90){

Serial.println(“Doorbell ringing!”);

//do the stuff you want

}

}

}

走得更远

现在您可以检测到门铃响起,由您继续,这里有一些想法:

  1. 检测到时,使用板子的 WiFi 发送消息或电子邮件:$ https://www.youtube.com/watch?v=KwFyCGYuV6Q $
  2. 创建托管在服务器上的仪表板并使用 WiFi 发送更新:$ https://www.youtube.com/watch?v=32VcKyI0dio $

感谢您阅读:)

CODE

数据记录器代码

/* Defines  ----------------------------------------------------------*/
#define SENSOR_SAMPLES    1024 //buffer size
#define AXIS              1    //microphone is 1 axis
#define DOWNSAMPLE        32   //microphone as a very high data rate, we downsample it


/* Prototypes ----------------------------------------------------------*/
void get_microphone_data(); //function to collect buffer of sound

/* Global variables ----------------------------------------------------------*/
static uint16_t neai_ptr = 0; //pointers to fill for sound buffer
static float neai_buffer[SENSOR_SAMPLES * AXIS] = {0.0}; //souhnd buffer
int const AMP_PIN = A0;       // Preamp output pin connected to A0

/* Setup function ----------------------------------------------------------*/
void setup() {
  Serial.begin(115200);
  delay(10);
}

/* Infinite loop ----------------------------------------------------------*/
void loop() {
  if (analogRead(A0)> 400){
    get_microphone_data();
  }

}


/* Functions declaration ----------------------------------------------------------*/
void get_microphone_data()
{
  static uint16_t temp = 0; //stock values
  int sub = 0; //increment to downsample
  //while the buffer is not full
  while (neai_ptr < SENSOR_SAMPLES) {
    //we only get a value every DOWNSAMPLE (32 in this case)
    if (sub > DOWNSAMPLE) {
      /* Fill neai buffer with new accel data */
      neai_buffer[neai_ptr] = analogRead(AMP_PIN);
      /* Increment neai pointer */
      neai_ptr++;
      sub = 0; //reset increment
    }
    else {
      //we read the sample even if we don't use it
      //else it is instantaneous and we don't downsample
      temp = analogRead(AMP_PIN);
    }
    sub ++;
  }
  //print the buffer values to send them via serial
  for (uint16_t i = 0; i < SENSOR_SAMPLES; i++) {
    Serial.print(neai_buffer[i]);
    Serial.print(" ");
  }
  Serial.print("\n");
  neai_ptr = 0; //reset the beginning position
}

主代码

需要 NEAI 库,请按照教程操作

/* Libraries ----------------------------------------------------------*/
#include "NanoEdgeAI.h"
#include "knowledge.h"

/* Defines  ----------------------------------------------------------*/
#define SENSOR_SAMPLES    1024 //buffer size
#define AXIS              1    //microphone is 1 axis
#define DOWNSAMPLE        32   //microphone as a very high data rate, we downsample it


/* Prototypes ----------------------------------------------------------*/
void get_microphone_data(); //function to collect buffer of sound

/* Global variables ----------------------------------------------------------*/
static uint16_t neai_ptr = 0; //pointers to fill for sound buffer
static float neai_buffer[SENSOR_SAMPLES * AXIS] = {0.0}; //souhnd buffer
int const AMP_PIN = A0;       // Preamp output pin connected to A0

/* NEAI PART*/
uint8_t neai_code = 0; //initialization code
uint8_t similarity; // Point to id class (see argument of neai_classification fct)


/* Setup function ----------------------------------------------------------*/
void setup() {
  Serial.begin(115200);
  delay(10);

  /* Initialize NanoEdgeAI AI */
  neai_code = neai_anomalydetection_init();
  if (neai_code != NEAI_OK) {
    Serial.print("Not supported board.\n");
  } else {
    neai_anomalydetection_knowledge(knowledge);
  }



}

/* Infinite loop ----------------------------------------------------------*/
void loop() {
  if (analogRead(A0) > 400) {
    get_microphone_data();
    neai_anomalydetection_detect(neai_buffer, &similarity);
    Serial.println(similarity);
    if (similarity > 90){
      Serial.println("Doorbell ringing!");
      //do stuff you want
    }
  }
}


/* Functions declaration ----------------------------------------------------------*/
void get_microphone_data()
{
  static uint16_t temp = 0; //stock values
  int sub = 0; //increment to downsample
  //while the buffer is not full
  while (neai_ptr < SENSOR_SAMPLES) {
    //we only get a value every DOWNSAMPLE (32 in this case)
    if (sub > DOWNSAMPLE) {
      /* Fill neai buffer with new accel data */
      neai_buffer[neai_ptr] = analogRead(AMP_PIN);
      /* Increment neai pointer */
      neai_ptr++;
      sub = 0; //reset increment
    }
    else {
      //we read the sample even if we don't use it
      //else it is instantaneous and we don't downsample
      temp = analogRead(AMP_PIN);
    }
    sub ++;
  }
  neai_ptr = 0; //reset the beginning position
}

Similar Posts

Leave a Reply