亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

用于控制 RGB 灯的 TinyML 关键字检测

组件和用品

Arduino Nano 33 BLE Sense
× 1

应用和在线服务

Edge Impulse Studio

关于这个项目

前提

边缘机器学习对于创建可以完成“智能”任务的设备非常有用,与传统代码相比,编程和逻辑流程图要少得多。这就是为什么我想结合边缘关键字检测,它可以识别某些单词,然后根据所说的内容执行任务。

硬件

该项目只有一个组件:Arduino Nano 33 BLE Sense。真正的魔法发生在机器学习模型中。 Arduino Nano 33 BLE Sense 充满传感器,包括麦克风、9 轴 IMU、环境传感器和手势/接近/颜色/环境光传感器 (APDS-9960)。其上的微控制器是 nRF52840,运行频率为 64MHz,包含 1MB 闪存和 256KB RAM。该项目还使用其板载 RGB LED 来显示当前颜色。

设置边缘脉冲

我首先在 Edge Impulse 上创建了一个新项目,然后安装了 Edge Impulse CLI 工具。有关如何执行此操作的更多说明,请访问安装说明页面。这让 Arduino Nano 与云服务通信以接收命令并自动发送传感器数据。我下载了最新的 Edge Impulse 固件,并通过双击重置按钮使其进入引导加载程序模式将其闪存到板上。然后我运行 flash_windows.bat 转移它。

在命令提示符下,我运行了 edge-impulse-daemon 并按照向导进行设置。现在,Nano 出现在项目的设备列表中,它允许将样本作为训练/测试数据集的一部分进行采集和上传。

收集样本

训练机器学习模型需要数据,而且需要相当多的数据。我想为 RGB LED 灯条设置以下模式:

  • 开启
  • 关闭
  • 红色
  • 绿色
  • 蓝色

对于每种模式,我都会听到大约 1 分钟的声音,其中我以 1-2 秒的间隔反复说这个词并将它们分开。

但是仅仅拥有这些样本是不够的,因为背景噪音和其他文字会给出错误的读数。幸运的是,Edge Impulse 已经为噪声和“未知”词提供了一个预先构建的数据集,所以我使用他们的“上传现有数据”工具将这些音频文件上传到训练数据中。

最后,我重新平衡了数据集,分别将推荐的 80-20 拆分用于训练和测试数据。

训练模型

现在有了一个小时的训练数据和大量标签,是时候训练模型了。我设计的impulse将音频作为时间序列数据,窗口大小为1秒,窗口增加500ms。然后它通过 MFCC 块进入 Keras 神经网络块。

MFCC 块允许您配置音频的处理方式,以及以视觉方式显示频率的频谱图。

我将神经网络设置保留为大部分默认设置,但也做了一些修改。首先,我将最小置信阈值从 0.80 更改为 0.70,并以附加噪声和屏蔽时间带的形式添加了一些数据增强。这有助于神经网络避免过度拟合模型,因为它有更多不同的数据可供使用。

在 Arduino Nano 33 BLE Sense 上部署

Arduino Nano 33 BLE Sense 充当始终开启的麦克风,持续对音频进行采样并检测是否有人说出了其中一个关键字。一旦找到,关键字就会转换为索引,用于解码所需的颜色。对于 on 或 off 关键字,LED 设置为黑色或浅灰色。

我将模型下载为库并将其添加到 Arduino IDE,然后编译并将代码写入 Nano。

代码

  • RGBLED 关键字检测
