カテゴリ
リンク

当サイトは、玄箱PRO (KURO-BOX/Pro)を中心とした組み込み、Linuxと電子工作を扱っています。
会社案内

情報セキュリティおよび個人情報の取り扱いについて


コメントとトラックバックは、spamを予防するために、編集担当が公開の作業をするまで非公開になっています。コメントはそれぞれ投稿した人のものです。

 前回の課題をもう一度確認すると、マイナス温度の測定(表示)を可能にすること、それと、マイナス温度も表示可能なグラフ化でした。
 今回はこの二つの改良をもって、温度計測の話が一段落することになります。

●マイナス温度の計測も可能なようにプログラムを改造する

 温度センサ(DS18S20)のディジタル値を以前の記事から再掲してみると、このようになっていました。

測定温度範囲 温度デジタル出力(バイナリ) 16進表示
+85.0 ℃ 0000 0000 1010 1010 00AAh
+25.0 ℃ 0000 0000 0011 0010 0032h
+0.5 ℃ 0000 0000 0000 0001 0001h
0 ℃ 0000 0000 0000 0000 0000h
-0.5 ℃ 1111 1111 1111 1111 FFFFh
-25.0 ℃ 1111 1111 1100 1110 FFCEh
-55.0 ℃ 1111 1111 1001 0010 FF92h

 上表において、マイナスの値であることを知る方法はいろいろとあるでしょうが、ここでは、赤色で示した値であればマイナスだとしましょう。
 正負の温度取得を可能にしたプログラムを次に示します。マイナス2度であれば、-2.0 のように表示されます。ダウンロード用として、program2.tarを用意しました。
/* DALLAS  DS18(S)20 と DS9097U-09 を使った温度計測
* マイナス側計算
* 2008-1-6 (k-wada)
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/fcntl.h>
#include <sys/termios.h>
#include <sys/ioctl.h>

#define SIO "/dev/ttyUSB0"
#define BAUD 9600

int FD232c;
char buff[32];
struct termios qtermios;

// Pullup 39
// Reset c1
// Skip rom cc
// Date mode e1
// Convert 44
// Read mem f0
// Data read ff
// Temp read be
// Arm Pullup ef
// Term pulse f1
char conv0[] = {9, 0x39, 0xc1, 0xe1, 0xcc, 0xe3, 0xef, 0xf1, 0xe1, 0x44};
char conv1[] = {5, 0xef, 0xe3, 0xed, 0xf1, 0xc1};
char get0[] = {15, 0xc1, 0xe1, 0xcc, 0xbe,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xe3, 0xc1};
char vb[] = {0x00};
char *q = vb;

trans(char *p) {
char byte;
byte = *p++;
while(byte--) {
usleep(50000);
write(FD232c, p++, 1);
}
}

dammyread() {
char c;
while(c = read(FD232c, buff, 1)) {
;
}
}

dataread() {
char c, data, datam, mflag=0;
float deg;
for(c = 0; c < 14; c++) {
read(FD232c, &data, 1);
switch(c) {
case 4:
deg = data;

datam = ~data;

break;
case 5:

if(data == 0xff) {
deg = -datam;
} else {
deg += 256 * data;
}

break;
}
}
deg *= 0.5 ;

fprintf(stdout, "%2.1f\n0\nTEMP\n-\n", deg);

}

int main() {
int r, c, loop;
if((r = open232c(SIO)) > 0) {
fprintf(stderr, "Can't Open.\n");
exit (1);
}
loop = 1;
while (loop--) {
trans(conv0); /* 変換開始シーケンス */
sleep(1); /* 変換時間待機 */
trans(conv1); /* 変換終了シーケンス */
dammyread(); /* 不要な受信をクリア */
trans(get0); /* 温度データ受信指示 */
dataread(); /* 温度データ取得 */
}
close(FD232c);
return 0;
}


int open232c(char* ttyname) {
struct termios tty;
int r;
int modemline;

if((FD232c = open(ttyname, O_RDWR|O_NDELAY|O_NONBLOCK, 0477)) >= 0) {
qtermios.c_iflag = IXOFF;
qtermios.c_lflag = (PENDIN|ECHOKE|ECHOE);
qtermios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8);
qtermios.c_ispeed = BAUD;
qtermios.c_ospeed = BAUD;
ioctl(FD232c, TIOCMGET, &modemline);
modemline = TIOCM_DTR | TIOCM_RTS;
ioctl(FD232c, TIOCMSET, &modemline);
tcsetattr (FD232c, TCSANOW, &qtermios);
return 0;
}
perror("Can't open SIO.\n");
return 1;
}
 上記のプログラムでの修正点は少なく、赤色で示したように温度データ部の2バイト目が "0xff"であれば、取得した1バイト目(実質的に意味のある温度値)を符号反転させています。

rrdtool のインストール
 さて、改造したプログラムを走らせて無事に正負の温度表示ができましたでしょうか?
 今度は、rrdtool という MRTG の改良版のインストールを行いますが、それは、

apt-get install rrdtool
となります。
 インストール後、ほかのソフトと連携させることも可能ですが、単純にコマンド(rrdtool + パラメータ)として利用しました。まとめると、記録準備、データ取得、グラフ作成、ブラウザでみる、という手順になります。

