安価な温度測定ツール

=温度測定ツールに必要な要件= 建屋内の機器の配置と空調運転の最適化を目的とした温度測定のツールには、以下のような要件が必要です.


 * 安価
 * 室内でも場所によって温度が異なります. サーバやフリーザの背面などは、前面とくらべて10℃前後も違うことがあります.
 * 省エネ対策を検討するためには、室内の温度分布を詳細に把握することが必要です.
 * 多箇所の温度測定を行うため、1点当たりの価格が安いことが重要です.


 * 自動記録
 * 温度は時間経過とともに変化します. 24時間の中でも変化しますし、曜日による変化、季節による変化もあります.
 * 時間経過による変化を把握することも重要です.
 * 温度計を目で見て紙に記録する運用方法では、手間がかかって継続できません.
 * データの加工や解析のために、データが電子的に記録されることも必要です.


 * オンライン・リアルタイム
 * 温度を測定をする場所と、そのデータを見たい場所は同じとは限りません.
 * 現時点のデータがすぐに見えることは、改善に対する意識付けに重要です.

=どんな温度測定ツールがあるの?=
 * 残念ながら、上記の要件をすべてみたすようなツールは見当たりませんでした.
 * 国内で販売しているオンライン温度モニター・ロガーは、1点当たり2万円程度します.
 * お金を出せば、立派な温度管理用システムを作ってくれる業者はあるでしょう.
 * お金をあまり使わずに、頭を(手も少し)使って工夫してみましょう.
 * 遺伝研・DDBJでは以下のツールを使ってみました.
 * ボタン電池型の超小型温度データロガー 「サーモクロン」 http://www.kn-labs.com/thermochron.htm
 * 温度測定記録装置 1個あたり2,700円(税別)と安価です. 他に、データ読み取り用の専用USBケーブル(税別22,500円)が必要ですが、これは1本あればOKです.
 * 付属ソフトは日本語対応しており、品質も良く、安心して使えます.
 * 欠点としては、オンライン・リアルタイム性がありません. データロガーを測定したい場所に配置し、一定期間後に回収してデータを読み取る運用になります.
 * 蛸足配線型の超安価なオンライン温度センサー 「TEMPerLAN」 http://www.pcsensor.com/index.php?_a=viewProd&productId=11
 * 親機1個に温度センサーが12個ついて$200以下と超安価です. 現在(2011年6月)の為替レートなら、送料や手数料を入れても2万円前後で購入できます.
 * 親機とセンサーの間は、ケーブルで接続します. 接続ケーブルは最大100mまで延長可能です.
 * 親機はTCP/IPでネットワークに接続します. ネットワークセキュリティポリシーが許せば地球の裏側の温度もリアルタイムに測定することができるでしょう.
 * WEBページの記述では、親機に温度データ記録メモリがあるような記述がありますが( http://www.pcsensor.com/index.php?_a=viewProd&productId=11 の5-i)を参照)、具体的な使用方法は不明です. 付属ソフトでは親機の温度データ記録機能は使っていないようです.
 * 付属ソフトには収集したデータをファイルに記録する機能が見当たりませんので、データを加工して利用することができません.
 * 付属ソフトはは日本語対応していないだけでなく、マニュアルも一切なく、さらに悪いことにバグだらけです. サポート窓口にE-mailで問い合わせてもなしのつぶてです. 正直言って失敗したと思いました.
 * 自作のTEMPerLAN用オンラインデータ収集ソフト
 * しかたがないので、TEMPerLAN付属ソフトの通信パケットを解析して(→)、親機からオンラインでデータ収集する簡単なソフトを作成しました. (→)
 * サーバ上でこのソフトを動作させて、測定データをファイルに記録することができます. ご自由にお使いください. Free of charge, but No Guaranteeです.
 * まだ、温度測定データを読み取る部分だけなので、初期設定作業は、使い勝手の悪い付属ソフトで行う必要があります. 最低限、親機のIPアドレスを設定する必要があります.
 * ドキュメントがまだありませんので、その点では付属ソフトと対して違わないかもしれません. 遺伝研内の方には、高木研(内線3404/3405)でサポートします.

=結局どうしてるの?=
 * 上記二つのツールを以下のように使い分けています.
 * 初めての場所やスポットの測定の場合には、ボタン電池型の温度ロガーを使います.
 * 電池内蔵で、ケーブルもなく、小さいので設置場所の制約が少ないです.
 * とりあえずあちこちにおいて測定してみて、測定すべきスポットを探し出したりします.
 * 連続して長期間測定することになれば、蛸足配線型のオンライン温度センサーと自作したソフトを使います.

=自作ソフト for TEMPerLAN= TEMPerLAN用の自作ソフトウェアです. 行数も少ないので、直接ソースコードを張り付けておきます. エラー処理がほとんどないので、サンプルコード程度とご理解ください.

温度測定データ取得ソフト
と があります. 機能はほとんど同じですが、出力形式が異なります. 使いやすいほうをお使いください. また、ご自分の好みと必要性にあわせて、ご自由に機能追加・改良してください.

Perl バージョン
use Socket;				# Socketモジュールを使用

$ipadrs="xxx.xxx.xxx.xxx";		# TEMPerLANのIPアドレス $port=5200;				# TEMPerLANのポートアドレス(キャプチャ結果から)

$rate=0.0625;				# TEMPerLANの温度変換係数

$cmd1=pack("H*","BB83");               # センサー数の要求コマンド $cmd2=pack("H*","BB80");               # センサーIDの要求コマンド $cmd3=pack("H*","BB82");               # 測定データの要求コマンド


 * 1) 温度を取得し、標準出力にタイプします.
 * 2) メッセージは標準エラー出力にタイプします.
 * 3) 適当にリダイレクトすれば、なんとか使えるでしょう.
 * 4) 外部でcronで回してください.
 * 5) エラー処理は入っていません. エラーが発生したら、その場で死にます.
 * 6) TEMPerLANの設定処理もありません. 付属のソフトで設定してください.
 * 7) TEMPerLANのIPアドレス($ipadrs)はプログラム内で固定的に記述しています.

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; printf STDERR ("%04d/%02d/%02d %02d:%02d:%02d start\n", $year+1900,$mon+1,$mday,$hour,$min,$sec);

