コンテンツにスキップ

【年内最終出荷および年末年始休業のご案内】2025年12月29日(月)11時のご注文/入金分までを年内出荷いたします。それ以降のご注文は年明け2026年1月5日(月)以降の出荷となりますので、ご注意ください。また、2025年12月30日(火)~2026年1月4日(日)まで年末年始休業とさせていただきます。

【年内最終出荷および年末年始休業のご案内】2025年12月29日(月)11時のご注文/入金分までを年内出荷いたします。それ以降のご注文は年明け2026年1月5日(月)以降の出荷となりますので、ご注意ください。また、2025年12月30日(火)~2026年1月4日(日)まで年末年始休業とさせていただきます。

Arduino IDEで始める!STM32開発ボード入門ガイド 応用編

Arduino IDEで始める!STM32開発ボード入門ガイド 応用編

前回の実践編では、スイッチサイエンス STM32開発ボード STM32G431CBU6搭載(以下、STM32開発ボード)でGPIO制御やPWM出力、DAC出力、アナログ入力、シリアル通信(USB/USART) といった主要機能の使い方を解説しました。今回は実用的なデバイスを作るために重要な4つのトピックを解説します。

  • Qwiic/STEMMA QTコネクターを使ったI2C通信
  • STM32LowPower ライブラリによるスリープモードの活用と省電力化
  • STM32RTC ライブラリを用いた内蔵RTCによる時刻制御
  • 精密なタイミング制御に重要な外部システムクロック(HSE)の有効化

STM32開発ボードの特徴とピン配置

すっかり忘れてしまった方も多いと思うので、STM32開発ボードの特徴とピン配置を再度確認しておきましょう。

  • STマイクロエレクトロニクス 32 bitマイコン STM32G431CBU6搭載
  • Arm Cortex-M4コア(FPU内蔵)、最大170 MHz動作
  • 128 KBフラッシュメモリ
  • 32 KB SRAM
  • リセットスイッチRSTとブートモード切替スイッチBOOT
  • 汎用LEDPC4
  • 16 MHzクリスタルと32.768 kHzクリスタル
  • 30本のGPIOポート
  • Qwiic/STEMMA QTコネクター
  • 電源は TPS63802 昇降圧コンバータ採用で 1.8–5.5 V 入力対応

スイッチサイエンス STM32開発ボード STM32G431CBU6搭載ピン配置図

Qwiic/STEMMA QTコネクターを使ったI2C通信

Qwiic/STEMMA QTってなに?

Qwiic/STEMMA QTはI2C通信を4ピンのコネクタ(JST SHコネクタ)で繋ぐための規格です。「Qwiic」はSparkFun社、「STEMMA QT」はAdafruit社が提唱しています。動作電圧は3.3 V※1でレベル変換回路なしで、STM32開発ボードと直結できます。デイジーチェーン(数珠つなぎ)でセンサー同士をどんどん繋いでいけるので、複数のセンサーを使う場合も配線がスッキリします。

Qwiic/STEMMA QTでセンサーをデイジーチェーン

※1 STEMMA QTは5 Vと3.3 Vの両方に対応

I2Cスキャン

プログラム側はいつもの Wire ライブラリがそのまま使えます。ファイルメニューからスケッチ例→Wirei2c_scannerを開いて書き込んでください。Qwiic/STEMMA QTコネクタに接続されているデバイスのアドレスが出力されます。

14:28:24.959 -> Scanning...
14:28:24.959 -> I2C device found at address 0x22
14:28:24.959 -> I2C device found at address 0x68
14:28:25.006 -> done

接続したセンサーのアドレスが表示されれば成功です。あとは、そのセンサー用のライブラリ(例えば Adafruit_BME280 など)を入れれば、すぐに計測を始められます。

ほかのピンをI2Cに割り当てる

STM32ボードにはピンがたくさんあるので、デフォルトのI2Cピン以外を使いたい場合や、配線の都合で別のピンを使いたい場合に非常に便利です。次のようにWire.begin() の前にピンを指定します。

