ESP32-S3 LSM6D

LSM6DSR 是意法半导体(ST)推出的一款高性能、低功耗的六轴惯性测量单元(IMU)。它在一个小型封装内集成了一个3D数字加速度计和一个3D数字陀螺仪,专为需要高精度和稳定性的应用而设计,尤其在陀螺仪方面提供了业界领先的满量程范围。

参数项加速度计 (Accelerometer)陀螺仪 (Gyroscope)
测量范围±2g, ±4g, ±8g, ±16g±125, ±250, ±500, ±1000, ±2000, ±4000 dps
输出分辨率16位16位
噪声性能低至 60 µg/√Hz低至 0.014 °/s/√Hz
零偏稳定性-优于 0.02 °/s
工作电压1.71 V 至 3.6 V1.71 V 至 3.6 V
功耗高性能模式下组合电流典型值为 1.2 mA
工作温度-40°C 至 +85°C
封装尺寸LGA-14L,2.5 mm x 3 mm x 0.83 mm

LSM6DSR是一款集高性能、高稳定性和丰富可编程特性于一身的旗舰级6轴IMU。它最大的亮点是高达4000 dps的陀螺仪量程和出色的全温域稳定性,配合内置的有限状态机和机器学习内核,能够为从消费电子到工业应用的各类复杂运动感知场景提供强大而灵活的解决方案。

点击 牛瘪汤 主页可以了解更多。


提示:LSM6DSR 支持多种通信协议,根据需求选择协议。


1. LSM6DSR

除了基本的传感功能,LSM6DSR还集成了许多高级特性,使其成为一个强大的运动处理平台:

  • 智能FIFO(先进先出):内置高达 9 KB 的FIFO缓冲区,支持数据压缩,可以批量存储传感器数据,从而减轻主处理器的负担,实现低功耗运行。
  • 可编程有限状态机 (FSM):内置最多 16个 可配置的有限状态机,可以在硬件层面上实现复杂的运动检测和手势识别(如抬手亮屏、摇晃、双击等),无需主处理器持续干预。
  • 机器学习内核 (MLC):部分型号(如LSM6DSRX)集成了硬件机器学习内核,能够在传感器内部直接运行决策树算法,对运动数据进行实时分类(如区分走路、跑步、骑车),功耗极低。
  • 多种通信接口:支持 SPI、I²C 和 MIPI I3C 串行接口,兼容性强,方便与各种主控器连接。同时,它还支持高通的Sensor Sync同步协议。
  • 辅助SPI (OIS):提供专用的辅助SPI接口,可以为相机光学防抖(OIS)系统提供高速陀螺仪数据。
  • 传感器集线器 (Sensor Hub):可以连接和管理外部传感器(如磁力计、气压计),实现多传感器数据融合。
    LSM6dsr
    原理图中使用 I2C 通信,有额外中断信号与 GPIO4 连接。
    供电 VDD 为3.3V。
    VDDIO供电范围可选1.8-3.3V,可以根据实际情况选择有效电压。

2. LSM6DSR 示例

2.1 LSM6DSR 读取加速度

#include <Wire.h>
#include <Adafruit_LSM6DS.h>

Adafruit_LSM6DS lsm6ds;
const int int1Pin = 4; // INT1连接的GPIO引脚

void setup() {
  Serial.begin(115200);
  pinMode(int1Pin, INPUT_PULLUP); // 配置中断引脚为输入上拉

  if (!lsm6ds.begin_I2C()) {
    Serial.println("Failed to initialize LSM6DS!");
    while (1);
  }

  // 配置传感器参数
  lsm6ds.setAccelRange(LSM6DS_ACCEL_RANGE_4_G);
  lsm6ds.setAccelDataRate(LSM6DS_RATE_104_HZ);

  // 配置INT1为加速度数据就绪中断
  lsm6ds.configInt1(false, false, true); // 仅加速度数据就绪触发
}

void loop() {
  if (digitalRead(int1Pin) == LOW) { // 中断触发
    sensors_event_t accel;
    lsm6ds.getEvent(NULL, &accel, NULL); // 仅读取加速度数据

    Serial.print("Accel X: "); Serial.print(accel.acceleration.x);
    Serial.print(" Y: "); Serial.print(accel.acceleration.y);
    Serial.print(" Z: "); Serial.print(accel.acceleration.z);
    Serial.println(" m/s^2");
  }
  delay(10); // 短暂延时减少CPU负载
}

lsm6ds.configInt1(false, false, true) 参数依次为:
陀螺仪就绪中断(禁用),陀螺仪阈值中断(禁用),加速度计就绪中断(启用)。

setAccelRange() 可调整量程(2G/4G/8G/16G)。
setAccelDataRate() 可更改输出数据率(12.5Hz至6.6KHz)。
提示:若需同时读取陀螺仪,修改getEvent()第一个参数为非NULL。

2.2 LSM6DSR 读取陀螺仪

#include <Wire.h>
#include <LSM6DSRSensor.h>

#define LSM6DSR_I2C_ADDR 0x6A  // 若ADDR引脚接地为0x6A,接VCC为0x6B
#define INT1_PIN 4

LSM6DSRSensor imu(&Wire);

