Arduino と気温センサーで温度計

なにするの?

始めての今回は、Arduino と気温センサーを使って室温の測定を行います。
温度計買えばいいやんなんて言わないで‼️

使用機材

回路図

ブレッドボードで作りました。見辛くてごめんなさい。 色とピン名の対応は以下の通りです。

  • 黒 : GND
  • 赤 : VCC
  • 白 : SDA
  • 茶 : SCL

GND,SDA,SCL は Arduino と気温センサーの両方にピンがあるので同じ名前同士で繋いでください。気温センサーの VCC は Arduino の 3.3V か 5V のどちらかと繋いでください。本記事では 5V に繋いでおきます。

f:id:etuetuetutan:20210927015132j:plain

作業

気温センサーです。ケースに入って届きました。とても、空間をもて余してますが。

f:id:etuetuetutan:20210926183814j:plain

はんだ付けしました。

f:id:etuetuetutan:20210926183858j:plain

これを、回路図通りに接続します。

次に、Arduino とセンサーを通信させるプログラムを作成します。Arduino とセンサーの通信は I2C という通信方式で行います。Wire.h というライブラリを使えば簡単にできるみたいです。

プログラム作ってて気がついたんですが、この気温センサー、AMAZON の商品名では LM75A と書いてあったので、そちらのデータシートを参考にしていたのですが、本体をよく見たら LM75B と書いてありました、、、紛らわしい。
https://www.switch-science.com/catalog/1813/ ここに、データシートや、サンプルプログラムまでありました。ありがたい。

サンプルを参考に、気温取得を行います。 プログラムはこんな感じです。 5秒ごとに気温を取得します。

#include <Wire.h>

#define LM75B_ADDR 0x48
  
void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("start");
}

void loop() {
  signed int message;
  double temp;
  Wire.requestFrom(LM75B_ADDR,2);
  message  = (Wire.read() << 8);
  message |= Wire.read();
  temp = ((message >> 5) & 0x3FF) * 0.125;
  Serial.print("temperature : ");
  Serial.println(temp);
  delay(5000);
}

少し、プログラムの解説をしておくと、

#define LM75B_ADDR 0x48

の部分でセンサーのアドレスを指定しています。
I2C では、通信時にデバイスのアドレスが必要になります。このアドレスによって特定のデバイスとだけ通信を行うことができます。データシートによると、アドレスは 0x48~0x4F のどれかみたいです。このセンサーは、アドレスを変えることで最大8個同時に接続できるので、家の部屋毎にセンサーをおいて気温を測ることもできそうですね。
ただ、私の手元のセンサーは0x48 として認識されたり、 0x4C として認識されたりします。部品をよく見ると A2 と書かれた部分に小さな穴が空いています。アドレス的に A2 が影響していそうなのでこいつが悪さしている?

f:id:etuetuetutan:20210927020510j:plain

message  = (Wire.read() << 8);
message |= Wire.read();

の部分でセンサーから送られてくるデータを message という名前で保存します。気温のデータが分解されて送られてくるので受け取って組み立てているイメージです。

temp = ((message >> 5) & 0x3FF) * 0.125;

の部分で実際に気温データを表している数値の部分を抜き出しています。実は、送られてくるデータには気温ではない部分もあるのでそこを除去しています。本当は、氷点下の場合だと別の処理が必要なのですが、今回はそこは考慮しません。

これを Arduino IDE を使って Arduino に書き込んでいきます。そして、ツール > シリアルモニタ を選んで、、

f:id:etuetuetutan:20210926184809p:plain

それっぽい値が取れました!!温度計完成です。
27℃ は少し高いような、、、? まぁ、いいでしょう!
さて、次は何を作ろうか。。。

余談

専門的な内容になってしまうのですが、I2C 通信開始時のアドレスの後に続く Write Read の指定に必要なビットの処理は、 Wire.h のライブラリの requestFrom や beginTransmission 関数で適切に処理されているのでしょうね。ここの部分でかなり悩んでしまいました。