BME280 搭載、温度・湿度・気圧センサーを SPI で動かしてみた( ESP-WROOM-02 ( ESP8266 )使用)

記事公開日:2016年8月3日
最終修正日:2017年8月17日

スポンサーリンク

最新記事では、ESP32 ( ESP-WROOM-32 )用 BME280 ライブラリを作成しました。
以下の記事を参照してください。
ESP32 用 BME280 ( 温度 湿度 気圧センサー ) ライブラリを作ってみた

以下の記事は ESP8266 ( ESP-WROOM-02 )用です。

こんばんは。

夏、真っ只中、カツンと晴れたり、スコールが降ったりと、梅雨が明けたのに天気が安定しないですねぇ・・・。この前は洗濯物を干していて放っておいたら、突然の雷と大雨で全滅してしまいました。

そこで、今回は天候の変化を素早く知りたいがために、温度・湿度・気圧センサーを表示させてみることに挑戦してみました。

以前の記事では2種類の温度・湿度センサー DHT11 をシリアル通信で使ったことがありますが、今回はSPI通信ができるスイッチサイエンス製のこのデバイスを使ってみたいと思います。

BME280搭載 温湿度・気圧センサモジュール(スイッチサイエンス製)
Amazon.co.jp

このBME280というデバイスはあの電動工具で有名なBOSCH(ボッシュ)製です。
こんな超極小デバイスも作っているとは知りませんでした。スゴイ会社ですねぇ・・・。

制御はもちろん、お馴染みのスイッチサイエンス製 ESPr Developer ( ESP-WROOM-02 ( ESP8266 )) を使います。

前回の記事まではSPI通信のフルカラーOLED ( 有機EL ) SSD1351 を使っていて、これを生かしていろいろと表示させてみたいと思っていました。
しかし、ESP-WROOM-02 ( ESP8266 ) はGPIOピンが少ないので、SPI通信とシリアルやI2C通信などを混在させることは難しいのです。。
そこで、SPI通信できるモジュールを探していたところ、BME280に出会ったわけです。

ただ、ネット上でBME280の情報はI2C通信ばかりで、SPIに関しては微々たるものでした。どうやってSPIで動かしたら良いのか、詳しく解説しているサイトは殆どありませんでした。
救いだったのは、Adafruitのライブラリを使うと問題なく動作したことでした。
ただ、このライブラリのサンプルスケッチを使っているだけでは細かいキャリブレーションや、どういう原理で動作してるのかということがサッパリ分からず・・・。
ライブラリを読み解いていると、難解な計算式が沢山ありました。
BME280のデータシートにその計算式が記載されていて、レジスタ設定方法も詳しく載っていましたが、相変わらず英語が苦手で解読が進まず・・・。
AdafruitさんのライブラリとスイッチサイエンスさんのBME280使い方ページも見ながらI2CをSPIに置き換えて何度もテストしているうちに、ついにようやく解明するに至りました。

ということで、今回もいつものようにライブラリを一切使わずにBME280をSPIで動かす方法を解説してみたいと思います。Arduino標準のSPIライブラリも使いません。
ただ、このデバイスはスイッチサイエンス製なので、分かりやすいようにスイッチサイエンスさんのBME280使い方ページにあるI2C接続用のサンプルスケッチに習ったプログラム構成にしてみました。

1.準備するもの

BME280搭載 温湿度・気圧センサモジュール  ( スイッチサイエンス 製)Amazon.co.jp
温度・湿度・気圧のセンサーがあり、I2C通信とSPI通信の両対応です。
ESPr Developer ピンソケット実装済みにArduinoシールドのように差し込み出来るモジュールもありますが、それはESP-WROOM-02や電源レギュレーターの熱に影響されて正しい測定が出来ないと思われますのでご注意ください。

●ESPr Developer ( スイッチサイエンス 製)
Amazon.co.jp
当ブログで何度も紹介しているお馴染みのESP-WROOM-02シリアルインターフェイス付きボードです。
ESPRESSIF社製 ESP8266 チップは2.4GHz帯Wi-Fi対応で、日本の電波法をクリア(技術適合認証)したパッケージとして販売している ESP-WROOM-02 をスイッチサイエンスさんがさらに余裕のある電源レギュレーターやUSBシリアルインターフェイスをモジュール化して使いやすくしてあるものです。
これの使い方や組み立て方は以下のページを参照してください。
ESPr Developer の使い方をザッと紹介

