WebIOPiを使って 温湿センサーの状態をブラウザに表示

ラズパイで、WebIOPiを使ってGPIO端子を制御し、温湿センサー(DHT11)からデータを取得して、ブラウザに表示します。

今回のシステム構成は以下です。

ブラウザを通して、ラズパイのGPIO端子にアクセスすることが可能です。ここでは、GPIO端子を使って、温湿センサ(DHT11)を制御しています。

動作としては、JavaScriptのCallMacro関数からPytyonプログラム呼び出して実行します。

動作に必要なファイルとプログラムの中身は以下です。

Webブラウザ表示に必要なファイル

  • index.html
  • styles.css

index.htmlの中身

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<title>温度センサ(DHT11)による温度の取得</title>
<script src="js/require.js"></script>
<script>
require(["/webiopi.js", "javascript.js"], function(){
    webiopi().ready( initialize_webiopi );
});
</script>
</head>
<body>

<div align="center">
温度(℃): <input type="text" id="temp_text">
湿度(%): <input type="text" id="humi_text">
</div>

</body>
</html>

syles.cssの中身

#temp_text{
    width: 12em;
}
#humi_text{
    width: 12em;
}

DHT11から温度と湿度データを取得するのに必要なファイル

  • javascript.js
  • script.py

javascript.jsの中身

// millisミリ秒ごとに温度を取得する関数
function getTempPeriodic(millis){
    // responseに温度が格納されている
    var drawTemp = function(macro, args, response){
        var temp = response;
        $("#temp_text").val(temp);
    }

    // script.py内のgetTemp関数を実行。終了後にdrawTemp関数を呼ぶ
    webiopi().callMacro("getTemp", [], drawTemp);

    // millisミリ秒後に自分自身を呼び出す
    setTimeout(function(){ getTempPeriodic(millis); }, millis);
}

// millisミリ秒ごとに湿度を取得する関数
function getHumiPeriodic(millis){
    // responseに湿度が格納されている
    var drawHumi = function(macro, args, response){
        var humi = response;
        $("#humi_text").val(humi);
    }

    // script.py内のgetHumi関数を実行。終了後にdrawHumi関数を呼ぶ
    webiopi().callMacro("getHumi", [], drawHumi);

    // millisミリ秒後に自分自身を呼び出す
    setTimeout(function(){ getHumiPeriodic(millis); }, millis);
}

function initialize_webiopi(){
    // webiopiの準備が終わってからstyles.cssを適用する
    applyCustomCss('styles.css');
    // 2秒ごとに温度と湿度を取得して描画
    getTempPeriodic(2000);
    getHumiPeriodic(2000);

    // GPIOの状態を監視しない(自分で作成した関数で温度を定期的に取得するため)
    webiopi().refreshGPIO(false);
}

function applyCustomCss(custom_css){
    var head = document.getElementsByTagName('head')[0];
    var style = document.createElement('link');
    style.rel = "stylesheet";
    style.type = 'text/css';
    style.href = custom_css;
    head.appendChild(style);
}

script.pyの中身

# -*-  coding: utf-8 -*-
import webiopi
import time
import RPi.GPIO as GPIO
#import smbus

# デバッグ出力を有効に
webiopi.setDebug()

# グローバル変数(温度/湿度格納用)
rTHdata = []

# センサ(dht11)から温度を取得する関数
def read_dht11():
    THdata = []
    channel = 7
    data = []
    GPIO.setmode(GPIO.BOARD)
    time.sleep(2)
    GPIO.setup(channel, GPIO.OUT)
    GPIO.output(channel, GPIO.LOW)
    time.sleep(0.02)
    GPIO.output(channel, GPIO.HIGH)
    GPIO.setup(channel, GPIO.IN)
    while GPIO.input(channel) == GPIO.LOW:
        continue
    while GPIO.input(channel) == GPIO.HIGH:
        continue
    j = 0
    while j < 40:
        k = 0
        while GPIO.input(channel) == GPIO.LOW:
            continue
        while GPIO.input(channel) == GPIO.HIGH:
            k += 1
            if k > 100:
                break
        if k < 8:
            data.append(0)
        else:
            data.append(1)
        j += 1

    # print("sensor is working.")
    # print(data)
    humidity_bit = data[0:8]
    humidity_point_bit = data[8:16]
    temperature_bit = data[16:24]
    temperature_point_bit = data[24:32]
    check_bit = data[32:40]
    humidity = 0
    humidity_point = 0
    temperature = 0
    temperature_point = 0
    check = 0
    for i in range(8):
        humidity += humidity_bit[i] * 2 ** (7 - i)
        humidity_point += humidity_point_bit[i] * 2 ** (7 - i)
        temperature += temperature_bit[i] * 2 ** (7 - i)
        temperature_point += temperature_point_bit[i] * 2 ** (7 - i)
        check += check_bit[i] * 2 ** (7 - i)
    tmp = humidity + humidity_point + temperature + temperature_point
    if check == tmp: #チェックビットがOKになると再起関数を抜ける
        #print "temperature:%d.%d" %(temperature,temperature_point),"C"," humidity :", humidity, "%"
        #print("chksum_ok")
        THdata.append( temperature + float( temperature_point )/10 )
        THdata.append( humidity + float( humidity_point )/10 )
        return THdata 
    else: #チェックビットがOKになるまで再起関数として自分自身に戻る
        # print("chksum_ng")
        time.sleep(1)
        return read_dht11()

# WebIOPiの起動時に呼ばれる関数
def setup():
    webiopi.debug("Script with macros - Setup")

# WebIOPiが起動している間、繰り返し呼ばれる関数
def loop():
    global rTHdata
    rTHdata = read_dht11()
    webiopi.sleep(1)

# WebIOPi終了時に呼ばれる関数
def destroy():
    webiopi.debug("Script with macros - Destroy")

# 自作のマクロ。JavaScriptから呼ぶことができる
@webiopi.macro
def getTemp():
    return rTHdata[0]

@webiopi.macro
def getHumi():
    return rTHdata[1]

# 戻り値を表示(デバック用)
#while True:
#    rTHdata = read_dht11()
#    print "temparature:",rTHdata[0],"℃","humidity:",rTHdata[1],"%"

WebIOPiをつかうことで、各センサのデータをブラウザで確認することができます。ブラウザが使える端末(PC,携帯など)で表示することができるので、いろんな使い方に活用できると思います。

WebIOPiのインストール手順は以下の記事を参照ください。

WebIOPiのインストール手順

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA