3、硬件基础:认识常用传感器(如麦克风、加速度计、摄像头)、了解Arduino板载资源及外设连接方法

TinyML 的核心价值在于“端侧智能”——让机器学习模型直接在嵌入式设备上运行,而这一切的起点是硬件。在 Arduino 平台上开展 TinyML 实验,你不需要先掌握复杂的电路设计,但必须理解三件事:传感器如何将物理世界转化为电信号、Arduino 板卡上有哪些资源可供调用、以及如何正确地将传感器与主控板连接。本章将围绕这三条主线展开,帮助你建立从“物理量”到“数字特征”再到“模型输入”的完整硬件认知链路。

Arduino TinyML 硬件链路总览 传感器域(模拟/数字) 麦克风(音频) I2S / 模拟输出 加速度计(运动) I2C / SPI 摄像头(视觉) DVP / SPI / 并行 Arduino 主控域 MCU(如 SAMD21/ESP32) CPU + SRAM + Flash TinyML 推理引擎 I2C / SPI / UART / I2S GPIO / ADC / PWM 电源管理 3.3V / 5V / VIN 模拟/I2S I2C/SPI DVP/SPI 供电 输出/调试域 串口监视器 UART USB LED / 蜂鸣器 GPIO 输出 PC 端可视化 串口绘图器 传感器采集 → 主控预处理 → TinyML 推理 → 输出/调试

上图展示了 TinyML 实验中最核心的硬件链路:左侧是传感器域,中间是 Arduino 主控域,右侧是输出与调试域。传感器负责将物理世界的声、动、光信号转换为电信号;主控板上的 MCU 通过 I2C、SPI、I2S 或模拟引脚读取这些信号,并在本地完成特征提取和模型推理;最终结果通过串口、LED 或蜂鸣器呈现。理解这条链路,是后续所有实验的基础。

3.1 常用传感器:从物理量到数字特征

在 TinyML 实验中,传感器是数据的源头。不同传感器输出的信号类型、数据速率和接口协议差异很大,这直接决定了你在 Arduino 上如何读取和处理它们。下面我们逐一分析三种最常用的传感器。

3.1.1 麦克风:声音的数字化

麦克风将声波(空气压力变化)转换为电信号。在 TinyML 场景中,我们通常关注两类麦克风:

  • 模拟输出麦克风(如 MAX9814、MAX4466):输出连续电压信号,需连接到 Arduino 的 ADC(模数转换)引脚。优点是接线简单,缺点是抗干扰能力较弱,且 ADC 采样率有限(Arduino Uno 约 10kHz,Nano 33 BLE Sense 约 1MHz)。
  • 数字 I2S 麦克风(如 INMP441、ICS-43434):内置 ADC 和数字接口,直接输出 PCM 音频数据。I2S 协议支持更高的采样率(典型 16kHz/32kHz)和更好的信噪比,是语音识别项目的首选。

对于 Arduino Nano 33 BLE Sense 这类自带麦克风的板卡,你无需额外接线,直接通过 PDM 库读取即可。而使用外部麦克风时,需要注意偏置电压和放大倍数——大多数驻极体麦克风需要 2.2kΩ 上拉电阻提供偏置,否则输出信号会非常微弱。

经验提示:在开始语音识别项目前,先用串口绘图器(Serial Plotter)观察原始音频波形。如果波形幅度始终小于 ADC 量程的 10%,说明信号太弱,需要增加放大增益;如果波形顶部或底部被“削平”,说明信号过强,需要降低增益或调整偏置。

3.1.2 加速度计:运动与姿态的感知

加速度计测量物体在 X、Y、Z 三个轴上的加速度(单位通常为 g,1g = 9.8m/s²)。在 TinyML 中,加速度计数据常用于活动识别(走路、跑步、静止)、跌倒检测和姿态分类。

主流数字加速度计(如 LIS3DH、MPU6050、BMI270)通过 I2C 或 SPI 接口与主控通信。I2C 只需两根线(SDA、SCL),适合连接多个传感器;SPI 速度更快,但需要额外的片选引脚。以 MPU6050 为例,它同时包含加速度计和陀螺仪,I2C 地址默认为 0x68,通过 Wire 库即可读取原始数据。

读取加速度计数据时,需要关注两个关键参数:量程(±2g、±4g、±8g、±16g)和采样率(典型 1Hz-1kHz)。量程决定了测量上限,采样率决定了时间分辨率。对于人体活动识别,±4g 量程和 50Hz 采样率通常足够;对于剧烈运动或振动监测,可能需要 ±16g 和更高采样率。

3.1.3 摄像头:视觉信息的入口

摄像头是 TinyML 中最复杂的传感器,因为它产生的数据量远大于麦克风和加速度计。一个 96×96 像素的灰度图像,每帧就有 9216 字节数据;如果使用 RGB 彩色,数据量再乘 3。因此,摄像头模块通常通过并行接口(DVP)或 SPI 接口传输数据,且需要较大的缓冲区。