他の以下のボードもGPIOは同じなので使えると思います。
Amazon.co.jp

●その他、ブレッドボード、ジャンパーワイヤー、USBケーブル、パソコン等

2.BME280 モジュールのピンヘッダハンダ付け

BME280搭載 温湿度・気圧センサモジュールを購入すると以下のようにピンヘッダが付属していました。
bme280_03

モジュールの中央にある銀色の小さい四角いケースがBME280です。こんなちっちゃいものに温度、湿度、気圧センサーが入っているなんて信じられないですよね。因みにこのピンヘッダは2.54mmです。
I2C通信用のプルアップ抵抗はありません。I2C通信を使う場合はR1,R2にプルアップ抵抗を自分でハンダ付けする必要があります。
ただ、今回はSPIなのでプルアップ抵抗は不要です。
SPI通信ではプルアップ抵抗が必要な場合と不要な場合があるようですが、BME280のデータシートによると不要だそうです。

裏面はこうなってます。
bme280_04

Vio と Vcore のPad 間がショートしてあるパターンがあり、要するに、BME280内のチップに別電源を使いたい場合はカッターなどでプリントパターンをカットして使うようです。おそらくノイズの影響を受けないようにクリーンな電源を使って精密な測定をしたい場合ということでしょうか・・・。
今回はカットせずにそのまま使います。
詳細はスイッチサイエンスさんのサイトにありますのでそちらもご参照ください。

ピンヘッダをハンダ付けしていきます。
一度、一カ所だけチョビっとハンダ付けして、その後ハンダを溶かしながら垂直になるように微調整して、バッチリになったら全部ハンダ付けすると良いです。bme280_05

3.BME280 モジュールと ESPr Developer をブレットボード上で接続する

ESPr Developer ( ESP-WROOM-02 ( ESP8266 )) と BME280 モジュールのSPI通信用接続方法はこんな感じになります。
bme280_06

BME280 の電源は3.3V までですので、間違っても5Vに接続しないように注意してください。

SPI通信の場合は、ESP-WROOM-02側がMaster(要するに親機)で制御する側となり、BME280 はSlave(要するに子機)となります。
後で紹介するサンプルスケッチで、ESP-WROOM-02 ( ESP8266 )側のGPIO設定をしますが、13番ピンを MOSI ( Master Output Slave Input ) として、それをBME280側の SDI ( Slave Data Input )に接続します。略した頭文字だけでは訳が分からないので、こうして訳すと分かりやすいですね。
12番ピンは MISO ( Master Input Slave Output ) で、SDO ( Slave Data Output )に接続します。
SCK は( Serial Clock ) です。
CSB は SPI接続の CS 信号 ( または SS 信号 )で、これを別のピン配置にすることによって、スレーブ機器を連結して、別々に制御することができます。ただ、デバイスが増える毎にCSピンを増やさなければいけないのが難点です。その点でいえば、多少速度が遅くなってもI2C接続の方が楽で便利ですね。

因みに、先に述べましたが、プルアップ抵抗は不要です。BME280 のデータシートにもそう書いてありました。

GPIO #16 CS ( SS ) —– CSB
GPIO #14 SCLK —– SCK
GPIO #13 MOSI ( Master Output Slave Input ) —– SDI ( Slave Data Input )
GPIO #12 MISO ( Master Input Slave Output ) —– SDO ( Slave Data Output )

3.Arduino IDE の ESP8266 ボード設定

Arduino IDE のバージョンはArduino.cc サイトのバージョン 1.6.10 で動作しています。(2016/8/3現在)
これに ESP8266 ボードをインストールしておいてください。
インストール方法は以下のページを参照してください。
Arduino IDE に Staging(Stable)版ESP8266 ボードをインストールする方法

4.スケッチの入力

