Skip to main content

SEEED XIAO RP2040 上的 TinyML(运动识别)

note

本文档由 AI 翻译。如您发现内容有误或有改进建议,欢迎通过页面下方的评论区,或在以下 Issue 页面中告诉我们:https://github.com/Seeed-Studio/wiki-documents/issues

在本教程中,我们将向您展示如何利用 Seeed Studio XIAO RP2040 上的加速度计结合 Edge Impulse 实现运动识别。我们提供的代码支持最新版本的 XIAO RP2040 开发板。

所需材料

硬件

在本教程中,我们需要准备以下材料:

pir

硬件连接

pir

软件

以下是所需的库。强烈建议使用这里的代码来检查硬件是否正常工作。如果您在安装库时遇到问题,请参考这里

开始

首先,我们将运行一些示例代码来检查开发板和显示屏是否正常工作。如果一切正常,您可以继续下一步操作。

检查电路连接和加速度计

打开 Arduino IDE,导航到 Sketch -> Include Library -> Manage Libraries...,然后在库管理器中搜索并安装 U8g2 library

pir

安装完成后,复制以下代码并运行。

#include <Wire.h>
#include "MMA7660.h"
MMA7660 accelemeter;
#define CONVERT_G_TO_MS2 9.80665f

void setup() {
Serial.begin(115200);
while (!Serial);
accelemeter.init();
}


void loop() {

float ax, ay, az;
accelemeter.getAcceleration(&ax, &ay, &az);

Serial.print(ax * CONVERT_G_TO_MS2,4); // 打印 X 轴加速度
Serial.print('\t');
Serial.print(ay * CONVERT_G_TO_MS2,4); // 打印 Y 轴加速度
Serial.print('\t');
Serial.println(az * CONVERT_G_TO_MS2,4); // 打印 Z 轴加速度

}

上传代码后,断开 Seeed Studio XIAO RP2040 的连接。 然后,打开串口监视器,您将看到如下输出:

pir

如果一切正常,我们可以继续将 Seeed Studio XIAO RP2040 连接到 Edge Impulse。

连接到 Edge Impulse

训练模型的精度对最终结果非常重要。如果您的训练结果低于 65%,我们强烈建议您多次训练或添加更多数据。

pir

  • 步骤 2. 选择“Accelerometer data”,然后点击“Let’s get started!”。

pir

pir

  • 步骤 3. 在您的电脑上安装 Edge Impulse CLI

  • 步骤 4. 在您的 终端cmdpowershell 中运行以下命令以启动它。

sudo edge-impulse-data-forwarder
  • 步骤 5. 我们需要使用 CLI 将 Seeed Studio XIAO RP2040 连接到 Edge Impulse。首先,登录您的账户并选择您的项目。

为加速度计和设备命名。

返回 Edge Impulse 的“Data acquisition”页面,如果连接成功,结果应如下所示。您可以在页面右侧找到设备 "XIAO RP2040"。

pir

  • 步骤 6. 选择传感器为“3 axes”。将标签命名为 updown,将采样长度(ms)修改为 20000,然后点击开始采样。

pir

pir

  • 步骤 8. 点击右上角的原始数据并选择“Split Sample”以分割数据。点击 +Add Segment,然后点击图表。重复操作超过 20 次以添加片段。点击 Split,您将看到每段 1 秒的样本数据。

pir

  • 步骤 9. 重复 步骤 7步骤 8,并使用不同的名称标记数据以捕获不同的运动数据,例如 circleline 等。提供的示例是对上下、左右和圆形进行分类。您可以根据需要在此处进行更改。
note

在步骤 8 中,分割时间为 1 秒,这意味着在步骤 7 中,你至少需要完成一次上下摆动,否则结果将不准确。同时,你可以根据自己的运动速度调整分割时间。

  • 步骤 10. 创建 Impulse

点击 Create impulse -> 添加一个处理块 -> 选择 Spectral Analysis -> 添加一个学习块 -> 选择 Classification (Keras) -> 保存 Impulse

pir

  • 步骤 11. 光谱特征

点击并设置

点击 Spectral features -> 下拉页面点击 Save parameters -> 点击 Generate features

输出页面应如下所示:

pir

pir

  • 步骤 12. 训练你的模型

点击 NN Classifier -> 点击 Start training -> 选择 Unoptimized (float32)

pir

  • 步骤 13. 模型测试