socket(SOCKET, PF_INET, SOCK_STREAM, 0) || die;          #socket通信をTCP/IPプロトコルでするよ

connect(SOCKET, pack_sockaddr_in($port,inet_aton($ipadrs))) || die;	#接続

print STDERR "conneted to TEMPerLAN $ipadrs\n";


 * 1) センサー数を取得する

$res="";                                # レスポンスを入れる変数の初期化 send(SOCKET,$cmd1,0);                   # 送信 recv(SOCKET,$res,500,0) ; $res=unpack("H*",$res);                 # asciiに変換


 * 1) print STDERR "*DEBUG* Receive Packet(Number)=$res\n";

$num10 = hex(substr($res,4,2)); print STDERR "Number of Sensor(s)=$num10\n";


 * 1) センサーIDを取得する

$res="";                                # レスポンスを入れる変数の初期化 send(SOCKET,$cmd2,0);                   # 送信 recv(SOCKET,$res,500,0); $res=unpack("H*",$res);                 # asciiに変換


 * 1) print STDERR "*DEBUG* Received Packet(IDs)=$res\n";

print STDERR "Sensor ID= "; $i=0;					 # センサーの数だけ、IDを16進で表示する $j=6; while ( $i < $num10 ) { $id = substr($res,$j,16); print STDERR "$id "; $i++; $j=$j+16; } print STDERR "\n";


 * 1) 温度測定データを取得する

$res="";                        # レスポンスを入れる変数の初期化 send(SOCKET,$cmd3,0);           # 送信 recv(SOCKET,$res,500,0); $res=unpack("H*",$res);         # asciiに変換 # print STDOUT "*DEBUG* Received Packet(TEMPs)=$res\n"; ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; printf STDOUT ("%04d/%02d/%02d %02d:%02d:%02d\t", $year+1900,$mon+1,$mday,$hour,$min,$sec);

$i=0;				 # センサーの数だけ、温度(℃)を表示する $j=6; while ( $i < $num10 ) { $temp10 = hex(substr($res,$j,4));		# 10進数に変換

# print STDOUT "*DEBUG* $temp10 ";

