ガイド · 読了まで19分

Arduinoの温度センサーの種類:8つのセンサーを比較

Arduinoで使う温度センサーの種類を比較します。DHT11、DHT22、DS18B20、LM35、NTC、BME280、MAX6675、MLX90614を精度、測定範囲、配線、ケーブルの長さ、価格で比べます。

Arduinoの温度センサーの種類選びは、最初に思うよりも大切です。同じ部屋に置いたDHT11とDS18B20で2 °Cも違うことがありますし、合わないセンサーで300 °Cのオーブンを測ろうとしてセンサーを溶かしてしまうことも十分にありえます。電子工作でよく使われる温度センサーは主に8つです。DHT11、DHT22、DS18B20、LM35、NTCサーミスタ、BME280、MAX6675(K型熱電対)、MLX90614(非接触の赤外線)。それぞれ測定範囲、精度、接続方法、価格が違います。どれが合うかは、何を測るかで決まります。部屋の空気でしょうか、水でしょうか、オーブンでしょうか、それとも触れられない回転中のモーターでしょうか?

このガイドでは、8つのセンサーを2つの大きな表で並べて比較します。測定範囲、精度、分解能、読み取り速度、インターフェース、電源電圧、ケーブルの長さ、価格の目安です。そのあと、それぞれの仕組みと長所・短所、Arduino Uno、ESP32、Raspberry Pi Picoでの配線、NTC・MAX6675・MLX90614のサンプルコード、3つのセンサーを競わせるテスト装置、そしてどのプロジェクトにどれを選ぶかを紹介します。ほとんどのセンサーには詳しいチュートリアルもあり、該当するセクションにリンクを載せています。

DHT11温湿度センサーモジュール
DHT11温湿度センサーモジュール
DHT22(AM2302)温湿度センサーモジュール
DHT22(AM2302)温湿度センサーモジュール
防水型DS18B20温度プローブ
防水型DS18B20温度プローブ
BME280温度・湿度・気圧センサーモジュール
BME280温度・湿度・気圧センサーモジュール
NTCサーミスタ
NTCサーミスタ

温度センサーを選ぶときに見るべきポイントは?

センサーを比較する前に、データシートの用語を正しく読めるようにしておきましょう。いちばん混同されやすいのは精度と分解能です。精度は、読み取った値が実際の温度にどれだけ近いかを表します。分解能は、センサーが区別できる最小の刻みです。BME280は温度を0.01 °C刻みで出力しますが、精度は±1 °C前後です。つまり画面に表示された23.47 °Cの下2桁は小さな変化を追うのには役立ちますが、実際の温度をそこまで正確に表しているわけではありません。選ぶときは次の7つの基準を確認します。

  • 測定範囲:測りたい最低温度と最高温度を余裕をもってカバーできるセンサーを選びます。DHT11は0 °C未満を測れません。冷蔵庫にはDS18B20、オーブンには熱電対が必要です。
  • 精度:室温計なら±2 °Cでも問題ありませんが、水槽や孵卵器には±0.5 °Cが必要です。
  • インターフェース:アナログセンサーにはADCピンが必要です。デジタルセンサーには1本以上のデジタルピンと、たいていはライブラリが必要です。ボードの空きピンの数で、つなげるセンサーの数が決まります。
  • ケーブルの長さ:庭や貯水タンクの底など、センサーをボードから5メートル離して置く場合、アナログセンサーやI2Cセンサーは苦手です。1-WireやDHTの単線式プロトコルのほうが、長い距離にずっと強いです。
  • 応答時間:ステンレスの保護管に入ったプローブやプラスチックケースのDHTは、急な温度変化をとらえるまでに数秒、ときには数分かかります。むき出しの小さなNTCのほうがはるかに速いです。
  • 追加の測定項目:湿度も必要ならDHT22かBME280で対応できます。気圧と高度も必要なら、BME280が1つのモジュールですべてをまかなえます。
  • 電源電圧:3.3 VのESP32やPicoでは、少なくとも4 Vが必要なLM35のようなセンサーに注意し、ADC入力に3.3 Vを超える電圧がかからないようにします。

8つの温度センサーの比較表

1つ目の表は測定性能を、2つ目の表は配線とコストの面をまとめています。値はデータシートによるものです。特に記載がない限り、精度は室温付近の値で、範囲の端に近づくほど悪くなります。

