赤外線温度センサーがちょっと遊んでみようか、というレベルの値段になっているので講習会で使ってみました。
GY-906というモジュールでMelexis MLX90614という赤外線センサーが使われています。Web上の情報ではESFBAAというタイプのようですがGY-906の回路図が見つかりませんでしたので正しいかどうかはわかりません。Melexisからデータシートが公開されているので、ESFBAAが正しいとするとOperating Temperature Rangeは-40℃から85℃で、TO-39型ケース、3V動作(モジュール内で5V→3V変換)、シングルゾーン(視野が単一)、標準パッケージ(視野角90°)ということです。測定できる温度は-70℃から+380℃です。
Amazonでは HiLetgoで670円でした。
https://www.amazon.co.jp/gp/product/B071VF2RWM/ref=od_aui_detailpages00?ie=UTF8&psc=1
AliexpressではMT Technology Co., Ltd.でさらにいくらか安い$4.05でした。
https://ja.aliexpress.com/item/Free-Shipping-GY-906-MLX90614ESF-New-MLX90614-Contactless-Temperature-Sensor-Module-For-Arduino-Compatible/32465344732.html?spm=a2g0s.9042311.0.0.aeFeEN
I2Cですのでライブラリを追加して配線4本でOKです。UNOでは(Nanoでも同じですが、)SDAをA4、SCLをA5に接続します。
表示器も欲しいということになって、I2CのOLED Display Module 128X64も接続しました。これもAmazonの HiLetgoで420円でした。
https://www.amazon.co.jp/gp/product/B071ZPFDWW/ref=od_aui_detailpages00?ie=UTF8&psc=1
AliexpressではHwa Yeh Tech CO.,LTDでいくらか安い$3.00でした。表示器のライブラリはAdafruit_SSD1306を使用しました。ディスプレイへの表示用ライブラリAdafruit_GFXも合わせてインストールします。Adafruit_SSD1306を使う時には使用しているディスプレイの解像度に合わせてAdafruit_SSD1306.hのコメントアウトの行を変更する必要があります。行番号72からの数行を抜き出しましたが、下記が変更後です。
|
---------------------------------------------------------------------*/ #define SSD1306_128_64 // #define SSD1306_128_32 // #define SSD1306_96_16 /*=======================================================================*/ |
講習会ではArduino Nano互換機を使いましたが、この記事を書いている今は手元にあったUno互換機を使っています。

この記事を書きながらセンサーの資料を見返していたら、放射率の補正が間違っていたことが分かりました。下のスケッチは訂正済みです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
//SSD1306 library by Adafruit Industries //MLX90614 Temp Sensor library by Adafruit Industries. #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_MLX90614.h> Adafruit_MLX90614 mlx = Adafruit_MLX90614(); #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); float TempEm(float Em, float TA, float TO); //コンパイルエラー回避のため void dispTemp(float T0, float T1, float T2);//コンパイルエラー回避のため void setup() { Serial.begin(9600); Serial.println("displayIrSensorEm_i2c_170815"); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C mlx.begin(); //Adafruit splashscreen display.display(); delay(1000); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); } void loop() { float temp0=mlx.readAmbientTempC(); float temp1=mlx.readObjectTempC(); float temp2=TempEm(0.98,temp0,temp1); Serial.print("Sensor = "); Serial.print(temp0); Serial.print("deg(C) "); Serial.print("Object = "); Serial.print(temp1); Serial.print("deg(C) "); Serial.print("CorrectedObj = "); Serial.print(temp2); Serial.println("deg(C)"); dispTemp(temp0,temp1,temp2); delay(500); } void dispTemp(float T0, float T1, float T2){ display.clearDisplay(); display.setCursor(5,5); display.print("Snr= "); display.println(T0); display.setCursor(5,25); display.print("PBk= "); display.println(T1); display.setCursor(5,45); display.print("Obj= "); display.println(T2); display.display(); } float TempEm(float Em, float TA, float TO){ TA=TA+273.15; TO=TO+273.15; float T=TO*TO*TO*TO/Em+TA*TA*TA*TA*(1-1/Em); float Temp=sqrt(sqrt(T))-273.15; return Temp; } |
赤外線温度センサーMelexis MLX90614は5.5μmから14μmの波長域の赤外線を受光して、赤外線で加熱された受光面の温度を多数の熱電対で測定して赤外線の量を求めているようです。赤外線を放出している物体は黒体(放射率=1.0)と仮定して、センサーの温度測定値も用いて、測定対象の温度を推定しています。実際は物体の表面によって放射率は異なり(1よりも小さくなる)、放射率の低い金属表面を測定した場合は黒体に比べて赤外線の放出量が少ないので測定結果は実際の表面温度よりも低い値を出力します。
MLX90614に内蔵されたEEPROMに測定対象の放射率を書き込んで補正した結果を出力するように設定することができます。しかしながらライブラリでは対応していないことと、書き込むためには通信エラー検出用のPEC値も書き込む必要があり、かなり面倒みたいなので、Arduinoのプログラムで補正をすることにしました。放射率E(0~1.0)と、センサー温度(K) Tsnr、測定対象の温度(K) Tact、赤外線量から推定した温度(K) Tmeasの関係式がMelexis社の資料に書かれています。
https://www.melexis.com/en/documents/documentation/application-notes/application-note-mlx90614-changing-emissivity-setting

放射率が分かっていればこの関係式を使って測定対象の温度に変換することができます。

実際の表面の放射率は分からないことが多いので、熱電対等で実測して赤外線センサーでの測定値がその値を示すように放射率で調整する使い方になるようです。
2017.08.15