if ($temp10 > 32767) {			# 負数の場合の処理(2の補数をとる) $temp10= $temp10 - 65536; }	      $temp = $temp10 * $rate;			# 係数=0.0625を掛け算して温度(℃)に printf STDOUT ("%+.1f\t",$temp);         # 小数点以下第1位まで表示 $i++; $j=$j+4; }	print STDOUT "\n";

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; printf STDERR ("%04d/%02d/%02d %02d:%02d:%02d stop\n\n", $year+1900,$mon+1,$mday,$hour,$min,$sec);

close(SOCKET); exit(0);


 * 標準出力に、日付時刻と、温度データをタブで区切って1行で出力します.
 * 温度データは小数点以下第1位まで表示します. センサー自体の精度は0.5℃です.
 * 標準エラー出力に、動作ログを出力します.
 * センサーを追加したり、接続を変更した際の、センサーIDと測定データの対応は、標準出力と標準エラー出力の結果を対比しないとわかりません.
 * センサー配置が固定的な場合は問題にならないと思いますが、試行錯誤している場合はちょっと不便かもしれません.
 * cronで定期的に起動し、標準出力をファイルに追加モードでリダイレクトすると、EXCELに読み込んで容易に加工できます.

Hiryamad 17:40, 10 June 2011 (JST)

Ruby バージョン
require "socket" require 'pp'

TEMPERLAN_IP = "xxx.xxx.xxx.xxx" TEMPERLAN_PORT = 5200 TEMPERLAN_PARAM = 0.0625 CMD1 = ["BB83"].pack("H*")		# センサー数の要求コマンド CMD2 = ["BB80"].pack("H*")		# センサーIDの要求コマンド CMD3 = ["BB82"].pack("H*")		# 測定データの要求コマンド

sock = TCPSocket.open(TEMPERLAN_IP, TEMPERLAN_PORT) begin sock.write(CMD1) sensor_num = sock.recv(500).unpack("H*")[0][4,2].hex sock.write(CMD2) sensor_ids = sock.recv(500).unpack("H*")[0][6..-3].scan(/.{16}/) time = Time.now sock.write(CMD3) sock.recv(500).unpack("H*")[0][6..-3].scan(/.{4}/).each_with_index { |temp_b,i| temp = ("8000" > temp_b) ? temp_b.hex*TEMPERLAN_PARAM : (temp_b.hex-"10000".hex)*TEMPERLAN_PARAM puts [time.strftime("%Y-%m-%d %H:%M:%S"),sensor_ids[i],temp].join("\t") } ensure sock.close end
 * 1)  puts "Number of Sensor(s)=#{sensor_num}"


 * 標準出力に、日付時刻と、センサーIDと温度データをタブで区切って出力します.
 * 1回のデータ収集で、センサー個数分の行数が標準出力に出力されます.
 * センサーを追加したり、接続順を変更した際にも、センサーIDと測定値の対応が明確です.

Kouwatan 17:41, 10 June 2011 (JST)

設定確認ソフト(Perl)

 * TEMPerLANの設定情報を確認するPerlのソフトです.
 * TEMPerLANのIPアドレスが分かっていれば、設定情報とセンサーIDが取得できます.
 * IPアドレスが分からなければどうしようもありません. TEMPerLANの工場出荷時のデフォルトアドレスは、192.168.1.188です.

use Socket;				# Socketモジュールを使用 $port=5200;				# TEMPerLANのポートアドレス(キャプチャ結果から)

$cmd1="call pcsensor!"; $cmd2="display configs!"; $cmd3="bye pcsensor!"; $cmd4=pack("H*","BB83");               # センサー数の要求コマンド $cmd5=pack("H*","BB80");               # センサーIDの要求コマンド

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; print STDERR sprintf("%04d/%02d/%02d %02d:%02d:%02d start\n", $year+1900,$mon+1,$mday,$hour,$min,$sec);

print "This program displays TEMPerLAN configurations\n";

$TEMPerLAN_IP = $ARGV[0];

if ($TEMPerLAN_IP eq "") { print "Please input current TEMPerLAN IP-address (default 192.168.1.188) = "; $TEMPerLAN_IP = ; if ($TEMPerLAN_IP eq "") { $TEMPerLAN_IP = "192.168.1.188"; } }


 * 1) SOCKETでTEMPerLANと接続

socket(SOCKET, PF_INET, SOCK_STREAM, 0); $rc = connect(SOCKET, pack_sockaddr_in($port,inet_aton($TEMPerLAN_IP)));

if($rc)	{ # ここで、接続先が本当にTEMPerLANかどうか確認する処理が必要だが、作りこんでいない print STDERR "connected to TEMPerLAN $TEMPerLAN_IP\n"; } else	{ ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; printf STDERR ("%04d/%02d/%02d %02d:%02d:%02d ", $year+1900,$mon+1,$mday,$hour,$min,$sec); print STDERR "Can't connect to TEMPerLAN $TEMPerLAN_IP\n"; exit(1); }

print "\n";


 * 1) TEMPerLANの設定を確認する

$res="";                               # レスポンスを入れる変数の初期化 send(SOCKET,$cmd1,0); print STDERR "-> $cmd1\n"; recv(SOCKET,$res,500,0) ; print $res;