センサー測定範囲精度分解能読み取り速度
DHT110〜+50 °C±2 °C1 °C1秒に1回
DHT22(AM2302)−40〜+80 °C±0.5 °C0.1 °C2秒に1回
DS18B20−55〜+125 °C±0.5 °C(−10〜+85 °Cの範囲)0.0625 °C(12ビット)750 ms(12ビット)、94 ms(9ビット)
LM35DZ0〜+100 °C(LM35:−55〜+150 °C)標準±0.6 °C、保証値±1.5 °CUnoで0.49 °C(5 V基準)、0.11 °C(1.1 V基準)即時(ADCの速度)
NTC 10 kΩ、B定数3950−40〜+125 °C(ガラス封止型は≈ 300 °C)25 °Cで±0.25 °C(1 %)〜±1 °C(5 %)Unoの室温付近で≈ 0.1 °C即時(ADCの速度)
BME280−40〜+85 °C±0.5 °C(25 °C)、±1 °C(0〜65 °C)0.01 °C1秒に数十回
MAX6675+K型熱電対0〜+1023.75 °C数 °C(変換器≈ ±2 °C、冷接点で最大±3 °C)0.25 °C1秒に≈ 4回(変換0.22秒)
MLX90614対象物−70〜+380 °C、周囲−40〜+125 °C±0.5 °C(室温付近)0.02 °C1秒に数回
センサーインターフェース電源ケーブルの長さ追加の測定項目価格の目安
DHT11単線式デジタル、1ピン3〜5.5 V最大20 m湿度とても安い
DHT22単線式デジタル、1ピン3.3〜6 V最大20 m湿度中程度
DS18B201-Wire、1ピンに複数のセンサー3.0〜5.5 V数十メートルなし安い
LM35アナログ、ADCピン1本4〜30 V短い、≈ 1 m(それ以上は対策が必要)なし安い
NTCアナログ、分圧回路経由でADCピン1本分圧回路経由で3.3 Vまたは5 V数メートルなしいちばん安い
BME280I2C(2ピン)またはSPIチップ1.71〜3.6 V、レギュレーター付きモジュールは5 V短い、50 cm未満湿度と気圧中程度
MAX6675SPI、3ピン(読み取り専用)3.0〜5.5 V熱電対の線は数メートル延ばせるなし中程度
MLX90614I2C(SMBus)、2ピン3 V版または5 V版(モジュールにはレギュレーター付きのものもある)短い(I2C)、非接触で測定周囲温度高い
価格はおおよそ次の順です。いちばん安いのはNTCで、次にDHT11、LM35、DS18B20が続きます。DHT22とBME280は中程度、熱電対プローブ付きのMAX6675モジュールは少し高めで、MLX90614がこのリストでいちばん高価です。安いセンサーには互換品がとても多く、特にDS18B20、LM35、BME280では、互換品がデータシートの精度に届かないことがあります。2つのセンサーを同じ場所に置いて値を比べるのが、手元のセンサーを信頼できるかどうかを確かめるいちばん簡単な方法です。

DHT11とDHT22:温度と湿度を同時に測る

DHTセンサーのプラスチックのケースの中には、湿度素子(DHT11は抵抗式、DHT22は静電容量式)、サーミスタ、そして測定値をデジタルデータに変換する小さなコントローラーが入っています。センサーは1本のデータ線で結果を40ビットのパケットとして送ります。内訳は湿度16ビット、温度16ビット、8ビットのチェックサムです。このプロトコルは1-Wireではなくメーカー独自の単線式プロトコルなので、DHTごとに専用のピンが必要です。DHT11は安く、室温を測るには十分ですが、0〜50 °Cの範囲と±2 °Cの誤差では屋外での使用や精密な用途には力不足です。同じ配線のままで、DHT22(AM2302)は−40〜+80 °Cを±0.5 °Cの精度で測り、湿度も0〜100 %の範囲で出力します。その代わり、読み取れるのは2秒に1回だけです。どちらにも共通する弱点は遅さです。ケースの中の空気がまず周囲と同じ状態になる必要があるため、変化が遅れて表示されます。配線、ライブラリのインストール、コードについてはDHT11温湿度センサーを参照してください。同じコードが、単語を1つ変えるだけでDHT22でも動きます。

4ピンのDHT単体を使う場合は、データ線とVCCのあいだに10 kΩのプルアップ抵抗を必ず入れてください。3ピンのモジュールには、この抵抗がすでに基板に載っています。DHTを2秒より短い間隔で読み取っても、新しい測定値は得られません。ライブラリは古い値を返すか、nanを返します。

DS18B20:防水で丈夫、1本のピンに複数のセンサー

防水型DS18B20温度プローブ
防水型DS18B20プローブ:ステンレスの保護管にデジタルセンサーが入り、3線のケーブル(赤がVDD、黒がGND、黄がデータ)が付いています。

DS18B20はチップの内部で温度を測り、9〜12ビットから選べる分解能のデジタル値として送ります。測定範囲は−55〜+125 °Cで、−10〜+85 °Cでは±0.5 °Cの精度があり、1-Wireプロトコルのおかげで1本のデータピンに数十個のセンサーをつなげます。各センサーには、工場で書き込まれた固有の64ビットのアドレスがあります。ステンレスの保護管に入った防水プローブ版は、水槽、貯水タンク、暖房の配管、土、冷凍庫にはうってつけです。必要なのはデータ線と電源のあいだの4.7 kΩのプルアップ抵抗だけで、これがないとライブラリは−127 °Cを返します。12ビットモードでは1回の変換に750 msかかるので、速く変わる温度を追うには分解能を下げる必要があるかもしれません。複数センサーのコードと、ESP32で処理を止めずに読み取る方法はDS18B20温度センサーにあります。

LM35:ライブラリ不要のいちばんシンプルなアナログセンサー

