★ Arduino 5.温湿度&気圧測定(I2C通信)
目的
温湿度&気圧を測定する。
温湿度&気圧センサー
AE-BME280 秋月電子通商にて1,080円(K-09421)
- 測定範囲と精度
温度 -40~+85℃, ±1℃ 湿度 0~100%, ±3% 気圧 300~1100hPa, ±1hPa
- Vcc=1.71~3.6V
- アドレスは、0x76(5pin=GND)と0x77(5pin=Vcc)のどちらか。
http://akizukidenshi.com/download/ds/akizuki/AE-BME280_manu_v1.1.pdf
I2C通信のため、J3をはんだでショート
回路図
スケッチ
BME280搭載 温湿度・気圧センサモジュールの使い方
https://trac.switch-science.com/wiki/BME280
にスケッチが出ていました。使用ICが同じなので
スケッチはそのまま使用可能でした。一部注記を追加(まだ途中です)
#include <Wire.h> // I2Cライブラリ使用 #define BME280_ADDRESS 0x76 // デバイスのアドレス pin5=GND時 unsigned long int hum_raw,temp_raw,pres_raw; // signed long int 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; int8_t dig_H1; int16_t dig_H2; int8_t dig_H3; int16_t dig_H4; int16_t dig_H5; int8_t dig_H6; void setup() { uint8_t osrs_t = 1; // 温度 oversampling x 1 uint8_t osrs_p = 1; // 気圧 oversampling x 1 uint8_t osrs_h = 1; // 湿度 oversampling x 1 uint8_t mode = 3; // 繰り返し測定 uint8_t t_sb = 5; // スタンバイ時間 1000mS uint8_t filter = 0; // IIRフィルタ無し uint8_t spi3w_en = 0; // 3-wire SPI Disable uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode; uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en; uint8_t ctrl_hum_reg = osrs_h; // Serial.begin(9600); // シリアルモニタ通信速度設定 Wire.begin(); // I2C初期化 writeReg(0xF2,ctrl_hum_reg); // サブ writeReg(0xF4,ctrl_meas_reg); // サブ writeReg(0xF5,config_reg); // サブ readTrim(); // サブ } void loop() { 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; // 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; // Serial.print("温度:"); // シリアルモニタに表示 Serial.print(temp_act); // 温度表示 Serial.print("℃ 湿度:"); // シリアルモニタに表示 Serial.print(hum_act); // 湿度表示 Serial.print("% 気圧:"); // シリアルモニタに表示 Serial.print(press_act); // 気圧表示 Serial.println("hPa"); // シリアルモニタに表示 delay(1000); // 1000mS待つ } void readTrim() { uint8_t data[32],i=0; // Wire.beginTransmission(BME280_ADDRESS); // 送信処理開始 Wire.write(0x88); // 送信 Wire.endTransmission(); // 送信完了 Wire.requestFrom(BME280_ADDRESS,24); // 24byteのデータ要求 while(Wire.available()){ // data[i] = Wire.read(); // データ読取り i++; // i=i+1 } Wire.beginTransmission(BME280_ADDRESS); // 送信処理開始 Wire.write(0xA1); // 送信 Wire.endTransmission(); // 送信完了 Wire.requestFrom(BME280_ADDRESS,1); // 1byteのデータ要求 data[i] = Wire.read(); // データ読取り i++; // i=i+1 Wire.beginTransmission(BME280_ADDRESS); // 送信処理開始 Wire.write(0xE1); // 送信 Wire.endTransmission(); // 送信完了 Wire.requestFrom(BME280_ADDRESS,7); // 7byteのデータ要求 while(Wire.available()){ // data[i] = Wire.read(); // データ読取り i++; // i=i+1 } 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(uint8_t reg_address, uint8_t data) // { Wire.beginTransmission(BME280_ADDRESS); // 送信処理開始 Wire.write(reg_address); // 送信 Wire.write(data); // 送信 Wire.endTransmission(); // 送信完了 } void readData() // { int i = 0; // 整数 uint32_t data[8]; // Wire.beginTransmission(BME280_ADDRESS); // 送信処理開始 Wire.write(0xF7); // 送信 Wire.endTransmission(); // 送信完了 Wire.requestFrom(BME280_ADDRESS,8); // 8byteのデータ要求 while(Wire.available()){ // data[i] = Wire.read(); // データ読取り i++; // i=i+1 } pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); hum_raw = (data[6] << 8) | data[7]; // } 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); // if else文 v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1); // if else文 return (unsigned long int)(v_x1 >> 12); // }
動作外観
次へ