工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

DS18B20センサーで作るWeb対応Arduino温度計

必要な部品と材料

部品 数量 備考
Arduino UNO 1
PHPoC WiFi Shield for Arduino 1 PHPoC Shieldでも代用可能
Adafruit DS18B20温度センサー 1
4.7kΩ抵抗 1 プルアップ用
熱収縮チューブ 1

プロジェクト概要

初心者の方は、以下のチュートリアルでWiFiとセンサーの基礎を学ぶことができます。

同様のプロジェクトをPHPoCのみで作成した例もあります。

デモ

Webブラウザ上でリアルタイムに温度変化をグラフィカルに表示します。

データフロー

Arduino → PHPoC WiFi Shield → Webブラウザ

Arduinoがセンサーから温度を読み取り、PHPoC WiFi Shieldに送信します。Shieldは受信した温度値をWebSocket経由でWebブラウザに送り、JavaScriptがUI上に可視化します。

注意: PHPoC ShieldにはArduinoからWebブラウザへデータを中継する組み込みプログラムがあるため、通信部分の実装を気にする必要はありません。

必要な作業

  1. PHPoC ShieldのWiFi設定(SSIDとパスワード)
  2. Web UIをPHPoC Shieldにアップロード
  3. Arduinoコードの作成とアップロード

PHPoC ShieldのWiFi設定

こちらの手順を参照してください。

Web UIのアップロード

Arduinoコードの作成

テスト手順

  1. Arduino IDEのシリアルモニタを開き、IPアドレスを確認
  2. Webブラウザでhttps://[IPアドレス]/remote_thermometer.phpにアクセス
  3. 「Connect」ボタンをクリックして動作確認

参考情報

Arduinoスターターキットをお探しの方は、初心者向けおすすめArduinoキットをご覧ください。

使用関数リファレンス

ソースコード

Arduinoコード

#include <OneWire.h>
#include <DallasTemperature.h>
#include "SPI.h"
#include "Phpoc.h"

// データ線はArduinoのポート8に接続
OneWire oneWire(8);
DallasTemperature sensors(&oneWire);
PhpocServer server(80);
boolean alreadyConnected = false;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  sensors.begin();
  Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
  server.beginWebSocket("thermometer");
  Serial.print("WebSocket server address: ");
  Serial.println(Phpoc.localIP());
}

void loop() {
  PhpocClient client = server.available();
  if (client) {
    sensors.requestTemperatures();
    float temp = sensors.getTempCByIndex(0);
    String txtMsg = String(temp) + "\r\n";
    char buf[txtMsg.length()];
    txtMsg.toCharArray(buf, txtMsg.length());
    server.write(buf, txtMsg.length());
    delay(300);
  }
}

remote_thermometer.php(Web UI)

このファイルをPHPoC WiFi ShieldまたはPHPoC Shieldにアップロードしてください。

