「Arduinoでセンサーデータを記録したいけど、シリアルモニターを閉じたら消えちゃう…」

そんな悩みを抱えたことがある方、多いんじゃないでしょうか。

リアルタイムで確認するだけなら問題ないのですが、長期間のデータを蓄積して分析したいとなると、やっぱりどこかに保存する仕組みが必要です。

今回は SDカードモジュール を使って、センサーデータをCSV形式でロギングする方法を完全解説します!タイムスタンプの付け方、停電(電源断)が起きてもデータが壊れない工夫まで丁寧にお伝えします。

✅ 対象読者: Arduino中級者(Lチカ・センサー読み取りはできる方)

SDカードモジュールとは?まずざっくり理解しよう

Arduino SD card data logging
Arduino SD card data logging / Photo by Luis Quintero via Pexels

SDカードモジュールは、一般的なmicroSDカードをArduinoから読み書きするためのモジュールです。

イメージとしては、「Arduinoに外付けのメモリ帳をくっつける」感じです。

Arduinoには SD.h という公式ライブラリがあり、ファイルの読み書きをシンプルなコードで実現できます。SPIという通信規格でArduinoと接続するのが一般的です。

必要なもの

  • Arduino UNO(またはNano・Megaなど)
  • SDカードモジュール(SPI接続タイプ。よく見かける青い基板のもので大丈夫です)
  • microSDカード(FAT32フォーマット済み、2〜32GB推奨)
  • DHT11またはDHT22(温湿度センサー)
  • ジャンパーワイヤー・ブレッドボード

配線図(ピン接続まとめ)

SDカードモジュールはSPI接続です。Arduino UNOでの接続は以下の通りです。

SDカードモジュール側 Arduino UNO側
VCC 5V
GND GND
MISO D12
MOSI D11
SCK D13
CS(チップセレクト) D4(任意変更可)

DHT11のデータピンはD2に接続してください。配線が終わったら、ショートしていないかざっと確認しておきましょう。

SDカードの初期化を確認する最小スケッチ

まずSDカードが正しく認識されているかを確認するミニスケッチを動かしてみましょう。いきなり本番コードを書く前にこのステップを踏むと、トラブルの切り分けが格段に楽になります。

// SDカード認識確認スケッチ
#include <SPI.h>
#include <SD.h>

const int CS_PIN = 4; // CSピンを4番に設定

void setup() {
  Serial.begin(9600);
  Serial.println("SDカード初期化中...");

  // SD.begin()が失敗したら停止
  if (!SD.begin(CS_PIN)) {
    Serial.println("SDカードの初期化に失敗しました!");
    Serial.println("配線・フォーマットを確認してください");
    while (1); // 無限ループで停止
  }

  Serial.println("SDカードの初期化成功!");
}

void loop() {
  // ここでは何もしない
}

シリアルモニターに「SDカードの初期化成功!」が表示されればOKです。失敗する場合は、FAT32フォーマットを再確認するか、CSピンの番号を見直してみてください。

本題!センサーデータをCSVで保存するスケッチ

ここからが本番です。DHT11で温湿度を読み取り、10秒ごとにCSVファイルへ追記するスケッチを作ります。

ポイントをまとめるとこんな感じです:

  • File.open() のモードは FILE_WRITE(追記モード)を使う
  • 1行書いたら必ず dataFile.close() を呼ぶ(これが停電対策の核心!)
  • タイムスタンプはRTCモジュール(DS3231など)があれば最高だが、今回はArduinoの起動からの経過秒で代用する
// センサーデータCSVロギングスケッチ
#include <SPI.h>
#include <SD.h>
#include <DHT.h>

#define DHTPIN 2        // DHTセンサーのデータピン
#define DHTTYPE DHT11   // DHT11を使用
#define CS_PIN 4        // SDカードのCSピン

DHT dht(DHTPIN, DHTTYPE);

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

  // SDカードを初期化
  if (!SD.begin(CS_PIN)) {
    Serial.println("SDカード初期化失敗!");
    while (1);
  }
  Serial.println("SDカード準備完了");

  // CSVヘッダーを書き込む(ファイルが新規の場合のみ)
  if (!SD.exists("log.csv")) {
    File headerFile = SD.open("log.csv", FILE_WRITE);
    if (headerFile) {
      headerFile.println("timestamp_sec,temperature_C,humidity_pct");
      headerFile.close(); // 必ずclose!
      Serial.println("ヘッダー行を書き込みました");
    }
  }
}

void loop() {
  // センサーから温湿度を取得
  float temp = dht.readTemperature();
  float humi = dht.readHumidity();

  // 読み取り失敗チェック
  if (isnan(temp) || isnan(humi)) {
    Serial.println("センサー読み取りエラー!");
    delay(10000);
    return;
  }

  // 起動からの経過秒をタイムスタンプとして使用
  unsigned long timestamp = millis() / 1000;

  // CSVに1行追記
  File dataFile = SD.open("log.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.print(timestamp);
    dataFile.print(",");
    dataFile.print(temp);
    dataFile.print(",");
    dataFile.println(humi);
    dataFile.close(); // ★ここが最重要!毎回closeで停電対策

    // シリアルモニターにも表示
    Serial.print("記録 → 経過:");
    Serial.print(timestamp);
    Serial.print("秒 / 温度:");
    Serial.print(temp);
    Serial.print("℃ / 湿度:");
    Serial.print(humi);
    Serial.println("%");
  } else {
    Serial.println("ファイルオープン失敗!");
  }

  delay(10000); // 10秒ごとに記録
}

停電対策の核心「毎回closeする」理由


これ、地味に大事なポイントです。

Arduinoの SD.h ライブラリは、close() を呼ぶまでデータをバッファ(メモリ上)にためておく設計になっています。

つまり、closeする前に電源が落ちると、バッファのデータが丸ごと消えるんです。

1回の記録ごとに open → write → close を繰り返すのは少し非効率に思えますが、ロギング用途ではこれが最も安全な方法です。10秒おきのロギングなら処理速度の問題は全く気にしなくて大丈夫です。

生成されるCSVのサンプル

SDカードを取り出してPCで開くと、こんなCSVが保存されているはずです。

timestamp_sec,temperature_C,humidity_pct
10,24.50,58.00
20,24.60,57.00
30,24.70,57.00
40,25.00,56.00

このままExcelやGoogleスプレッドシートに読み込んでグラフ化できます。Pythonのpandasやmatplotlibでもすぐに扱える形式なので、データ分析に繋げやすいのも嬉しいポイントです。

【応用】RTCモジュールで本物のタイムスタンプを付ける

「経過秒じゃなくて、実際の日時を記録したい!」という場合は DS3231 などのRTC(リアルタイムクロック)モジュールを追加するのがおすすめです。

DS3231は RTClib ライブラリを使うと数行で日時取得できます。ロギング行の書き方だけサンプルを示しておきます。

// RTClib使用時のタイムスタンプ取得例(RTClib導入済みの場合)
#include <RTClib.h>

RTC_DS3231 rtc;

void setup() {
  rtc.begin();
  // 初回のみ時刻合わせが必要
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

// loop内でのタイムスタンプ取得
DateTime now = rtc.now();
String timestamp = String(now.year()) + "/"
                 + String(now.month()) + "/"
                 + String(now.day()) + " "
                 + String(now.hour()) + ":"
                 + String(now.minute()) + ":"
                 + String(now.second());

// CSVに書き込む時はこんな感じ
dataFile.print(timestamp);
dataFile.print(",");

こうすることで「2025/7/15 09:30:00」のような本物の日時がCSVに記録されます。本格的な温度ロガーやデータ収集機器を作るときはぜひ組み合わせてみてください。

よくあるトラブルと対処法

  • 🔴 SDカードが認識されない → FAT32フォーマットを確認。32GB超のカードはFAT32でフォーマットし直す必要あり
  • 🔴 ファイルが開けない(false返る) → CSピンの番号を見直す。他のSPIデバイスと競合していないか確認
  • 🔴 データが途中で切れている → close()が呼ばれる前に電源が落ちた可能性大。書き込み頻度と電源安定化を見直す
  • 🔴 センサーの値がnanになる → DHT11は最低1〜2秒の読み取り間隔が必要。isnan()チェックを忘れずに

まとめ


今回は ArduinoとSDカードモジュールを使って、センサーデータをCSV形式でロギングする方法を解説しました。

特に大事なポイントは「1回の記録ごとに必ずclose()する」という停電対策の習慣です。この一手間がデータ損失を防ぐ最大の保険になります。

RTCモジュールを組み合わせれば、本格的な長期データロガーとして十分実用的な装置が作れます。温湿度の記録だけでなく、照度・土壌水分・CO2濃度など、様々なセンサーに応用できますので、ぜひ試してみてください!💪

「動いた!」「ここでつまずいた」などあればコメント欄でぜひ教えてください。一緒に学んでいきましょう!

📡 Arduinoをもっと深く学ぼう!

Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。

Arduinoロボット入門のおすすめコース・部品を見る →

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

Arduinoをはじめよう 第4版 (Make: PROJECTS)

もしも

Arduinoをはじめよう 第4版 (Make: PROJECTS)

Arduino公式推薦の定番入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。