ステップ指示内容必要なもの
記録準備create開始時間、記録間隔、記録期間などのデータベース定義生成ファイル名(*.rrd)
データ取得update温度データを追加記録していく温度取得プログラムと cron 設定(5分間隔)
グラフ作成graphグラフ作成に必要なパラメータを指定生成用画像ファイル名
ブラウザでみるCGI自動更新や見やすさの工夫温度表示用画像ファイル名

 rrdtool についての解説にページを割けませんので http://cc.ii2.cc/~fors/sysworks/data/rrdtool/などに設定値の詳細が載っているので、参照してください。
 rrdtool のプログラムはコマンドとして実行させるわけですが、スクリプトとしてまとめたほうが何かと便利です。これらのサンプル例を四つ用意してみました。

記録準備のためのスクリプト(create.bsh)
#! /bin/sh

/usr/bin/rrdtool create ondo.rrd \
--step 300 \
DS:ondo:GAUGE:600:-10:50 \
RRA:AVERAGE:0.5:1:600 \
RRA:AVERAGE:0.5:6:700 \
RRA:AVERAGE:0.5:24:775 \
RRA:AVERAGE:0.5:288:797 \
RRA:MAX:0.5:1:600 \
RRA:MAX:0.5:6:700 \
RRA:MAX:0.5:24:775 \
RRA:MAX:0.5:288:797


#--start 1088481600 \         # データ取得開始時間の指定(default 現在時刻)
#--step 300 \                 # データを格納する時間の間隔の指定(default 300s)
#DS:in:COUNTER:600:U:U \      # データソースの定義
#DS:out:COUNTER:600:U:U \     # データソースの定義
#RRA:AVERAGE:0.5:1:600 \      # ラウンドロビンアーカイブの定義(一日グラフ用)
#RRA:AVERAGE:0.5:6:700 \      # ラウンドロビンアーカイブの定義(週間グラフ用)
#RRA:AVERAGE:0.5:24:775 \     # ラウンドロビンアーカイブの定義(月間グラフ用)
#RRA:AVERAGE:0.5:288:797 \    # ラウンドロビンアーカイブの定義(年間グラフ用)
#RRA:MAX:0.5:1:600 \          # ラウンドロビンアーカイブの定義(一日グラフ用)
#RRA:MAX:0.5:6:700 \          # ラウンドロビンアーカイブの定義(週間グラフ用)
#RRA:MAX:0.5:24:775 \         # ラウンドロビンアーカイブの定義(月間グラフ用)
#RRA:MAX:0.5:288:797          # ラウンドロビンアーカイブの定義(年間グラフ用)
  

 ここでは、データ記録用の定義をして実際の格納ファイルを生成しておく段階です。自分としても覚え難いのでコメント部などを残してあります。この部分に関しては、ラウンドロビンデータベースの作成で詳細を知ることができます。

データ記録用スクリプト(update.bsh)
#! /bin/sh

RRD="/usr/bin/rrdtool update"
RRA="/var/www/mrtg/ondo.rrd"
awk="/usr/bin/awk"
date="/bin/date"

TEMP=`/home/k-wada/program/ondo/ds18s20M`;
ONDO=`echo $TEMP | $awk '{print $1}' `

#TIME=`$date +%s`
#echo $TIME
#$RRD $RRA $TIME:$ONDO

$RRD $RRA N:$ONDO
  
 crontab で 5 分ごとに起動して温度記録を rrdtool のデータベースに追加していく部分となります。

●グラフ作成用スクリプト(graph.bsh)
#! /bin/sh

RRD="/usr/bin/rrdtool graph"
RRA="/var/www/mrtg/ondo.rrd"
GRP="/var/www/mrtg/ondo.png"
date="/bin/date"
END=`$date +%s`
D=`$date +"%F"`
T=`$date +"%H\:%M"`

oneday=86400
START=`expr $END - $oneday `

$RRD $GRP \
--start $START \
--end $END  \
--imgformat PNG \
--title Temperature \
--width 600 \
--height 200 \
--lower-limit -10 \
--upper-limit 40 \
--vertical-label  dig. \
--x-grid MINUTE:30:HOUR:6:HOUR:1:0:%H \
DEF:temp=$RRA:ondo:AVERAGE \
LINE2:temp#00CC00:UPDATE \
COMMENT:$D \
COMMENT:$T \
#GPRINT:temp:MAX:"MAX\:%2.1lf"
  

 どのようなグラフにするかは、グラフの作成の 記事が参考になります。特に開始時間、終了時間に注意を払いましょう。また、最後の GPRINT 部分のコメントですが、これがあるとどうしてもコア・ダンプをしてしまいました。グラフ生成のタイミングは任意なのですが、cron で温度データが更新される度(5分ごと)にグラフ化するのが普通だと思います。

 次回は、続きとして、Webページの作成スクリプトなどを説明します。


<和田 好司>

 カテゴリ 

 

トラックバック(0)

このブログ記事を参照しているブログ一覧: シリアル・インターフェースで温度を観測する(その4) RRDTOOL編・前編

このブログ記事に対するトラックバックURL: http://www.eleki-jack.com/mt/mt-tb.cgi/1343

コメントする

おすすめ書籍
Powered by
Movable Type 4.1