LM35は温度をそのまま電圧に変換します。出力は1度あたり10 mV上がり、25 °Cでは250 mVになります。ライブラリは不要で、温度 = analogRead × 5.0 / 1024 × 100という式で結果が得られます。このシンプルさは、ADCを学ぶ最初の一歩として最適です。弱点も同じところから来ます。5 V基準では、Arduino Unoの10ビットADCの刻みは約0.49 °Cしかなく、USBから来る5 Vのずれはすべてそのまま温度に表れ、ケーブルが長いほど出力にノイズが乗ります。市販のLM35のほとんどはLM35DZで、保証されているのは0〜100 °Cだけです。また、少なくとも4 Vが必要なので、ESP32やPicoでは5 Vピンから電源をとる必要があります。3.3 Vのボードでは、TMP36のほうが実用的なアナログの選択肢です。2.7〜5.5 Vで動作し、−40〜+125 °Cを測れ、出力も10 mV/°Cですが、0 °Cで500 mVを出力するので式は温度 = (V − 0.5) × 100になります。標準精度は25 °Cで±1 °C、全範囲で±2 °Cです。1.1 Vの内部基準電圧で刻みを0.11 °Cまで小さくする方法はLM35温度センサーでステップごとに解説しています。ADCの仕組みはアナログ-デジタル変換で確認できます。

LM35とDS18B20は同じ黒いTO-92パッケージで、見た目はほとんど同じですが、電源ピンが逆です。逆向きにつないだセンサーは、数秒で触れないほど熱くなります。初めて電源を入れるときはセンサーに指で触れ、熱くなってきたらすぐに電源を切って、本体の表記を確認してください。

NTCサーミスタ:いちばん安くて速いセンサー

NTC(Negative Temperature Coefficient、負の温度係数)サーミスタは、温度が上がると抵抗値が下がる抵抗です。電子工作でいちばんよく使われるのは、25 °Cで10 kΩ、B定数3950 Kのタイプです。Arduinoは抵抗値を直接測れないため、NTCは固定抵抗と組み合わせて分圧回路にし、中点の電圧をアナログピンで読み取ります。この回路にはよい性質があります。分圧回路をADCの基準と同じ5 Vから給電すると、測定はレシオメトリック測定になり、電源が4.8 Vでも5.1 Vでも結果は変わりません。分圧回路の電圧は分圧計算ツールで簡単に計算できます。

NTCの抵抗値は温度に対して直線的ではなく指数関数的に変わるため、LM35のように1つの係数を掛けるだけでは結果が出ません。実際にはB定数の式(Beta式)を使います。1/T = 1/T0 + (1/B) × ln(R/R0)。ここでTはケルビン単位の温度、T0 = 298.15 K(25 °C)、R0 = 10 kΩ、B = 3950です。室温付近の感度はとても高く、B/T²の式によると、抵抗値は1度あたり約4.4 %変化します。そのため誤差1 %のNTCでも、25 °Cでのずれは±0.25 °C程度にすぎません。ただし範囲の端に近づくと、B定数の誤差が効いてきて誤差が大きくなります。広い範囲でより高い精度が必要なら、3点で校正するSteinhart-Hartの式を使います。詳しくはNTCサーミスタで解説しています。

C++ (Arduino IDE)
1const int NTC_PIN = A1;          // bölücünün orta noktası / divider midpoint
2const float R_FIXED = 10000.0;   // 5V ile A1 arasındaki direnç / resistor between 5V and A1
3const float R0 = 10000.0;        // NTC'nin 25 °C'deki direnci / NTC resistance at 25 °C
4const float BETA = 3950.0;       // B katsayısı (veri sayfası) / B coefficient (datasheet)
5const float T0 = 298.15;         // 25 °C Kelvin cinsinden / 25 °C in kelvin
6const int SAMPLES = 16;          // ortalama için ölçüm sayısı / samples to average
7
8void setup() {
9  Serial.begin(9600);
10}
11
12void loop() {
13  long sum = 0;
14  for (int i = 0; i < SAMPLES; i++) {
15    sum += analogRead(NTC_PIN);
16    delay(2);
17  }
18  float adc = sum / (float)SAMPLES;
19
20  if (adc < 1.0 || adc > 1022.0) {                    // kopuk ya da kısa devre / open or shorted
21    Serial.println(F("NTC baglantisini kontrol et / Check the NTC wiring"));
22    delay(1000);
23    return;
24  }
25
26  float r = R_FIXED * adc / (1023.0 - adc);           // NTC direnci (ohm) / NTC resistance (ohm)
27  float invT = 1.0 / T0 + log(r / R0) / BETA;         // Beta denklemi / Beta equation
28  float tempC = 1.0 / invT - 273.15;                  // Kelvin -> °C
29
30  Serial.print(F("R: "));
31  Serial.print(r, 0);
32  Serial.print(F(" ohm  Sicaklik / Temp: "));
33  Serial.print(tempC, 1);
34  Serial.println(F(" C"));
35  delay(1000);
36}

この回路では、10 kΩの固定抵抗が5VとA1のあいだに、NTCがA1とGNDのあいだに入っています。温度が上がるとNTCの抵抗値が下がり、それとともにA1の電圧も下がります。コードはまず生の値からNTCの抵抗値を求め、次にB定数の式でケルビン単位の温度を出し、それを摂氏に変換します。16回の読み取りを平均すると、ADCのノイズは4分の1になります。室温付近では、UnoのADCの1刻みは約0.09 °Cに相当するので、5 V基準で読むLM35より分解能が5倍よくなります。市販のNTCモジュール(たとえばKY-013)では、固定抵抗がどちら側に入っているかが基板によって違います。NTCに温かいものを当てたときに値が下がるなら、抵抗値の式を逆にしてください。r = R_FIXED × (1023 − adc) / adc。