それでは Arduino IDE のスケッチはこのようになります。
これは、スイッチサイエンスさんのBME280使い方ページにあるI2C通信用ブログラムを独自にSPI通信用に書き換えたものです。
ライブラリは一切使用しません。Arduino IDE 標準のSPIライブラリも使わずに動作します。

const uint8_t sclk = 14;
const uint8_t mosi =13; //Master Output Slave Input ESP8266=Master,BME280=slave 
const uint8_t miso =12; //Master Input Slave Output
const uint8_t cs_bme = 16; //CS pin

uint32_t hum_raw, temp_raw, pres_raw;
 int32_t t_fine;

uint16_t dig_T1;
 int16_t dig_T2;
 int16_t dig_T3;
 
uint16_t dig_P1;
 int16_t dig_P2;
 int16_t dig_P3;
 int16_t dig_P4;
 int16_t dig_P5;
 int16_t dig_P6;
 int16_t dig_P7;
 int16_t dig_P8;
 int16_t dig_P9;
 
uint8_t  dig_H1;
 int16_t dig_H2;
uint8_t  dig_H3;
 int16_t dig_H4;
 int16_t dig_H5;
 int8_t  dig_H6;

double SeaLevelPressure_hPa = 1009.4; //標準は1013.25

//*********************セットアップ********************************
void setup() {
  Serial.begin(115200);
  
  uint8_t t_sb = 5; //stanby 1000ms
  uint8_t filter = 0; //filter O = off
  uint8_t spi3or4 = 0; //SPI 3wire or 4wire, 0=4wire, 1=3wire
  uint8_t osrs_t = 4; //OverSampling Temperature x4
  uint8_t osrs_p = 4; //OverSampling Pressure x4
  uint8_t osrs_h = 4; //OverSampling Humidity x4
  uint8_t Mode = 3; //Normal mode

  uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | Mode;
  uint8_t config_reg    = (t_sb << 5) | (filter << 2) | spi3or4;
  uint8_t ctrl_hum_reg  = osrs_h;
  
  pinMode(sclk, OUTPUT);
  pinMode(miso, INPUT);
  pinMode(mosi, OUTPUT);
  pinMode(cs_bme, OUTPUT);

  digitalWrite(cs_bme, HIGH);
 
  writeReg(0xF2,ctrl_hum_reg);
  writeReg(0xF4,ctrl_meas_reg);
  writeReg(0xF5,config_reg);
  delay(1000);
  
  readTrim();
  Serial.println();
}
//******************メインループ************************************
void loop() {
  double temp_act = 0.0, press_act = 0.0, hum_act = 0.0, altitude_act = 0.0;
  int32_t temp_cal;
  uint32_t press_cal,hum_cal;
  
  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;
  press_act = (double)press_cal / 100.0;
  hum_act = (double)hum_cal / 1024.0;
  altitude_act = ReadAltitude(SeaLevelPressure_hPa, press_act);
  
  Serial.println("-----------------------");
  Serial.print("Temperature = "); Serial.print(temp_act); Serial.println(" *C");
  Serial.print("Humidity = "); Serial.print(hum_act); Serial.println(" %");
  Serial.print("Pressure = "); Serial.print(press_act); Serial.println(" hPa");
  Serial.print("Altitude = "); Serial.print(altitude_act); Serial.println(" m");

  delay(2000);
}
//*****************初期値読み込み**************************************
void readTrim(void) {
    dig_T1 = read16bit(0x88);
    dig_T2 = (int16_t)read16bit(0x8A);
    dig_T3 = (int16_t)read16bit(0x8C);

    dig_P1 = read16bit(0x8E);
    dig_P2 = (int16_t)read16bit(0x90);
    dig_P3 = (int16_t)read16bit(0x92);
    dig_P4 = (int16_t)read16bit(0x94);
    dig_P5 = (int16_t)read16bit(0x96);
    dig_P6 = (int16_t)read16bit(0x98);
    dig_P7 = (int16_t)read16bit(0x9A);
    dig_P8 = (int16_t)read16bit(0x9C);
    dig_P9 = (int16_t)read16bit(0x9E);

    dig_H1 = read8bit(0xA1);
    dig_H2 = (int16_t)read16bit(0xE1);
    dig_H3 = read8bit(0xE3);
    dig_H4 = (int16_t)((read8bit(0xE4) << 4) | (read8bit(0xE5) & 0x0F));
    dig_H5 = (int16_t)((read8bit(0xE6) << 4) | (read8bit(0xE5) >> 4));
    dig_H6 = (int8_t)read8bit(0xE7);
}
//***************BME280へ初期レジスタ書き込み関数****************************
void writeReg(uint8_t reg_address, uint8_t data) {
  digitalWrite(cs_bme, LOW);
  SpiWrite(reg_address & B01111111); // write, bit 7 low
  SpiWrite(data);
  digitalWrite(cs_bme, HIGH);
}
//***************BME280からの温度、湿度、気圧データ読み込み関数****************************
void readData() {

  uint32_t data[8];
  uint8_t i;

  digitalWrite(cs_bme, LOW);
  SpiWrite(0xF7 | B10000000); //0xF7 pressure msb read, bit 7 high
  for(i=0; i<8; i++){
    data[i] = SpiRead();
  }
  digitalWrite(cs_bme, HIGH);
  pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); //0xF7, msb+lsb+xlsb=19bit
  temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); //0xFA, msb+lsb+xlsb=19bit
  hum_raw  = (data[6] << 8) | data[7];  //0xFD, msb+lsb=19bit(16:0)
}
//***************温度キャリブレーション関数****************************
int32_t calibration_T(int32_t adc_T) {
    int32_t var1, var2, T;
    var1 = ((((adc_T >> 3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;
    var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) * ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
    
    t_fine = var1 + var2;
    T = (t_fine * 5 + 128) >> 8;
    return T; 
}
//***************気圧キャリブレーション関数****************************
uint32_t calibration_P(int32_t adc_P) {
    int32_t var1, var2;
    uint32_t P;
    var1 = (((int32_t)t_fine)>>1) - (int32_t)64000;
    var2 = (((var1>>2) * (var1>>2)) >> 11) * ((int32_t)dig_P6);
    var2 = var2 + ((var1*((int32_t)dig_P5))<<1);
    var2 = (var2>>2)+(((int32_t)dig_P4)<<16);
    var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((int32_t)dig_P2) * var1)>>1))>>18;
    var1 = ((((32768+var1))*((int32_t)dig_P1))>>15);
    if (var1 == 0) {
        return 0;
    }    
    P = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;
    if(P<0x80000000) {
       P = (P << 1) / ((uint32_t) var1);   
    }else{
        P = (P / (uint32_t)var1) * 2;    
    }
    var1 = (((int32_t)dig_P9) * ((int32_t)(((P>>3) * (P>>3))>>13)))>>12;
    var2 = (((int32_t)(P>>2)) * ((int32_t)dig_P8))>>13;
    P = (uint32_t)((int32_t)P + ((var1 + var2 + dig_P7) >> 4));
    return P;
}
//***************湿度キャリブレーション関数****************************
uint32_t calibration_H(int32_t adc_H) {
    int32_t v_x1;
    
    v_x1 = (t_fine - ((int32_t)76800));
    v_x1 = (((((adc_H << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1)) + 
              ((int32_t)16384)) >> 15) * (((((((v_x1 * ((int32_t)dig_H6)) >> 10) * 
              (((v_x1 * ((int32_t)dig_H3)) >> 11) + ((int32_t) 32768))) >> 10) + ((int32_t)2097152)) * 
              ((int32_t) dig_H2) + 8192) >> 14));
   v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
   v_x1 = (v_x1 < 0 ? 0 : v_x1);
   v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
   return (uint32_t)(v_x1 >> 12);   
}
//***************標高計算関数****************************************************
double ReadAltitude(double SeaLevel_Pres, double pressure) {
  double altitude = 44330.0 * (1.0 - pow(pressure / SeaLevel_Pres, (1.0/5.255)));  
  return altitude;
}
//***************BME280から16bitデータ読み込み関数****************************
uint16_t read16bit(uint8_t reg) {
  uint16_t d1, d2;
  uint16_t data;
  digitalWrite(cs_bme, LOW);
  SpiWrite(reg | B10000000); // read, bit 7 high
  d1 = SpiRead();
  d2 = SpiRead();
  data = (d2 << 8) | d1;
  digitalWrite(cs_bme, HIGH);
  return data;
}
//***************BME280から8bitデータ読み込み関数****************************
uint8_t read8bit(uint8_t reg) {
  uint8_t data;
  digitalWrite(cs_bme, LOW);
  SpiWrite(reg | B10000000); // read, bit 7 high
  data = SpiRead();
  digitalWrite(cs_bme, HIGH);
  return data;
}
//***************BME280へSPI信号データ送信関数****************************
void SpiWrite(uint8_t data) {
  for (int i=7; i>=0; i--) {
    digitalWrite(sclk, LOW);
    digitalWrite(mosi, data & (1<<i));
    digitalWrite(sclk, HIGH);
  }
}
//***************BME280からのSPI信号データ読み込み関数****************************
uint8_t SpiRead() {
  uint8_t r_data = 0;
  for (int i=7; i>=0; i--) {
    r_data <<= 1;
    digitalWrite(sclk, LOW);
    digitalWrite(mosi, LOW);
    digitalWrite(sclk, HIGH);
    if(digitalRead(miso)){
      r_data |= 1;
    }
  }
  return r_data;
}

