NodeMCU(ESP8266)+アナログ温度センサLM61CIZで温度測定 (NodeMCU Webサーバ化 & LINE Notify)

WifiモジュールNodeMCU(v0.9)と秋月電子で買えるアナログ温度センサIC LM61CIZをつないで、Webブラウザから測定した温度を確認してみました。今回はNodeMCUのアナログデジタル変換回路(ADC)を使ってLM61CIZの出力電圧を読み取っていますが、ほかのアナログセンサを利用する場合も同様の手順で行けます。

#LM61CIZについて
↓LM61CIZのスペックシートは秋月電子のサイトに載っています。
[http://akizukidenshi.com/catalog/g/gI-11160/](http://akizukidenshi.com/catalog/g/gI-11160/)

- 電源電圧は2.7V～10V⇒NodeMCUの3.3V出力がそのまま使えます
- 最大消費電力(25℃)は125&micro;A⇒NodeMCUで十分供給可能です
- LM61CIZは0℃で600mVを出力し、±1℃上下するごとに±10mV出力電圧が上下する

ところで

- NodeMCUのADCはA0ピンに入力された0V~3.3Vの電圧を0~1023の10bitの整数値に変換する

よってNodeMCUのA0ピンとLM61CIZの出力ピンを直接つないで測定した場合、温度は以下のように求められます。

```math
T[℃] = (A_0-\frac{0.6[V]}{\frac{3.3[V]}{1023-0}})\times\frac{\frac{3.3[V]}{1023-0}}{0.01[V/℃]}=(A_0-186)\times0.32
```
T<sub>0</sub> : 気温、A<sub>0</sub> : ADCから得られる整数値

0.32℃単位で温度測定が可能であるという計算になりますが、元々LM61CIZで測定した温度には±4℃の範囲の誤差が含まれます。大まかな温度変化を確認する程度のものとして使ってください。

#回路図
LM61CIZの平らな面からみて左がVcc、右がGNDにつなぐ足で、真ん中が出力になります。
![temperature_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/228798/6321b69f-1191-d09b-ae83-2d775029e02c.png)

#ソースコード(Webサーバ)
今回はArduinoで行きます。あらかじめ Arduino core for ESP8266 WiFi chip を導入しておく必要があります。導入方法については下記サイト様をご参照ください。
https://www.mgo-tec.com/esp8266-board-install01-html

Arduino core for ESP8266 WiFi chip 導入時に追加されるスケッチ例(NodeMCU 0.9 > ESP8266WebServer > HelloServer) を参考にしています。また、NodeMCUからアクセスポイント(ルーター)につなぎに行くコードになっているので、NodeMCUをアクセスポイントとしたい場合は書き換えが必要になります。

NodeMCUのIPアドレスが 192.168.43.2 に固定で設定されていますが、ネットワーク環境に合わせて変更してください。  


```cpp

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "APのSSID";
const char* password = "パスワード";

MDNSResponder mdns;
ESP8266WebServer server(80);

float temperature(void) {
  return (analogRead(A0) - 186) * 0.32;
}

void setup(void){

  // Wifi APにアクセスできるまでは赤のオンボードLEDを点灯
  pinMode(D0, OUTPUT);
  pinMode(D4, OUTPUT);
  
  digitalWrite(D0, LOW);
  digitalWrite(D4, HIGH);
  
  // NodeMCUのIPアドレス
  WiFi.config(IPAddress(192,168,43,2),IPAddress(0,0,0,0),IPAddress(255,255,255,0));

   
  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  Serial.println("");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  // Wifi APにアクセス出来たら青のオンボードLEDを点灯
  digitalWrite(D0, HIGH);
  digitalWrite(D4, LOW);

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  
  if (mdns.begin("esp8266")) {
    Serial.println("MDNS responder started.");
  }
  
  server.on("/", [](){
    String webPage = "<p>室温" + String(temperature()) + "℃</p>"; 
    webPage += "<p><a href=\".\">再読み込み</a></p>";
    server.send(200, "text/html", webPage);
  });
  server.begin();
  Serial.println("HTTP server started.");
}
 
void loop(void){
  server.handleClient();
} 
```

##接続
プログラムを書き込んだらNodeMCUを電源につないでください。起動すると基板上の赤色のLEDが点灯し、アクセスポイントにつながると青色のLEDが点灯します。その後、同じローカルネットワーク上のPCかスマートフォン上のブラウザから「http://[NodeMCUのIPアドレス]/」に接続すると温度が表示されます。「再読み込み」リンクをクリックすることで温度情報が更新されるので、センサ部分を指で温めてみながら温度変化を確認してみてください。

なお、Bonjourを導入している環境であれば、「http\://esp8266/」からでもアクセス可能です。

##ソースコード(LINE Notify)

以下のリンクのサイトを参考にさせていただき、LINE Notifyを用いLINEアプリ上で温度を確認できるようにするプログラムのソースコードも書いてみました。
http://doc.inex.co.th/ตัวอย่างการใช้งาน-nodemcu-ส่งข/

Line Notifyを使いたい場合、LINE Notifyのアクセストークンが必要になります。下のリンクからあらかじめアクセストークンを入手しておいてください。
https://notify-bot.line.me/ja/

ほぼ1分ごとに温度を計測してLINEに通知します。

```cpp
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char* ssid = "APのSSID";
const char* password = "パスワード";
const String LINE_TOKEN = "アクセストークン";

float temperature(void) {
  return (analogRead(A0) - 186) * 0.32;
}

void setup() {
  pinMode(D0, OUTPUT);
  pinMode(D4, OUTPUT);
  
  digitalWrite(D0, LOW);
  digitalWrite(D4, HIGH);

  Serial.begin(115200);
  
  WiFi.begin(ssid, password);
  Serial.println("");

  while (WiFi.status() != WL_CONNECTED) {
    delay(3000);
    Serial.print(".");
  }
  digitalWrite(D0, HIGH);
  digitalWrite(D4, LOW);

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

}

void loop() {
  Line_Notify(LINE_TOKEN, "室温: " + String(temperature()) + "℃");
  unsigned long timeout = millis();
  while (true) {
    delay(10);
    if (millis() - timeout > 60000UL) {
      break;
    }
  }
}

void Line_Notify(String LINE_Token, String message) {

  String msg = String("message=") + message;

  WiFiClientSecure client;
  if (!client.connect("notify-api.line.me", 443)) {
    Serial.println("connection failed");
    return;
  }

  String req = "";
  req += "POST /api/notify HTTP/1.1\r\n";
  req += "Host: notify-api.line.me\r\n";
  req += "Content-Type: application/x-www-form-urlencoded\r\n";
  req += "Authorization: Bearer " + LINE_TOKEN + "\r\n";
  req += "Content-Length: " + String(msg.length()) + "\r\n";
  req += "\r\n";
  req +=  msg;

  client.print(req);

  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println("closing connection");
}
```

##参考文献

Fritzingのパーツデータはそれぞれ以下のリンク先からお借りしました。

NodeMCU V1.0
[GitHub squix78/esp8266-fritzing-parts](https://github.com/squix78/esp8266-fritzing-parts)

NodeMCU V1.0
[きむ工房ガレージハウス](http://www.geocities.jp/zattouka/GarageHouse/index.htm)

---
18/01/30 実際に温度をブラウザ上で見るための手順を書いていなかったので追記しました。
18/02/18 LINE Notifyについての記述を追加しました。