BME280:温度、湿度、気圧を1つのモジュールで

BoschのBME280は、わずか2.5 × 2.5 mmのチップで温度、相対湿度、気圧を測り、I2C(アドレス0x76または0x77)かSPIで通信します。温度については0.01 °Cの分解能と、25 °Cで±0.5 °C、0〜65 °Cで±1 °Cの精度があります。1秒に数十回測定でき、スリープ中の消費電流は1 µAよりはるかに少ないです。そのため電池で動く気象ステーションに最適です。チップ自体は3.6 Vを超える電圧に耐えられません。6ピンの紫色のモジュールはたいてい3.3 V専用で、レギュレーター付きの4ピンのモジュールは5 Vにつなげます。連続して測定するとチップが少し温まり、0.数度高く出ることがあります。気象の測定なら、1分に数回測るフォースドモード(forced mode)で十分です。I2Cバスの仕組みはI2Cとは?で解説しています。

BME280として売られているモジュールの中には、実は湿度を測れないBMP280のものがあります。この2つは見た目がほぼ同じで、確実に見分けるにはチップIDのレジスタを読み取ります。BME280なら0x60、BMP280なら0x58を返します。BMP280だった場合、Adafruit BME280ライブラリのサンプルスケッチは「Could not find a valid BME280 sensor」(有効なBME280センサーが見つからない)と表示します。IDを読み取るコードと対処法はBME280とBMP280にあります。

MAX6675とK型熱電対:1000 °Cまで

熱電対は、異なる金属でできた2本の線の一端を溶接してつないだものです。溶接部(温接点)と、線が機器につながる点(冷接点)の温度差によって、線に小さな電圧が生じます。K型熱電対では1度あたり約41 µVです。これほど小さな電圧はArduinoのADCでは読み取れませんし、冷接点の温度も知る必要があります。MAX6675はこの2つを同時にこなします。熱電対の電圧を増幅し、自分自身の温度を測って冷接点補償を行い、結果を12ビット、0.25 °Cの分解能でSPIから出力します。測定範囲は0〜+1023.75 °Cで、はんだごて、ピザ窯、バーベキュー、陶芸窯、排気管など、ほかのセンサーでは耐えられない場所で使える唯一の選択肢です。

MAX6675の限界も知っておきましょう。0 °C未満は測れません。変換器自体の誤差は0〜700 °Cで約±2 °Cで、そこに最大±3 °Cの冷接点補償の誤差と熱電対の線の誤差が加わります。つまり全体の精度は数度と考えてください。800 °Cのオーブンなら、その差は問題になりません。1回の変換に0.17〜0.22秒かかるので、読み取りの間隔は少なくとも250 ms空けます。マイナスの温度も測りたいなら、新しいMAX31855(−200〜+1350 °C、14ビット)のほうが適しています。SPIバスの仕組みはSPIとは?で確認できます。Arduino IDEのライブラリマネージャからAdafruitのMAX6675ライブラリをインストールしたら、次のコードを書き込みます。

C++ (Arduino IDE)
1#include "max6675.h"
2
3const int thermoDO  = 4;    // SO: veri çıkışı / data out
4const int thermoCS  = 5;    // CS: çip seçimi / chip select
5const int thermoCLK = 6;    // SCK: saat / clock
6
7MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
8
9void setup() {
10  Serial.begin(9600);
11  delay(500);                                   // ilk ölçümü bekle / wait for the first conversion
12}
13
14void loop() {
15  float c = thermocouple.readCelsius();
16  if (isnan(c)) {                               // D2 biti: termokupl açık / bit D2: thermocouple open
17    Serial.println(F("Termokupl takili degil / Thermocouple not connected"));
18  } else {
19    Serial.print(F("Sicaklik / Temp: "));
20    Serial.print(c, 2);
21    Serial.println(F(" C"));
22  }
23  delay(500);                                   // en az 250 ms bekle / wait at least 250 ms
24}
熱電対の線には極性があります。+と−の印がある線を、モジュールの同じ印のネジ端子につないでください。逆にすると、プローブが熱くなるにつれて値が下がります。モジュールは加熱される機器のそばに置かないでください。MAX6675は自分自身の温度を使って冷接点を補正するので、基板が温まるとそのまま測定値に表れます。プローブがつながっていないか線が切れている場合、ライブラリはnanを返します。

MLX90614:非接触で温度を測る

MLX90614は、物体が放射する赤外線をサーモパイルで検出する非接触の温度センサーです。2つの値を同時に出力します。1つは自分の本体の温度を表す周囲温度(−40〜+125 °C)、もう1つは向けた先の表面の温度を表す対象物の温度(−70〜+380 °C)です。室温付近で±0.5 °Cの精度と0.02 °Cの分解能があり、工場でキャリブレーション済みです。I2C(SMBus)のアドレス0x5Aで通信し、バスの速度は100 kHzを超えてはいけません。回転中のモーター、ベアリング、基板上の熱いチップ、コンロの上の鍋などに触れずに測るのに最適です。

