BME280にアクセスするためのライブラリ
BME280.cpp@8:c5f2c8022931, 2018-07-11 (annotated)
- Committer:
- j_rocket_boy
- Date:
- Wed Jul 11 16:28:32 2018 +0000
- Revision:
- 8:c5f2c8022931
- Parent:
- 4:4c4e3ec9a2c4
modify license year
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
j_rocket_boy | 4:4c4e3ec9a2c4 | 1 | // -*- coding: utf-8 -*- |
j_rocket_boy | 4:4c4e3ec9a2c4 | 2 | /** |
j_rocket_boy | 4:4c4e3ec9a2c4 | 3 | @file BME280.cpp |
j_rocket_boy | 4:4c4e3ec9a2c4 | 4 | @brief MBE280のライブラリ |
j_rocket_boy | 4:4c4e3ec9a2c4 | 5 | |
j_rocket_boy | 4:4c4e3ec9a2c4 | 6 | @author D.Nakayama |
j_rocket_boy | 4:4c4e3ec9a2c4 | 7 | @version 1.0 |
j_rocket_boy | 4:4c4e3ec9a2c4 | 8 | @date 2018-07-10 D.Nakayama Written for C++/mbed. |
j_rocket_boy | 4:4c4e3ec9a2c4 | 9 | |
j_rocket_boy | 4:4c4e3ec9a2c4 | 10 | |
j_rocket_boy | 4:4c4e3ec9a2c4 | 11 | @see |
j_rocket_boy | 8:c5f2c8022931 | 12 | Copyright (C) 2018 D.Nakayama. |
j_rocket_boy | 4:4c4e3ec9a2c4 | 13 | Released under the MIT license. |
j_rocket_boy | 4:4c4e3ec9a2c4 | 14 | http://opensource.org/licenses/mit-license.php |
j_rocket_boy | 4:4c4e3ec9a2c4 | 15 | |
j_rocket_boy | 4:4c4e3ec9a2c4 | 16 | */ |
j_rocket_boy | 4:4c4e3ec9a2c4 | 17 | |
j_rocket_boy | 0:95f2b96cdc7f | 18 | #include "mbed.h" |
j_rocket_boy | 0:95f2b96cdc7f | 19 | #include "BME280.h" |
j_rocket_boy | 0:95f2b96cdc7f | 20 | #include "i2c_general_io.h" |
j_rocket_boy | 0:95f2b96cdc7f | 21 | |
j_rocket_boy | 3:df1107ddf502 | 22 | //コンストラクタ1 |
j_rocket_boy | 3:df1107ddf502 | 23 | BME280::BME280(PinName sda, PinName scl, |
j_rocket_boy | 3:df1107ddf502 | 24 | char mode, |
j_rocket_boy | 3:df1107ddf502 | 25 | char press_sample, |
j_rocket_boy | 3:df1107ddf502 | 26 | char temp_sample, |
j_rocket_boy | 3:df1107ddf502 | 27 | char hum_sample, |
j_rocket_boy | 3:df1107ddf502 | 28 | char filter, |
j_rocket_boy | 3:df1107ddf502 | 29 | char stanby) |
j_rocket_boy | 0:95f2b96cdc7f | 30 | : |
j_rocket_boy | 0:95f2b96cdc7f | 31 | i2c_p(new GEN_I2C(sda, scl)), |
j_rocket_boy | 0:95f2b96cdc7f | 32 | sensor(*i2c_p) |
j_rocket_boy | 0:95f2b96cdc7f | 33 | { |
j_rocket_boy | 3:df1107ddf502 | 34 | _mode = mode; |
j_rocket_boy | 3:df1107ddf502 | 35 | _press_sample = press_sample; |
j_rocket_boy | 3:df1107ddf502 | 36 | _temp_sample = temp_sample; |
j_rocket_boy | 3:df1107ddf502 | 37 | _hum_sample = hum_sample; |
j_rocket_boy | 3:df1107ddf502 | 38 | _filter = filter; |
j_rocket_boy | 3:df1107ddf502 | 39 | _stanby = stanby; |
j_rocket_boy | 0:95f2b96cdc7f | 40 | init(); |
j_rocket_boy | 0:95f2b96cdc7f | 41 | } |
j_rocket_boy | 0:95f2b96cdc7f | 42 | |
j_rocket_boy | 3:df1107ddf502 | 43 | //コンストラクタ2 |
j_rocket_boy | 3:df1107ddf502 | 44 | BME280::BME280(GEN_I2C &i2c_obj, |
j_rocket_boy | 3:df1107ddf502 | 45 | char mode, |
j_rocket_boy | 3:df1107ddf502 | 46 | char press_sample, |
j_rocket_boy | 3:df1107ddf502 | 47 | char temp_sample, |
j_rocket_boy | 3:df1107ddf502 | 48 | char hum_sample, |
j_rocket_boy | 3:df1107ddf502 | 49 | char filter, |
j_rocket_boy | 3:df1107ddf502 | 50 | char stanby) |
j_rocket_boy | 0:95f2b96cdc7f | 51 | : |
j_rocket_boy | 0:95f2b96cdc7f | 52 | i2c_p(NULL), |
j_rocket_boy | 0:95f2b96cdc7f | 53 | sensor(i2c_obj) |
j_rocket_boy | 0:95f2b96cdc7f | 54 | { |
j_rocket_boy | 3:df1107ddf502 | 55 | _mode = mode; |
j_rocket_boy | 3:df1107ddf502 | 56 | _press_sample = press_sample; |
j_rocket_boy | 3:df1107ddf502 | 57 | _temp_sample = temp_sample; |
j_rocket_boy | 3:df1107ddf502 | 58 | _hum_sample = hum_sample; |
j_rocket_boy | 3:df1107ddf502 | 59 | _filter = filter; |
j_rocket_boy | 3:df1107ddf502 | 60 | _stanby = stanby; |
j_rocket_boy | 0:95f2b96cdc7f | 61 | init(); |
j_rocket_boy | 0:95f2b96cdc7f | 62 | } |
j_rocket_boy | 0:95f2b96cdc7f | 63 | |
j_rocket_boy | 3:df1107ddf502 | 64 | //デストラクタ |
j_rocket_boy | 0:95f2b96cdc7f | 65 | BME280::~BME280() |
j_rocket_boy | 0:95f2b96cdc7f | 66 | { |
j_rocket_boy | 0:95f2b96cdc7f | 67 | if (NULL != i2c_p) |
j_rocket_boy | 0:95f2b96cdc7f | 68 | delete i2c_p; |
j_rocket_boy | 0:95f2b96cdc7f | 69 | } |
j_rocket_boy | 0:95f2b96cdc7f | 70 | |
j_rocket_boy | 3:df1107ddf502 | 71 | //センサーからデータ読み取り |
j_rocket_boy | 0:95f2b96cdc7f | 72 | void BME280::read_sensor(void){ |
j_rocket_boy | 0:95f2b96cdc7f | 73 | char sensor_raw_data[8]; |
j_rocket_boy | 1:0dbf59c6e564 | 74 | long signed int T,P,H; //ADC読み込み後温度,気圧,湿度の生データ |
j_rocket_boy | 1:0dbf59c6e564 | 75 | long signed int T_cor; //温度の補正データ |
j_rocket_boy | 1:0dbf59c6e564 | 76 | long unsigned int P_cor,H_cor; //気圧,湿度の補正データ |
j_rocket_boy | 0:95f2b96cdc7f | 77 | |
j_rocket_boy | 3:df1107ddf502 | 78 | |
j_rocket_boy | 0:95f2b96cdc7f | 79 | //読み込み |
j_rocket_boy | 3:df1107ddf502 | 80 | |
j_rocket_boy | 3:df1107ddf502 | 81 | //ノーマルモードでないとき |
j_rocket_boy | 3:df1107ddf502 | 82 | if( _mode != BME280_NORMAL_MODE ){ |
j_rocket_boy | 3:df1107ddf502 | 83 | set_force_mode(); //強制モードで測定開始 |
j_rocket_boy | 3:df1107ddf502 | 84 | while(BME280_STATUS_IS_MEASURING); //測定待ち |
j_rocket_boy | 3:df1107ddf502 | 85 | } |
j_rocket_boy | 3:df1107ddf502 | 86 | |
j_rocket_boy | 3:df1107ddf502 | 87 | sensor.read_reg(BME280_add, BME280_PRESS_MSB, sensor_raw_data, 8); //PRESS_MSBレジスタから8バイト読み込み |
j_rocket_boy | 3:df1107ddf502 | 88 | |
j_rocket_boy | 3:df1107ddf502 | 89 | //ビットシフトしてデータを結合 |
j_rocket_boy | 0:95f2b96cdc7f | 90 | T = sensor_raw_data[3] << 12 | sensor_raw_data[4] << 4 | sensor_raw_data[5] >> 4 ; |
j_rocket_boy | 0:95f2b96cdc7f | 91 | P = sensor_raw_data[0] << 12 | sensor_raw_data[1] << 4 | sensor_raw_data[2] >> 4 ; |
j_rocket_boy | 0:95f2b96cdc7f | 92 | H = sensor_raw_data[6] << 8 | sensor_raw_data[7]; |
j_rocket_boy | 0:95f2b96cdc7f | 93 | |
j_rocket_boy | 3:df1107ddf502 | 94 | |
j_rocket_boy | 0:95f2b96cdc7f | 95 | //補正 |
j_rocket_boy | 0:95f2b96cdc7f | 96 | T_cor = BME280_compensate_T_int32(T); |
j_rocket_boy | 0:95f2b96cdc7f | 97 | P_cor = BME280_compensate_P_int64(P); |
j_rocket_boy | 0:95f2b96cdc7f | 98 | H_cor = BME280_compensate_H_int32(H); |
j_rocket_boy | 3:df1107ddf502 | 99 | |
j_rocket_boy | 0:95f2b96cdc7f | 100 | |
j_rocket_boy | 3:df1107ddf502 | 101 | //不動小数点数に直す |
j_rocket_boy | 3:df1107ddf502 | 102 | press = P_cor / 256.0; //単位Pa |
j_rocket_boy | 3:df1107ddf502 | 103 | temp = T_cor / 100.0; //単位℃ |
j_rocket_boy | 3:df1107ddf502 | 104 | hum = H_cor / 1024.0; //単位% |
j_rocket_boy | 3:df1107ddf502 | 105 | |
j_rocket_boy | 0:95f2b96cdc7f | 106 | } |
j_rocket_boy | 0:95f2b96cdc7f | 107 | |
j_rocket_boy | 3:df1107ddf502 | 108 | //強制測定モードをセットする関数。 |
j_rocket_boy | 3:df1107ddf502 | 109 | inline void BME280::set_force_mode(void){ |
j_rocket_boy | 3:df1107ddf502 | 110 | sensor.write_reg(BME280_add, BME280_CTRL_MEAS, (_press_sample & 0x1C) | (_temp_sample & 0xE0) | BME280_FORCE_MODE ); |
j_rocket_boy | 0:95f2b96cdc7f | 111 | } |
j_rocket_boy | 0:95f2b96cdc7f | 112 | |
j_rocket_boy | 0:95f2b96cdc7f | 113 | |
j_rocket_boy | 0:95f2b96cdc7f | 114 | //データシートより,補正関数 |
j_rocket_boy | 0:95f2b96cdc7f | 115 | // 温度を℃で返します。分解能は0.01℃です。「5123」の出力値は、51.23℃に相当します。 |
j_rocket_boy | 0:95f2b96cdc7f | 116 | // t_fineは、グローバル値として細かい温度値を持ちます。 |
j_rocket_boy | 1:0dbf59c6e564 | 117 | long signed int BME280::BME280_compensate_T_int32(long signed int adc_T){ |
j_rocket_boy | 1:0dbf59c6e564 | 118 | long signed int var1, var2, T; |
j_rocket_boy | 1:0dbf59c6e564 | 119 | var1 = ((((adc_T>>3) - ((long signed int)dig_T1<<1))) * ((long signed int)dig_T2)) >> 11; |
j_rocket_boy | 1:0dbf59c6e564 | 120 | var2 = (((((adc_T>>4) - ((long signed int)dig_T1)) * ((adc_T>>4) - ((long signed int)dig_T1))) >> 12) * |
j_rocket_boy | 1:0dbf59c6e564 | 121 | ((long signed int)dig_T3)) >> 14; |
j_rocket_boy | 0:95f2b96cdc7f | 122 | t_fine = var1 + var2; |
j_rocket_boy | 0:95f2b96cdc7f | 123 | T = (t_fine * 5 + 128) >> 8; |
j_rocket_boy | 0:95f2b96cdc7f | 124 | return T; |
j_rocket_boy | 0:95f2b96cdc7f | 125 | } |
j_rocket_boy | 0:95f2b96cdc7f | 126 | |
j_rocket_boy | 0:95f2b96cdc7f | 127 | // 圧力(Pa)を、Q24.8形式の符号なし32ビット整数として返します。(24個の整数ビットと8個の小数ビット) |
j_rocket_boy | 0:95f2b96cdc7f | 128 | // 「24674867」の出力値は、24674867/256 = 96386.2Pa = 963.862hPaに相当します。 |
j_rocket_boy | 1:0dbf59c6e564 | 129 | long unsigned int BME280::BME280_compensate_P_int64(long signed int adc_P){ |
j_rocket_boy | 1:0dbf59c6e564 | 130 | long long signed int var1, var2, p; |
j_rocket_boy | 1:0dbf59c6e564 | 131 | var1 = ((long long signed int)t_fine) - 128000; |
j_rocket_boy | 1:0dbf59c6e564 | 132 | var2 = var1 * var1 * (long long signed int)dig_P6; |
j_rocket_boy | 1:0dbf59c6e564 | 133 | var2 = var2 + ((var1*(long long signed int)dig_P5)<<17); |
j_rocket_boy | 1:0dbf59c6e564 | 134 | var2 = var2 + (((long long signed int)dig_P4)<<35); |
j_rocket_boy | 1:0dbf59c6e564 | 135 | var1 = ((var1 * var1 * (long long signed int)dig_P3)>>8) + ((var1 * (long long signed int)dig_P2)<<12); |
j_rocket_boy | 1:0dbf59c6e564 | 136 | var1 = (((((long long signed int)1)<<47)+var1))*((long long signed int)dig_P1)>>33; |
j_rocket_boy | 0:95f2b96cdc7f | 137 | if (var1 == 0){ |
j_rocket_boy | 0:95f2b96cdc7f | 138 | return 0; // ゼロ除算による例外を避ける。 |
j_rocket_boy | 0:95f2b96cdc7f | 139 | } |
j_rocket_boy | 0:95f2b96cdc7f | 140 | p = 1048576-adc_P; |
j_rocket_boy | 0:95f2b96cdc7f | 141 | p = (((p<<31)-var2)*3125)/var1; |
j_rocket_boy | 1:0dbf59c6e564 | 142 | var1 = (((long long signed int)dig_P9) * (p>>13) * (p>>13)) >> 25; |
j_rocket_boy | 1:0dbf59c6e564 | 143 | var2 = (((long long signed int)dig_P8) * p) >> 19; |
j_rocket_boy | 1:0dbf59c6e564 | 144 | p = ((p + var1 + var2) >> 8) + (((long long signed int)dig_P7)<<4); |
j_rocket_boy | 1:0dbf59c6e564 | 145 | return (long unsigned int)p; |
j_rocket_boy | 0:95f2b96cdc7f | 146 | } |
j_rocket_boy | 0:95f2b96cdc7f | 147 | |
j_rocket_boy | 0:95f2b96cdc7f | 148 | // 湿度(%RH)を、Q22.10形式の符号なし32ビット整数として返します。(22個の整数と10個の小数ビット) |
j_rocket_boy | 0:95f2b96cdc7f | 149 | // 「47445」の出力値は、47445/1024 = 46.333%RHに相当します。 |
j_rocket_boy | 1:0dbf59c6e564 | 150 | long unsigned int BME280::BME280_compensate_H_int32(long signed int adc_H){ |
j_rocket_boy | 1:0dbf59c6e564 | 151 | long signed int v_x1_u32r; |
j_rocket_boy | 1:0dbf59c6e564 | 152 | v_x1_u32r = (t_fine - ((long signed int)76800)); |
j_rocket_boy | 1:0dbf59c6e564 | 153 | v_x1_u32r = (((((adc_H << 14) - (((long signed int)dig_H4) << 20) - (((long signed int)dig_H5) * v_x1_u32r)) + |
j_rocket_boy | 1:0dbf59c6e564 | 154 | ((long signed int)16384)) >> 15) * (((((((v_x1_u32r * ((long signed int)dig_H6)) >> 10) * (((v_x1_u32r * |
j_rocket_boy | 1:0dbf59c6e564 | 155 | ((long signed int)dig_H3)) >> 11) + ((long signed int)32768))) >> 10) + ((long signed int)2097152)) * |
j_rocket_boy | 1:0dbf59c6e564 | 156 | ((long signed int)dig_H2) + 8192) >> 14)); |
j_rocket_boy | 1:0dbf59c6e564 | 157 | v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((long signed int)dig_H1)) >> 4)); |
j_rocket_boy | 0:95f2b96cdc7f | 158 | v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); |
j_rocket_boy | 0:95f2b96cdc7f | 159 | v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); |
j_rocket_boy | 1:0dbf59c6e564 | 160 | return (long unsigned int)(v_x1_u32r>>12); |
j_rocket_boy | 0:95f2b96cdc7f | 161 | } |
j_rocket_boy | 0:95f2b96cdc7f | 162 | //補正関数終わり |
j_rocket_boy | 0:95f2b96cdc7f | 163 | |
j_rocket_boy | 3:df1107ddf502 | 164 | //初期化関数 |
j_rocket_boy | 0:95f2b96cdc7f | 165 | void BME280::init(void){ |
j_rocket_boy | 3:df1107ddf502 | 166 | |
j_rocket_boy | 3:df1107ddf502 | 167 | char calib[32] = {0}; //補正係数読み取り用 |
j_rocket_boy | 3:df1107ddf502 | 168 | char reg_data; //レジスタ読み取り用 |
j_rocket_boy | 0:95f2b96cdc7f | 169 | |
j_rocket_boy | 3:df1107ddf502 | 170 | //リセット |
j_rocket_boy | 3:df1107ddf502 | 171 | sensor.write_reg(BME280_add, BME280_RESET_REG, BME280_RESET_VALUE); |
j_rocket_boy | 3:df1107ddf502 | 172 | |
j_rocket_boy | 3:df1107ddf502 | 173 | //ID読み込み |
j_rocket_boy | 3:df1107ddf502 | 174 | reg_data = sensor.read_reg(BME280_add,BME280_ID); |
j_rocket_boy | 3:df1107ddf502 | 175 | if(reg_data != BME280_ID_VALUE){ //ID不一致エラー |
j_rocket_boy | 0:95f2b96cdc7f | 176 | printf("error\n"); |
j_rocket_boy | 0:95f2b96cdc7f | 177 | while(1); |
j_rocket_boy | 0:95f2b96cdc7f | 178 | } |
j_rocket_boy | 3:df1107ddf502 | 179 | |
j_rocket_boy | 3:df1107ddf502 | 180 | //不揮発メモリのデータのレジスタコピー待ち |
j_rocket_boy | 3:df1107ddf502 | 181 | while(BME280_STATUS_IS_COPYING); |
j_rocket_boy | 0:95f2b96cdc7f | 182 | |
j_rocket_boy | 0:95f2b96cdc7f | 183 | //ADC補償式用定数読み込み |
j_rocket_boy | 3:df1107ddf502 | 184 | sensor.read_reg(BME280_add, BME280_CALIB00, &(calib[0]), 24); |
j_rocket_boy | 3:df1107ddf502 | 185 | sensor.read_reg(BME280_add, BME280_CALIB25, &(calib[24]), 1); |
j_rocket_boy | 3:df1107ddf502 | 186 | sensor.read_reg(BME280_add, BME280_CALIB26, &(calib[25]), 7); |
j_rocket_boy | 0:95f2b96cdc7f | 187 | |
j_rocket_boy | 3:df1107ddf502 | 188 | //ビットシフトして対応する変数に格納(温度補正係数) |
j_rocket_boy | 0:95f2b96cdc7f | 189 | dig_T1 = calib[ 0] | (calib[ 1] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 190 | dig_T2 = calib[ 2] | (calib[ 3] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 191 | dig_T3 = calib[ 4] | (calib[ 5] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 192 | |
j_rocket_boy | 3:df1107ddf502 | 193 | //ビットシフトして対応する変数に格納(気圧補正係数) |
j_rocket_boy | 0:95f2b96cdc7f | 194 | dig_P1 = calib[ 6] | (calib[ 7] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 195 | dig_P2 = calib[ 8] | (calib[ 9] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 196 | dig_P3 = calib[10] | (calib[11] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 197 | dig_P4 = calib[12] | (calib[13] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 198 | dig_P5 = calib[14] | (calib[15] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 199 | dig_P6 = calib[16] | (calib[17] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 200 | dig_P7 = calib[18] | (calib[19] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 201 | dig_P8 = calib[20] | (calib[21] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 202 | dig_P9 = calib[22] | (calib[23] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 203 | |
j_rocket_boy | 3:df1107ddf502 | 204 | //ビットシフトして対応する変数に格納(湿度補正係数) |
j_rocket_boy | 0:95f2b96cdc7f | 205 | dig_H1 = calib[24]; |
j_rocket_boy | 0:95f2b96cdc7f | 206 | dig_H2 = calib[25] | (calib[26] << 8); |
j_rocket_boy | 0:95f2b96cdc7f | 207 | dig_H3 = calib[27]; |
j_rocket_boy | 0:95f2b96cdc7f | 208 | dig_H4 = (calib[28]<<4) | (calib[29] & 0x0F); |
j_rocket_boy | 0:95f2b96cdc7f | 209 | dig_H5 = ((calib[29]>>4) & 0x0F) | (calib[30] << 4); |
j_rocket_boy | 0:95f2b96cdc7f | 210 | dig_H6 = calib[31]; |
j_rocket_boy | 0:95f2b96cdc7f | 211 | |
j_rocket_boy | 0:95f2b96cdc7f | 212 | //センサ設定 |
j_rocket_boy | 3:df1107ddf502 | 213 | sensor.write_reg(BME280_add, BME280_CTRL_HUM , (_hum_sample & 0x07) ); |
j_rocket_boy | 3:df1107ddf502 | 214 | sensor.write_reg(BME280_add, BME280_CTRL_MEAS, (_press_sample & 0x1C) | (_temp_sample & 0xE0) | (_mode & 0x03) ); |
j_rocket_boy | 3:df1107ddf502 | 215 | sensor.write_reg(BME280_add, BME280_CONFIG , (_stanby & 0xE0) | (_filter & 0x1C) ); |
j_rocket_boy | 0:95f2b96cdc7f | 216 | |
j_rocket_boy | 0:95f2b96cdc7f | 217 | } |
j_rocket_boy | 0:95f2b96cdc7f | 218 | |
j_rocket_boy | 0:95f2b96cdc7f | 219 |