YU2TA7KA's BLOG ~take one step at a time~

派生開発、組み込み開発周りのこと。

Raspberry pi でNode.jsを使って温度センサ値をブラウザに表示する

はじめに

おうちカメラを実装する時に苦労した「Raspberry pi でNode.jsを使って温度センサ値をブラウザに表示する」をまとめます。Webブラウザ表示する場合サーバー側の実装が必要になり、そこをNode.jsに担ってもらいます。また、温度センサ周りは「Raspberry Piで学ぶ電子工作」のサンプルコードをベースにします。

実装の環境

ハードウェア

名前 用途 価格
ラズパイ環境(Raspberry Pi 3 Model b+) 温度センサ値の取得、Webサーバー。 8,800円
温度センサ(ADT7410 温度取得。 500円
ブレッドボード 温度センサの設置。 500円
ジャンパ線(オス-メス) 温度センサとラズパイの接続。 500円

ソフトウェア

名前 バージョン
Python 2.7.13
Nodejs 8.11.1
npm 1.4.21

実装の構成

f:id:yuji-tanaak:20190706070953j:plain

Node.js環境の構築

インストール

下記では最新版をインストールすることはできません。最新版をインストールする場合は別途調査ください。

$ sudo apt-get update
$ sudo apt-get install nodejs
$ sudo apt-get install npm
$ nodejs -v
v8.11.1
$ npm -v
1.4.21

HelloWorld

実装

const http = require('http');
const PORT = 8808;
http.createServer((request, response) => {
 response.writeHead(200, {'Content-Type': 'text/plain'});
 response.end('Hello Nodejs');
}).listen(PORT);
console.log(`Server running at http://localhost:${PORT}/`);

helloworld.jsの実行
$ node example.js
Server running at http://localhost:8808/

f:id:yuji-tanaak:20190714070826j:plain
ブラウザ表示画面

テキストファイルの読み込み出力

作業環境の構築
$ mkdir test_sensor
$ cd test_sensor
$ npm init
$ npm install express ejs --save

test_sensor
|-/views
   |-landing.ejs
|-/node_modules **自動で生成される
|-app.js
|-package.json **自動で生成される
|-package-lock.json **自動で生成される

実装

app.jsのgetTemperature()関数にて温度が書かれたテキストファイルを読み込みます。msg変数に格納し、landing.ejsへ渡してブラウザで表示します
(<%= message %>の部分)。テキストファイルの生成は温度センサ処理の項で記載します。動作確認する場合は、適当なファイルを作成し、fs.readFile()のパスをそれに合わせれば任意に設定可能です。

'use strict';
var express = require("express");
var app = express();
var fs = require('fs');

getTemperature();

app.set("view engine", "ejs");

let msg ='';
function getTemperature(){
  fs.readFile('/temperature_log/latest.txt', 'utf-8', (err, data) => {
    if (err) { throw err; }
    msg = data;
    console.log(msg);
  });
}

app.get('/', function(req, res){
            res.render("landing", {message: msg});
});

app.listen(3000, () => console.log('app listening on port 3000!'))

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Page Title</title>
</head>
<body>
    <h1>Landing page</h1>
    <!-- コードから渡されたデータを表示-->
    <p><%= message %></p>
</body>
</html>

ここまででテキストファイルの読み込み出力が完了です。あとは、温度センサ値を取得して、それをテキストファイルに書き出せればOKです。

温度センサ値の取得

I2C制御の準備

温度センサに利用するADT7410はI2Cモジュールのため、ラズパイのI2C制御の準備をします。

インターフェースの有効化
$ sudo raspi-config 

以下で有効化
5 Interfacing Options > P5 I2C > はい

パッケージのインストール
$ sudo apt-get update
$ sudo apt-get install i2c-tools python-smbus 
有効化の確認
$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

以上で準備は完了です。
以下に、温度センサを使った回路図とソースコードを示します。

回路図

f:id:yuji-tanaak:20190811082412p:plain

ソースコード

# -*- coding: utf-8 -*-
import smbus
from time import sleep

def read_adt7410():
    word_data =  bus.read_word_data(address_adt7410, register_adt7410)
    data = (word_data & 0xff00)>>8 | (word_data & 0xff)<<8
    data = data>>3 # 13ビットデータ
    if data & 0x1000 == 0:  # 温度が正または0の場合
        temperature = data*0.0625
    else: # 温度が負の場合、 絶対値を取ってからマイナスをかける
        temperature = ( (~data&0x1fff) + 1)*-0.0625
    return temperature

bus = smbus.SMBus(1)
address_adt7410 = 0x48
register_adt7410 = 0x00

inputValue = read_adt7410()
inputValue = int(inputValue)
print(inputValue)

# write file
path = 'temperature_log/latest.txt'
with open(path,mode='w') as f:
    f.write(str(inputValue))

温度センサ制御部分の処理は「Raspberry Piで学ぶ電子工作」のサンプルコード07-01-temp.pyをベースにしています。

おわりに

サーバー側の実装、Node.js周りの知識が皆無でやりたいことの実現方法がわからず、四苦八苦しました。上記の実装でようやくできました。テキストファイルではなく、拡張性を考えるとjson形式のファイルにしたほうが良いのかもしれません。あとは任意ファイルの読み込みについてもうちょっとスマートな方法があるような気がします。ご存知の方コメントいただけると嬉しいです。