温湿度データのグラフ化

更新日 2021-09-24 (金) 11:43:03

構成

デバイスDHT11のデータをArdiunoで受信し、USB(シリアル)でPCに転送する。(プログラム:dht11-s)
PCにはProcessingで作成したプログラム(DHT11_now_only)で受信し、Textファイル(now.txt)に書き込む。
スケジューラで30分間隔に受信情報のTextファイルを、日付ファイル(例 data_20210820.txt)にアペンドする。(プログラム:cp30m.bat)
Apache+phpで日付ファイルを読込み、グラフページを作成する。
外部からのアクセスはロードバランサ経由で表示する。

ブロック図

  ---------       ------------
  | DHT11 |       | Ardiuno  |
  |       |=======|          |
  |       |       |          |
  ---------       ------------
                       ||
                       ||USB
                       ||
           -----------------------        ---------------------
           |          PC         |        |  サーバ           |
           |  Apache + PHP(GD2)  |========|  ロードバランサ   |
           |                     |        |  Pound            |
           -----------------------        ---------------------

プログラム

Ardiuno

  • 60秒間隔に温度と湿度のデータをセンサから受信しUSB(シリアル)に出力する

''dth-s.ino"

#include <DHT.h>
#include <DHT_U.h>

/*
 * DHT11センサー
 * Arduinoのデジタル2ピンでDHT11センサーを接続する
 */

#define DHT11_PIN 2 

DHT dht(DHT11_PIN, DHT11);

unsigned long time, ti;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  dht.begin();

  
}

void loop() {
  // put your main code here, to run repeatedly:

  //プログラム起動時間(ms)
  time = millis();
  // シリアルに転送する間隔
  ti = 60000; // 60秒間隔
  if(time % ti == 0){
  
  // delay(2000);
 
  // 湿度
  float humidity = dht.readHumidity();
  String str_hum = String(humidity);
  // 温度
  float temperature = dht.readTemperature();
  String str_temp = String(temperature);
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println("センサーから読み取りに失敗しました。");
    return;
  }


  String str_data =str_hum + " " +str_temp;
//  Serial.println(str_data);

  // テキストファイルに出力用
 
//Serial.write(int(temperature));
//文字列をシリアルに転送
Serial.print(str_data);
//int bytesSent = Serial.write("Hello", 64);

  }
}

Processing

  • USBのデータを受信するごとに画面に表示する
  • USBのデータを受信するごとにTextファイル(now.txt)に書き込む

DTH_now_only.pde

//---------------------------------
//
// シリアルデータがDHT11から送られるごとに
// "now.txt"というファイルに上書きするプログラム
//
//                           DE JE2SM
//               2021/08
//----------------------------------

import processing.serial.*;
Serial myPort;
PrintWriter output;
 

String senout;
String[] data;
int count=0;
int y, m, d, h, mm, s;
String filedata;
String NewDataFile;

float HUM_OFFSET = 15.00; //湿度のOFFSET
float f_HUM; //湿度計算用 数値
String str_HUM; //湿度計算用 文字列
void setup () {
size(400, 200);
background(255);


NewDataFile ="c:/Usr/Apache24/htdocs/dht11/now.txt";

//シリアル通信の指定
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);

//日本が利用できるようにフォント指定
PFont font = createFont("Meiryo",24);
textFont(font);
}

void draw () { 
 if(count==0){
   myPort.write(255);
 }
 if(myPort.available()>0){
   delay(100);
   h = hour();
   mm = minute();
   s = second ();
   y =  year(); 
   m = month();
   d = day();
     
   //シリアルから受信文字列
   senout=myPort.readString();
   if (senout.length() == 11){
   
   
     data = splitTokens(senout, ", ");
   
      //湿度の適当な補正
     f_HUM = float(data[0]);
     f_HUM = f_HUM +HUM_OFFSET;
     str_HUM = nf(f_HUM,2, 2);

     // 書き込みData内容
     filedata = y + "/" + nf(m, 2) + "/" + nf(d, 2) + " " + nf(h, 2) + ":" + nf(mm, 2) + ":" + nf(s, 2) +" " + str_HUM + " " + data[1];
  

     // 画面表示
     background(255); //画面クリア
     fill(0, 0, 255);
     textSize(24);
     textAlign(CENTER);
     text("サーバ室 温度・湿度", 200,35);
     fill(0);
     textSize(16);
     textAlign(RIGHT);
     text("データ取得時間: " + nf(h, 2) + ":" + nf(mm, 2) + ":" + nf(s, 2),200,70);
     textAlign(CENTER);
     text("湿度: " + str_HUM + "%", 200, 105); //Hum
     text("温度: " + data[1] + "℃", 200, 140); //Temp
     textSize(12);
     fill(0, 64, 255);
     textAlign(LEFT);
     // text(senout, 100, 180);
     text("(Rev. 0.02)", 200, 160);
     text("( DE JE2ISM)", 200, 180);

     count++;
   }
 }
 if (count>0) {
   
   // ファイルに上書き
   String[] NewData = new String[1];
   NewData[0] = filedata;
   saveStrings(NewDataFile, NewData);
   
   count=0;
//   exit();
 }
}

バッチ処理

  • 30分ごとにバッチを起動して、受信データのファイル(now.txt)を日付ファイル(例 data_20210820.txt)にアペンドする。

cp30m.bat

REM -----------------------
REM DTH11から送られてくるデータを
REM 一定間隔ごと日付ファイル(例:data_20210818.txt)
REM 保存するバッチ
REM タスクスケジューラで起動する
REM ----------------------