●1-4行:
ESPr Developer ( ESP-WROOM-02 ( ESP8266 ))側のGPIOピンを設定してます。

●6-28行:
温度、湿度、気圧センサーのキャリブレーション(校正)用の変数宣言です。これは、BME280のデータシートに型宣言方法が書いてあります。
下図の様にデータシートのTable 16 にあります。
bme280_07

符号有り(signed)と符号なし(unsigned)変数があるので注意してください。
short はArduinoでは16bitになります。私の場合はshort型やchar型宣言は何ビットか分からない場合があるので、極力 uint16_t という宣言にしてます。

●30行:
標高計算のための海面(海抜0m)気圧変数です。
後で述べますが、海面気圧というのは頻繁に変動しますので、気象庁のアメダス表形式ページを参照して、近辺の海面気圧を入力します。

●36-42行:
ここはスイッチサイエンスさんのBME280使い方ページを参照して、値を決めます。
filter はオフ以外でもあまり変化なかったのでオフで良いと思いました。
オーバーサンプリングはさらに高い周波数でサンプリングするかどうかで精度が変わりますが、その分計算に時間がかかります。オーバーサンプリングが1よりか4くらいにすると、手持ちの温度湿度計に近い値が出たのでそうしました。

●44-46行:
この変数設定はBME280のデータシートに設定方法があります。
bme280_08

36-42行で初期化した値をビットシフトして、それぞれ8bitに収めます。

●48-53行;
GPIOピンをそれぞれ設定しておきます。
53行で予めCS ( SS) ピンをHIGHにしておかないとうまく動作しませんでした。
BME280 にデータを書き込む場合はこのCSピンをLOWにします。

●55-57行:
44-46行で設定したフィルターやオーバーサンプリングなどの値をBME280へSPI通信で書き込みます。書込みは111-116行の関数を呼び出します。

●60行:
ここで88-109行の関数を呼び出して、BME280のフラッシュメモリにある補正データを呼び出して、9-28行の変数を初期化します。

●64-86行:
ここがメインループです。
69行で118-132行の関数を呼び出して、温度、湿度、気圧のセンサー値を一括して呼び出します。
呼び出したセンサー値のtemp_raw, pres_raw, hum_raw を134-185行のキャリブレーション関数にそれぞれ代入して、実際に理解できる数値に置き換えます。
それをシリアルモニターに表示させます。
ちなみに、Serial.printf関数はdouble型やfloat型は表示してくれませんので、このような形でプログラミングするしかありませんでした。

●88-109行:
BME280のメモリに入っている初期構成データを読み出します。それぞれ符号有りの型と符号なしの型があるので、左辺等辺で型を合わせる必要があります。
これの抽出方法はデータシートのTable16にあります。

