ESP32 & BME280 温湿度センサーを7セグLEDに表示するプロジェクト

 


ESP32 & BME280 温湿度センサーを7セグLEDに表示するプロジェクト 🌡️

このページでは、ESP32マイコンを使って、高精度なBME280センサーから温度と湿度を読み取り、MAX7219ドライバーICを使った8桁の7セグメントLEDディスプレイに表示する方法を詳しく解説します。


🎯 プロジェクトの概要

  • 温度湿度をBME280センサーから取得します。

  • 取得した値を、見やすい7セグメントLEDにリアルタイムで表示します。

  • 温度はXX.X℃、湿度はXX.X%の形式で表示します。

  • プログラムのデバッグ用に、シリアルモニターにも値を出力します。


🛠️ 準備するもの

ハードウェア

  1. ESP32開発ボード (ESP-WROOM-32など)

  2. BME280 温湿度・気圧センサーモジュール

  3. MAX7219 8桁7セグメントLEDディスプレイモジュール

  4. ブレッドボードとジャンパーワイヤー

ソフトウェア・ライブラリ

Arduino IDEに、以下のライブラリをインストールしてください。

  1. Adafruit BME280 Library

  2. Adafruit Unified Sensor (BME280ライブラリの依存ライブラリ)

  3. LedControl (MAX7219の制御用)

ライブラリのインストール方法:

Arduino IDEのメニューから スケッチ > ライブラリをインクルード > ライブラリを管理 を選択し、上記のライブラリ名を検索してインストールします。


🔌 回路と配線

マイコンと各モジュールを以下のように接続します。このプログラムでは、BME280センサーとの通信にソフトウェアSPIを使用しています。

BME280センサー センサー → ESP32

BME280ピン

ESP32 GPIO

役割

VIN (VCC)

3V3

電源

GND

GND

グラウンド

SCK

GPIO 19

クロック

SDO (MISO)

GPIO 21

データ出力

SDI (MOSI)

GPIO 22

データ入力

CS

GPIO 23

チップセレクト

7セグLED (MAX7219) → ESP32

MAX7219ピン

ESP32 GPIO

役割

VCC

5V or 3V3

電源

GND

GND

グラウンド

DIN

GPIO 25

データ入力

CS (LOAD)

GPIO 26

チップセレクト

CLK

GPIO 27

クロック


💻 プログラム解説

提供されたプログラム全体をセクションごとに詳しく見ていきましょう。

1. ライブラリの読み込み

最初に、プロジェクトで必要なライブラリをインクルードします。

C++
#include <Arduino.h>
#include <SPI.h> // SPI通信に必要
#include <Adafruit_Sensor.h> // Adafruitセンサーライブラリの基本
#include <Adafruit_BME280.h> // BME280センサー用
#include <LedControl.h> // MAX7219 7セグLED用
  • Adafruit_BME280.h: 温湿度センサーBME280を制御するための機能が含まれています。

  • LedControl.h: 7セグメントLEDドライバMAX7219を制御するための機能が含まれています。

2. ピン設定と定数定義

次に、ESP32と各モジュールを接続するピン番号を定義します。こうすることで、後からピン配置を変更するのが簡単になります。

C++
// BME280センサーのSPIピン設定
#define BME_SCK 19
#define BME_MISO 21
#define BME_MOSI 22
#define BME_CS 23

// 7セグLEDのピン設定
#define DIN_PIN 25 // データ入力(DIN)
#define CS_PIN  26 // チップセレクト(CS or LOAD)
#define CLK_PIN 27 // クロック(CLK)

3. オブジェクトの作成

各ライブラリを使うために、センサーとLEDディスプレイの「オブジェクト」を作成します。これは、プログラムからハードウェアを操作するための準備です。

C++
// BME280オブジェクトをソフトウェアSPIモードで作成
Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);

// LedControlオブジェクトを作成
// LedControl(データピン, クロックピン, CSピン, デバイス数)
LedControl lc = LedControl(DIN_PIN, CLK_PIN, CS_PIN, 1);
  • bmeオブジェクトはBME280センサーを操作するために使います。

  • lcオブジェクトは7セグメントLEDを操作するために使います。最後の引数1は、MAX7219が1つだけ接続されていることを示します。

4. setup()関数

setup()関数は、ESP32が起動したときに一度だけ実行されます。ここでは、センサーやディスプレイの初期化を行います。

