レッスン96-4:気圧、温度、およびおおよその高度センサーBMP390をArduinoでサーモスタットとして使用する
このチュートリアルでは、BMP390気圧・温度・近似高度センサーをArduinoで使用してスマートサーモスタットを構築する方法を説明します。BMP390はBosch製の高精度センサーで、温度、気圧を測定し、海面気圧に基づいておおよその高度を計算できます。このプロジェクトでは、温度しきい値に基づいてヒーターやクーラーのオン/オフを切り替えるリレーを制御し、完全に機能するサーモスタットシステムを作成します。
このプロジェクトにはいくつかの実用的な応用があり、以下が含まれます:
- 快適な室温を維持するスマートホームサーモスタットの作成
- 温度管理された温室換気システムの構築
- 敏感な電子機器を過熱から保護する
- 卵や爬虫類用のインキュベーターの制御
- ワインセラーや保管室の温度監視と調整
必要なハードウェア
- Arduino Uno(または互換ボード)
- BMP390気圧センサーモジュール
- リレーモジュール(ヒーター/クーラーの制御用)
- 制御するヒーターまたはクーラー機器
- ジャンパーワイヤー
- ブレッドボード(オプション)
BMP390センサーの理解
BMP390はBosch製の高精度気圧センサーです。実際のセンサーはわずか2mm x 2mm x 0.75mmで、非常にコンパクトです。使用するブレークアウトボードには、プルアップ抵抗、電圧レギュレーター、ロジックレベルコンバーターなどの必要なサポート部品がすべて含まれており、3.3Vまたは5Vのいずれかで電源を供給できます(ビデオの01:44時点)。
このセンサーは、0〜65℃の範囲で絶対精度±0.5 hPaで300〜1250ヘクトパスカルの気圧を測定できます。相対精度はさらに優れており、±0.03 hPaで、これは約±25センチメートルの高度差に相当します。また、最大サンプリングレートは200 Hzで、高速な読み取りが必要なアプリケーションに適しています(ビデオの04:10時点)。
配線ガイド
BMP390をArduinoに接続するのは、データ通信に2本のワイヤーと電源接続のみを必要とするI2Cインターフェースを使用するため簡単です。センサーのVINピンはArduinoの5V(または3.3V)に、グランドはグランドに、SCLはSCLピン(UnoではA5)に、SDAはSDAピン(UnoではA4)に接続します(ビデオの05:45時点)。
リレーモジュールについては、その制御ピンをArduinoのデジタルピン8に、VCCを5Vに、グランドをグランドに接続します。制御したい機器(ヒーターまたはクーラー)はリレーの出力端子に接続します。
このプロジェクトのユニークな特徴の1つは、コードがピン12をBMP390モジュールの電源出力として定義していることです。つまり、別のブレッドボードの電源レールを必要とせずに、Arduinoのピンから直接センサーに電源を供給できます(ビデオの08:46時点)。コードはセットアップでこのピンをHIGHに設定して、センサーに5Vを供給します。
必要なライブラリのインストール
コードをアップロードする前に、Adafruit BMP3XXライブラリをインストールする必要があります。Arduino IDEを開き、スケッチ → ライブラリをインクルード → ライブラリを管理 に移動し、「Adafruit BMP3XX」を検索して、インストールをクリックします(ビデオの10:29時点)。このライブラリはBMP390センサーとのすべての低レベル通信を処理します。
コードの説明
このサーモスタットプロジェクトのコードは、高度に設定可能になるように設計されています。プログラムの先頭にある主要なユーザー設定可能なオプションを見てみましょう。
ピン定義
センサーの電源とリレー制御に使用するArduinoピンを変更できます:
int bmpVCCPin = 12;//define pin 12 as VCC for bmp sensor
const int relayPin = 8;
bmpVCCPinはBMP390モジュールに5V電源を供給します。relayPinはヒーターまたはクーラーを切り替えるリレーモジュールを制御します。
サーモスタット設定
これらの定数はサーモスタットの動作を定義します:
const int TEMPERATURE_UNIT = 1;//1=Celsius, 2=Fahrenheit, 3=Kelvin
const float START_TEMPERATURE = 32.0;//unit above
const float STOP_TEMPERATURE = 45.0;//unit above
const int CONTROL_TYPE = 2;// 1= heater, 2=cooler- TEMPERATURE_UNIT: 温度単位を設定します。摂氏は1、華氏は2、ケルビンは3を使用します。
- START_TEMPERATURE: リレーがオンになる温度(ヒーターモードの場合)またはオフになる温度(クーラーモードの場合)。
- STOP_TEMPERATURE: リレーがオフになる温度(ヒーターモードの場合)またはオンになる温度(クーラーモードの場合)。
- CONTROL_TYPE: ヒーター制御(寒いときにオン)の場合は1、クーラー制御(暑いときにオン)の場合は2に設定します。
例えば、デモでは開始温度を30°C、停止温度を45°Cに設定しているため、ヒートガンで動作をすぐにテストできます。実際の用途では、快適な室温を維持するために、20°Cと23°Cのように近い値に設定します(ビデオの30:07参照)。
カスタム関数
コードには、使用および変更できるカスタム関数がいくつか含まれています:
- loadControl(): この関数はサーモスタットのロジックを実装します。現在の温度をSTARTおよびSTOPのしきい値と比較し、それに応じて
relayControl()を呼び出します。動作はCONTROL_TYPEを1(ヒーター)または2(クーラー)のどちらに設定したかによって変わります。 - relayControl(int state): この関数はリレーをオンまたはオフにし、ステータスをシリアルモニターに出力します。
relayONまたはrelayOFFを渡します。 - readValues(): この関数はセンサーを読み取り、温度、気圧、高度をグローバル変数に格納します。選択した単位に温度を自動的に変換します。
- printTemperature(): この関数は温度の読み取り値を適切な単位記号とともにシリアルモニターに出力します。
サーモスタットの仕組み
サーモスタットのロジックは、現在の温度を設定したしきい値と比較することで動作します。ヒーターモード(CONTROL_TYPE = 1)では、温度がSTART_TEMPERATURE以下に下がると、リレーがオンになり加熱装置が作動します。ヒーターは温度がSTOP_TEMPERATUREまで上昇するまでオンを維持し、その時点でリレーがオフになります。これにより、急速なオン/オフの繰り返しを防ぐヒステリシス効果が生まれます(ビデオの31:04参照)。
クーラーモード(CONTROL_TYPE = 2)では、ロジックは逆になります。リレーは温度がSTOP_TEMPERATUREに達するか超えるとオンになり、START_TEMPERATUREまで下がるとオフになります。
ビデオのデモでは、ヒートガンを使用してこの動作を示しています。温度が45°Cに達するとリレーがオフになり、インジケーターライトが消えました。30°Cまで冷えた後、リレーが再び作動してヒーターがオンになりました(ビデオの31:53参照)。
ライブプロジェクトデモ
ビデオにはBMP390の実用的な高度テストが含まれています。発表者はセンサーをカナダのオンタリオ州アジャックスにある場所に持ち込み、アイススケート場近くの地上レベルで高度を測定しました。センサーは最初に約-15メートルを示しました。これは、現地の海面気圧の較正とその場所の実際の標高との差を表しています(ビデオの33:04参照)。
センサーを近くの建物の25階に持っていくと、読み取り値は約57.2メートルに変わりました。地上階と25階の間の約72メートルの差は、センサーが意味のある高度変化を検出できることを示しています。このテストは、標高監視を必要とするアプリケーションにおけるBMP390の有用性を確認しています(ビデオの36:16参照)。
サーモスタットのデモでは、温度が45°Cの停止しきい値を超えるとリレーがオフになり、インジケーターライトが消えることを示しています。センサーが30°C以下に冷えた後、リレーが再び作動し、信頼性の高いヒステリシスベースの温度制御を示しました(ビデオの31:04参照)。
このビデオの関連プロジェクト
- レッスン96-1: 気圧・温度・おおよその高度センサーBMP390とArduinoの基本コード
- レッスン96-2: 気圧・温度・おおよその高度センサーBMP390とArduinoをLCD1602に表示
- レッスン96-3: 気圧・温度・おおよその高度センサーBMP390とArduinoをLCD2004に表示
チャプター
- [00:00] BMP390センサープロジェクトの紹介
- [01:19] BMP390センサーの仕様を理解する
- [05:45] Arduino UnoとのBMP390配線図
- [10:29] Adafruit BMP3XXライブラリのインストール
- [11:38] 基本的なセンサー読み取りのコード解説
- [15:51] サーモスタット動作のためのリレー制御の追加
- [17:30] LCDディスプレイの設定(オプション)
- [22:52] LCDに気圧と高度を表示
- [30:07] ヒートガンを使ったサーモスタットデモ
- [32:12] 25階での高度テスト
/*
* Lesson 96: Using BMP390 as thermostat
* with Arduino using it as a Thermostat to control a heater or cooler
* Download and resource page https://robojax.com/RJT457
* Watch video instruction on YouTube: https://youtu.be/XevQYG_A5xA
*
* Code updated by Ahmad Shamshiri for Robojax.com
* on Jan 13, 2022 at 17:10 in Ajax, Ontario, Canada
This video is part of the Arduino Step by Step Course which starts here: https://youtu.be/-6qSrDUA5a8
If you found this tutorial helpful, please support me so I can continue creating content like this
and make a donation using PayPal http://robojax.com/L/?id=64
This is a library for the BMP390 temperature & pressure sensor
Designed specifically to work with the Adafruit BMP388 Breakout
----> http://www.adafruit.com/products/3966
These sensors use I2C or SPI to communicate; 2 or 4 pins are required
to interface.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing products
from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
**************************************************************************
*/
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BMP3XX bmp;
int bmpVCCPin = 12;//define pin 12 as VCC for bmp sensor
// all thermostat settings
const int relayPin =8;
const int relayON = HIGH;//
const int relayOFF = LOW; //
int relayState = relayOFF;//initial state of relay
const int TEMPERATURE_UNIT =1;//1=Celsius, 2=Fahrenheit, 3=Kelvin
const float START_TEMPERATURE = 32.0;//unit above
const float STOP_TEMPERATURE = 45.0;//unit above
const int CONTROL_TYPE = 2;// 1= heater, 2=cooler
//do not change the line below
float temperature, pressure, altitude;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("Adafruit BMP388 / BMP390 test");
pinMode(bmpVCCPin, OUTPUT);// set pin as output
digitalWrite(bmpVCCPin,HIGH);// always keep it high (5V) for BMB390 module
delay(500);//wait for the bmpVCCPin to turn ON.
pinMode(relayPin, OUTPUT);//pin for relay
digitalWrite(relayPin, relayState);//change initial state of relay
if (!bmp.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire
Serial.println("Could not find a valid BMP3 sensor, check wiring!");
while (1);
}
// Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);
}
void loop() {
if (! bmp.performReading()) {
Serial.println("Failed to perform reading :(");
return;
}
readValues();
printTemperature();
Serial.println();
loadControl();
//do extra action if temperature is greater than 89.5
if(temperature >=89.5)
{
///and your code here
}
delay(2000);//wait 2 seconds or make is less or more
}
/*
* loadControl()
* @brief controls the load based
* @param state can be either : relayON or relayOFF
* @return returns none
* Written by Ahmad Shamshiri for robojax.com
* on Jan 15, 2022 at 08:11 in Ajax, Ontario, Canada
*/
void loadControl()
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
// Serial.print("Start: ");
// Serial.print(START_TEMPERATURE);
// Serial.print(" Stop: ");
//Serial.println(STOP_TEMPERATURE);
if(CONTROL_TYPE ==1)
{
if(START_TEMPERATURE >= temperature && STOP_TEMPERATURE >=temperature)
{
relayControl(relayON);
}
if(STOP_TEMPERATURE <=temperature)
{
relayControl(relayOFF);
}
}else{
if(START_TEMPERATURE >= temperature && STOP_TEMPERATURE >=temperature)
{
relayControl(relayOFF);
}
if(STOP_TEMPERATURE <=temperature)
{
relayControl(relayON);
}
}
//Robojax.com heater/cooler with BMP390 Thermocoupler
}//loadControl()
/*
* relayControl(int state))
* @brief turns the relay ON or OFF
* @param state is "relayON" or "relayOFF" defined at the top of the code
* @return returns none
* Written by Ahmad Shamshiri for robojax.com
* on May 20, 2020 at 15:23 in Ajax, Ontario, Canada
*/
void relayControl(int state)
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
if(state ==relayON)
{
digitalWrite(relayPin, relayON);
Serial.println("Relay ON");
}else{
digitalWrite(relayPin, relayOFF);
Serial.println("Relay OFF");
}
//Robojax.com heater/cooler with BMP390 Thermocoupler
}//relayControl()
/*
* readValues()
* @brief reads the temperature based on the TEMPERATURE_UNIT
* @param average temperature
* @return returns one of the values above
* Written by Ahmad Shamshiri for robojax.com
* on Jan 15, 2022 at 08:02 in Ajax, Ontario, Canada
*/
void readValues()
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
altitude = bmp.readAltitude(SEALEVELPRESSURE_HPA);// read altitude
pressure = bmp.pressure / 100.0F; // get pressure in hecto pascal
if(TEMPERATURE_UNIT ==2)
{
temperature = bmp.temperature *9/5 + 32;//convert to Fahrenheit
}else if(TEMPERATURE_UNIT ==3)
{
temperature = bmp.temperature + 273.15;//convert to Kelvin
}else{
temperature = bmp.temperature;// return Celsius
}
//Robojax.com heater/cooler with BMP390 Thermocoupler
}// readValues()
/*
* printTemperature()
* @brief prints temperature on serial monitor
* @param character type
* @param "type" is character
* C = Celsius
* K = Kelvin
* F = Fahrenheit
* @return none
* Written by Ahmad Shamshiri for robojax.com
* on Jan 15, 2022 at 08:09 in Ajax, Ontario, Canada
* www.Robojax.com
*/
void printTemperature()
{
//Robojax.com heater/cooler with BMP390 Thermocoupler
Serial.print(temperature);
printDegree();
if(TEMPERATURE_UNIT ==2)
{
Serial.print("F");
}else if(TEMPERATURE_UNIT ==3)
{
Serial.print("K");
}else{
Serial.print("C");
}
Serial.println();
//Robojax.com heater/cooler with BMP390 Thermocoupler
}//printTemperature()
/*
* @brief prints degree symbol on serial monitor
* @param none
* @return returns nothing
* Written by Ahmad Shamshiri on July 13, 2019
* for Robojax Tutorial Robojax.com
*/
void printDegree()
{
Serial.print("\\xC2");
Serial.print("\\xB0");
}
必要かもしれないもの
-
アリエクスプレスAliExpressで購入してください。s.click.aliexpress.com
-
アリエクスプレスBMP388 High Precision Digital Atmospheric Pressure on AliExpresss.click.aliexpress.com
-
バングッドBanggoodから購入してください。banggood.com
リソースと参考文献
-
外部AliExpressで購入してください。s.click.aliexpress.com
-
外部Banggoodから購入してください。banggood.com
-
外部BMP390 ボッシュ公式製品ページbosch-sensortec.com
-
外部アメリカのアマゾンで購入してください。amzn.to
-
外部カナダのアマゾンで購入してください。amzn.to
-
外部他のすべてのAmazonサイトから購入してください。amzn.to