非接触の測定には2つのコツがあります。1つ目は視野角です。センサーは視野の円すいの中にあるものすべての平均を測ります。いちばん一般的なMLX90614ESF-BAAの視野角は90°で、5 cm離れると直径約10 cmの範囲を平均することになります。小さな物体を測るには、センサーを近づけるか、35°(BCC)や5°(BCI)のような狭角版を選びます。2つ目は放射率です。センサーは工場で1.0に設定されています。つや消しの塗装、プラスチック、木、皮膚、水では係数が0.9〜0.98なので、ほぼ正しい結果になります。一方、光沢のある金属の表面はほとんど放射しないので、実際よりずっと冷たく見えます。つや消しの黒いテープを1枚貼るのが、簡単で効果的な対策です。ライブラリマネージャからAdafruit MLX90614ライブラリをインストールして、次のコードを試してください。

C++ (Arduino IDE)
1#include <Wire.h>
2#include <Adafruit_MLX90614.h>
3
4Adafruit_MLX90614 mlx = Adafruit_MLX90614();
5
6void setup() {
7  Serial.begin(9600);
8  if (!mlx.begin()) {                           // varsayılan adres 0x5A / default address 0x5A
9    Serial.println(F("MLX90614 bulunamadi / not found"));
10    while (true) delay(10);
11  }
12  Serial.print(F("Emisivite / Emissivity: "));
13  Serial.println(mlx.readEmissivity(), 2);      // fabrika ayarı 1.00 / factory default 1.00
14}
15
16void loop() {
17  Serial.print(F("Ortam / Ambient: "));
18  Serial.print(mlx.readAmbientTempC(), 2);      // sensör gövdesi / sensor body
19  Serial.print(F(" C   Nesne / Object: "));
20  Serial.print(mlx.readObjectTempC(), 2);       // baktığı yüzey / surface in view
21  Serial.println(F(" C"));
22  delay(500);
23}
MLX90614はガラス越しには測れません。光学フィルターが通すのは5.5〜14 µmの波長で、ガラスはこの範囲でほとんど不透明だからです。窓の外にセンサーを向けても、測れるのは外ではなくガラスです。また、寒い部屋から暖かい部屋にセンサーを持ち込むと、本体の温度がなじむまでの数分間は正しく測れないことがあります。

配線のまとめ:Arduino Uno、ESP32、Raspberry Pi Pico

センサーとピンArduino UnoESP32Raspberry Pi Pico
DHT11 / DHT22:DATAD2GPIO 27GP15
DS18B20:DQ(+4.7 kΩのプルアップ)D3GPIO 4GP22
LM35:Vout(5 V電源)A0GPIO 34(ADC1)GP26(ADC0)
NTC:分圧回路の中点A1(5Vから分圧)GPIO 35(ADC1、3V3から分圧)GP27(ADC1、3V3から分圧)
BME280:SDA / SCLA4 / A5GPIO 21 / 22GP4 / GP5
MLX90614:SDA / SCLA4 / A5(同じI2Cバス)GPIO 21 / 22GP4 / GP5
MAX6675:SO / CS / SCKD4 / D5 / D6GPIO 19 / 23 / 18GP16 / GP17 / GP18
電源(VCC)5V(6ピンのBME280は3.3V)3V3(LM35は5V/VIN)3V3(OUT)(LM35はVBUS)

ESP32とPicoは3.3 Vで動作します。NTCの分圧回路を3V3から給電すれば、ADC入力に危険な電圧がかかることはありません。ESP32では、Wi-FiがオンのあいだはADC2のピンが使えないため、アナログセンサーはADC1のピン(GPIO 32〜39)だけにつなぎます。一方、DHTやDS18B20のような双方向のデータ線では、GPIO 34〜39は入力専用なので避けてください。BME280(0x76)とMLX90614(0x5A)はアドレスが違うので、同じ2本のI2C線を問題なく共有できます。ボードのすべてのピンは「ピン配置」ツールで、プルアップ抵抗のカラーコードは「抵抗のカラーコード」ツールで確認できます。

ESP32で比較テスト:3つのセンサーを同じ場所に

センサーの違いを知るいちばんの方法は、自分の目で見ることです。次のESP32のコードはDS18B20、DHT22、BME280を同時に読み取り、結果をArduino IDEのシリアルプロッタに3本の線として表示します。センサーはブレッドボード上に並べ、ESP32から少なくとも10 cm離して置いてください。ESP32は動作中に温まり、すぐそばのセンサーに影響します。このコードにはOneWire、DallasTemperature、DHT sensor library、Adafruit BME280の各ライブラリが必要です。

C++ (Arduino IDE)
1#include <OneWire.h>
2#include <DallasTemperature.h>
3#include <DHT.h>
4#include <Wire.h>
5#include <Adafruit_Sensor.h>
6#include <Adafruit_BME280.h>
7
8const int ONE_WIRE_PIN = 4;     // DS18B20 DQ (4,7 kΩ pull-up -> 3V3)
9const int DHT_PIN = 27;         // DHT22 DATA
10
11OneWire oneWire(ONE_WIRE_PIN);
12DallasTemperature ds(&oneWire);
13DHT dht(DHT_PIN, DHT22);
14Adafruit_BME280 bme;            // I2C: SDA GPIO 21, SCL GPIO 22
15bool bmeOk = false;
16
17void setup() {
18  Serial.begin(115200);
19  ds.begin();
20  dht.begin();
21  bmeOk = bme.begin(0x76) || bme.begin(0x77);   // iki adresi de dene / try both addresses
22  if (!bmeOk) Serial.println("BME280 bulunamadi / not found");
23}
24
25void loop() {
26  ds.requestTemperatures();                     // 12 bitte ~750 ms sürer / takes ~750 ms at 12-bit
27  float tDs  = ds.getTempCByIndex(0);           // sensör yoksa -127 / -127 if missing
28  float tDht = dht.readTemperature();           // hata olursa NAN / NAN on error
29  float tBme = bmeOk ? bme.readTemperature() : NAN;
30
31  // Seri Çizici için etiket:değer biçimi / label:value format for the Serial Plotter
32  Serial.printf("DS18B20:%.2f,DHT22:%.1f,BME280:%.2f\n", tDs, tDht, tBme);
33  delay(2000);                                  // DHT22 en fazla 2 sn'de bir / DHT22 at most every 2 s
34}

