BME280にアクセスするためのライブラリ
Diff: BME280.cpp
- Revision:
- 0:95f2b96cdc7f
- Child:
- 1:0dbf59c6e564
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BME280.cpp Tue Jul 10 07:38:08 2018 +0000 @@ -0,0 +1,165 @@ +#include "mbed.h" +#include "BME280.h" +#include "i2c_general_io.h" + +BME280::BME280(PinName sda, PinName scl) + : + i2c_p(new GEN_I2C(sda, scl)), + sensor(*i2c_p) +{ + init(); +} + +BME280::BME280(GEN_I2C &i2c_obj) + : + i2c_p(NULL), + sensor(i2c_obj) +{ + init(); +} + +BME280::~BME280() +{ + if (NULL != i2c_p) + delete i2c_p; +} + + +void BME280::read_sensor(void){ + char sensor_raw_data[8]; + BME280_S32_t T,P,H; //ADC読み込み後温度,気圧,湿度の生データ + BME280_S32_t T_cor; //温度の補正データ + BME280_U32_t P_cor,H_cor; //気圧,湿度の補正データ + + //読み込み + set_force_mode(); //測定開始 + while(STATUS_IS_MEASURING); //測定待ち + sensor.read_reg(BME280_add, PRESS_MSB, sensor_raw_data, 8); //PRESS_MSBレジスタから8バイト読み込み + T = sensor_raw_data[3] << 12 | sensor_raw_data[4] << 4 | sensor_raw_data[5] >> 4 ; + P = sensor_raw_data[0] << 12 | sensor_raw_data[1] << 4 | sensor_raw_data[2] >> 4 ; + H = sensor_raw_data[6] << 8 | sensor_raw_data[7]; + + //補正 + T_cor = BME280_compensate_T_int32(T); + P_cor = BME280_compensate_P_int64(P); + H_cor = BME280_compensate_H_int32(H); + + temp = T_cor / 100.0; + press = P_cor / 256.0; + hum = H_cor / 1024.0; +} + +bool BME280::data_is_ready(void){ + return !STATUS_IS_MEASURING; +} + +void BME280::set_sleep_mode(void){ + sensor.write_reg(BME280_add, CTRL_MEAS, (meas_reg_value&0xFC) | SLEEP_MODE ); +} + +void BME280::set_force_mode(void){ + sensor.write_reg(BME280_add, CTRL_MEAS, (meas_reg_value&0xFC) | FORCE_MODE ); +} + +void BME280::set_normal_mode(void){ + sensor.write_reg(BME280_add, CTRL_MEAS, (meas_reg_value&0xFC) | NORMAL_MODE ); +} + + +//データシートより,補正関数 +// 温度を℃で返します。分解能は0.01℃です。「5123」の出力値は、51.23℃に相当します。 +// t_fineは、グローバル値として細かい温度値を持ちます。 +BME280_S32_t BME280::BME280_compensate_T_int32(BME280_S32_t adc_T){ + BME280_S32_t var1, var2, T; + var1 = ((((adc_T>>3) - ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11; + var2 = (((((adc_T>>4) - ((BME280_S32_t)dig_T1)) * ((adc_T>>4) - ((BME280_S32_t)dig_T1))) >> 12) * + ((BME280_S32_t)dig_T3)) >> 14; + t_fine = var1 + var2; + T = (t_fine * 5 + 128) >> 8; + return T; +} + +// 圧力(Pa)を、Q24.8形式の符号なし32ビット整数として返します。(24個の整数ビットと8個の小数ビット) +// 「24674867」の出力値は、24674867/256 = 96386.2Pa = 963.862hPaに相当します。 +BME280_U32_t BME280::BME280_compensate_P_int64(BME280_S32_t adc_P){ + BME280_S64_t var1, var2, p; + var1 = ((BME280_S64_t)t_fine) - 128000; + var2 = var1 * var1 * (BME280_S64_t)dig_P6; + var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17); + var2 = var2 + (((BME280_S64_t)dig_P4)<<35); + var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12); + var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33; + if (var1 == 0){ + return 0; // ゼロ除算による例外を避ける。 + } + p = 1048576-adc_P; + p = (((p<<31)-var2)*3125)/var1; + var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25; + var2 = (((BME280_S64_t)dig_P8) * p) >> 19; + p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4); + return (BME280_U32_t)p; +} + +// 湿度(%RH)を、Q22.10形式の符号なし32ビット整数として返します。(22個の整数と10個の小数ビット) +// 「47445」の出力値は、47445/1024 = 46.333%RHに相当します。 +BME280_U32_t BME280::BME280_compensate_H_int32(BME280_S32_t adc_H){ + BME280_S32_t v_x1_u32r; + v_x1_u32r = (t_fine - ((BME280_S32_t)76800)); + v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - (((BME280_S32_t)dig_H5) * v_x1_u32r)) + + ((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r * + ((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) * + ((BME280_S32_t)dig_H2) + 8192) >> 14)); + v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_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 (BME280_U32_t)(v_x1_u32r>>12); +} +//補正関数終わり + +void BME280::init(void){ + char calib[32] = {0}; + char reg_data; + sensor.write_reg(BME280_add, RESET_REG, RESET_VALUE); + + reg_data = sensor.read_reg(BME280_add,ID); //ID読み込み + if(reg_data != ID_VALUE){ //ID不一致エラー + printf("error\n"); + while(1); + } + while(STATUS_IS_COPYING); //不揮発メモリのデータのレジスタコピー待ち + + //ADC補償式用定数読み込み + sensor.read_reg(BME280_add, CALIB00, &(calib[0]), 24); + sensor.read_reg(BME280_add, CALIB25, &(calib[24]), 1); + sensor.read_reg(BME280_add, CALIB26, &(calib[25]), 7); + + dig_T1 = calib[ 0] | (calib[ 1] << 8); + dig_T2 = calib[ 2] | (calib[ 3] << 8); + dig_T3 = calib[ 4] | (calib[ 5] << 8); + + dig_P1 = calib[ 6] | (calib[ 7] << 8); + dig_P2 = calib[ 8] | (calib[ 9] << 8); + dig_P3 = calib[10] | (calib[11] << 8); + dig_P4 = calib[12] | (calib[13] << 8); + dig_P5 = calib[14] | (calib[15] << 8); + dig_P6 = calib[16] | (calib[17] << 8); + dig_P7 = calib[18] | (calib[19] << 8); + dig_P8 = calib[20] | (calib[21] << 8); + dig_P9 = calib[22] | (calib[23] << 8); + + dig_H1 = calib[24]; + dig_H2 = calib[25] | (calib[26] << 8); + dig_H3 = calib[27]; + dig_H4 = (calib[28]<<4) | (calib[29] & 0x0F); + dig_H5 = ((calib[29]>>4) & 0x0F) | (calib[30] << 4); + dig_H6 = calib[31]; + //ADC補償式用定数読み込みEND + + //センサ設定 + sensor.write_reg(BME280_add, CTRL_HUM , hum_reg_value); + sensor.write_reg(BME280_add, CTRL_MEAS, meas_reg_value); + sensor.write_reg(BME280_add, CONFIG , config_reg_value); + +} + +