$res="";                               # レスポンスを入れる変数の初期化 send(SOCKET,$cmd2,0); print STDERR "-> $cmd2\n"; recv(SOCKET,$res,500,0) ; print $res;

$res="";                               # レスポンスを入れる変数の初期化 send(SOCKET,$cmd3,0); print STDERR "-> $cmd3\n"; recv(SOCKET,$res,500,0) ; print $res;

print "\n";


 * 1) センサー数を取得する

$res="";                               # レスポンスを入れる変数の初期化 send(SOCKET,$cmd4,0); recv(SOCKET,$res,500,0) ; $res=unpack("H*",$res);                # asciiに変換

$num = hex(substr($res,4,2)); print "Number of Sensor(s)=$num\n";


 * 1) センサーIDを取得する

$res="";                               # レスポンスを入れる変数の初期化 send(SOCKET,$cmd5,0); recv(SOCKET,$res,500,0); $res=unpack("H*",$res);                # asciiに変換

$i=0; $j=6; while ( $i < $num ) { $id = substr($res,$j,16); $i++; $j=$j+16; print "$id\n"; }

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime; printf STDERR ("%04d/%02d/%02d %02d:%02d:%02d stop\n", $year+1900,$mon+1,$mday,$hour,$min,$sec);

close(SOCKET); exit(0);

Hiryamad 18:44, 14 June 2011 (JST)

IPアドレス設定ソフト(Python)

 * TEMPerLANのIPアドレスとnetmaskとgatewayアドレスを設定するPythonのソフトです. 勉強のため別の言語で作ってみました.
 * TEMPerLANの現在の(古い)IPアドレスが分かっていれば、新しいIPアドレスを設定できます.
 * IPアドレスが分からなければどうしようもありません. TEMPerLANの工場出荷時のデフォルトアドレスは、192.168.1.188です.
 * このソフトを使って設定する前に、 で現在の設定情報を確認し、メモしておいてください.


 * 1) -*- coding: utf-8 -*-

import sys			# import socket			# ソケットを使う import binascii			# バイナリ<-->文字列変換処理 import time			# import datetime			# 日付時刻処理

TEMPerLAN_PORT=5200

cmd1="call pcsensor!" cmd2="display configs!" cmd3="bye pcsensor!"

cmd6="set device ipaddress:" cmd7="set device gateway:" cmd8="save configs!" cmd9="device reset!" cmd10="set device netmask:"

DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "start\n"

print "This program setup TEMPerLAN configurations"

argvs = sys.argv argnum = len(argvs)

if ( argnum >= 2 ) : TEMPerLAN_IP = argvs[1] else : TEMPerLAN_IP = raw_input("Please input current TEMPerLAN IP-address (default 192.168.1.188) = ") if TEMPerLAN_IP == "" : TEMPerLAN_IP = "192.168.1.188"

NEW_TEMPerLAN_IP = raw_input("Please input NEW TEMPerLAN IP-address (current " + TEMPerLAN_IP + ") = ") if NEW_TEMPerLAN_IP == "" : NEW_TEMPerLAN_IP = TEMPerLAN_IP

NEW_TEMPerLAN_GW = raw_input("Please input NEW TEMPerLAN GateWay-address = ")

NEW_TEMPerLAN_MASK = raw_input("Please input NEW TEMPerLAN NetMask = ")


 * 1) ソケットでTCP接続する

print "\n" print "current TEMPer_LAN IP-address =" + TEMPerLAN_IP print "NEW TEMPer_LAN IP-address =" + NEW_TEMPerLAN_IP print "NEW TEMPer_LAN GateWay IP-address =" + NEW_TEMPerLAN_GW print "NEW TEMPer_LAN NetMask =" + NEW_TEMPerLAN_MASK

RECONFIRM = raw_input("You are going to change TEMPerLAN (" + TEMPerLAN_IP + ") configs, sure? [yes/No] ")

if ( RECONFIRM.lower != "y" and RECONFIRM.lower != "yes") : DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "stopped without change!\n" sys.exit(1)

try : sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except : print "socket接続できません" DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "abort\n" sys.exit(1)

try : sock.connect((TEMPerLAN_IP, TEMPerLAN_PORT)) except : print "TEMPerLANに接続できません. 現在のIPアドレスが間違っている可能性があります" DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "abort\n" sock.close sys.exit(1)


 * 1) TEMPerLANと通信する

rcvmsg = "" sock.send(cmd1)			# configモードに入る rcvmsg = sock.recv(500) print rcvmsg

