Open1

M5Stack CoreS3でデジタルコンパスを作成

kok828kok828

M5Stack CoreS3でデジタルコンパスを作成

M5Stack CoreS3の内蔵磁気センサーを使用してデジタルコンパスを作成する方法について記載する。HelloWorldの環境をベースに開発を行う。

1. プロジェクトの作成

  • 新規プロジェクトを作成(PlatformIOで)
  • Name: m5stack_compass
  • Board: M5Stack CoreS3
  • Framework: Arduino
    を選択

2. 必要なライブラリの設定

platformio.iniに以下の設定を追加:

[env:m5stack-cores3]
platform = espressif32
board = m5stack-cores3
framework = arduino
lib_deps = 
    m5stack/M5Unified
    m5stack/M5GFX
monitor_speed = 115200

3. コンパスプログラムの実装

src/main.cppに以下のコードを記述:

#include <M5Unified.h>

float lastHeading = -1;  // 前回の方位角を保存する変数

void drawCompassArrow(float angle) {
    // 前回と同じ角度なら再描画しない
    if (abs(lastHeading - angle) < 0.5) {  // 0.5度以内の変化は無視
        return;
    }
    lastHeading = angle;

    const int cx = M5.Display.width() / 2;
    const int cy = M5.Display.height() / 2;
    const int r = 50;

    float rad = (angle - 90) * PI / 180.0;
    int x2 = cx + r * cos(rad);
    int y2 = cy + r * sin(rad);

    // 背景色を黒に設定
    M5.Display.fillScreen(BLACK);
    
    // コンパスの外枠
    M5.Display.drawCircle(cx, cy, r + 10, WHITE);
    
    // 方位の表示
    M5.Display.setTextSize(2);
    M5.Display.drawString("N", cx - 5, cy - r - 25);
    M5.Display.drawString("E", cx + r + 15, cy - 5);
    M5.Display.drawString("S", cx - 5, cy + r + 15);
    M5.Display.drawString("W", cx - r - 25, cy - 5);

    // 矢印を赤で描画
    M5.Display.drawLine(cx, cy, x2, y2, RED);
    
    // 角度の表示
    M5.Display.fillRect(0, M5.Display.height() - 40, M5.Display.width(), 40, BLACK);
    M5.Display.setCursor(10, M5.Display.height() - 30);
    M5.Display.printf("Heading: %.1f°", angle);
}

void setup() {
    auto cfg = M5.config();
    M5.begin(cfg);
    
    if (!M5.Imu.begin()) {
        M5.Display.println("IMU initialization failed!");
        return;
    }

    M5.Display.setTextSize(2);
    M5.Display.println("Compass Ready!");
    delay(1000);
    M5.Display.fillScreen(BLACK);
}

void loop() {
    M5.update();
    
    float mx, my, mz;
    if (M5.Imu.getMag(&mx, &my, &mz)) {
        // 方位角の計算
        float heading = atan2(my, mx) * 180.0 / PI;
        if (heading < 0) {
            heading += 360;
        }
        
        // 移動平均フィルタの適用
        static float headings[5] = {0};
        static int index = 0;
        headings[index] = heading;
        index = (index + 1) % 5;
        
        float smoothedHeading = 0;
        for (int i = 0; i < 5; i++) {
            smoothedHeading += headings[i];
        }
        smoothedHeading /= 5;
        
        drawCompassArrow(smoothedHeading);
    }
    
    delay(50);
}

4. プログラムの説明

  • コンパスの主な機能:

    • 内蔵磁気センサーから方位データを取得
    • 方位角を計算(0-360度)
    • 円形のコンパスUIを描画
    • 方位を示す矢印を表示
    • 現在の方位角を数値で表示
  • 実装上の工夫:

    • 移動平均フィルタによる値の安定化
    • 前回値との比較による不要な再描画の防止
    • 部分的な画面更新による表示のちらつき防止

5. ビルドとアップロード

  • M5StackをUSBケーブルでPCに接続
  • PlatformIOメニューからビルドとアップロード
  • 本体の電源をON
  • キャリブレーションのため、本体を8の字を描くように動かす

注意点

  • 磁気センサーは周囲の金属の影響を受けやすいため、使用環境に注意
  • 初回使用時はキャリブレーションが必要
  • デバイスの傾きによって精度が変化する可能性あり

以上。