まず数分待って、線どうしがどれくらい離れているかを見ます。0.5〜1 °Cの差は、これらのセンサーの精度の範囲内です。次に、温かい水を入れたコップをそばに置くか、3つのセンサーにそっと息を吹きかけてみてください。DS18B20とBME280は数秒以内に反応しますが、DHT22の線はプラスチックのケースのせいで明らかに遅れます。BME280がいつもほかより0.数度高いままなら、それはチップの自己発熱です。この小さな実験で、どのデータシートにも書かれていない違いが見えてきます。長期間の記録にはSDカードモジュールを使うか、データをGoogleスプレッドシートに送ることができます。

Raspberry Pi PicoとMicroPythonで温度を測る

PicoのMicroPythonファームウェアにはdht、onewire、ds18x20モジュールが組み込まれているので、DHTとDS18B20のために追加のファイルをPicoにコピーする必要はありません。RP2040チップには、ADCのチャンネル4につながった内蔵温度センサーもあります。次のコードは3つをまとめて読み取ります。

MicroPython
1from machine import Pin, ADC
2import dht, onewire, ds18x20, time
3
4dht22 = dht.DHT22(Pin(15))                          # DHT22 DATA -> GP15
5ds = ds18x20.DS18X20(onewire.OneWire(Pin(22)))      # DS18B20 DQ -> GP22 (4,7 kΩ pull-up)
6roms = ds.scan()                                    # hattaki sensörler / sensors on the bus
7cpu = ADC(4)                                        # RP2040 dahili sensörü / internal sensor
8
9def cpu_temp():
10    v = cpu.read_u16() * 3.3 / 65535                # ham değer -> volt / raw value -> volts
11    return 27 - (v - 0.706) / 0.001721              # RP2040 veri sayfası formülü / datasheet formula
12
13while True:
14    t_ds = None
15    if roms:
16        ds.convert_temp()                           # ölçümü başlat / start conversion
17        time.sleep_ms(750)                          # 12 bit dönüşüm süresi / 12-bit conversion time
18        t_ds = round(ds.read_temp(roms[0]), 2)
19    try:
20        dht22.measure()
21        t_dht, nem = dht22.temperature(), dht22.humidity()
22    except OSError:                                 # okuma hatası / read error
23        t_dht = nem = None
24    print("DS18B20:", t_ds, "DHT22:", t_dht, "Nem / RH:", nem,
25          "Pico:", round(cpu_temp(), 1))
26    time.sleep(2)

内蔵センサーが測るのは部屋ではなくチップの温度で、ADCの基準電圧の小さなずれで結果が数度ずれることがあります。そのため周囲の温度の測定には向きませんが、ボードが熱くなりすぎていないかを確かめるのには便利です。DS18B20のデータ線の4.7 kΩのプルアップも忘れないでください。Picoの内部プルアップ抵抗は1-Wireには弱すぎます。Picoが初めてなら、Raspberry Pi Picoとは?から始めましょう。

どのプロジェクトにどの温度センサーを選ぶ?

プロジェクトや用途おすすめのセンサー理由
初めてのプロジェクト、室温計DHT11いちばん安く、湿度も測れる。部屋なら±2 °Cで十分
屋内と屋外の気象ステーションBME280またはDHT22−40 °Cまで測れて湿度もわかる。BME280は気圧と高度も測れる
水槽、貯水タンク、ボイラーの水DS18B20防水プローブステンレスの保護管、±0.5 °C、長いケーブル
冷蔵庫と冷凍庫DS18B20−55 °Cまで測れる。DHT11は0 °C未満を測れない
多数の地点の測定(部屋、温室、配管)DS18B201本のピンに数十個のセンサー、それぞれに固有のアドレス
孵卵器DHT22またはBME28037.5 °C付近で±0.5 °C、さらに湿度も管理できる
オーブン、バーベキュー、はんだごてMAX6675+K型熱電対1000 °Cまで耐えられる
3Dプリンターのホットエンド、バッテリーパックNTCサーミスタ小さく、安く、速い。3Dプリンターでは100 kΩのガラス封止型NTCが使われる
モーター、ベアリング、基板、動く部品MLX90614非接触で測れる
ADCとアナログ測定の学習LM35またはNTCライブラリ不要、式だけで動く

