BME280で気圧等の測定

更新日 2017-07-17 (月) 16:39:54

H/Wの設定

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

データシート filebme280.pdf

raspberry pi とBME280の接続

------------- 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: はんだブリッジ(ショート)

気圧センサー.jpg

インターフェイスの設定(I2Cの有効化)

設定1.png

設定2.png

接続確認

  • 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 --

ソフト作成

bme280の測定部

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

サーバへのファイル転送等

  • 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

  • 20分おきに測定
*/20 * * * * /home/pi/BME280/press.php
  • 24時前に元ファイルの削除(このファイルに測定結果を追記している)
45 23 * * * /bin/rm /home/pi/BME280/press_temp

サーバの設定

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

  • 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

  • 24時前に日付ファイルに変更
48 23 * * * /usr/bin/php /home/okada/script/move_press.php  > /dev/null 2>&1

実行結果

グラフ作成

Jpgraphでグラフを作成

Jpgraphをインストール

から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 Supportenabled
    GD Versionbundled (2.0.34 compatible)
    FreeType Supportenabled
    FreeType Linkagewith freetype
    FreeType Version2.3.9
    GIF Read Supportenabled
    GIF Create Supportenabled
    JPEG Supportenabled
    libJPEG Version6b
    PNG Supportenabled
    libPNG Version1.2.44
    WBMP Supportenabled
    XBM Supportenabled

プログラム

  • /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();

?>

確認

すべてのデバイスの表示

参考


添付ファイル: filebme280.pdf 690件 [詳細] file気圧センサー.jpg 77件 [詳細] file設定2.png 76件 [詳細] file設定1.png 71件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-07-17 (月) 16:39:54 (393d)