在 Arduino 生态中,常见的摄像头模块包括:

  • OV7670:老牌 VGA 摄像头,DVP 并行接口,需要至少 8 个数据引脚和 3 个控制引脚,接线复杂,适合有一定硬件基础的学习者。
  • OV2640:支持 JPEG 输出,可通过 SPI 或 DVP 接口,常见于 ESP32 系列板卡。
  • Arduino Nano 33 BLE Sense 板载摄像头:部分版本集成 HM01B0 低分辨率摄像头(320×320),通过并行接口连接,适合 TinyML 入门。

摄像头数据的读取通常需要 DMA(直接内存访问)支持,否则 MCU 在传输图像时无法执行其他任务。在 Arduino 上,这意味着你需要使用 PImage 或 Camera 库,并注意帧缓冲区的内存管理。

传感器类型 输出信号 接口协议 典型采样率/分辨率 TinyML 应用场景
麦克风(模拟) 模拟电压 ADC 10kHz(Uno) 简单声音检测、关键词唤醒
麦克风(I2S) 数字 PCM I2S 16kHz/32kHz 语音命令识别、声学事件分类
加速度计 数字(X/Y/Z) I2C/SPI 50Hz-1kHz 活动识别、跌倒检测、姿态分类
摄像头 数字图像 DVP/SPI 96×96 或 320×320 图像分类、物体检测、手势识别

3.2 Arduino 板载资源:算力、存储与接口

Arduino 家族庞大,不同板卡的 MCU 性能差异巨大。对于 TinyML 项目,你需要重点关注以下资源:

3.2.1 算力与内存

TinyML 模型推理需要 CPU 执行大量乘加运算,同时模型参数和中间结果需要占用 RAM。以 Arduino Uno(ATmega328P)为例,它只有 2KB SRAM 和 32KB Flash,几乎无法运行任何实用的神经网络模型。而 Arduino Nano 33 BLE Sense 搭载的 nRF52840 拥有 256KB RAM 和 1MB Flash,可以运行经过量化的 MobileNet 或 LSTM 模型。

选择板卡时,建议遵循以下原则:

  • 入门学习:Arduino Nano 33 BLE Sense(自带麦克风、加速度计、陀螺仪、环境传感器)是最佳选择,无需额外接线。
  • 视觉项目:ESP32-S3 或 Arduino Portenta H7(带摄像头接口)更适合,因为它们有更快的 CPU 和更大的 RAM。
  • 超低功耗:Arduino MKR WAN 1300 或 SparkFun Artemis 可用于电池供电的端侧推理。

3.2.2 通信接口与引脚映射

Arduino 的引脚功能并非完全固定,很多引脚复用多种功能。以 Nano 33 BLE Sense 为例:

I2C:  SDA = D4, SCL = D5(用于加速度计、陀螺仪)
SPI:  MOSI = D11, MISO = D12, SCK = D13, SS = D10(用于 SD 卡或外部传感器)
I2S:  SD = D0, SCK = D1, WS = D2(用于板载麦克风)
ADC:  A0-A7(模拟输入,12 位分辨率)
PWM:  D2-D13(部分引脚支持 PWM 输出)

在连接外部传感器前,务必查阅板卡的引脚功能图(Pinout Diagram)。一个常见的错误是将 I2C 设备连接到不支持 I2C 的引脚上,导致通信失败。另外,注意 3.3V 与 5V 逻辑电平的差异——nRF52840 和 ESP32 都是 3.3V I/O,如果连接 5V 传感器,需要电平转换模块。

3.2.3 电源设计

TinyML 推理时,MCU 的电流消耗会显著增加。例如,nRF52840 在运行神经网络时,峰值电流可达 15mA(不含传感器)。如果使用电池供电,需要计算总功耗:

  1. MCU 工作电流(约 10-20mA)
  2. 传感器电流(麦克风约 1mA,加速度计约 0.2mA,摄像头约 50-100mA)
  3. LED 和外部负载电流

Arduino 板载稳压器通常支持 5V USB 供电或 3.7V 锂电池(通过 VIN 引脚)。但注意,当同时驱动摄像头和多个传感器时,稳压器可能过热,此时建议使用外部 5V 电源或独立供电。

风险提示:切勿将 5V 信号直接连接到 3.3V 引脚,否则可能烧毁 MCU。同样,不要从 3.3V 引脚抽取超过 500mA 的电流(具体限值参考板卡手册)。在连接任何外部模块前,先确认其工作电压和逻辑电平。

3.3 外设连接方法:从原理图到实物接线

外设连接是 TinyML 实验中最容易出错的环节。下面以三个典型场景为例,演示完整的连接流程。

3.3.1 场景一:I2C 加速度计(LIS3DH)连接

背景与目标:在 Arduino Nano 33 BLE Sense 上通过 I2C 读取 LIS3DH 加速度计数据,用于后续的活动识别模型训练。

接线步骤:

  1. 将 LIS3DH 的 VCC 连接到 3.3V 引脚(注意:LIS3DH 支持 1.71-3.6V,不能接 5V)。
  2. 将 GND 连接到 GND。
  3. 将 SDA 连接到 Nano 的 D4(I2C 数据线)。
  4. 将 SCL 连接到 Nano 的 D5(I2C 时钟线)。
  5. (可选)将 SAO 引脚接地,设置 I2C 地址为 0x18(默认 0x19)。