if ( NEW_TEMPerLAN_IP != TEMPerLAN_IP ) : rcvmsg = "" sock.send(cmd6 + NEW_TEMPerLAN_IP)	# ipアドレス設定 rcvmsg = sock.recv(500) print rcvmsg

if ( NEW_TEMPerLAN_GW != "" ) : rcvmsg = "" sock.send(cmd7 + NEW_TEMPerLAN_GW)	# GWアドレス設定 rcvmsg = sock.recv(500) print rcvmsg

if ( NEW_TEMPerLAN_MASK != "" ) : rcvmsg = "" sock.send(cmd10 + NEW_TEMPerLAN_MASK)	# GWアドレス設定 rcvmsg = sock.recv(500) print rcvmsg

if ( NEW_TEMPerLAN_IP != TEMPerLAN_IP ) or ( NEW_TEMPerLAN_GW != "" ) or ( NEW_TEMPerLAN_MASK != "") : rcvmsg = "" sock.send(cmd8)			# 設定情報を保存する rcvmsg = sock.recv(500) print rcvmsg			# 保存された設定情報が通知される

i = 1 while (i<5) : sock.send(cmd9)		# TEMPerLANをリセット(4回繰り返し) time.sleep(0.1) i += 1 else :					# 設定を変更しない場合は、設定情報の表示だけ行う rcvmsg = "" sock.send(cmd2) rcvmsg = sock.recv(500) print rcvmsg

rcvmsg = "" sock.send(cmd3)			# configモードを終了する rcvmsg = sock.recv(500) print rcvmsg

sock.close sys.exit(0)


 * 実行すると、host ipaddress や host port という項目が表示されますが、付属のソフトを使わずにこのサイトで公開している自作ソフトを使う場合には、このアドレスが違っていても問題ありません.

Hiryamad 13:58, 20 June 2011 (JST)

リセットソフト(Python)

 * 設定フソトのうちから、リセットする部分だけを切り出したソフトです.
 * 温度センサーを追加したり変更した時は、TEMPerLANのリセットが必要になります. これまでは電源ケーブルを抜き/差しすることでリセットしていましたが、このソフトを使うことにより遠隔からリセットできるようになります.
 * TEMPerLANのIPアドレスが必要です.


 * 1) -*- coding: utf-8 -*-

import sys			# import socket			# ソケットを使う import binascii			# バイナリ<-->文字列変換処理 import time			# import datetime			# 日付時刻処理

TEMPerLAN_PORT=5200

cmd1="call pcsensor!" cmd9="device reset!"

DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "start\n"

argvs = sys.argv argnum = len(argvs)

if ( argnum >= 2 ) : TEMPerLAN_IP = argvs[1] else : TEMPerLAN_IP = raw_input("Please input current TEMPerLAN IP-address (default 192.168.1.188) = ") if TEMPerLAN_IP == "" : TEMPerLAN_IP = "192.168.1.188"

RECONFIRM = raw_input("You are going to RESET TEMPerLAN (" + TEMPerLAN_IP + "), sure? [yes/No] ")

if ( RECONFIRM.lower != "y" and RECONFIRM.lower != "yes") : DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "stop\n" sys.exit(1)


 * 1) ソケットでTCP接続する

try : sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except : print "socket接続できません" DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "abort\n" sys.exit(1)

try : sock.connect((TEMPerLAN_IP, TEMPerLAN_PORT)) except : print "TEMPerLANに接続できません. IPアドレスが間違っている可能性があります" DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "abort\n" sock.close sys.exit(1)


 * 1) TEMPerLANと通信する

rcvmsg = "" sock.send(cmd1)			# configモードに入る rcvmsg = sock.recv(500) print rcvmsg

i = 1 while (i<5) : sock.send(cmd9)		# TEMPerLANをリセット(4回繰り返し) time.sleep(0.1) i += 1

DATE_TIME = datetime.datetime.today print DATE_TIME.strftime("%Y/%m/%d %H:%M:%S"), "reset!\n"

sock.close sys.exit(0) Hiryamad 16:18, 20 June 2011 (JST)

=ドキュメント=

TEMPerLANの初期設定手順
ipaddress:192.168.1.188 netmask:255.255.255.0 default gateway:192.168.1.1
 * TEMPerLANの工場出荷時の設定は以下のとおりです.

