ラズパイで、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のインストール手順は以下の記事を参照ください。