●111-116行:
SPI通信でBME280にデータを書き込む関数です。
書き込む場合はCS ( SS )ピンをLOWにして、BME280のレジスタアドレスを書き込むのですが、書き込みの場合はレジスタアドレスの7bit(8番目のビット)をゼロにする必要があります。
それはデータシートの以下の部分に記載されています。
bme280_09

というわけで、113行にあるように01111111を&演算してやれば7bitをゼロにすることができます。
レジスタアドレスを書き込んだら、即該当データを送ります。
送り終わったらCSピンをHIGHにします。

●118-132行:
BME280から一括して温度・湿度・気圧のセンサー値を読み込む関数です。
読み込む前にSPI通信で読み取りたいレジスタアドレスを書き込んでからその後SDOからセンサー値が送出されます。
124行目では0xF7というレジスタアドレスを読み取りモードでBME280に書き込みます。読み取りモードは7bitを1にします。
そのレジスタを書き込むと、それ以降のセンサー値がBME280のSDOから順次送出されます。
つまり、press_msb, press_lsb, …..hum_msb, hum_lsb という感じでセンサー値を8バイト連続でSDOから送信してきます。それをESP-WROOM-02側で読み取るわけです。
ですから、書き込みレジスタはその最初のアドレス(0xF7)で良いということです。
送られてくる順番はこの表をみると分かります。
bme280_10

●133-180行:
これは得られたセンサー値を計算式に入れることによって人間が理解できる温度、湿度、気圧の値に変換できることになります。
この式はBME280のデータシートの最後の方に下図の様に丸ごとそのままそっくり掲載されていますので、それをそのままArduino スケッチに当てはめただけです。

bme280_11

●182-185行:
気圧から標高を計算する関数です。
これはネットのどこかのページにありましたが、Adafruitライブラリにもありました。
SeaLevel_Presは海面気圧(海抜0m気圧)をhPa単位で入力して、pressure値はBME280で測定した値を入力すれば標高が出てきます。
しかし、あまりこの式では正確ではありません。
海面気圧の求め方は後述します。

●187-197行:
BME280から16bit分のデータを読み取る関数です。
読み取りモードですからレジスタを書き込む際には7bitを1にします。
194行目が注意ですが、後で読み込んだバイトが上位ビットになるので注意です。

●199-206行:
BME280から8bit分のデータを読み取る関数です。

●208-214行:
レジスタアドレスをSPI通信で送信する関数です。
spi.hライブラリを使わないでもこうすることによって送信できます。

●216-228行:
ESP-WROOM-02 ( ESP8266 )のmosiピンからデータを読み取って、バイトに変換する関数です。

5.海面気圧(海抜0m気圧、又は海面更正気圧)を入力する。

では、気圧から標高を計算するために、30行目のSeaLevelPressure_hPaに値を入力してみましょう。

ついこの前に知ったのですが、以下のことが正確でなかったらスミマセン。
海面気圧とは正確には海面更正気圧というらしいです。
つまり、標高が明らかになっている場所で測った気圧や温度の値からある計算式を使えば、標高0mの気圧の近似値が求められるらしいです。
例えば、こちらのサイトには標高と気温と気圧を入力すると海面気圧が表示されます。

ただ、それだと、BME280の気圧値が正確でないと、入力しても意味無いですよね。
そこで、気象庁のアメダス表形式ページでは、実はご自分の住んでいる地域近辺の海面気圧が分かるんです。
例えば、地域を東京で選んで表示してみると以下のようになります。
bme280_12

気圧を測っているところは気象台のある地域と測候所がある地域だけですので、そのページを開きます。するとこんな感じの表が出てきます。
bme280_14

東京の気象台の標高は25mですが、気圧の欄の値は実はその地点の気圧値ではないのです。
それはなぜかというと、アメダス表形式のトップページに注意書きがありました。
こんな感じです。
bme280_13

つまり、アメダス表形式の気圧値はその地点の気圧ではなく、海面気圧なのです。
それはどうやら天気図を書く時に、海からの等圧線を描くとなると、すべて同じ標高で考えねばならないからのようです。なるほど・・・。
忘れてしまいましたが、昔、中学校の理科か何かで習ったような習ってないような・・・。