RGBLEDKeywordDetectionC/C++
/* Edge Impulse Arduino 示例 * 版权所有 (c) 2020 EdgeImpulse Inc. * * 特此免费授予获得此软件和相关文档文件(“软件”)副本 * 的任何人的许可, * 不受限制地处理 * 软件,包括但不限于 * 使用、复制、修改、合并、发布、分发、再许可和/或出售 * 软件副本的权利,并允许使用软件的人*提供这样做,受以下条件的约束: * * 上述版权声明和本许可声明应包含在 * 本软件的所有副本或重要部分中。 * * 本软件“按原样”提供,不提供任何形式的明示或 * 暗示保证,包括但不限于适销性保证, * 适用于特定用途和不侵权。在任何情况下,*作者或版权持有人均不对任何索赔、损害或其他*责任承担责任,无论是在合同诉讼、侵权行为或其他方面,*因软件或其他软件的使用而引起的或与之相关的* 软件中的交易。 */// 如果您的目标内存有限,请删除此宏以节省 10K RAM#define EIDSP_QUANTIZE_FILTERBANK 0/** * 定义每个模型窗口的切片数。例如。 1000 ms * 的模型窗口,每个模型窗口的切片设置为 4。切片大小为 250 ms。 * 更多信息:https://docs.edgeimpulse.com/docs/continuous-audio-sampling */#define EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW 3/* 包括-------------------- --------------------------------------------- */#include #include #include 
#define CONFIDENCE_THRESHOLD 0.7static const uint32_t colors[] ={0x00ff0000, 0x0000ff00, 0x000000ff}; // red, green, blueenum Actions { LED_ON =1, LED_OFF =0, LED_RED =2, LED_GREEN =3, LED_BLUE =4, NONE =5};enum Functions{ CHANGE_LED_ON_OFF =0, CHANGE_LED_COLOR =1, CHANGE_LED_NONE =2 static const uint8_t redPin =22, greenPin =23, bluePin =24;const std::map actionToFunctionMap ={ {LED_ON, CHANGE_LED_ON_OFF}, {LED_OFF, CHANGE_LED_ON_OFF}, {LED_RED, CHANGE_LED_LED_COLLEOR }, {LED_BLUE, CHANGE_LED_COLOR}, {NONE, CHANGE_LED_NONE}};const std::map labelToActionMap ={ {"on", LED_ON}, {"off", LED_OFF}, {"red" , LED_RED}, {"green", LED_GREEN}, {"blue", LED_BLUE}, {"unknown", NONE}, {"noise", NONE}};/** 音频缓冲区、指针和选择器 */typedef struct { 签名短 *buffers[2];无符号字符 buf_select;无符号字符 buf_ready;无符号整数 buf_count; unsigned int n_samples;} inference_t;static inference_t inference;static bool record_ready =false;static signed short *sampleBuffer;static bool debug_nn =false; // 将此设置为 true 以查看例如从原始信号生成的特征static int print_results =-(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW);/** * @brief Arduino setup function */void setup(){ // 把你的设置代码放在这里,运行一次:Serial.begin(115200); Serial.println("边缘脉冲推理"); setPixelColor(0xaeae00); // 推理设置摘要(来自 model_metadata.h) ei_printf("Inferencing settings:\n"); ei_printf("\tInterval:%.2f ms.\n", (float)EI_CLASSIFIER_INTERVAL_MS); ei_printf("\t帧大小:%d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE); ei_printf("\t样本长度:%d 毫秒。\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])); run_classifier_init(); if (microphone_inference_start(EI_CLASSIFIER_SLICE_SIZE) ==false) { ei_printf("ERR:无法设置音频采样\r\n");返回; }}/** * @brief Arduino 主函数。运行推理循环。 */void loop(){ bool m =mic_inference_record(); if (!m) { ei_printf("ERR:无法录制音频...\n");返回; } 信号_t 信号; signal.total_length =EI_CLASSIFIER_SLICE_SIZE; signal.get_data =µphone_audio_signal_get_data; ei_impulse_result_t 结果 ={0}; EI_IMPULSE_ERROR r =run_classifier_continuous(&signal, &result, debug_nn); if (r !=EI_IMPULSE_OK) { ei_printf("ERR:无法运行分类器 (%d)\n", r);返回; } if (++print_results>=(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW)) { // 打印预测 ei_printf("Predictions "); ei_printf("(DSP:%d ms., 分类:%d ms., 异常:%d ms.)", result.timing.dsp, result.timing.classification, result.timing.anomaly); ei_printf(":\n"); for (size_t ix =0; ix  CONFIDENCE_THRESHOLD) { performAction(result.classification[ix].label); } ei_printf(" %s:%.5f\n", result.classification[ix].label, result.classification[ix].value); }#if EI_CLASSIFIER_HAS_ANOMALY ==1 ei_printf("异常分数:%.3f\n", result.anomaly);#endif print_results =0; }}void setPixelColor(uint32_t c){analogWrite(redPin, 255 - (c>> 16));模拟写入(greenPin, 255 - ((c>> 8) &0xff));模拟写入(bluePin, 255 - (c &0xff));}void performAction(const char* classificationLabel){ auto itr =labelToActionMap.find(classificationLabel); if(itr ==labelToActionMap.end()) 返回; auto itr2 =actionToFunctionMap.find(itr->second); if(itr2 ==actionToFunctionMap.end()) 返回; switch(itr2->second) { case CHANGE_LED_ON_OFF:setPixelColor((itr->second) ? 0x5c5c5c :0x00);休息; case CHANGE_LED_COLOR:{ uint32_t pixelColor =colors[itr->second - 2];设置像素颜色(像素颜色); } 休息; case CHANGE_LED_NONE:中断; }}/** * @brief Printf 函数使用 vsnprintf 并使用 Arduino Serial 输出 * * @param[in] 格式变量参数列表 */void ei_printf(const char *format, ...) { static char print_buf[1024] ={0}; va_list 参数; va_start(参数,格式); int r =vsnprintf(print_buf, sizeof(print_buf), format, args); va_end(参数);如果 (r> 0) { Serial.write(print_buf); }}/** * @brief PDM 缓冲区满回调 * 获取数据并调用音频线程回调 */static void pdm_data_ready_inference_callback(void){ int bytesAvailable =PDM.available(); // 读入样本缓冲区 int bytesRead =PDM.read((char *)&sampleBuffer[0], bytesAvailable); if (record_ready ==true) { for (int i =0; i> 1; i++) { inference.buffers[inference.buf_select][inference.buf_count++] =sampleBuffer[i]; if (inference.buf_count>=inference.n_samples) { inference.buf_select ^=1; inference.buf_count =0; inference.buf_ready =1; } } }/** * @brief 初始化推理结构和设置/启动 PDM * * @param[in] n_samples n 个样本 * * @return { description_of_the_return_value } */static boolmic_inference_start(uint32_t n_samples){ inference.buffers[ 0] =(signed short *)malloc(n_samples * sizeof(signed short)); if (inference.buffers[0] ==NULL) { return false; } inference.buffers[1] =(signed short *)malloc(n_samples * sizeof(signed short)); if (inference.buffers[0] ==NULL) { free(inference.buffers[0]);返回假; } sampleBuffer =(signed short *)malloc((n_samples>> 1) * sizeof(signed short)); if (sampleBuffer ==NULL) { free(inference.buffers[0]);免费(推理。缓冲区[1]);返回假; } inference.buf_select =0; inference.buf_count =0; inference.n_samples =n_samples; inference.buf_ready =0; // 配置数据接收回调 PDM.onReceive(&pdm_data_ready_inference_callback); // 可选设置增益,默认为 20 PDM.setGain(80); PDM.setBufferSize((n_samples>> 1) * sizeof(int16_t)); // 初始化 PDM: // - 一个通道(单声道模式) // - 16 kHz 采样率 if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) { ei_printf("无法启动 PDM!"); } record_ready =true; return true;}/** * @brief 等待新数据 * * @return True 完成后 */static boolmic_inference_record(void){ bool ret =true; if (inference.buf_ready ==1) { ei_printf( "错误样本缓冲区溢出。减少每个模型窗口的切片数量" "(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW)\n"); ret =假; } while (inference.buf_ready ==0) { delay(1); } inference.buf_ready =0; return ret;}/** * 获取原始音频信号数据 */static intmic_audio_signal_get_data(size_t offset, size_t length, float *out_ptr){ numpy::int16_to_float(&inference.buffers[inference.buf_select ^ 1][offset], out_ptr , 长度); return 0;}/** * @brief 停止 PDM 并释放缓冲区 */static voidmic_inference_end(void){ PDM.end();免费(推理。缓冲区[0]);免费(推理。缓冲区[1]);自由(样本缓冲区);}#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR !=EI_CLASSIFIER_SENSOR_MICROPHONE#error "电流传感器的型号无效。"#endif

制造工艺

  1. 2020 年 IIoT 安全提示和趋势
  2. 物联网的云和边缘计算:简短的历史
  3. 为什么是物联网边缘计算?
  4. 控创 KBox A-150-WKL 用于数据密集型物联网边缘应用
  5. 为 TinyML 设备设计的 Arm core
  6. 多种颜色的纳米涂层
  7. 边缘计算使 AI 结晶化的优势
  8. 确保边缘计算成功的四个步骤
  9. 微软为 5G 应用程序推出 Azure Edge Zones
  10. 边缘开源的需求(电子书)
  11. 低浓度化学检测系统
  12. 维护气体检测设备的三大理由