// デフォルトのピン(PA8/PA9)以外を使いたい場合
Wire.setSDA(PB7); // SDAをPB7ピンに設定
Wire.setSCL(PB8); // SCLをPB8ピンに設定
Wire.begin();     // 設定したピンでI2C開始

以下の表から、同じI2C番号のSDAとSCLを選んでペアにしてください。

I2Cバス SDAピン候補 (データ) SCLピン候補 (クロック)
I2C1 PA14, PB7, PB9 PA13, PA15, PB8
I2C2 PA8 PA9
I2C3 PB5 PA8

2つ目のI2Cバスを使う(上級者向け)

「Qwiicコネクタ(I2C1)には低速なセンサー」を、「ピンヘッダ(I2C2)には高速なディスプレイ」を繋ぐ、といった使い分けが可能です。次のようにWire クラスのインスタンスを新しく作ります。

// 新しいI2Cバス(Wire2)を作成
// 引数でピンを指定:TwoWire(SDAピン, SCLピン)
TwoWire Wire2(PA14, PA13);

void setup() {
  Wire.begin();  // Qwiicコネクタ等の通常のI2C
  Wire2.begin(); // 別系統のI2C
}

STM32LowPower ライブラリによるスリープモードの活用と省電力化

STM32のスリープ設定はレジスタ操作などが必要で非常に難解です。STM32LowPower ライブラリを使えば、Arduinoのdelay()感覚で簡単に省電力化できます。

ライブラリのインストール

Arduino IDEのライブラリマネージャからインストールします。

  1. ライブラリマネージャの検索窓に「STM32LowPower」と入力
  2. STM32LowPower by STMicroelectronics をインストール

サンプルコード

Lチカの合間に、消費電力を極限まで抑える「ディープスリープ」を行うサンプルです。

#include "STM32LowPower.h"

const int LEDPin = PC4;

void setup() {
  pinMode(LEDPin, OUTPUT);
  
  // 省電力機能の初期化
  LowPower.begin(); 
}

void loop() {
  // 1. 起きている状態:LEDを1秒点灯(アクティブロー)
  digitalWrite(LEDPin, LOW);
  delay(5000); 
  
  // 2. LEDを消す
  digitalWrite(LEDPin, HIGH);

  // 3. ディープスリープへ移行
  // この間、マイコンは動作を停止し、消費電流が激減します
  LowPower.deepSleep(5000); 
}

ポイント

LowPower.deepSleep()で指定した時間だけスリープし、自動的に復帰して次の行から処理を再開します。通常のdelay()だとCPUは動き続けていますが、LowPower.deepSleep()ならCPUや周辺回路の多くが停止するため、電池寿命が数倍〜数十倍に伸びることもあります。

注意

ディープスリープ中はUSB通信なども停止するため、次のスケッチを書き込む際にArduino IDEがボードを見失うことがあります。その場合は、「書き込みモード※1」にしてからスケッチを書き込んでください。

※1 BOOT ボタンを押しながらRST ボタンを押す

STM32RTC ライブラリを用いた内蔵RTCによる時刻制御

Arduino Unoなどで時計機能を持たせる場合、通常は外付けのRTC(リアルタイムクロック)モジュール(DS3231など)を配線する必要があります。STM32開発ボードにはRTC機能と時計用の32768Hzクリスタル(水晶振動子)が搭載されていて、正確な時刻管理が可能になっています。このRTCはSTM32RTCライブラリを用いて制御できます。

ライブラリのインストール

Arduino IDEのライブラリマネージャからインストールします。

  1. ライブラリマネージャの「STM32RTC」と入力
  2. STM32RTC by STMicroelectronics をインストール

サンプルコード

起動時に時刻をセットし、1秒ごとに現在時刻をシリアルモニタに表示するシンプルな時計のスケッチです。

#include <STM32RTC.h>

STM32RTC& rtc = STM32RTC::getInstance();

