这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » Arduino Nicla Vision 开发指南【板载6轴IMU使用】

共1条 1/1 1 跳转至

Arduino Nicla Vision 开发指南【板载6轴IMU使用】

菜鸟
2025-12-16 21:06:15     打赏

一、硬件介绍

1、产品特点

Arduino Nicla Vision 搭载STM32H747AII6 双核芯片(Cortex-M7_480MHz + Cortex-M4_240MHz),板载六轴智能运动传感器、集成麦克风和距离传感器、Wi-Fi和蓝牙模块、以及一个200万的彩色摄像头;image-20251201235158510.png


特性

image.png


系统框图


image-20251202202441525.png



功率


image-20251202204111527.png



二、六轴 IMU (LSM6DSOX)

LSM6DSOX是一款具有3D数字加速度计和3D数字陀螺仪的系统级封装模块,在高性能模式下以0.55mA的电流工作,并且具有始终开启的低功耗特性;通过开发板的 SPI5 连接;

image-20251202205948794.png


特性

高达9 KB的智能FIFO

±2/±4/±8/±16 g满量程

±125/±250/±500/±1000/±2000 dps 满量程


原理图

image-20251203212440956.png


三、代码编写

安装支持库

安装以下两个库

image-20251211205640463.png


获取3轴加速度数据

#include <Arduino_LSM6DSOX.h>

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

  if (!IMU.begin()) {
    Serial.println("初始化失败!");
    while (1);
  }

  Serial.print("采样速率: ");
  Serial.print(IMU.accelerationSampleRate());
  Serial.println(" Hz");
  Serial.println();
  Serial.println("三轴加速度数据如下: ");
}

void loop() {
  float x, y, z;

  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);

    Serial.print("X: ");
    Serial.print(x);

    Serial.print("    Y: ");
    Serial.print(y);

    Serial.print("    Z: ");
    Serial.print(z);

    Serial.println();
  }
}

image-20251211203227324.png

获取3轴角速度数据

#include <Arduino_LSM6DSOX.h>

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

  if (!IMU.begin()) {
    Serial.println("初始化失败!");
    while (1);
  }

  Serial.print("采样速率: ");
  Serial.print(IMU.gyroscopeSampleRate());
  Serial.println(" Hz");
  Serial.println();
  Serial.println("角速度数据如下: ");
}

void loop() {
  float x, y, z;

  if (IMU.gyroscopeAvailable()) {
    IMU.readGyroscope(x, y, z);

    Serial.print("X: ");
    Serial.print(x);

    Serial.print("    Y: ");
    Serial.print(y);

    Serial.print("    Z: ");
    Serial.print(z);

    Serial.println();
  }
}

image-20251211204131388.png



运动状态检测:

通过IMU内置的MLC 判断 运动状态(静止、中等强度运动、高强度运动)

模型以 UCF(Unified Configuration Format) 形式,存储在 lsm6dsox_motion_intensity.h 中;


根据 MLC 输出值,点亮不同颜色 LED 并打印当前状态:

image.png


#include "LSM6DSOXSensor.h"
#include "lsm6dsox_motion_intensity.h"

#define INT_1 LSM6DS_INT

// 中断事件标志
volatile int mems_event = 0;

// Components
LSM6DSOXSensor AccGyr(&SPI1, PIN_SPI_SS1);

// MLC
ucf_line_t *ProgramPointer;
int32_t LineCounter;
int32_t TotalNumberOfLine;

void INT1Event_cb();
void printMLCStatus(uint8_t status);

void setup()
{
  // Led 初始化
  pinMode(LEDB, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDR, OUTPUT);
  digitalWrite(LEDB, HIGH);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDR, HIGH);

  Serial.begin(115200);

  // 初始化加速度计
  SPI1.begin();
  AccGyr.begin();


  // 加载 MLC 模型数据
  ProgramPointer = (ucf_line_t *)lsm6dsox_motion_intensity;
  TotalNumberOfLine = sizeof(lsm6dsox_motion_intensity) / sizeof(ucf_line_t);

  for (LineCounter = 0; LineCounter < TotalNumberOfLine; LineCounter++) {
    if (AccGyr.Write_Reg(ProgramPointer[LineCounter].address, ProgramPointer[LineCounter].data)) {
      Serial.print("加载失败的行: ");
      Serial.println(LineCounter);
      while (1) {
        digitalWrite(LED_BUILTIN, LOW);
        delay(250);
        digitalWrite(LED_BUILTIN, HIGH);
        delay(250);
      }
    }
  }

  //配置加速度计
  AccGyr.Enable_X();
  AccGyr.Set_X_ODR(104.0f);
  AccGyr.Set_X_FS(2);

  // 中断引脚
  pinMode(INT_1, INPUT);
  attachInterrupt(INT_1, INT1Event_cb, RISING);
}