温度センサーを使ったプロジェクトのアイデア

  • スマート温室:DHT22で空気の温度と湿度を、DS18B20のプローブで地温を測り、リレーモジュールでファンと水やりを制御します。プロジェクト全体はスマート温室プロジェクトを参照してください。
  • サーモスタット付きの水槽ヒーター:防水型DS18B20で水温を25〜26 °Cに保ちます。小さな変化のたびにリレーがオン・オフしないよう、0.5 °Cのヒステリシスを設けます。
  • 電池で動く気象ステーション:BME280とESP32のディープスリープモードを組み合わせ、10分ごとに測定すれば、電池で何か月も動作します。
  • ピザ窯やバーベキューの温度計:MAX6675とK型プローブで、窯の温度をOLEDディスプレイに大きな数字で表示します。
  • 非接触のモーター温度アラーム:MLX90614でモーターや3Dプリンターのベッドの表面温度を監視し、しきい値を超えたらブザーを鳴らします。
  • ホームオートメーション:ESP32で各部屋の温度をMQTTでHome Assistantに送り、それに応じて暖房を制御します。
  • 冷凍庫の見張り番:DS18B20で、冷凍庫の中が−12 °Cより上がったらアラームを鳴らし、値をI2C LCDディスプレイに表示します。

よくある間違いと対処法

症状考えられる原因対処法
DHT:nanまたは「Failed to read from DHT sensor!」(読み取り失敗)コードのタイプ(DHT11/DHT22)の間違い、プルアップなし、読み取りが頻繁すぎるタイプを直し、10 kΩのプルアップを入れ、読み取りの間隔を2秒空ける
DS18B20:−127 °Cセンサーが見つからない:プルアップなし、ケーブルの不良、ピンの間違いDQとVCCのあいだに4.7 kΩを入れ、接続を確認する
DS18B20:いつも85 °C変換が終わる前に読み取っている、または電源の不足変換時間を待ち、VDDに直接給電する
LM35:異常に高い値、センサーが熱くなる電源ピンを逆につないでいるすぐに電源を切り、ピンの順番を直す
LM35またはNTC:値が跳ね続けるADCのノイズ、長いケーブル、不安定なUSB電源読み取り値を平均し、0.1 µFのコンデンサを入れ、ケーブルを短くする
NTC:温まると温度が下がる分圧回路の向きがコードと合っていない抵抗値の式を逆にする
BME280:「Could not find a valid BME280 sensor」(有効なBME280センサーが見つからない)アドレス(0x76/0x77)の間違い、または実はBMP280アドレスを変え、チップIDを読み取る(0x60 / 0x58)
BME280またはDHT:1〜3 °C高い自己発熱、近くのESP32やレギュレーターセンサーをボードから離し、読み取り回数を減らし、オフセットを補正する
MAX6675:nan熱電対がつながっていない、または線が切れているネジ端子とプローブを確認する
MAX6675:熱くなると値が下がる熱電対の極性が逆+と−の線を入れ替える
MLX90614:光沢のある金属がとても冷たく見える放射率が低いつや消しの黒いテープを貼るか、放射率を設定する
MLX90614:小さな物体を正しく測れない視野が物体より大きいセンサーを近づけるか、狭角版を使う
どのセンサーを選んでも、いちばん大きな誤差の原因はセンサーそのものではなく、置き場所にあることがよくあります。直射日光の当たる場所、電圧レギュレーターやESP32のすぐそば、密閉した箱の中に置いたセンサーは、部屋ではなく自分の周りの温度を測ってしまいます。センサーをボードから離し、空気の流れがある場所に置き、信頼できる温度計と一度比べて、一定の差をコードで補正してください。ばらつく値をなめらかにするには、センサーデータのフィルタリングの方法も見てみてください。

まとめると、部屋や気象にはDHT22かBME280、水や寒い場所にはDS18B20、アナログ測定の学習や速い応答にはLM35かNTC、高温にはMAX6675、触れられない表面にはMLX90614が、最初に選ぶべきセンサーです。ほかの種類のセンサーも知りたい場合は、Arduinoセンサーガイドをご覧ください。BlueGraysアプリでは、DHT11で温度と湿度を測定、NTCとLCDで作る温度計、ESP32とDHT22とLCDで作る温度表示、ESP32温度データロガー、スマート水やりなどのプロジェクトを、ステップごとの回路図とコードつきで見つけられます。

よくある質問

Arduinoでいちばん正確な温度センサーはどれですか?

電子工作向けのセンサーの中で、室温付近でいちばん正確なのはDS18B20、DHT22、BME280(25 °C時)、MLX90614で、いずれも±0.5 °Cです。有線や防水の測定ならDS18B20、湿度も必要ならDHT22かBME280がおすすめです。どれを選んでも、信頼できる温度計と一度比べてオフセットをコードで補正すると、精度がはっきりよくなります。

DHT11とDHT22のどちらを買えばいいですか?

部屋の温度と湿度をおおまかに見たいだけなら、DHT11で十分です。屋外での使用、0 °C未満の温度、±0.5 °Cの精度が必要ならDHT22にしましょう。−40〜+80 °Cを測れ、湿度もより正確です。どちらも同じライブラリとコードで動き、スケッチのセンサーのタイプを変えるだけです。

Arduinoで水温を測るにはどうすればいいですか?