验证代码:

#include <Wire.h>
#include <LIS3DH.h>
LIS3DH accel;
void setup() {
  Serial.begin(9600);
  if (!accel.begin(0x18)) { // 尝试地址 0x18
    Serial.println("传感器未找到!");
    while (1);
  }
  accel.setRange(LIS3DH_RANGE_4G);
}
void loop() {
  float x = accel.readFloat(LIS3DH_X_AXIS);
  float y = accel.readFloat(LIS3DH_Y_AXIS);
  float z = accel.readFloat(LIS3DH_Z_AXIS);
  Serial.print(x); Serial.print(",");
  Serial.print(y); Serial.print(",");
  Serial.println(z);
  delay(20); // 50Hz 采样
}

排障过程:如果串口输出“传感器未找到”,首先检查 I2C 地址是否正确(用 I2C 扫描程序确认),其次检查 SDA/SCL 是否接反,最后确认电源电压。在本案例中,我们最初将 SDA 接到了 D5,导致通信失败,交换后恢复正常。

3.3.2 场景二:模拟麦克风(MAX4466)连接

背景与目标:使用 MAX4466 麦克风模块采集环境声音,用于简单的响度分类。

接线步骤:

  1. VCC → 3.3V(MAX4466 支持 2.4-5.5V,但 3.3V 可减少噪声)。
  2. GND → GND。
  3. OUT → A0(模拟输入引脚)。

关键参数:MAX4466 的增益可通过板载电位器调节(默认 25dB,最大 60dB)。在安静环境下,输出直流偏置约为 VCC/2 = 1.65V,声音信号叠加在偏置上。

数据读取:使用 analogRead(A0) 读取 0-1023 的整数值(Uno)或 0-4095(Nano 33)。为了提取声音特征,你需要计算一段时间内的峰值或 RMS 值,而不是直接使用原始值。

实战要点:模拟麦克风的 ADC 采样率有限,无法直接用于语音识别(需要 16kHz 采样)。如果要做关键词识别,建议改用 I2S 数字麦克风。但模拟麦克风非常适合做“声音触发”或“响度检测”等简单任务,且代码量极少。

3.3.3 场景三:摄像头(OV7670)连接与初始化

背景与目标:在 ESP32-S3 开发板上连接 OV7670 摄像头,采集 96×96 灰度图像用于图像分类。

接线清单(部分关键引脚):

OV7670 引脚 ESP32-S3 引脚 说明
VCC 3.3V 摄像头供电
GND GND 共地
SIOC GPIO 10 SCCB 时钟(类似 I2C)
SIOD GPIO 11 SCCB 数据
VSYNC GPIO 6 帧同步信号
HREF GPIO 7 行同步信号
PCLK GPIO 13 像素时钟
XCLK GPIO 15 主时钟输入(24MHz)
D0-D7 GPIO 16-23 8 位并行数据

初始化流程:

  1. 通过 SCCB 接口写入寄存器,配置输出格式(RGB565 或 YUV422)、分辨率(QQVGA 160×120 或 QVGA 320×240)。
  2. 设置 XCLK 为 24MHz,等待摄像头稳定输出。
  3. 在 VSYNC 上升沿开始采集一帧数据,在 PCLK 上升沿读取 D0-D7 数据。

常见问题:图像花屏通常是因为 PCLK 采样时序不对,或数据线接错。建议先用逻辑分析仪检查 VSYNC 和 PCLK 波形,确认帧率和像素时钟是否符合预期。

3.4 常见误区与总结复盘

在硬件连接环节,初学者经常陷入以下误区,这里逐一澄清:

  • 误区一:所有传感器都接 5V。很多现代传感器是 3.3V 逻辑,接 5V 会永久损坏。务必查阅数据手册。
  • 误区二:忽略共地。传感器和主控板必须共地(GND 相连),否则通信信号无法形成回路,数据会乱码。
  • 误区三:I2C 地址冲突。多个 I2C 设备地址相同时,需要修改地址引脚或使用 I2C 多路复用器。
  • 误区四:采样率设置过高。MCU 处理不过来时,数据会丢失或阻塞主循环。建议先以较低采样率(如 50Hz)验证流程,再逐步提高。
  • 误区五:忽视电源纹波。摄像头和无线模块工作时,电源噪声会影响 ADC 精度。可以在电源引脚并联 10μF 和 0.1μF 电容滤波。

总结复盘:硬件连接的本质是“信号完整性”问题——确保传感器输出的信号能无失真地到达 MCU 的引脚。在开始任何 TinyML 实验前,建议先完成以下检查清单:

  1. 确认传感器工作电压与主控 I/O 电平匹配。
  2. 确认所有 GND 已连接。
  3. 使用 I2C 扫描程序或串口打印验证传感器是否被识别。
  4. 用串口绘图器观察原始数据,确认信号幅度和噪声水平。
  5. 记录当前接线图和引脚映射,便于后续调试。