@echo off
set d=%date%
REM 日付を年、月、日に分解する
set yyyy=%d:~-10,4%
set mm=%d:~-5,2%
set dd=%d:~-2,2%
set today=%yyyy%%mm%%dd%
set pathname=C:\Usr\Apache24\htdocs\dht11\
REM コピー先ファイル名
set dfilename=%pathname%data_%today%.txt
REM コピー元ファイル名
set sfilename=%pathname%now.txt

rem echo %sfilename%
rem echo %dfilename%

type %sfilename% >> %dfilename%

php(GD2)で描画

  • php、GD2、JpGraphのインストールはここを参考。

g.php

<?php 

// 折れ線グラフ描画に必要なライブラリ

require_once 'libs/jpgraph.php';

require_once 'libs/jpgraph_line.php';

require_once 'libs/jpgraph_mgraph.php';

$date = "";

$date = trim($_GET["date"]);

// echo $date ;

// データ、凡例、描画色を準備

$dirname = "C:/Usr/Apache24/htdocs/dht11/";

if ($date == "" ){
   $today = date("Ymd");
   $filename = $dirname . "data_" . $today . ".txt";
}else{
   $today = $date;
   $filename = $dirname . "data_" . $date . ".txt" ;
}

// echo $filename;
// echo "<br /> \n";
// echo $today;

// exit();

$fp = fopen($filename, 'r');

$Time = array();
$rTime = array();

$Hum = array();
$rHum = array(); 

$Ta = array();
$rTa = array();

$i = 0;


while (!feof($fp)) {


      $txt = fgets($fp);

      if (strlen(trim($txt))==0) break;

      $temp =strtok(trim($txt), " ");

      $Time[$i] = substr(strtok( " " ), 0, 5);
      $Hum[$i] = strtok( " " );
      $Ta[$i] = strtok( " " );


   
//      printf("%s %s %s<br /> \n", $Time[$i], $Ta[$i], $Hum[$i] );
       $i++;

}


fclose($fp); 

// exit();
 

$objar = array();

//------------

// グラフの描画先(温度)


$g1 = new Graph(1800, 600, "auto"); // サイズ



$g1->setScale('textlin'); // 目盛り

$g1->title->setFont(FF_MINCHO, FS_NORMAL, 18); // タイトルフォント


$g1->title->set('温度 [' . $today . ']'); // タイトル
 

// 温度の表示

//X軸ラベル
  $g1->xaxis->SetTickLabels($Time);

//グラフに表示するラベルの間隔(データが30分間隔なため1時間ごとにX軸にラベルが表示)
  $g1->xaxis->SetTextLabelInterval(2);

  $g1->xaxis->title->Set("Time");
  $g1->yaxis->title->setFont(FF_MINCHO, FS_NORMAL, 10);
  $g1->yaxis->title->Set("(度)");
  $g1->SetFrame(true,'red',1);

  $l = new LinePlot($Ta); // データ


//グラフの色はadd → SetColorの順で指定しないと反映されない

  $g1->add($l); // 追加 

//グラフの太さ変更
  $g1->img->SetAntiAliasing(false);  // ←SetWeightを有効にすのに必要

  $l->SetWeight(4); // 4 ピクセルの幅

  $l->SetColor('red'); // 描画色

// $g1->Stroke();

// exit();

// グラフを描画(温度)

array_push($objar, $g1);

//------------

// グラフの描画先(湿度)


$g1 = new Graph(1800, 600, "auto"); // サイズ

$g1->setScale('textlin'); // 目盛り

$g1->title->setFont(FF_MINCHO, FS_NORMAL, 18); // タイトルフォント

$g1->title->set('湿度 [' . $today . ']'); // タイトル

// 湿度の表示

//X軸ラベル
  $g1->xaxis->SetTickLabels($Time);

//グラフに表示するラベルの間隔(データが30分間隔なため1時間ごとにX軸にラベルが表示)
  $g1->xaxis->SetTextLabelInterval(2);

  $g1->xaxis->title->Set("Time");
  $g1->yaxis->title->setFont(FF_MINCHO, FS_NORMAL, 10);
  $g1->yaxis->title->Set("(%)");
  $g1->SetFrame(true,'blue',1);

  $l = new LinePlot($Hum); // データ

  $g1->add($l); // 追加

//グラフの太さ変更
  $g1->img->SetAntiAliasing(false);  // ←SetWeightを有効にすのに必要

  $l->SetWeight(4); // 4 ピクセルの幅

  $l->SetColor('#000000'); // 描画色(黒)

 
// グラフを描画(湿度)

array_push($objar, $g1);


//-----------------------
// Create a multigraph
//----------------------
$mgraph = new MGraph();
$mgraph->SetMargin(20,20,20,20);
$mgraph->SetFrame(true,'darkgray',2);
$mgraph->SetFillColor('lightgray');

$i = 0; 

foreach($objar as $g1){
               $mgraph->Add($g1,0,600*$i );
               $i++;
}

//echo $i;
$mgraph->Stroke();

?>
  • アクセス
  • 当日

http://(IP)/dht11/g.php?date=

  • 日付指定

http://(IP)/dht11/g.php?date=20210822

表示.png

前日データが表示される問題

日付が変わっても日付指定しないとき、グラフが前日の値を表示する。
phpのdate()関数がUTCを取得していそう

以下を変更

  • php.ini
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = Asia/Tokyo  ←ここを追加

Poundのインストール


添付ファイル: file表示.png 6件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2021-09-24 (金) 11:43:03 (3d)