void loop()
{
  if (mems_event) {
    mems_event = 0;
    LSM6DSOX_MLC_Status_t status;
    AccGyr.Get_MLC_Status(&status);
    if (status.is_mlc1) {
      uint8_t mlc_out[8];
      AccGyr.Get_MLC_Output(mlc_out);
      printMLCStatus(mlc_out[0]);
    }
  }
}

void INT1Event_cb()
{
  mems_event = 1;
}

void printMLCStatus(uint8_t status)
{

  digitalWrite(LEDB, HIGH);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDR, HIGH);

  switch (status) {
    case 1:
      // LEDB On
      digitalWrite(LEDB, LOW);
      Serial.println("静止");
      break;
    case 4:
      // LEDG On
      digitalWrite(LEDG, LOW);
      Serial.println("中等强度运动");
      break;
    case 8:
      // LEDR On
      digitalWrite(LEDR, LOW);
      Serial.println("高强度运动");
      break;
    default:
      Serial.println("未知状态");
      break;
  }
  Serial.println();
}




lsm6dsox_motion_intensity.h:

#ifndef LSM6DSOX_MOTION_INTENSITY_H
#define LSM6DSOX_MOTION_INTENSITY_H

#ifdef __cplusplus
  extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#ifndef MEMS_UCF_SHARED_TYPES
#define MEMS_UCF_SHARED_TYPES

/** Common data block definition **/
typedef struct {
  uint8_t address;
  uint8_t data;
} ucf_line_t;

#endif /* MEMS_UCF_SHARED_TYPES */

/** Configuration array generated from Unico Tool **/
const ucf_line_t lsm6dsox_motion_intensity[] = {
  {.address = 0x10, .data = 0x00,},
  {.address = 0x11, .data = 0x00,},
  {.address = 0x01, .data = 0x80,},
  {.address = 0x04, .data = 0x00,},
  {.address = 0x05, .data = 0x00,},
  {.address = 0x17, .data = 0x40,},
  {.address = 0x02, .data = 0x11,},
  {.address = 0x08, .data = 0xEA,},
  {.address = 0x09, .data = 0x46,},
  {.address = 0x09, .data = 0x03,},
  {.address = 0x09, .data = 0x50,},
  {.address = 0x09, .data = 0x03,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x0A,},
  {.address = 0x02, .data = 0x11,},
  {.address = 0x08, .data = 0xF2,},
  {.address = 0x09, .data = 0x34,},
  {.address = 0x02, .data = 0x11,},
  {.address = 0x08, .data = 0xFA,},
  {.address = 0x09, .data = 0x3C,},
  {.address = 0x09, .data = 0x03,},
  {.address = 0x09, .data = 0x52,},
  {.address = 0x09, .data = 0x03,},
  {.address = 0x09, .data = 0x5E,},
  {.address = 0x09, .data = 0x03,},
  {.address = 0x02, .data = 0x31,},
  {.address = 0x08, .data = 0x3C,},
  {.address = 0x09, .data = 0x3F,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x01,},
  {.address = 0x09, .data = 0x10,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x1F,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x02, .data = 0x31,},
  {.address = 0x08, .data = 0x52,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x01, .data = 0x00,},
  {.address = 0x01, .data = 0x80,},
  {.address = 0x17, .data = 0x40,},
  {.address = 0x02, .data = 0x31,},
  {.address = 0x08, .data = 0x5E,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x2C,},
  {.address = 0x09, .data = 0x80,},
  {.address = 0x09, .data = 0xA0,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x00,},
  {.address = 0x09, .data = 0x41,},
  {.address = 0x09, .data = 0xE0,},
  {.address = 0x01, .data = 0x80,},
  {.address = 0x17, .data = 0x00,},
  {.address = 0x04, .data = 0x00,},
  {.address = 0x05, .data = 0x10,},
  {.address = 0x02, .data = 0x01,},
  {.address = 0x01, .data = 0x00,},
  {.address = 0x5E, .data = 0x02,},
  {.address = 0x01, .data = 0x80,},
  {.address = 0x0D, .data = 0x01,},
  {.address = 0x60, .data = 0x35,},
  {.address = 0x01, .data = 0x00,},
  {.address = 0x10, .data = 0x40,},
  {.address = 0x11, .data = 0x00,}
};

#ifdef __cplusplus
}
#endif

#endif /* LSM6DSOX_MOTION_INTENSITY_H */


Vision_IMU.gif











关键词: Arduino Nicla Vision    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]