C++
void setup() {
  // デバッグ用にシリアル通信を開始
  Serial.begin(115200);

  // BME280センサーの初期化
  unsigned status = bme.begin();  
  if (!status) {
      Serial.println("BME280センサーが見つかりません!");
      // エラーメッセージを表示して処理を停止
      while (1) delay(10);
  }

  // 7セグLEDの初期化
  lc.shutdown(0,false); // 省電力モードを解除
  lc.setIntensity(0,8); // 明るさを設定 (0-15)
  lc.clearDisplay(0);   // ディスプレイをクリア
}
  • bme.begin()でセンサーが正しく接続されているか確認します。失敗した場合はシリアルモニターにエラーを出力します。

  • lc.shutdown(0, false)は、MAX7219を省電力モードから復帰させて点灯させるために必須の命令です。

5. loop()関数

loop()関数はsetup()が終わった後、繰り返し実行され続けるメインの処理です。

C++
void loop() { 
  // BME280から温度と湿度を読み取る
  float temp_c = bme.readTemperature();
  float humidity = bme.readHumidity();

  // 7セグLEDに温度と湿度を表示
  displayData(temp_c, 0);   // 温度を右側の桁(0-2)に表示
  displayData(humidity, 4); // 湿度を左側の桁(4-6)に表示

  // デバッグ用にシリアルモニターにも出力
  Serial.print("Temperature: ");
  Serial.print(temp_c, 2);
  Serial.print(" C, Humidity: ");
  Serial.print(humidity, 2);
  Serial.println(" %");

  // 2秒待つ
  delay(2000);
}
  1. bme.readTemperature()bme.readHumidity()でセンサー値を取得します。

  2. 後述する自作関数displayData()を使って、取得した値を7セグLEDに表示します。

  3. Serial.print()でPCのシリアルモニターに値を出力し、動作確認に役立てます。

  4. delay(2000)で2秒間待機し、2秒ごとに表示を更新します。

6. displayData()関数

このプログラムの核となる、数値を7セグLEDに表示するためのカスタム関数です。小数点を含む数値をうまく表示する工夫がされています。

C++
/**
 * @brief 数値を7セグメントディスプレイに表示する関数 (XX.Xの形式)
 * @param data 表示する数値 (温度や湿度)
 * @param digit 表示を開始する桁位置 (0:右端)
 */
void displayData(float data, int digit) {
  // 0.0〜99.9の範囲外ならエラー表示
  if (data < 0 || data >= 100) {
    lc.setChar(0, digit+2, 'E', false);
    lc.setChar(0, digit+1, 'r', false);
    lc.setChar(0, digit,   'r', false);
    return;
  }

  // 各桁の数値に分解
  int tens = (int)data / 10;          // 10の位
  int units = (int)data % 10;         // 1の位
  int decimal = (int)(data * 10) % 10; // 小数点第1位

  // 10の位 (10未満の場合は表示しない)
  if (tens == 0) {
    lc.setChar(0, digit+2, ' ', false);
  } else {
    lc.setDigit(0, digit+2, tens, false);
  }

  // 1の位 (ここに小数点を付ける)
  lc.setDigit(0, digit+1, units, true);

  // 小数点第1位
  lc.setDigit(0, digit+0, decimal, false);
}
  • 桁の分解: 25.8という数値が与えられた場合、tens = 2, units = 5, decimal = 8 のように整数に分解します。

  • 表示処理:

    • lc.setDigit(デバイス番号, 桁位置, 数字, 小数点ON/OFF)という関数を使って各桁に数字を表示します。

    • 1の位の数字を表示する際に、第4引数をtrueにすることで小数点を点灯させています。

    • 温度が10℃未満のとき(tensが0のとき)、先頭に0が表示されないように空白を表示する処理 (lc.setChar(0, digit+2, ' ', false);) を入れています。


✨ まとめ

このプロジェクトでは、基本的なセンサーとディスプレイモジュールを組み合わせて、実用的な温湿度計を作成しました。

コード内のdisplayData()関数を理解することが、7セグメントLEDで様々な数値を表示させるための鍵となります。

応用例

  • bme.readPressure() を使って気圧も表示してみる。

  • ESP32のWi-Fi機能を使って、取得したデータをクラウドに送信する。

  • 一定の温度や湿度になったら、LEDやブザーを鳴らすような機能を追加する。

コメント