<!DOCTYPE html>
<html>
<head>
  <title>Arduino - PHPoC Shield - Thermometer</title>
  <meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
  <meta charset="utf-8">
  <style>
    body { text-align: center; font-size: width/2pt; }
    h1 { font-weight: bold; font-size: width/2pt; }
    h2 { font-weight: bold; font-size: width/2pt; }
    button { font-weight: bold; font-size: width/2pt; }
  </style>
  <script>
    var canvas_width = 200, canvas_height = 450;
    var ws;
    var buffer = "";

    function init() {
      var canvas = document.getElementById("remote");
      canvas.width = canvas_width;
      canvas.height = canvas_height;
      var ctx = canvas.getContext("2d");
      ctx.translate(canvas_width/2, canvas_height - 80);
      update_view(0);
    }

    function connect_onclick() {
      if(ws == null) {
        var ws_host_addr = "";
        if((navigator.platform.indexOf("Win") != -1) && (ws_host_addr.charAt(0) == "[")) {
          ws_host_addr = ws_host_addr.replace(/[\[\]]/g, '');
          ws_host_addr = ws_host_addr.replace(/:/g, "-");
          ws_host_addr += ".ipv6-literal.net";
        }
        ws = new WebSocket("ws://" + ws_host_addr + "/thermometer", "text.phpoc");
        document.getElementById("ws_state").innerHTML = "CONNECTING";
        ws.onopen = ws_onopen;
        ws.onclose = ws_onclose;
        ws.onmessage = ws_onmessage;
      } else {
        ws.close();
      }
    }

    function ws_onopen() {
      document.getElementById("ws_state").innerHTML = "<font color='blue'>CONNECTED</font>";
      document.getElementById("bt_connect").innerHTML = "Disconnect";
      ws.send("B\r\n");
      update_view(0);
    }

    function ws_onclose() {
      document.getElementById("ws_state").innerHTML = "<font color='gray'>CLOSED</font>";
      document.getElementById("bt_connect").innerHTML = "Connect";
      ws.onopen = null;
      ws.onclose = null;
      ws.onmessage = null;
      ws = null;
      update_view(0);
    }

    function ws_onmessage(e_msg) {
      e_msg = e_msg || window.event;
      console.log(e_msg.data);
      update_view(parseFloat(e_msg.data));
    }

    function update_view(temp) {
      var canvas = document.getElementById("remote");
      var ctx = canvas.getContext("2d");
      var radius = 70;
      var offset = 5;
      var width = 45;
      var height = 330;

      ctx.clearRect(-canvas_width/2, -350, canvas_width, canvas_height);

      if(ws != null) {
        ctx.strokeStyle = "blue";
        ctx.fillStyle = "blue";
      } else {
        ctx.strokeStyle = "Gray";
        ctx.fillStyle = "Gray";
      }

      // 5度ごとの目盛り
      var x = -width/2;
      ctx.lineWidth = 2;
      for (var i = 0; i <= 100; i+=5) {
        var y = -(height - radius)*i/100 - radius - 5;
        ctx.beginPath();
        ctx.lineTo(x, y);
        ctx.lineTo(x - 20, y);
        ctx.stroke();
      }

      // 20度ごとの太い目盛りと数値
      ctx.lineWidth = 5;
      for (var i = 0; i <= 100; i+=20) {
        var y = -(height - radius)*i/100 - radius - 5;
        ctx.beginPath();
        ctx.lineTo(x, y);
        ctx.lineTo(x - 25, y);
        ctx.stroke();
        ctx.font = "20px Georgia";
        ctx.textBaseline = "middle";
        ctx.textAlign = "right";
        ctx.fillText(i.toString(), x - 35, y);
      }

      // 温度計の形状描画
      ctx.lineWidth = 16;
      ctx.beginPath();
      ctx.arc(0, 0, radius, 0, 2 * Math.PI);
      ctx.stroke();
      ctx.beginPath();
      ctx.rect(-width/2, -height, width, height);
      ctx.stroke();
      ctx.beginPath();
      ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
      ctx.stroke();

      // 背景塗りつぶし
      ctx.fillStyle = "#e6e6ff";
      ctx.beginPath();
      ctx.arc(0, 0, radius, 0, 2 * Math.PI);
      ctx.fill();
      ctx.beginPath();
      ctx.rect(-width/2, -height, width, height);
      ctx.fill();
      ctx.beginPath();
      ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
      ctx.fill();

      // 温度値の表示
      if(ws != null) ctx.fillStyle = "#ff1a1a";
      else ctx.fillStyle = "Gray";

      ctx.beginPath();
      ctx.arc(0, 0, radius - offset, 0, 2 * Math.PI);
      ctx.fill();

      temp = Math.round(temp);
      var y = (height - radius)*temp/100.0 + radius + 5;
      ctx.beginPath();
      ctx.rect(-width/2 + offset, -y, width - 2*offset, y);
      ctx.fill();

      if(ws != null) {
        ctx.fillStyle = "white";
        ctx.font = "bold 34px Georgia";
        ctx.textBaseline = "middle";
        ctx.textAlign = "center";
        ctx.fillText(temp.toString() + "°C", 0, 0);
      }
    }

    window.onload = init;
  </script>
</head>
<body>
  <h1>Arduino - Web Thermometer</h1>
  <canvas id="remote"></canvas>
  <h2>
    <p>WebSocket: <span id="ws_state">null</span></p>
    <button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button>
  </h2>
</body>
</html>

配線図

  1. PHPoC WiFi ShieldまたはPHPoC ShieldをArduinoにスタック
  2. 以下の画像のように配線

DS18B20センサーで作るWeb対応Arduino温度計
DS18B20センサーで作るWeb対応Arduino温度計

製造プロセス

  1. 温度計:ガリレオの温度スコープから現代デジタルセンサーまで
  2. Bluetooth操作のArduinoスパイボットを自作する
  3. FlickMote:ジェスチャー操作のIRリモコンでスマートホームを制御
  4. 自作Arduino TV-B-Gone:全テレビ対応の万能リモコン
  5. 12メートル先から見える大型LEDマスタークロック(アラーム機能付き)を自作しよう
  6. ArduinoとBluetoothで作るスマート紛失防止タグ「Find Me」
  7. Arduinoプロジェクトのための最適化電源ソリューション
  8. Arduinoウェブ制御MP3プレーヤー:ブラウザから簡単オーディオ再生
  9. Arduino三目並べ:MAX7219 LEDマトリクスと段ボールケースで自作
  10. スマートArduino四足歩行ロボットの製作:ステップバイステップガイド
  11. ArduinoをWebパターンロックで保護 - 簡単セットアップとリモート制御