(例) ipaddress:192.168.1.100 netmask:255.255.255.0 default gateway:192.168.1.1
 * あなたのPC(サーバでもいいですが)のネットワーク設定を、上記のTEMPerLANと同じネットワークセグメントのアドレスに変更し、LANケーブルで直接接続します.


 * を使って、TEMPerLANの設定を確認します.
 * コンソール画面に表示される設定情報を、メモソフトなどにコピー&ペーストして保存(紙に印刷もしておくとよいかも)しておきましょう.


 * この状態で、温度センサーを1点ずつ接続して、センサーIDを記録しておきましょう.
 * 温度センサーを追加・変更すると、TEMPerLAN親機のリセットが必要になります.  が便利です.
 * 温度センサーにIDのタグを付けておくことをおすすめします.
 * あとからいつでもできますが、最初にやっておいたほうが楽です.


 * を使って、新しいネットワークアドレスを設定します.
 * 別のサブネットのアドレスに変更した場合、設定が完了すると通信ができなくなりますが、それは正しい現象です.


 * あなたのPCのネットワーク設定をもとに戻します.
 * TEMPerLANを正しくネットワークに接続します.
 * 温度センサーを測定箇所に設置します. センサーのIDと設置場所を記録しておきましょう.
 * TEMPerLAN親機をリセットしてセンサーを正しく親機に認識させてください.  が便利です.


 * を使って、温度測定を行います.

温度センサー設置上の留意点

 * TEMPerLANのケーブルコネクタの工作精度があまりよくありません. うまく測定できないときは、ケーブルを交換してみましょう. カチッと嵌らない場合はうまくいかないことが多いようです.


 * TEMPerLANの温度センサーはケーブルでタコ足配線されますが、ケーブルの配線状況によってはノイズを拾って正しく温度データを伝えられないことがあります. 経験したトラブルの例は以下のとおりです.
 * 信号ケーブルの余長部分をループ状にぐるぐる巻きにしていたら、正しい温度データが測定できなかった. ループ状態をほどいたら解消した.
 * 信号ケーブルを、大電流(数百ワット)が流れている電源ケーブルと並べて配線したら、正しい温度データが測定できなかった. 信号ケーブルと電源ケーブルが並ばないようにし、近くを通る場合も直交するように配線しなおしたら解消した.

パケット解析メモ
TEMPerLANと付属ソフトの通信パケットの解析メモです.

TEMPerLAN → PC 測定データパケット
 * TEMPerLAN → PC 測定データパケット

14 50 06 CD B8 8E AF 28 98 21 53 C1 50 18 02 00 12 9C 00 00 BB 82 04 01 4D 01 7F 01 56 01 48 FF

addr data                        value 0000 14 50          送信元ポート  5200 0002 06 CD          宛て先ポート  1741 0004 B8 8E AF 28    送信seq 0008 98 21 53 C1    受信seq 000C 50             ヘッダ長        20バイト(5×4) 000D 18             コードビット 000E 02 00          ウィンドウ     512 0010 12 9C          チェックサム 0012 00 00          緊急ポインタ

ここまでTCPヘッダ部 以下、データ部

0014 BB             不明(データ部の最初を示すコード?) 0015 82             不明(データ種別を示すコード?) → データ通知コードらしい 0016 04             データ数? 4 0017 01 4D          測定値(1)       334 →334*0.0625=20.875 0019 01 7F          測定値(2)       383 →383*0.0625=23.9375 001B 01 56          測定値(3)       342 →342*0.0625=21.375 001D 01 48          測定値(4)       329 →329*0.0625=20.5625 001F FF             不明(データ部の最後を示すコード?)

※ 測定値を2バイト整数として0.0625を掛け算した値が、温度(℃)となる. PC側の付属ソフトでは、小数点以下3桁目を四捨五入して、小数点第二位まで 表示している. センサーの測定範囲はマイナスまで可能なので、(推測だが)2バイトの符号付き 整数として計算すればいいのではないか.

センサーのドキュメントの日本語訳があった. http://www.ne.jp/asahi/shared/o-family/ElecRoom/AVRMCOM/DS18B20/DS18B20manual.html

それによると、上記の推測が正しいことがわかる. 以下、上記ページからの抜粋.

> ・温度センサーの分解能は、0.5℃、0.25℃、0.125℃、0.0625℃の増分に対応して、9、10、11、12ビットにユーザーが選択できます. > ・電源投入時のデフォルト分解能は、12ビットです. > ・DS18B20の温度データ出力は、摂氏度で正確に測定されます. > ・温度データは、温度レジスターに、符号付16ビットに拡張された2の補数で格納されます. （図2を参照） > ・符号ビット(S)は、温度が(＋)か(－)かを示します. S = 0 (＋) および S = 1 (－) > ・もしDS18B20が12ビット分解能に設定されるならば、温度レジスターのすべてのビットが有効なデータです.

