1. 入门

任务目标

本案例将使用Edge Impulse完成一个完整的边缘AI分类任务:从加速度计采集的三轴数据中,识别三种不同的手势动作(水平晃动、垂直晃动、静止)。你将学习从数据采集、模型训练到部署验证的完整流程,最终在PC上通过串口读取传感器数据并实时分类。

硬件与软件准备

  • 硬件:Arduino Nano 33 BLE Sense(板载IMU LSM9DS1)、Micro USB线
  • 软件:Arduino IDE(≥1.8.13)、Edge Impulse CLI(npm install -g edge-impulse-cli)、Google Chrome浏览器
  • 账号:Edge Impulse Studio账号(免费版即可)

实现步骤

1. 连接开发板并采集数据

在Arduino IDE中安装Arduino_LSM9DS1库,然后烧录以下固件,使开发板通过串口向Edge Impulse发送IMU原始数据:

#include <Arduino_LSM9DS1.h>

const float accelerationThreshold = 2.0;
const int numSamples = 119;
int samplesRead = numSamples;

void setup() {
  Serial.begin(115200);
  while (!Serial);
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }
  Serial.println("Started");
}

void loop() {
  float x, y, z;
  while (samplesRead == numSamples) {
    if (IMU.accelerationAvailable()) {
      IMU.readAcceleration(x, y, z);
      if (abs(x) + abs(y) + abs(z) > accelerationThreshold) {
        samplesRead = 0;
        break;
      }
    }
  }
  while (samplesRead < numSamples) {
    if (IMU.accelerationAvailable()) {
      IMU.readAcceleration(x, y, z);
      Serial.print(x); Serial.print('\t');
      Serial.print(y); Serial.print('\t');
      Serial.println(z);
      samplesRead++;
      if (samplesRead == numSamples) break;
    }
  }
}

2. 在Edge Impulse Studio中创建项目

  1. 打开Edge Impulse Studio并创建新项目,命名为gesture-classifier。
  2. 在Devices页面点击Connect a new device,选择Arduino Nano 33 BLE Sense,按提示使用CLI连接开发板。
  3. 连接成功后,进入Data acquisition页面,设置采样频率为62.5Hz,样本时长2000ms(约125个样本/条)。
  4. 采集三类数据,每类至少采集30条样本:
    • idle:开发板静止放置
    • horizontal:沿水平方向快速来回晃动
    • vertical:沿垂直方向快速上下晃动
  5. 点击Add sample保存,重复采集直至每类满足数量要求。

3. 设计Impulse并训练模型

  1. 进入Create impulse页面,添加Spectral Analysis处理模块和Classification学习模块。
  2. 在Spectral features页面,设置:
    • Filter:Low-pass,截止频率25Hz
    • FFT length:32
    • 其余保持默认
  3. 点击Save parameters,然后进入Generate features页面生成特征。
  4. 进入Classifier页面,设置训练轮数60,学习率0.0005,点击Start training。

4. 模型验证与部署

  1. 训练完成后,查看Model testing页面的准确率。若测试准确率≥90%,模型合格。
  2. 进入Deployment页面,选择Arduino library,点击Build下载生成的ZIP库。
  3. 在Arduino IDE中通过Sketch → Include Library → Add .ZIP Library导入下载的库。

5. 部署到开发板进行实时推理

烧录以下推理代码,实现实时手势分类:

#include <Arduino_LSM9DS1.h>
#include <gesture-classifier_inferencing.h>

const float accelerationThreshold = 2.0;
const int numSamples = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
int samplesRead = numSamples;

void setup() {
  Serial.begin(115200);
  while (!Serial);
  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }
  Serial.println("Edge Impulse inference started");
}

void loop() {
  float x, y, z;
  while (samplesRead == numSamples) {
    if (IMU.accelerationAvailable()) {
      IMU.readAcceleration(x, y, z);
      if (abs(x) + abs(y) + abs(z) > accelerationThreshold) {
        samplesRead = 0;
        break;
      }
    }
  }
  while (samplesRead < numSamples) {
    if (IMU.accelerationAvailable()) {
      IMU.readAcceleration(x, y, z);
      signal_t signal;
      signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
      signal.get_data = [](size_t offset, size_t length, float *out_ptr) {
        return 0;
      };
      // 实际推理使用批量读取方式
      float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE * 3];
      buffer[samplesRead * 3] = x;
      buffer[samplesRead * 3 + 1] = y;
      buffer[samplesRead * 3 + 2] = z;
      samplesRead++;
      if (samplesRead == numSamples) {
        signal.get_data = [&](size_t offset, size_t length, float *out_ptr) {
          for (size_t i = 0; i < length; i++) {
            out_ptr[i] = buffer[offset + i];
          }
          return 0;
        };
        EI_CLASSIFIER_RESULT result;
        EI_CLASSIFIER_RESULT_SIZE = EI_CLASSIFIER_LABEL_COUNT;
        run_classifier(&signal, &result, false);
        for (int i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
          Serial.print(result.classification[i].label);
          Serial.print(": ");
          Serial.print(result.classification[i].value * 100);
          Serial.print("%  ");
        }
        Serial.println();
        samplesRead = numSamples;
      }
    }
  }
}

验证方法与判定标准

  • 数据采集验证:在Edge Impulse Studio的Data acquisition页面,点击Record new data,观察实时波形是否随手势变化产生明显幅值差异。
  • 训练验证:在Model testing页面,测试集准确率应≥90%。若低于此值,增加每类样本量至50条以上并重新训练。
  • 实时推理验证:烧录推理代码后,打开Arduino IDE串口监视器(115200波特率),依次执行三种手势各10次,观察串口输出的分类结果。判定标准:每种手势的正确识别率≥8/10,且静止时能稳定输出idle类别。

常见问题

  • 开发板无法连接Edge Impulse:确认已安装CLI并执行edge-impulse-daemon,且开发板通过USB线直接连接电脑(非Hub)。
  • 训练准确率低:检查采集数据时是否混入了其他动作,或样本间差异不明显。重新采集时确保三种手势动作幅度足够大且可区分。
  • 推理结果不稳定:确认推理代码中EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE与训练时样本长度一致(本案例为125),且触发阈值accelerationThreshold设置合理。