ということで、ご自分の住んでいる地域に近い気象台の海面気圧をhPa単位で入力してください。

6.コンパイル書き込みおよび実行する

では、いよいよ、コンパイル書き込みして、実行させてみます。
起動当初のシリアルモニターはこんな感じで表示されました。
bme280_15

別の温度・湿度計の値はこんな感じです。bme280_16

立ち上げ当初は湿度に誤差がありますね。3~4%くらいの誤差です。

しかし、立ち上げて15分ほど経過するとシリアルモニターはこうなります。bme280_17

温度・湿度計の値はこうなってます。
bme280_18

どうでしょうか。ほとんど誤差が無くなってます。オーバーサンプリングを4にするとかなり正確ですね。1だと湿度が2%くらい誤差がありました。

ちなみに、私の住んでいるところの標高は66mほどのところです。
近くの気象台の海面気圧を入力しても10m以上の誤差があります。これはなかなか正確とはいかないですね。仕方のないところです。
標高をより正しく表示し続けるためには、当然のことなが常に変化する海面気圧を毎回入力してコンパイルし直さなければいけません。
Webから自動取得して海面気圧を校正していくこともできなくはないのですが、これを持って登山するわけではないので、そこまでしなくてもいいのかなぁと思ってます。

ところで、自分の地点の標高を知るには国土地理院の以下のサイトが良いです。
地理院地図サイト
例えば、新宿駅付近の標高を調べるには下図のように中心の十字印を調べたい地点に合わせます。そして下図の様なところをクリックします。
bme280_21

すると下図の様に標高が表示されます。便利なサイトがあるもんですねぇ・・・。
bme280_22

ちなみに、話は変わりますが、私の使っている温度・湿度計は薄くて軽くて意外と正確でとても重宝しています。bme280_19

自立することもできるのでなかなか使い勝手が良いのでおすすめです。
bme280_20

EMPEX の TD-8173 というものです。
Amazon.co.jpではこんな感じで売ってます。

以上です。

いかがでしょうか。
BME280 を調べているうちに気象庁や気圧についてまである程度学習できて個人的に面白かったです。

さて、次回はこのデータをフルカラー有機ELディスプレイに表示させたり、グラフ表示させたりしてみようと思います。
さぁ、そろそろオリンピック間近ですね。いろいろ楽しみです。

ではまた・・・。

最新記事では、ESP32 ( ESP-WROOM-32 )用 BME280 ライブラリを作成しました。
以下の記事を参照してください。

ESP32 用 BME280 ( 温度 湿度 気圧センサー ) ライブラリを作ってみた

mgo-tec電子工作 関連コンテンツ ( 広告含む )

スポンサーリンク

Amazon.co.jp 当ブログのおすすめ



投稿者:

mgo-tec

Arduino , ESP32 ( ESP-WROOM-32 ) , ESP8266 ( ESP-WROOM-02 )等を使って、主にスマホと連携した電子工作やプログラミング記事を書いてます。ライブラリも作ったりしてます。趣味、独学でやってますので、動作保証はしません。 電子回路やプログラミングの専門家ではありません。 畑違いの仕事をしてます。 でも、少しだけ電気の知識が必要な仕事なので、電気工事士や工事担任者等の資格は持ってます。

「BME280 搭載、温度・湿度・気圧センサーを SPI で動かしてみた( ESP-WROOM-02 ( ESP8266 )使用)」への2件のフィードバック

  1. この取得したデータ(温度、湿度、気圧、高度)をsdに保存したいのですが、どうすればいいですか? 

    1. かいじさん

      当ブログをご覧いただき、ありがとうございます。

      以下のページでその方法を紹介していますのでご参照ください。
      ただ、OLED SSD1351 というちょっと高価なディスプレイを使用していることと、OLED_SSD1351 ライブラリが beta ver 1.40 を使っていることに注意してください。

      NTP時刻・温度・湿度・気圧データのSDカードロガー制作。日本語フォントもSDカードから読み込む

コメントを残す

メールアドレスが公開されることはありません。

*画像の文字を入力してください。(スパム防止の為)