点击 Model testing -> 点击 Classify all

如果你的准确率较低,可以通过增加训练集和延长采样时间来检查数据集

我们也可以在下载模型时获得评估结果。

pir

  • 步骤 14. 构建 Arduino 库

点击 Deployment -> 点击 Arduino Library -> 点击 Build -> 下载 .ZIP 文件

pir

  • 步骤 15. .ZIP 文件的名称非常重要,它默认设置为你的 Edge Impulse 项目名称。例如,这里的项目名称是 "RP2040"。选择文件并将其作为 ""添加到 Arduino 库中。

pir

  • 步骤 16. 打开 Arduino -> 点击 Sketch -> 点击 Include Library -> ADD .ZIP Library

复制以下代码,如果 Edge Impulse 项目名称是自定义的,那么 ZIP 文件的名称也会相同。你可以将第一行的 include 更改为你的头文件名称。

#include <XIAO_RP2040_inferencing.h> // 如果是自定义名称,需要将此头文件更改为你自己的文件名
#include <Wire.h>
#include "MMA7660.h"
MMA7660 accelemeter;

#define CONVERT_G_TO_MS2 9.80665f
#define MAX_ACCEPTED_RANGE 2.0f

static bool debug_nn = false;

void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println("Edge Impulse Inferencing Demo");
accelemeter.init();
}

float ei_get_sign(float number) {
return (number >= 0.0) ? 1.0 : -1.0;
}

void loop()
{
ei_printf("\nStarting inferencing in 2 seconds...\n");

delay(2000);

ei_printf("Sampling...\n");

// 在此处为我们将从 IMU 读取的值分配一个缓冲区
float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE] = { 0 };

for (size_t ix = 0; ix < EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE; ix += 3) {
// 确定下一个时间点(然后稍后休眠)
uint64_t next_tick = micros() + (EI_CLASSIFIER_INTERVAL_MS * 1000);
accelemeter.getAcceleration(&buffer[ix], &buffer[ix + 1], &buffer[ix + 2]);

for (int i = 0; i < 3; i++) {
if (fabs(buffer[ix + i]) > MAX_ACCEPTED_RANGE) {
buffer[ix + i] = ei_get_sign(buffer[ix + i]) * MAX_ACCEPTED_RANGE;
}
}

buffer[ix + 0] *= CONVERT_G_TO_MS2;
buffer[ix + 1] *= CONVERT_G_TO_MS2;
buffer[ix + 2] *= CONVERT_G_TO_MS2;

delayMicroseconds(next_tick - micros());
}

// 将原始缓冲区转换为信号,以便我们可以进行分类
signal_t signal;
int err = numpy::signal_from_buffer(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal);
if (err != 0) {
ei_printf("Failed to create signal from buffer (%d)\n", err);
return;
}

// 运行分类器
ei_impulse_result_t result = { 0 };

err = run_classifier(&signal, &result, debug_nn);
if (err != EI_IMPULSE_OK) {
ei_printf("ERR: Failed to run classifier (%d)\n", err);
return;
}

// 打印预测结果
ei_printf("Predictions ");
ei_printf("(DSP: %d ms., Classification: %d ms., Anomaly: %d ms.)",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
ei_printf(": \n");
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
}
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf(" anomaly score: %.3f\n", result.anomaly);
#endif

}

pir

  • 步骤 17. 移动或握住 Seeed Studio XIAO RP2040 并检查结果:

点击 Arduino 界面右上角的监视器。

当你以 圆形和直线 方向移动 Seeed Studio XIAO RP2040 时:

监视器将输出如下内容:

15:45:45.434 -> 
15:45:45.434 -> Starting inferencing in 2 seconds...
15:45:47.414 -> Sampling...
15:45:48.439 -> Predictions (DSP: 6 ms., Classification: 1 ms., Anomaly: 0 ms.):
15:45:48.439 -> Circle: 0.59766
15:45:48.439 -> line: 0.40234
15:45:48.439 ->

恭喜!你完成了项目的最后一步。建议你尝试更多的方向,并检查哪个方向会产生最佳输出。

资源

技术支持与产品讨论

感谢您选择我们的产品!我们致力于为您提供各种支持,以确保您使用我们的产品时能够获得尽可能顺畅的体验。我们提供多个沟通渠道,以满足不同的偏好和需求。

Loading Comments...