※ データ測定値の順序が不明. 上記例では逆順になっているが、必ずしも逆順とは限らないみたい. →PC側のTEMPerLANソフトを起動した時に、装置側と通信をして、センサーのIDを取得しているが、その時の順番 になっているらしい.


 * TEMPerLAN → PC デバイス通知パケット

TEMPerLAN → PC デバイス通知パケット

14 50 07 95 B8 8F 80 46 3C 91 DB 04 50 18 02 00 A7 F4 00 00 BB 01 30 28 EA 28 1B 03 00 00 76 28 A6 2B 1B 03 00 00 30 28 E6 19 1B 03 00 00 42 28 81 09 1B 03 00 00 78 28 31 ED 1A 03 00 00 35 28 2D 02 1B 03 00 00 29 FF

addr data                        value 0000 14 50          送信元ポート  5200 0002 07 95          宛て先ポート  1941 0004 B8 8F 80 46    送信seq 0008 3C 91 DB 04    受信seq 000C 50             ヘッダ長        20バイト(5×4) 000D 18             コードビット 000E 02 00          ウィンドウ     512 0010 12 9C          チェックサム 0012 00 00          緊急ポインタ

0014 BB             不明(データ部の最初を示すコード?) 0015 01             不明(データ種別を示すコード?) → センサーID通知を示すらしい 0016 30             不明(センサーIDのバイト長?) 0017 28 EA 28 1B 03 00 00 76  センサーID(1) → センサー当たり8バイト固定長 001F 28 A6 2B 1B 03 00 00 30  センサーID(2) (以下同様) 003f 28 2D 02 1B 03 00 00 29  センサーID(6) 0047 FF             不明(データ部の最後を示すコード?)


 * PC側ソフト起動時のフロー

PC側ソフト起動時のフロー

PC     TEMPerLAN   データ

SYN → ← ACK ACK →

ACK →              BB 83  →接続センサー数の要求 ← ACK          BB 83 06 00 00 00 00 00 00 FF  →接続センサー数=6 ACK →

ACK →              BB 80  →センサーIDの要求 ← ACK          BB 01 30 (sensorID(8byte) × n) FF →センサーIDの通知 →3バイト目(0x30)はセンサーIDの合計長(8×6)

ACK →              BB 82  →測定データの要求 → ACK          BB 82 06 0209 01F5 0216 01F1 0208 01FF FF →温度データ →3バイト目の0x06は温度データ数 ACK →              BB 82 → ACK          BB 82 06 0209 01F5 0216 01F1 0208 01FF FF →温度データ ACK → →なぜか最初だけはデータ取得を2回連続で実行している エラー確認のため?

ACK →              BB 82 → ACK          BB 82 06 0208 01F6 0216 01F1 0208 01FF FF →温度データ ACK →

(以下、測定データの要求/通知/ACKの繰り返し)

※ PC側ポート番号は、最初にSYNを投げる時に決まる? ※ TEMPerLAN側ポート番号は、5200固定?


 * display / configを実行した時のフロー

display configを実行した時のフロー

PC    TEMPERLAN     data

ACK →              call pcsensor! ← ACK          enter config state.(CRLF) ACK →              display configs! ← ACK          device ipaddress:xxx.xxx.xxx.xxx(CRLF)～(CRLF) ACK →              bye pcsensor! ← ACK          exit config state.(CRLF) ACK → ACK →

※ PC側のポート番号は、測定データを読み取る時とは異なる ※ データ種別コード(BBxx)はつかない


 * ip-address / netmask / gw-addressを設定する際のフロー

ip-addressを設定する際のフロー

PC    TEMPERLAN     data

ACK →              call pcsensor! ← ACK          enter config state.(CRLF) ACK →              set device netmask:xxx.xxx.xxx.xxx ← ACK          device netmask XXX.XXX.XXX.XXX (CRLF)config ok!(CRLF) ACK →              save configs! ← ACK          device ipaddress:xxx.xxx.xxx.xxx(CRLF)～(CRLF) ACK →              device reset! ACK →              device reset! ACK →              device reset! ACK →              device reset!

netmaskを設定する際のフロー

PC    TEMPERLAN     data

