M5Stack Fan Module V1.1 の つかいかた


## はじめに

M5Stack Fan Module v1.1 (STM32F030)は、M5Stackシリーズで使用できるファン制御モジュールです。このモジュールを使用することで、プロジェクトに冷却機能を簡単に追加することができます。本記事では、M5Module-Fanライブラリの使い方とAPIの詳細、そして実際のサンプルコードについて解説します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30621/27dc2000-4c2f-41c4-b6bb-b420cec2f357.png)

## 目次

1. [M5Stack Fan Moduleの概要](#m5stack-fan-moduleの概要)
2. [M5Module-Fanライブラリのインストール](#m5module-fanライブラリのインストール)
3. [APIの使い方](#apiの使い方)
4. [サンプルコードの解説](#サンプルコードの解説)
5. [応用例](#応用例)

## M5Stack Fan Moduleの概要

M5Stack Fan Moduleは、STM32F030マイクロコントローラを搭載したI2C通信対応のファンモジュールです。主な特徴は以下の通りです：

- I2C通信によるファン制御
- PWM制御による回転速度の調整
- 回転数（RPM）の取得機能
- 複数のPWM周波数設定（1KHz/12KHz/24KHz/48KHz）
- 設定の内部フラッシュへの保存機能
- I2Cアドレスの変更機能

このモジュールは、電子機器の冷却、空気循環、または温度管理が必要なプロジェクトに最適です。

## M5Module-Fanライブラリのインストール

### PlatformIOの場合

`platformio.ini`ファイルに以下の依存関係を追加します：

```ini
lib_deps = 
    https://github.com/m5stack/M5Unified
    https://github.com/m5stack/M5Module-Fan
```

### Arduino IDEの場合

1. メニューから「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理...」を選択
2. 検索バーに「M5Module-Fan」と入力
3. 表示されたライブラリをインストール

## APIの使い方

### ライブラリのインクルード

```cpp
#include <m5_module_fan.hpp>
```

### モジュールの初期化

```cpp
M5ModuleFan moduleFan;

// 基本的な初期化
bool success = moduleFan.begin();

// カスタムI2C設定での初期化
bool success = moduleFan.begin(&Wire1, MODULE_FAN_BASE_ADDR, 12, 11, 400000);
// パラメータ: Wire, I2Cアドレス, SDAピン, SCLピン, I2C速度(Hz)
```

### 主要なAPI関数

#### ファンの制御

```cpp
// ファンの有効化
moduleFan.setStatus(MODULE_FAN_ENABLE);

// ファンの無効化
moduleFan.setStatus(MODULE_FAN_DISABLE);

// 現在の状態を取得
module_fan_status_t status = moduleFan.getStatus();
```

#### PWM周波数の設定

```cpp
// PWM周波数を設定（1KHz, 12KHz, 24KHz, 48KHz）
moduleFan.setPWMFrequency(PWM_1KHZ);  // 1KHz
moduleFan.setPWMFrequency(PWM_12KHZ); // 12KHz
moduleFan.setPWMFrequency(PWM_24KHZ); // 24KHz
moduleFan.setPWMFrequency(PWM_48KHZ); // 48KHz

// 現在のPWM周波数設定を取得
module_fan_pwm_freq_t freq = moduleFan.getPWMFrequency();
```

#### デューティサイクルの設定

```cpp
// デューティサイクルを設定（0-100%）
moduleFan.setPWMDutyCycle(80); // 80%の速度でファンを回転

// 現在のデューティサイクルを取得
uint8_t dutyCycle = moduleFan.getPWMDutyCycle();
```

#### 回転数の取得

```cpp
// 現在のファン回転数（RPM）を取得
uint16_t rpm = moduleFan.getRPM();
```

#### 信号周波数の取得

```cpp
// ファンの出力信号周波数を取得
uint16_t signalFreq = moduleFan.getSignalFrequency();
```

#### 設定の保存

```cpp
// 現在の設定を内部フラッシュに保存
moduleFan.saveConfig();
```

#### ファームウェアバージョンの取得

```cpp
// ファームウェアバージョンを取得
uint8_t version = moduleFan.getFirmwareVersion();
```

#### I2Cアドレスの設定と取得

```cpp
// I2Cアドレスを設定（有効範囲: 0x08-0x77）
uint8_t newAddr = moduleFan.setI2CAddress(0x19);

// 現在のI2Cアドレスを取得
uint8_t addr = moduleFan.getI2CAddress();
```

## サンプルコードの解説

以下は、M5Stack Fan Moduleを制御するための基本的なサンプルコードです。このコードでは、ファンの状態表示とボタン操作によるファン制御を実装しています。

```cpp
#include <M5Unified.h>
#include <m5_module_fan.hpp>

// ファンモジュールのインスタンス
M5ModuleFan moduleFan;
// ファンモジュールのI2Cアドレス
uint8_t deviceAddr = MODULE_FAN_BASE_ADDR;
// ファンのデューティサイクル（0-100%）
uint8_t dutyCycle  = 80;
// ファンの動作状態
bool fan_status    = true;
// 表示用キャンバス
M5Canvas canvas(&M5.Display);

void setup()
{
    M5.begin();
    Serial.begin(115200);
    canvas.createSprite(320, 240);
    canvas.setFont(&fonts::lgfxJapanGothic_24);
    canvas.setTextDatum(top_center);
    canvas.setTextColor(WHITE);

    // ファンモジュールの初期化
    // Wire1を使用、I2Cアドレス=deviceAddr、SDA=12、SCL=11、速度=400000Hz
    while (!moduleFan.begin(&Wire1, deviceAddr, 12, 11, 400000)) {
        Serial.printf("Module FAN Init faile\r\n");
        canvas.drawString("Module FAN Init faile", 160, 120);
        canvas.pushSprite(0, 0);
        delay(1000);
    }

    // ファンを80%のデューティサイクルで回転させる
    moduleFan.setPWMDutyCycle(dutyCycle);
    // PWM周波数を1KHzに設定
    moduleFan.setPWMFrequency(PWM_1KHZ);
    // ファンを有効化
    moduleFan.setStatus(MODULE_FAN_ENABLE);
}

void loop()
{
    // 現在のPWM周波数設定インデックス
    int pwm_config_index  = moduleFan.getPWMFrequency();
    // PWM周波数の文字列表現
    String pwm_config_str = "";

    // PWM周波数インデックスを文字列に変換
    switch (pwm_config_index) {
        case PWM_1KHZ:
            pwm_config_str = "1KHz";
            break;
        case PWM_12KHZ:
            pwm_config_str = "12KHz";
            break;
        case PWM_24KHZ:
            pwm_config_str = "24KHz";
            break;
        case PWM_48KHZ:
            pwm_config_str = "48KHz";
            break;
    }
    
    // 画面表示の更新
    canvas.setCursor(0, 10);
    canvas.clear();
    // ファンの動作状態を表示
    canvas.printf("Work Status    :%s\r\n", moduleFan.getStatus() == MODULE_FAN_ENABLE ? "RUNNING" : "STOP");
    // PWM周波数を表示
    canvas.printf("PWM  Frequency :%s\r\n", pwm_config_str.c_str());
    // デューティサイクルを表示
    canvas.printf("PWM  Duty Cycle:%d%%\r\n", moduleFan.getPWMDutyCycle());
    // 回転数（RPM）を表示
    canvas.printf("RPM            :%drpm\r\n", moduleFan.getRPM());
    canvas.pushSprite(0, 0);

    // ボタン状態の更新
    M5.update();
    auto t = M5.Touch.getDetail();
    
    // ボタンAが押された場合：ファンのON/OFF切り替え
    if (M5.BtnA.wasPressed()) {
        fan_status = !fan_status;
        if (fan_status) {
            moduleFan.setStatus(MODULE_FAN_ENABLE);
        } else {
            moduleFan.setStatus(MODULE_FAN_DISABLE);
        }
    }
    
    // ボタンBが押された場合：デューティサイクルを10%ずつ減少
    if (M5.BtnB.wasPressed()) {
        dutyCycle -= 10;
        if (dutyCycle < 0) {
            dutyCycle = 100;
        }
        moduleFan.setPWMDutyCycle(dutyCycle);
    }
    
    // ボタンCが押された場合：デューティサイクルを10%ずつ増加
    if (M5.BtnC.wasPressed()) {
        dutyCycle += 10;
        if (dutyCycle > 100) {
            dutyCycle = 0;
        }
        moduleFan.setPWMDutyCycle(dutyCycle);
    }
    
    delay(10);
}
```

### コードの解説

#### 初期化部分（setup関数）

1. M5Stackの初期化と表示設定
2. ファンモジュールの初期化（Wire1、I2Cアドレス、SDA/SCLピン、通信速度を指定）
3. 初期設定：
   - デューティサイクル：80%
   - PWM周波数：1KHz
   - ファン状態：有効（回転中）

#### メインループ（loop関数）

1. 現在のPWM周波数設定を取得し、対応する文字列に変換
2. 画面表示の更新：
   - ファンの動作状態（RUNNING/STOP）
   - PWM周波数（1KHz/12KHz/24KHz/48KHz）
   - デューティサイクル（0-100%）
   - 現在の回転数（RPM）
3. ボタン操作の処理：
   - ボタンA：ファンのON/OFF切り替え
   - ボタンB：デューティサイクルを10%ずつ減少
   - ボタンC：デューティサイクルを10%ずつ増加

## 応用例

### 温度制御システム

温度センサーと組み合わせて、温度に応じてファンの速度を自動調整するシステムを構築できます。

```cpp
#include <M5Unified.h>
#include <m5_module_fan.hpp>

M5ModuleFan moduleFan;
float temperature;

void setup() {
    M5.begin();
    moduleFan.begin(&Wire1, MODULE_FAN_BASE_ADDR, 12, 11, 400000);
    moduleFan.setPWMFrequency(PWM_1KHZ);
    moduleFan.setStatus(MODULE_FAN_ENABLE);
}

void loop() {
    // 温度センサーから温度を取得（例）
    temperature = M5.Imu.getTemp();
    
    // 温度に応じてファン速度を調整
    if (temperature < 25.0) {
        // 25℃未満：ファン停止
        moduleFan.setStatus(MODULE_FAN_DISABLE);
    } else if (temperature < 30.0) {
        // 25-30℃：低速（30%）
        moduleFan.setStatus(MODULE_FAN_ENABLE);
        moduleFan.setPWMDutyCycle(30);
    } else if (temperature < 35.0) {
        // 30-35℃：中速（60%）
        moduleFan.setStatus(MODULE_FAN_ENABLE);
        moduleFan.setPWMDutyCycle(60);
    } else {
        // 35℃以上：高速（100%）
        moduleFan.setStatus(MODULE_FAN_ENABLE);
        moduleFan.setPWMDutyCycle(100);
    }
    
    // 画面表示
    M5.Display.clear();
    M5.Display.setCursor(0, 0);
    M5.Display.printf("Temperature: %.1f C\n", temperature);
    M5.Display.printf("Fan Speed: %d%%\n", moduleFan.getPWMDutyCycle());
    M5.Display.printf("RPM: %d\n", moduleFan.getRPM());
    
    delay(1000);
}
```

### 複数ファンの制御

I2Cアドレスを変更することで、複数のファンモジュールを個別に制御できます。

```cpp
#include <M5Unified.h>
#include <m5_module_fan.hpp>

M5ModuleFan fan1;
M5ModuleFan fan2;

void setup() {
    M5.begin();
    
    // ファン1の初期化（デフォルトアドレス）
    fan1.begin(&Wire1, MODULE_FAN_BASE_ADDR, 12, 11, 400000);
    
    // ファン2の初期化（アドレスを0x19に変更）
    fan2.begin(&Wire1, 0x19, 12, 11, 400000);
    
    // 両方のファンを有効化
    fan1.setStatus(MODULE_FAN_ENABLE);
    fan2.setStatus(MODULE_FAN_ENABLE);
    
    // 異なる速度設定
    fan1.setPWMDutyCycle(50);  // ファン1: 50%
    fan2.setPWMDutyCycle(80);  // ファン2: 80%
}

void loop() {
    // 状態表示
    M5.Display.clear();
    M5.Display.setCursor(0, 0);
    M5.Display.printf("Fan 1 - Speed: %d%%, RPM: %d\n", 
                     fan1.getPWMDutyCycle(), fan1.getRPM());
    M5.Display.printf("Fan 2 - Speed: %d%%, RPM: %d\n", 
                     fan2.getPWMDutyCycle(), fan2.getRPM());
    
    delay(1000);
}
```

## まとめ

M5Stack Fan Moduleは、I2C通信を使用して簡単に制御できるファンモジュールです。M5Module-Fanライブラリを使用することで、ファンの有効化/無効化、回転速度の調整、回転数の取得などの機能を簡単に実装できます。

このモジュールは、電子機器の冷却、空気循環、温度管理など、様々なプロジェクトに活用できます。特に、温度センサーと組み合わせることで、インテリジェントな冷却システムを構築することが可能です。

## 参考リンク

- [M5Stack Fan Module 公式ドキュメント](https://shop.m5stack.com/products/m5stack-fan-module-v1-1-stm32f030)
- https://docs.m5stack.com/en/module/Module%20Fan%20v1.1
- [M5Module-Fan GitHub リポジトリ](https://github.com/m5stack/M5Module-Fan)
- [M5Unified GitHub リポジトリ](https://github.com/m5stack/M5Unified)

## 自分でやってみた

- https://github.com/GOROman/M5Module-Fan-Test

https://x.com/GOROman/status/1897205370818527680