水にいちばん適したセンサーは、ステンレスの保護管に入った防水型のDS18B20プローブです。プローブを水に入れ、データ線を4.7 kΩのプルアップ抵抗とともにArduinoのデジタルピンにつなぎます。ケーブルやその接合部は、たいてい熱いお湯に長時間つけることを想定していないので、水に入れるのは金属の先端部分だけにしてください。

Arduinoで500 °Cのような高温を測れますか?

はい。K型熱電対とMAX6675モジュールを使えば、0〜約1024 °Cを測れます。熱電対の先端はオーブンの中に入れ、MAX6675モジュールは熱から離しておく必要があります。購入したプローブのシースとケーブルが何度まで耐えられるかを必ず確認してください。

Arduinoで非接触の温度計を作れますか?

MLX90614を使えば、Arduinoにつないだ非接触の赤外線温度計を作れます。標準版は室温付近で±0.5 °Cの精度です。体温を測るには医療用精度の版(±0.2 °C)と適切な測定距離が必要で、それでもこの構成は医療機器の代わりにはなりません。測るときは、対象の表面がセンサーの視野を完全に埋めるようにしてください。

温度センサーの値が高く出るのはなぜですか?

いちばん多い原因は、センサーの近くにある熱源です。ESP32、電圧レギュレーター、日光などです。BME280のようなセンサーは、連続して測定すると自分自身も少し温まります。センサーをボードから10〜15 cm離し、読み取り回数を減らし、信頼できる温度計と比べて残った一定の差をコードで補正してください。

全プロジェクトを見る
DHT11で温度と湿度を測定
#55中級

DHT11で温度と湿度を測定

部屋の温度は何度で、空気は湿っているでしょうか、それとも乾燥しているでしょうか?DHT11センサーが温度と湿度を測定し、Arduinoが2行のLCDディスプレイに値を表示して、数秒ごとに更新します。センサーに異常があればエラーメッセージが表示されます。自分だけの小さな気象観測装置を作る第一歩です。

4.7(47)
73
NTCと2x16 LCDディスプレイで温度を測定
#44初級
プレミアム

NTCと2x16 LCDディスプレイで温度を測定

小さなビーズのようなセンサーで周囲の温度を測ります。NTCというこの部品は、温まるほど電気が流れやすくなります。Arduinoがその変化を読み取り、数式で摂氏温度に変換して、2行のLCDディスプレイに0.5秒ごとに表示します。手のひらでセンサーを温めて、数値が上がる様子を見るのも楽しみの1つです。

4.5(33)
44
ESP32 DHT22温湿度計(LCDディスプレイ付き)
#117中級

ESP32 DHT22温湿度計(LCDディスプレイ付き)

DHT22センサーで周囲の温度と湿度を測定し、16x2 I2C LCDにリアルタイムで表示するプロジェクトです。Adafruit DHTライブラリを使い、1本の信号線を使うプロトコルでセンサーからデータを読み取ります。IoT気象観測装置やスマートホームの自動化、温室の環境監視システムの基礎となります。ESP32のGPIO 4ピンを介してDHT22と通信します。

4.8(38)
56
ESP32温度データロガー(DHT22 + DS1307 RTC + microSD + OLED)
#144上級
プレミアム

ESP32温度データロガー(DHT22 + DS1307 RTC + microSD + OLED)

ESP32で日時付きの温度・湿度記録システムを作ります!DHT22で1分ごとに温度と湿度を読み取り、DS1307 RTCから取得した日時とともにmicroSDカードへCSV形式で記録します。OLEDには最新の温度を大きな文字で表示し、湿度のパーセント値、日時、総記録数も表示します。SDカードの/temp_log.csvファイルはExcel、Google Sheets、Pythonのpandasで開いて分析できます。温室の監視、家や部屋の温度管理、実験室のデータ収集、食品の保管環境や養蜂箱の監視に適しています。

4.7(7)
12
ドットマトリクス時計・カレンダー・気象ステーション(MAX7219、DS1307)
#85中級
プレミアム

ドットマトリクス時計・カレンダー・気象ステーション(MAX7219、DS1307)

机や壁に置いて、時刻、日付、室内の温湿度を順番に表示する、文字がスクロールする表示板です。8x32のLEDディスプレイには、まず摂氏と華氏の温度、次に湿度、そして2つの点が1秒ごとに点滅する時計が表示されます。分が変わると、曜日と日付がスクロール表示されます。時計モジュールが時刻を保持し、DHT22センサーが温度と湿度を測定します。

5.0(50)
66
スマート水やりステーション
#83上級
プレミアム

スマート水やりステーション

旅行中も植物が枯れないよう、自動で水やりをするシステムです。土壌水分センサーで土の湿り具合を測定し、乾燥するとArduinoが給水ポンプを数秒間動かして、青いライトを点灯させます。水分が適切なときは緑のライトが点灯します。土がひどく乾燥すると、赤いライトが点滅し、ブザーが鳴って知らせます。

5.0(42)
57
I2CでLCDディスプレイを使う
#32初級
プレミアム

I2CでLCDディスプレイを使う

Arduinoにディスプレイを接続し、最初のメッセージを表示します。2行のLCDディスプレイは数本の配線だけで接続できます。まず上の行にあいさつを表示し、次に下の行にもう1つのメッセージを表示します。その後、表示を消去して最初から繰り返します。温度や時刻、スコアを表示するプロジェクトは、すべてこのステップから始まります。

4.8(53)
70