简体中文
English
简体中文
日本語

Arduino 上手教程

2. 设备开发 & 案例程序

5. 扩展模块

6. 应用案例

Unit DoF6 Arduino 使用教程

1. 准备工作

2. 案例程序

  • 本教程中使用的主控设备为 CoreS3,搭配 Unit DoF6。Unit DoF6 采用 I2C 通信,BMI270 默认地址为 0x69,可通过板载开关切换为 0x68(切换后需同步修改程序中的 BMI270_ADDRESS)。设备连接后对应的引脚为 G2 (SDA)、G1 (SCL)。示例程序每 500 ms 读取一次 BMI270 的三轴加速度、三轴角速度及温度数据,在 CoreS3 屏幕上以仪表盘显示加速度、角速度和温度,并通过串口同步输出对应数据。
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
#include <M5Unified.h>
#include <M5UnitUnified.h>
#include <M5UnitUnifiedIMU.h>

constexpr uint8_t BMI270_ADDRESS = 0x69;

m5::unit::UnitUnified units;
m5::unit::UnitDoF6 dof6{BMI270_ADDRESS};
m5::imu::imu_convert_param_t convert_param{};

void drawHeader(bool connected) {
    M5.Display.fillScreen(TFT_BLACK);
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(TFT_CYAN, TFT_BLACK);
    M5.Display.setCursor(12, 8);
    M5.Display.print("UNIT DoF6");
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(connected ? TFT_GREEN : TFT_ORANGE, TFT_BLACK);
    M5.Display.setCursor(240, 8);
    M5.Display.print(connected ? "READY" : "WAIT");
}

void drawStatus(const char* message, uint16_t color) {
    M5.Display.fillScreen(TFT_BLACK);
    drawHeader(false);
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(color, TFT_BLACK);
    M5.Display.setCursor(12, 72);
    M5.Display.print(message);
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(TFT_DARKGREY, TFT_BLACK);
    M5.Display.setCursor(12, 108);
    M5.Display.print("I2C 400 kHz");
}

void drawVectorCard(int x, int y, const char* title, const char* unit,
                    float x_value, float y_value, float z_value) {
    // Clear the whole card before redrawing, otherwise old glyphs remain.
    M5.Display.fillRect(x, y - 4, 148, 88, TFT_BLACK);
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(TFT_CYAN, TFT_BLACK);
    M5.Display.setCursor(x + 10, y + 8);
    M5.Display.printf("%s  (%s)   ", title, unit);
    M5.Display.setTextColor(TFT_WHITE, TFT_BLACK);
    M5.Display.setCursor(x + 10, y + 28);
    M5.Display.printf("X  %+8.2f   ", x_value);
    M5.Display.setCursor(x + 10, y + 48);
    M5.Display.printf("Y  %+8.2f   ", y_value);
    M5.Display.setCursor(x + 10, y + 68);
    M5.Display.printf("Z  %+8.2f   ", z_value);
}

void drawData(float ax, float ay, float az, float gx, float gy, float gz, float temperature) {
    M5.Display.startWrite();
    drawVectorCard(8, 48, "ACCEL", "g", ax, ay, az);
    drawVectorCard(164, 48, "GYRO", "dps", gx, gy, gz);
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(TFT_CYAN, TFT_BLACK);
    M5.Display.setCursor(8, 138);
    M5.Display.print("TEMPERATURE");
    M5.Display.setTextColor(TFT_WHITE, TFT_BLACK);
    M5.Display.setTextSize(1);
    M5.Display.setCursor(8, 158);
    M5.Display.printf("%+7.1f C", temperature);
    M5.Display.setTextSize(1);
    M5.Display.setTextColor(TFT_DARKGREY, TFT_BLACK);
    M5.Display.setCursor(12, 218);
    M5.Display.print("LIVE  |  500 ms  |  I2C");
    M5.Display.endWrite();
}

void setup() {
    Serial.begin(115200);
    const uint32_t serial_start = millis();
    while (!Serial && millis() - serial_start < 3000) {
        delay(10);
    }
    Serial.println("Starting Unit DoF6...");

    auto config = M5.config();
    M5.begin(config);
    M5.Display.setFont(&fonts::FreeSansBold9pt7b);
    M5.Display.setTextSize(1);
    M5.Display.setRotation(1);
    M5.Display.setTextWrap(false, false);
    drawStatus("Initializing...", TFT_YELLOW);

    auto cfg = dof6.component_config();
    cfg.clock = 400000;
    dof6.component_config(cfg);

    if (!M5.Ex_I2C.begin() || !units.add(dof6, M5.Ex_I2C) || !units.begin()) {
        while (true) {
            Serial.println("Unit DoF6 not found. Check wiring and BMI270 address.");
            drawStatus("Sensor not found", TFT_ORANGE);
            delay(1000);
        }
    }

    dof6.imuConvertParam(convert_param);
    Serial.printf("Unit DoF6 ready, BMI270 address: 0x%02X\n", BMI270_ADDRESS);
    drawHeader(true);
}

void loop() {
    M5.update();
    units.update();

    static uint32_t last_output = 0;
    if (millis() - last_output < 500) {
        return;
    }
    last_output = millis();

    m5::imu::imu_raw_data_t raw{};
    static bool waiting_shown = false;
    if (m5::imu::any(dof6.readImuRaw(raw))) {
        waiting_shown = false;
        const float ax = raw.accel[0] * convert_param.accel_res;
        const float ay = raw.accel[1] * convert_param.accel_res;
        const float az = raw.accel[2] * convert_param.accel_res;
        const float gx = raw.gyro[0] * convert_param.gyro_res;
        const float gy = raw.gyro[1] * convert_param.gyro_res;
        const float gz = raw.gyro[2] * convert_param.gyro_res;
        const float temperature = raw.temp * convert_param.temp_res + convert_param.temp_offset;

        Serial.printf("Accel: %.3f, %.3f, %.3f g\n",
                      ax, ay, az);
        Serial.printf("Gyro:  %.3f, %.3f, %.3f dps\n",
                      gx, gy, gz);
        Serial.printf("Temperature: %.2f C\n\n", temperature);

        drawData(ax, ay, az, gx, gy, gz, temperature);
    } else {
        if (!waiting_shown) {
            waiting_shown = true;
            Serial.println("Waiting for Unit DoF6 data...");
            drawStatus("Waiting for data...", TFT_YELLOW);
        }
    }
}

3. 编译上传

  • 复制粘贴上述例程代码到项目代码区,选中设备端口(详情请参考 程序编译与烧录),点击 Arduino IDE 左上角编译上传按钮,等待程序完成编译并上传至设备。

4. 姿态数据查看

  • 程序运行后,屏幕每 500 ms 刷新一次三轴加速度、三轴角速度及温度数据,串口监视器同步输出对应数值。
Page Tools
PDF
On This Page