BME280 温湿度気圧センサーを使ってみよう。
Arduino基板に接続する
ArduinoのI2C通信端子を使う
VDDは3.3V CSB、SDOをVddに接続することで、(J1,J2,J3をショート) アドレスは0x77になる
サイトから、BME280のライブラリをダウンロードすることができる
CODEの中から ZIPファイルをダウンロードする
スケッチの中からZIPファイルをインストールする、、を選択し、先ほどの BME280のZIPファイルを読み込んでおく
後は、#include "SparkFunBME280.h" インクルードしておこう
データの設定を行う。
ーーーーーーーー」
#include <Wire.h> //I2C通信
#include "SparkFunBME280.h" //ライブラリをダウンロードしておく
#define BME280 0x77 // BME280 のアドレス
#define CONFIG 0xF5 //書き込みレジスタ
#define CTRL_MEAS 0xF4 //書き込みレジスタ
#define CTRL_HUM 0xF2 // 書き込みレジスタ
int LED2 = 10; // LEDのポート
int LED1 = 11; //LED1のポート
int INTERVAL = 500; // タイマー
int inpin = 2; //input ポート
int inpin1 = 1; // input ポート
int count;
//気温補正データ
uint16_t ond_T1;
int16_t ond_T2;
int16_t ond_T3;
//湿度補正データ
uint8_t ond_H1;
int16_t ond_H2;
uint8_t ond_H3;
int16_t ond_H4;
int16_t ond_H5;
int8_t ond_H6;
//気圧補正データ
uint16_t ond_P1;
int16_t ond_P2;
int16_t ond_P3;
int16_t ond_P4;
int16_t ond_P5;
int16_t ond_P6;
int16_t ond_P7;
int16_t ond_P8;
int16_t ond_P9;
unsigned char dac[26];
unsigned int i;
int32_t t_fine;
int32_t adc_P, adc_T, adc_H;
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
void setup(){
pinMode( LED2,OUTPUT); //ポートをOUTPUTに設定
pinMode(LED1,OUTPUT); //
pinMode(inpin, INPUT); //ポートをINPUTに設定
pinMode(inpin1,INPUT);
pinMode(inpin,INPUT_PULLUP); //内部プルアップしておく
pinMode(inpin1,INPUT_PULLUP);
Serial.begin(9600); //I2C通信を9600bps設定
Wire.begin(); //I2C通信設定
//動作設定 CONFIGに0x00を書き込む
Wire.beginTransmission(BME280);
Wire.write(CONFIG);
Wire.write(0x00);
Wire.endTransmission();
// 測定条件 CTRL_MEASに 0x24 を設定する
Wire.beginTransmission(BME280);
Wire.write(CTRL_MEAS);
Wire.write(0x24);
Wire.endTransmission();
// 温度測定条件 CTRL_HUM に0x01を設定する
Wire.beginTransmission(BME280);
Wire.write(CTRL_HUM);
Wire.write(0x01);
Wire.endTransmission();
// 補正測定条件 補正用 0x88を設定する
Wire.beginTransmission(BME280);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280, 26); //I2Cデバイス「BME280」に26Byteのデータ要求
for (i=0; i<26; i++){
while (Wire.available() == 0 ){}
dac[i] =Wire.read();}
// dac[1]-dac[24]までのデータを 温度と湿度、気圧に変換する
ond_T1 = ((uint16_t)((dac[1] << 8) | dac[0]));
ond_T2 = ((int16_t)((dac[3] << 8) | d
ond_P1 = ((uint16_t)((dac[7] << 8) | dac[6]));
ond_P2 = ((int16_t)((dac[9] << 8) | dac[8]));
ond_P3 = ((int16_t)((dac[11] << 8) | dac[10]));
ond_P4 = ((int16_t)((dac[13] << 8) | dac[12]));
ond_P5 = ((int16_t)((dac[15] << 8) | dac[14]));
ond_P6 = ((int16_t)((dac[17] << 8) | dac[16]));
ond_P7 = ((int16_t)((dac[19] << 8) | dac[18]));
ond_P8 = ((int16_t)((dac[21] << 8) | dac[20]));
ond_P9 = ((int16_t)((dac[23] << 8) | dac[22]));
ond_H1 = ((uint8_t)(dac[25]));
Wire.beginTransmission(BME280); //I2Cスレーブ「Arduino Uno」のデータ送信開始
Wire.write(0xE1); //出力データバイトを「補正データ」のアドレスに指定
Wire.endTransmission(); //I2Cスレーブ「Arduino Uno」のデータ送信終了
Wire.requestFrom(BME280, 7); //I2Cデバイス「BME280」に7Byteのデータ要求
for (i=0; i<7; i++){
while (Wire.available() == 0 ){}
dac[i] = Wire.read(); //dacにI2Cデバイス「BME280」のデータ読み込み
}
ond_H2 = ((int16_t)((dac[1] << 8) | dac[0]));
ond_H3 = ((uint8_t)(dac[2]));
ond_H4 = ((int16_t)((dac[3] << 4) + (dac[4] & 0x0F)));
ond_H5 = ((int16_t)((dac[5] << 4) + ((dac[4] >> 4) & 0x0F)));
ond_H6 = ((int8_t)dac[6]);
delay(500);
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
プログラムがスタートする
//LED1を点滅させる
void loop() {
digitalWrite( LED1,HIGH);
delay(INTERVAL);
digitalWrite(LED1,LOW);
delay(500);
//
int32_t temp_cal;
uint32_t humi_cal,pres_cal;
float temp,humi,pres;
//BME280測定条件設定(1回測定後、スリープモード)
Wire.beginTransmission(BME280);
Wire.write(CTRL_MEAS);
Wire.write(0x25); //「温度・気圧オーバーサンプリングx1」、「1回測定後、スリープモード」
Wire.endTransmission();
delay(10);//10msec待機
digitalWrite( LED1,HIGH);
//測定データ取得
Wire.beginTransmission(BME280);
Wire.write(0xF7); //SSピンの出力をLOW(0V)に設定
Wire.endTransmission();
Wire.requestFrom(BME280 , 8);
for (i=0; i<8; i++){
while (Wire.available() == 0){}
dac[i] = Wire.read(); //データ読み込み
}
adc_P = ((uint32_t)dac[0] << 12) | ((uint32_t)dac[1] << 4) | ((dac[2] >> 4) & 0x0F);
adc_T = ((uint32_t)dac[3] << 12) | ((uint32_t)dac[4] << 4) | ((dac[5] >> 4) & 0x0F);
adc_H = ((uint32_t)dac[6] << 8) | ((uint32_t)dac[7]);
pres_cal = BME280_compensate_P_int32(adc_P); //気圧データ補正計算
temp_cal = BME280_compensate_T_int32(adc_T); //温度データ補正計算
humi_cal = bme280_compensate_H_int32(adc_H); //湿度データ補正計算
pres = (float)pres_cal / 100.0; //気圧データを実際の値に計算
temp = (float)temp_cal / 100.0; //温度データを実際の値に計算
humi = (float)humi_cal / 1024.0; //湿度データを実際の値に計算
//シリアルモニタ送信
Serial.print("Pressure:"); //文字列「Pressure:」をシリアルモニタに送信
Serial.print(pres); //「pres」をシリアルモニタに送信
Serial.print("hPa "); //文字列「hPa 」をシリアルモニタに送信
Serial.print("Temp:"); //文字列「Temp:」をシリアルモニタに送信
Serial.print(temp); //「temp」をシリアルモニタに送信
Serial.print("°C "); //文字列「°C 」をシリアルモニタに送信
Serial.print("Humidity:"); //文字列「Humidity:」をシリアルモニタに送信
Serial.print(humi); //「humi」をシリアルモニタに送信
Serial.println("%"); //文字列「%」をシリアルモニタに送信、改行
delay(1000);//1000msec待機(1秒待機)
}
//温度補正 関数
int32_t BME280_compensate_T_int32(int32_t adc_T)
{
int32_t var1, var2, T;
var1 = ((((adc_T>>3) - ((int32_t)ond_T1<<1))) * ((int32_t)ond_T2)) >> 11;
var2 = (((((adc_T>>4) - ((int32_t)ond_T1)) * ((adc_T>>4) - ((int32_t)ond_T1))) >> 12) * ((int32_t)ond_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
//湿度補正 関数
uint32_t bme280_compensate_H_int32(int32_t adc_H)
{
int32_t v_x1_u32r;
v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)ond_H4) << 20) -
(((int32_t)ond_H5) * v_x1_u32r)) +
((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)ond_H6))
>> 10) * (((v_x1_u32r * ((int32_t)ond_H3)) >> 11) +
((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)ond_H2)
+ 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)ond_H1)) >> 4));
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
return (uint32_t)(v_x1_u32r>>12);
}
/気圧補正 関数
uint32_t BME280_compensate_P_int32(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)ond_P6);
var2 = var2 + ((var1*((int32_t)ond_P5))<<1);
var2 = (var2>>2)+(((int32_t)ond_P4)<<16);
var1 = (((ond_P3 * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)ond_P2) * var1)>>1))>>18;
var1 =((((32768+var1))*((int32_t)ond_P1))>>15);
if (var1 == 0)
{
return 0; // avoid exception caused by division by zero
}
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)ond_P9) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;
var2 = (((int32_t)(p>>2)) * ((int32_t)ond_P8))>>13;
p = (uint32_t)((int32_t)p + ((var1 + var2 + ond_P7) >> 4));
return p;
}