*BME280で気圧等の測定 [#leacdc28]

RIGHT:更新日 &lastmod();

**H/Wの設定 [#y1e01f6e]

秋月電子で購入したBME280で気圧、温度、湿度を自動測定

データシート
&ref("./bme280.pdf");

***raspberry pi とBME280の接続 [#x281ba94]

 ------------- 1.VDD          1. 3.3V ------------------------
 | BME280    |-----------------------|   raspberry pi        |
 |           | 2.GND          25.GND |                       |
 |           |-----------------------|                       |
 |           | 3.NC                  |                       |
 |           |---------              |                       |
 |           | 4.SDI          3. SDA |                       |
 |           |-----------------------|                       |
 |           | 5.SDD         34.GND  |                       |
 |           |-----------------------|                       |
 |           | 6.SCK          5.SCL  |                       |
 |           |-----------------------|                       |
 -------------                       -------------------------

-J3: はんだブリッジ(ショート)

&ref("./気圧センサー.jpg");

***インターフェイスの設定(I2Cの有効化) [#zd27f3c5]

&ref("./設定1.png");

&ref("./設定2.png");

***接続確認 [#u165b0a1]

-toolsパッケージの確認
 # dpkg -l | grep i2c
 ii  i2c-tools                             3.1.1+svn-2                               armhf        heterogeneous set of I2C tools for Linux
 ii  libi2c-dev                            3.1.1+svn-2                               all          userspace I2C programming library development files
 ii  python-smbus                          3.1.1+svn-2                               armhf        Python bindings for Linux SMBus access through i2c-dev
 ii  python3-codebug-i2c-tether            0.2.3-1                                   all          CodeBug I2C Tether module.
 ii  python3-smbus                         3.1.1+svn-2                               armhf        Python 3 bindings for Linux SMBus access through i2c-dev

i2c-toolsがインストールされていることを確認

無いときは以下でインストール

 $ sudo apt-get install i2c-tools

-接続確認

 # i2cdetect -y 1
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- --
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 70: -- -- -- -- -- -- 76 --

**ソフト作成 [#a115a98a]

***bme280の測定部 [#pc1c4120]

10回測定して平均を求める。

-bme280-2.c


 #include <stdio.h>
 
 #include <wiringPi.h>
 #include <wiringPiI2C.h>
 
 #define BME280_ADDRESS 0x76
 unsigned long int hum_raw,temp_raw,pres_raw;
 signed long int t_fine; 
 
 unsigned int dig_T1;
 int dig_T2;
 int dig_T3;
 unsigned int dig_P1;
 int dig_P2;
 int dig_P3;
 int dig_P4;
 int dig_P5;
 int dig_P6;
 int dig_P7;
 int dig_P8;
 int dig_P9;
 char  dig_H1;
 int dig_H2;
 char  dig_H3;
 int dig_H4;
 int dig_H5;
 char  dig_H6;
 
 static int dev; 
 
 static int init_dev(void)
 {
   if ((dev = wiringPiI2CSetup(BME280_ADDRESS)) == -1)
   {
      return 1 ;
   }
      return 0;
 }
 void getRegisters(char address, int numData, unsigned char *data) {
   char adr;
   int i;
 
   adr = address;
   for (i = 0; i < numData; i++) {
     *data = wiringPiI2CReadReg8 (dev, adr);
 //      printf("adr:%x data:%x\n",adr, *data);
     adr ++;
     data ++;
   }
 }
 
 void readTrim()
 {
     unsigned char data[32],i=0;
 
     getRegisters(0x88, 24, &data[0]);
     i+=24;
 
     getRegisters(0xA1, 1, &data[i]);
     i+=1;
 
     getRegisters(0xE1, 7, &data[i]);
     i+=7;
 
     dig_T1 = (data[1] << 8) | data[0];
     dig_T2 = (data[3] << 8) | data[2];
     dig_T3 = (data[5] << 8) | data[4];
     dig_P1 = (data[7] << 8) | data[6];
     dig_P2 = (data[9] << 8) | data[8];
     dig_P3 = (data[11]<< 8) | data[10];
     dig_P4 = (data[13]<< 8) | data[12];
     dig_P5 = (data[15]<< 8) | data[14];
     dig_P6 = (data[17]<< 8) | data[16];
     dig_P7 = (data[19]<< 8) | data[18];
     dig_P8 = (data[21]<< 8) | data[20];
     dig_P9 = (data[23]<< 8) | data[22];
     dig_H1 = data[24];
     dig_H2 = (data[26]<< 8) | data[25];
     dig_H3 = data[27];
     dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
     dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
     dig_H6 = data[31];
 }
 
 void writeReg(unsigned char address, unsigned char data) {
   char adr;
   int i;
 
   adr = address;
   wiringPiI2CWriteReg8 (dev, adr, data);
 //  printf("adr:%x data:%x\n",adr, data);
 }
 
 void readData()
 {
     int i = 0;
     unsigned char data[8];
 
     getRegisters(0xF7, 8, &data[0]);
 
     pres_raw = data[0];
     pres_raw = (pres_raw<<8) | data[1];
     pres_raw = (pres_raw<<4) | (data[2] >> 4);
 
     temp_raw = data[3];
     temp_raw = (temp_raw<<8) | data[4];
     temp_raw = (temp_raw<<4) | (data[5] >> 4);
 
     hum_raw  = data[6];
     hum_raw  = (hum_raw << 8) | data[7];
 //    printf("TEMP :%x  DegC  PRESS :%x  hPa  HUM :%x \n",temp_raw,pres_raw,hum_raw);
 }
 
 
 signed long int calibration_T(signed long int adc_T)
 {
 
     signed long int var1, var2, T;
     var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
     var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
 
     t_fine = var1 + var2;
     T = (t_fine * 5 + 128) >> 8;
     return T;
 }
 
 unsigned long int calibration_P(signed long int adc_P)
 {
     signed long int var1, var2;
     unsigned long int P;
     var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
     var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
     var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
     var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
     var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
     var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
     if (var1 == 0)
     {
         return 0;
     }
     P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
     if(P<0x80000000)
     {
        P = (P << 1) / ((unsigned long int) var1);
     }
     else
     {
         P = (P / (unsigned long int)var1) * 2;
     }
     var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
     var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
     P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
     return P;
 }
 
 unsigned long int calibration_H(signed long int adc_H)
 {
     signed long int v_x1;
 
     v_x1 = (t_fine - ((signed long int)76800));
     v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
               ((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
               (((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
               ((signed long int) dig_H2) + 8192) >> 14));
    v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
    v_x1 = (v_x1 < 0 ? 0 : v_x1);
    v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
    return (unsigned long int)(v_x1 >> 12);
 }
 
 void main(int argc, char **argv)
 {
     unsigned char osrs_t = 1;             //Temperature oversampling x 1
     unsigned char osrs_p = 1;             //Pressure oversampling x 1
     unsigned char osrs_h = 1;             //Humidity oversampling x 1
     unsigned char mode = 3;               //Normal mode
     unsigned char t_sb = 5;               //Tstandby 1000ms
     unsigned char filter = 0;             //Filter off
     unsigned char spi3w_en = 0;           //3-wire SPI Disable
 
     unsigned char ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
     unsigned char config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;
     unsigned char ctrl_hum_reg  = osrs_h;
 
 
     double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
     signed long int temp_cal;
     unsigned long int press_cal,hum_cal;
     int i;
 
     if(init_dev()==1)  return;
 
     writeReg(0xF2,ctrl_hum_reg);
     writeReg(0xF4,ctrl_meas_reg);
     writeReg(0xF5,config_reg);
     readTrim();                    //
 
     for(i = 0 ; i < 10 ; i++)
     {
         delay(1000);
         readData();
 
         temp_cal = calibration_T(temp_raw);
         press_cal = calibration_P(pres_raw);
         hum_cal = calibration_H(hum_raw);
         temp_act = (double)temp_cal / 100.0 + temp_act ;
         press_act = (double)press_cal / 100.0 + press_act;
         hum_act = (double)hum_cal / 1024.0 + hum_act;
 //        printf("TEMP :%f  DegC  PRESS :%f  hPa  HUM :%f <br /> \n",temp_act,press_act,hum_act);
 
     }
 // I calculate ten times of average
    temp_act = temp_act/10;
    press_act = press_act/10;
    hum_act = hum_act/10;
    printf("TEMP :%f  DegC  PRESS :%f  hPa  HUM :%f %% <br /> \n",temp_act,press_act,hum_act);

 }

-コンパイル

 $ gcc -o bme280-2 bme280-2.c -lwiringPi

***サーバへのファイル転送等 [#yd2dfee2]

-press.php

 #! /usr/bin/php
 <?php
 
 $today = date("Ymd");
 $time = date("H:i");
 
 $outfile = '/home/pi/BME280/press_temp';
 $outfile2 = '/home/pi/BME280/index.html';
 
 if( $handle = fopen( $outfile , 'a' ) ){
 fputs( $handle, $today."-".$time."  \n" );
 fclose($handle);
 }
 
 $cmd = '/home/pi/BME280/bme280-2  >> '.$outfile;
 exec($cmd);
  
 $cmd = '/usr/bin/tac '. $outfile . ' > '. $outfile2;
 exec($cmd);
 
 $cmd = '/usr/bin/rsync -avz -e ssh '.$outfile2.' okada@192.168.10.46:/var/www/html/ondo/press/';
 exec($cmd);
 return;
 ?>

***raspberry pi のcrontab [#g493dc16]

-20分おきに測定

 */20 * * * * /home/pi/BME280/press.php

-24時前に元ファイルの削除(このファイルに測定結果を追記している)

 45 23 * * * /bin/rm /home/pi/BME280/press_temp


**サーバの設定 [#u160d9ff]

***24時前に日付ファイルに変更 [#l081d78e]

-move_press.php

 #! /usr/bin/php
 <?php
 $today = date("Ymd").'.html';
 $cmd = '/bin/mv /var/www/html/ondo/press/index.html /var/www/html/ondo/press/'.$today;
 exec($cmd);
 return;
 ?>

***サーバのcrontab [#g172b143]

-24時前に日付ファイルに変更

 48 23 * * * /usr/bin/php /home/okada/script/move_press.php  > /dev/null 2>&1

**実行結果 [#ocb989af]

-http://mz80.ism21.net/ondo/press/

**グラフ作成 [#h7240167]

Jpgraphでグラフを作成

***Jpgraphをインストール [#z2b465cd]

-http://http://jpgraph.net/download/

からjgraph-4.0.2.tar.gzをDL

Linux上の適当なフォルダで解凍

-/var/www/html/ondo/graph/libsの下に解凍したsrcの中身をコピー

-日本語が利用できるようにシンボリックリンク作成

-- # cd /usr/share/fonts
-- # ln -s TrueType-ipafont truetype

-phpでGDが利用できるように設定

 # cd /etc/php5

-php.ini

 ;;extension=php_gd2.dll
 extension=php_gd2.dll

-Apache 再起動

 # /etc/rc.d/init.d/apache2 restart

 <?php
 phpinfo()
 ?>

-gd
|GD Support	|enabled|
|GD Version	|bundled (2.0.34 compatible)|
|FreeType Support	|enabled|
|FreeType Linkage	|with freetype|
|FreeType Version	|2.3.9|
|GIF Read Support	|enabled|
|GIF Create Support	|enabled|
|JPEG Support	|enabled|
|libJPEG Version	|6b|
|PNG Support	|enabled|
|libPNG Version	|1.2.44|
|WBMP Support	|enabled|
|XBM Support	|enabled|


***プログラム [#e9a6a2e2]

-/var/www/html/ondo/graph/index.php

 <?php
 
 // 折れ線グラフ描画に必要なライブラリ
 
 require_once 'libs/jpgraph.php';
 
 require_once 'libs/jpgraph_line.php';
 
 require_once 'libs/jpgraph_mgraph.php';
 
 $date = trim($_GET["date"]);
 
 // echo $date ;
 
 // データ、凡例、描画色を準備
 
 $dirname = "/var/www/html/ondo/press/";
 
 if ($date == "" ){
    $filename = $dirname . "index.html";
    $today = date("Ymd");
 }else{
    $filename = $dirname . $date . ".html" ;
    $today = $date;
 }
 
 // echo $filename;
 
 
 $fp = fopen($filename, 'r');
 
 $Time = array();
 $rTime = array();
 
 $Pa = array();
 $rPa = array();
 
 $i = 0;
 
 
 while (!feof($fp)) {
 
 
       $txt = fgets($fp);
 
       if (strlen(trim($tex))==0) bleak;
       $S = strpos($txt , '-') + 1;
       $E = strpos($txt , 'TEMP');
 
       $tmp1 = trim(substr($txt, $S, $E-$S));
       $Time[$i] = $tmp1;
 
       $S = strpos($txt , 'PRESS :') + 7;
       $E = strpos($txt , 'hPa');
 
       $tmp2= trim(substr($txt, $S, $E-$S));
 
       $Pa[$i] = $tmp2;
 
       $S = strpos($txt , 'TEMP :') + 6;
       $E = strpos($txt , 'DegC');
 
       $tmp2= trim(substr($txt, $S, $E-$S));
 
       $Ta[$i] = $tmp2;
 
       $S = strpos($txt , 'HUM :') + 5;
       $E = strpos($txt , '%');
 
       $tmp2= trim(substr($txt, $S, $E-$S));
 
       $Hum[$i] = $tmp2;
 
 
 
 
 //      printf("%d %s %s<br /> \n", $i, $Ta[$i], $HUM[$i] );
       $i++;
 
 }
  
 
 fclose($fp);
 
 // exit; 
 
 //配列を逆転
 $rTime = array_reverse($Time);
 $rPa = array_reverse($Pa);
 $rTa = array_reverse($Ta);
 $rHum = array_reverse($Hum);
 $objar = array();
 
 
 // print_r($Pa);
  
 
 // グラフの描画先(気圧)
 
 
 $g1 = new Graph(1200, 600, "auto"); // サイズ
 
 $g1->setScale('textlin'); // 目盛り 
 
 $g1->title->setFont(FF_MINCHO, FS_NORMAL, 18); // タイトルフォント 
 
 $g1->title->set('気圧 [' . $today . ']'); // タイトル
 
 $g1->legend->setFont(FF_MINCHO, FS_NORMAL, 14); // 凡例フォント
 
 
 
 
 // 気圧の表示
 
 //X軸ラベル
   $g1->xaxis->SetTickLabels($rTime);
 
   $g1->xaxis->SetTextLabelInterval(3);
 
   $g1->xaxis->title->Set("Time");
   $g1->yaxis->title->Set("(hPa)");
   $g1->SetFrame(true,'blue',1);
 
   $l = new LinePlot($rPa); // データ
 
   $l->SetColor('#FFFF00'); // 描画色
 
   $g1->add($l); // 追加
 
  
 // グラフを描画(気圧)
 
 //  $g1->stroke();
 
   array_push($objar, $g1);
 
 
 
 // グラフの描画先(温度)
 
 
 $g1 = new Graph(1200, 600, "auto"); // サイズ
 
 
 $g1->setScale('textlin'); // 目盛り
 
 $g1->title->setFont(FF_MINCHO, FS_NORMAL, 18); // タイトルフォント
 
 
 $g1->title->set('温度 [' . $today . ']'); // タイトル
 
 // $g1->legend->setFont(FF_MINCHO, FS_NORMAL, 14); // 凡例フォント
 
 
 
 
 // 温度の表示
 
 //X軸ラベル
   $g1->xaxis->SetTickLabels($rTime);
 
   $g1->xaxis->SetTextLabelInterval(3);
 
   $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($rTa); // データ
 
   $l->SetColor('red'); // 描画色
 
   $g1->add($l); // 追加
 
 
 
 
 // グラフを描画(温度)
 
 // $g1->stroke();
 
 array_push($objar, $g1);
 
 
 
 // グラフの描画先(湿度)
 
 
 $g1 = new Graph(1200, 600, "auto"); // サイズ
 
 
 $g1->setScale('textlin'); // 目盛り
 
 $g1->title->setFont(FF_MINCHO, FS_NORMAL, 18); // タイトルフォント
 
 
 $g1->title->set('湿度 [' . $today . ']'); // タイトル
 
 
 // $g1->legend->setFont(FF_MINCHO, FS_NORMAL, 14); // 凡例フォント
 
 
 
 
 // 湿度の表示
 
 //X軸ラベル
   $g1->xaxis->SetTickLabels($rTime); 
 
   $g1->xaxis->SetTextLabelInterval(3);
 
   $g1->xaxis->title->Set("Time");
   $g1->yaxis->title->Set("(%)");
   $g1->SetFrame(true,'blue',1);
 
   $l = new LinePlot($rHum); // データ
 
   $l->setColor('green'); // 描画色
 
   $g1->add($l); // 追加
 
 // グラフを描画(湿度)
 
 // $g1->stroke();
 
 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();
 
 ?>

***確認 [#a368a791]

-当日のグラフ
--http://mz80.ism21.net/ondo/graph/index.php

-日付指定のグラフ
--http://mz80.ism21.net/ondo/graph/index.php?date=20170715


**すべてのデバイスの表示 [#kc8c6079]

-当日のグラフ
--http://mz80.ism21.net/ondo/graph/g.php

-日付指定のグラフ
--http://mz80.ism21.net/ondo/graph/g.php?date=20170715
--http://mz80.ism21.net/ondo/graph/g.php?date=20170718



**参考 [#pf590753]

-http://tomosoft.jp/design/?p=6963
-秋月電子
--http://akizukidenshi.com/catalog/g/gK-09421/

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS