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 の 3 軸加速度、3 軸角速度、温度データを読み取り、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. 姿勢データの読み取り

  • プログラムの実行後、画面には 3 軸加速度、3 軸角速度、温度データが 500 ms ごとに更新され、シリアルモニタにも対応する値が同時に出力されます。
Page Tools
PDF
On This Page