void setup() {
  Serial.begin(9600);

	// 時計用の32768Hzクリスタルを使用
  rtc.setClockSource(STM32RTC::LSE_CLOCK);
  rtc.begin();

  // 時刻の設定(例:12時00分00秒)
  rtc.setTime(12, 0, 0);
  // 日付の設定(例:2025年12月31日水曜日)
  // 引数:週(1-7), 日, 月, 年(下2桁)
  rtc.setDate(RTC_WEEKDAY_WEDNESDAY, 31, 12, 25);
}

void loop() {
  // シリアルモニタに表示
  Serial.printf("%02d/%02d/%02d ", rtc.getDay(), rtc.getMonth(), rtc.getYear());
  Serial.printf("%02d:%02d:%02d.%03d\n", rtc.getHours(), rtc.getMinutes(), rtc.getSeconds(), rtc.getSubSeconds());
  delay(1000);
}

設定した時刻が表示されればOKです。

18:15:54.245 -> 2025/12/31 12:00:23.949
18:15:55.264 -> 2025/12/31 12:00:24.949
18:15:56.273 -> 2025/12/31 12:00:25.945
18:15:57.254 -> 2025/12/31 12:00:26.945

バックアップ電源

電源を抜いた後も時刻を保持したい場合、BAT_INピンに 1.5 V ~ 3.3 V のバックアップ電源(コイン電池や単3/単4乾電池など)を繋いでください。これにより、メイン電源が落ちてもRTC回路だけはバックアップ電源で動き続けるため、次に電源を入れたときも正しい時刻から動作を再開できます。

精密なタイミング制御に重要な外部システムクロック(HSE)の有効化

最後に、システムの信頼性を高めるために重要な「システムクロック」の設定について解説します。

「HSI」と「HSE」の違い

STM32マイコンのクロック源には、主に以下の2種類があります。

  1. HSI (High Speed Internal)
    マイコン内部のRC発振回路。外付け部品が不要ですが、温度変化などで誤差が生じやすい特性があります。

  2. HSE (High Speed External)
    ボードに搭載された水晶振動子(クリスタル)を使用します。非常に高い周波数精度を持ちます。

Arduino IDEのデフォルト状態では、汎用性を優先して「HSI(内部クロック)」が使用される設定になっています。

一般的な用途であればこれでも十分動作しますが、長時間のログ記録で時刻のズレを最小限に抑えたい場合や、シビアなタイミング制御が必要なI/O操作を行う場合など、ボードに搭載されている16MHzの水晶振動子=HSEを使用する設定に切り替えることをおすすめします。

システムクロック設定のオーバーライド

Arduino IDEのメニューからHSEを選択するオプションがありません。そのため、以下の2つの手順で設定を切り替えます。

手順1:build_opt.h で周波数を定義する

まず、コンパイラに対して「このボードには16MHzの水晶が接続されている」という情報を伝える必要があります。STM32duino環境では、build_opt.h というファイルをスケッチと同じフォルダに置き、-D HSE_VALUE=16000000と記述すればOKです。

手順2:SystemClock_Config 関数を再定義する

次に、実際にクロックを切り替える処理を記述します。 STM32duinoのコアライブラリには、デフォルトのクロック設定を行う SystemClock_Config という関数が含まれていますが、これは「Weak(弱)定義」されています。

ユーザー側のスケッチ(.inoファイル)の中に、同名の SystemClock_Config 関数を記述すると、ライブラリ側のデフォルト設定は無視され、ユーザーが記述した関数が優先して実行されます(オーバーライド)。

この仕組みを利用して、HSEを使用する設定コードをスケッチに追加します。STM32開発ボード(16MHz水晶搭載)向けのSystemClock_Config 関数はこちら。リンク先のコードをコピーして、スケッチの末尾に追加してください。

HSEを使うとこのような綺麗な1kHzの波形が出せるようになります(HSIだと1.003KHzとか)。

外部システムクロックの1KHz波形

以上です。今回紹介したスケッチはこちらからダウンロードできます。

次の記事 【アルバイト募集】スイッチサイエンスでパート/アルバイトしませんか? 【2025~2026年 冬】