ACK →              call pcsensor! ← ACK          enter config state.(CRLF) ACK →              set device ipaddress:xxx.xxx.xxx.xxx ← ACK          ipaddress XXX.XXX.XXX.XXX (CRLF)config ok!(CRLF) ACK →              save configs! ← ACK          device ipaddress:xxx.xxx.xxx.xxx(CRLF)～(CRLF) ACK →              device reset! ACK →              device reset! ACK →              device reset! ACK →              device reset!

gateway addressを設定する際のフロー

PC    TEMPERLAN     data

ACK →              call pcsensor! ← ACK          enter config state.(CRLF) ACK →              set device gateway:xxx.xxx.xxx.xxx ← ACK          device gateway XXX.XXX.XXX.XXX (CRLF)config ok!(CRLF) ACK →              save configs! ← ACK          device ipaddress:xxx.xxx.xxx.xxx(CRLF)～(CRLF) ACK →              device reset! ACK →              device reset! ACK →              device reset! ACK →              device reset!

※ PC側のポート番号は、測定データを読み取る時とは異なる ※ データ種別コード(BBxx)はつかない


 * データ部の種別コード(BBxx 部分)の意味(推測)

データ部の種別コード(BBxx 部分)の意味(推測)

BB80 センサーIDの要求 BB81 ? BB82 測定データの要求/測定データ(2バイト符号付き整数*0.0625)×nの通知 BB83 センサー数の要求/センサー数(1バイト整数)とキャリブレーション値(1バイト符号付き整数*0.0625)×nの通知? BB84 キャリブレーションの設定/応答(4ビットb"1001" × n)? ※BB84でキャリブレーション値を指定せずにPCからコマンドを発行すると、なにかの値(不定値?)をキャリブレーション値として設定するらしい

BB01 データ長(1バイト整数)とセンサーID(8バイト×n)の通知

Hiryamad 09:19, 13 June 2011 (JST)

=「おんどとり TR-71W」を使ってみた= 蛸足配線型温度センサーやボタン電池型温度ロガーよりも測定点あたりの価格は高価ですが、定番商品らしいので試してみました. http://www.tandd.co.jp/product/

製品概要

 * TR-71Wは「おんどとり」シリーズのなかでも、ネットワークに直接接続できるタイプの製品です.
 * 温度測定センサー2chがついて、メーカ希望小売価格が39,800円(税別). 蛸足配線型温度センサー(センサー12点で200$以下)やボタン電池型温度ロガー(USB読取器とロガー5点のセットで34,000円(税別))に比べればやはりちょっと高価です.
 * オンラインでネットワークにつながり、この製品だけでリアルタイムの温度測定監視と、温度データ記録ができるようです.
 * また、カタログでは複数台の「おんどとり TR-71W」のデータをいっしょのWEB画面で確認できるらしいので、今回は3台購入しました.

よかった点

 * 本体に液晶画面がついていて、本体だけでもその場で温度が確認できます.
 * ネットワークとWEBブラウザがあればそれだけで、異なる場所からでもリアルタイム温度監視と、記録データのダウンロードができます. (初期設定には添付のソフトが必要です)
 * 初期設定ソフトは日本語対応しており、品質も良さそうです.

ちょっと残念だった点

 * InternerExplorer(とSleipnir)以外のブラウザでは、現在値のリアルタイム表示ができません. グラフ表示はIE以外のブラウザでも可能です.
 * 複数台の一括表示は、現在値表示機能にしかありません.
 * 複数台の測定データをひとつのグラフにする場合は、データをダウンロードしてから添付の専用ソフトで表示する方法になります.
 * ダウンロードしたデータは専用形式になっており、添付の専用ソフトでしか読み込むことができません. 専用ソフトで読み込んだあとは、CSV形式などで保存できます.

(はやすぎるかもしれない)結論

 * とり急ぎ温度測定・監視が必要、という場合には使いやすいと思います.
 * 大規模な温度測定・監視やデータ分析・管理を行いたい場合には、アプリケーションソフトウェア開発が必要になるでしょう.
 * 測定データを加工するためのインターフェースは、専用ソフトから出力するCSV形式などしかありません.
 * 情報開示がされていないので、アプリケーションソフトウェアからオンラインでデータを取得しようとすると、ネットワーク通信内容の解析が必要になります.
 * アプリケーションソフトウェア開発を行うなら、安価な蛸足配線型センサー(TEMPerLAN)でもいいんじゃないかなと思います. (個人的感想です)


 * 「おんどとり」シリーズにはTR-71W以外にもさまざまな機種がありますので、それらを適切に選択し、使い分ければ、上記とは異なる結論が導かれる可能性が高いです.

Hiryamad 17:20, 12 August 2011 (JST)