void setup() {
  Serial.begin(115200);
  Wire.begin();  // 初始化I2C
  
  pinMode(INT1_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INT1_PIN), interruptHandler, FALLING);

  imu.begin();
  imu.Enable_X();  // 启用加速度计
  imu.Enable_G();  // 启用陀螺仪
  
  // 配置INT1引脚输出陀螺仪数据就绪中断
  imu.Set_INT1_DRDY_G(1);
}

void loop() {
  static bool dataReady = false;
  
  if (dataReady) {
    float gyro[3];
    imu.Get_G_Axes(gyro);
    Serial.print("Gyro X: "); Serial.print(gyro[0]);
    Serial.print(" Y: "); Serial.print(gyro[1]);
    Serial.print(" Z: "); Serial.println(gyro[2]);
    dataReady = false;
  }
  delay(10);  // 降低CPU占用
}

void interruptHandler() {
  dataReady = true;  // 中断触发标志
}

2.3 LSM6DSR 抬腕唤醒

LSM6DSR实现"抬腕唤醒",以下代码利用芯片内置硬件(FSM有限状态机/AWT绝对手腕倾斜)的低功耗方案。

#include <Wire.h>
#include "LSM6DSRSensor.h"

#define INT1_PIN 4  // INT1连接GPIO4
volatile bool wakeUpDetected = false;

// LSM6DSR实例化
LSM6DSRSensor lsm6dsr(&Wire);

void IRAM_ATTR interruptHandler() {
  wakeUpDetected = true;
}

void setup() {
  Serial.begin(115200);
  Wire.begin(8, 9);  // 初始化I2C,GPIO8(SDA), GPIO9(SCL)

  // 初始化传感器
  lsm6dsr.begin();
  lsm6dsr.Enable_X();

  // 配置唤醒检测
  lsm6dsr.Enable_Wake_Up_Detection();
  lsm6dsr.Set_Wake_Up_Threshold(2);  // 设置阈值,单位取决于FS_XL设置
  lsm6dsr.Set_Wake_Up_Duration(1);   // 最小持续时间

  // 配置INT1引脚
  pinMode(INT1_PIN, INPUT_PULLUP);
  attachInterrupt(INT1_PIN, interruptHandler, FALLING);

  Serial.println("等待抬腕唤醒...");
  esp_sleep_enable_ext0_wakeup((gpio_num_t)INT1_PIN, LOW);
}

void loop() {
  if (wakeUpDetected) {
    detachInterrupt(INT1_PIN);
    Serial.println("抬腕动作检测到!");

    // 读取加速度数据验证
    float accel[3];
    lsm6dsr.Get_X_Axes(accel);
    Serial.printf("加速度: X=%.2f, Y=%.2f, Z=%.2f\n", accel[0], accel[1], accel[2]);

    wakeUpDetected = false;
    attachInterrupt(INT1_PIN, interruptHandler, FALLING);
  }

  // 进入低功耗模式
  if (Serial.available()) {
    Serial.read();
  } else {
    delay(100);
    esp_light_sleep_start();
  }
}

关键函数说明 :

  • 传感器初始化
    通过Enable_X()启用加速度计,必须调用此函数后才能配置唤醒功能。

  • 唤醒参数设置
    Set_Wake_Up_Threshold(2)
    设置唤醒阈值,实际g值取决于FS_XL量程(默认±2g时约为62.5mg/LSB)。
    Set_Wake_Up_Duration(1)
    设置持续时间,对应1个采样周期(ODR决定时间长度)。

  • 中断配置
    INT1引脚配置为下降沿触发,当加速度超过阈值时产生中断信号。
    esp_sleep_enable_ext0_wakeup使中断能唤醒芯片从深度睡眠。

提示:

  1. 确保I2C上拉电阻(通常4.7kΩ)已正确连接。
  2. 若使用深度睡眠,需通过RTC引脚唤醒,GPIO4需支持此功能。抬腕检测实际是X/Y/Z任一轴超过阈值的加速度变化。

2.4 LSM6DSR 计步

#include <Adafruit_LSM6DS.h>
#include <Adafruit_Sensor.h>

Adafruit_LSM6DS lsm6ds;
volatile int stepCount = 0;
const int intPin = 4;

void IRAM_ATTR stepInterrupt() {
  stepCount++;
}

void setup() {
  Serial.begin(115200);
  pinMode(intPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(intPin), stepInterrupt, RISING);

  if (!lsm6ds.begin_I2C()) {
    Serial.println("Failed to initialize LSM6DSR");
    while (1);
  }

  // 配置加速度计范围与数据速率
  lsm6ds.setAccelRange(LSM6DS_ACCEL_RANGE_4_G);
  lsm6ds.setAccelDataRate(LSM6DS_RATE_104_HZ);

  // 启用步数检测功能
  lsm6ds.enablePedometer(true);
}

void loop() {
  sensors_event_t accel;
  lsm6ds.getEvent(&accel, NULL, NULL);

  Serial.print("Steps: ");
  Serial.println(stepCount);
  delay(1000); // 降低输出频率
}

提示

  • 校准步骤
    将设备静止放置10秒以初始化步数检测算法。
  • 中断消抖
  • 若信号不稳定,可在硬件上增加0.1μF电容或在代码中设置短延时滤波。
  • 功耗优化
    降低数据速率至26Hz(LSM6DS_RATE_26_HZ)可减少能耗。

结语

文章都看到完了,就不点个关注吗,老铁!
欢迎关注博主–牛瘪汤

更多推荐