BME280 Combined humidity and pressure sensor library with SPI interface

Dependents:   BME280_SPI_Hello TYBLE16_simple_data_logger mpl115a2_display_local GS_final

Fork of BME280 by Toyomasa Watarai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BME280_SPI.cpp Source File

BME280_SPI.cpp

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    BME280_SPI.cpp
00004  * @author  Toyomasa Watarai
00005  * @version V1.0.0
00006  * @date    11 March 2017
00007  * @brief   BME280_SPI class implementation
00008  ******************************************************************************
00009  * @attention
00010  *
00011  * Licensed under the Apache License, Version 2.0 (the "License");
00012  * you may not use this file except in compliance with the License.
00013  * You may obtain a copy of the License at
00014  *
00015  *     http://www.apache.org/licenses/LICENSE-2.0
00016  *
00017  * Unless required by applicable law or agreed to in writing, software
00018  * distributed under the License is distributed on an "AS IS" BASIS,
00019  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020  * See the License for the specific language governing permissions and
00021  * limitations under the License.
00022  */
00023 
00024 #include "mbed.h"
00025 #include "BME280_SPI.h"
00026 
00027 BME280_SPI::BME280_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs)
00028     :
00029     _spi(mosi, miso, sclk),
00030     _cs(cs),
00031     t_fine(0)
00032 {
00033     initialize();
00034 }
00035 
00036 
00037 BME280_SPI::~BME280_SPI()
00038 {
00039 }
00040 
00041 void BME280_SPI::initialize()
00042 {
00043     char cmd[18];
00044 
00045     _cs = 1;
00046     _spi.format(8, 0); // 8-bit, mode=0
00047     _spi.frequency(1000000); // 1MHZ
00048 
00049     _cs = 0;
00050     _spi.write(0xd0); // chip_id
00051     cmd[0] = _spi.write(0); // read chip_id
00052     _cs = 1;
00053     
00054     DEBUG_PRINT("chip_id = 0x%x\n", cmd[0]);
00055 
00056     _cs = 0;
00057     _spi.write(0xf2 & BME280_SPI_MASK); // ctrl_hum
00058     _spi.write(0x04); // Humidity oversampling x4
00059     _cs = 1;
00060 
00061     _cs = 0;
00062     _spi.write(0xf4 & BME280_SPI_MASK); // ctrl_meas
00063     _spi.write((4<<5)|(4<<2)|3); // Temparature oversampling x4, Pressure oversampling x4, Normal mode
00064     _cs = 1;
00065 
00066     _cs = 0;
00067     _spi.write(0xf5 & BME280_SPI_MASK); // config
00068     _spi.write(0xa0); // Standby 1000ms, Filter off, 4-wire SPI interface
00069     _cs = 1;
00070 
00071     wait(1);
00072     
00073     _cs = 0;
00074     _spi.write(0x88); // read dig_T regs
00075     for(int i = 0; i < 6; i++)
00076         cmd[i] = _spi.write(0);
00077     _cs = 1;
00078 
00079     dig_T1 = (cmd[1] << 8) | cmd[0];
00080     dig_T2 = (cmd[3] << 8) | cmd[2];
00081     dig_T3 = (cmd[5] << 8) | cmd[4];
00082 
00083     DEBUG_PRINT("dig_T = 0x%x, 0x%x, 0x%x\n", dig_T1, dig_T2, dig_T3);
00084     DEBUG_PRINT("dig_T = %d, %d, %d\n", dig_T1, dig_T2, dig_T3);
00085 
00086     _cs = 0;
00087     _spi.write(0x8e); // read dig_P regs
00088     for(int i = 0; i < 18; i++)
00089         cmd[i] = _spi.write(0);
00090     _cs = 1;
00091 
00092     dig_P1 = (cmd[ 1] << 8) | cmd[ 0];
00093     dig_P2 = (cmd[ 3] << 8) | cmd[ 2];
00094     dig_P3 = (cmd[ 5] << 8) | cmd[ 4];
00095     dig_P4 = (cmd[ 7] << 8) | cmd[ 6];
00096     dig_P5 = (cmd[ 9] << 8) | cmd[ 8];
00097     dig_P6 = (cmd[11] << 8) | cmd[10];
00098     dig_P7 = (cmd[13] << 8) | cmd[12];
00099     dig_P8 = (cmd[15] << 8) | cmd[14];
00100     dig_P9 = (cmd[17] << 8) | cmd[16];
00101 
00102     DEBUG_PRINT("dig_P = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9);
00103     DEBUG_PRINT("dig_P = %d, %d, %d, %d, %d, %d, %d, %d, %d\n", dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9);
00104 
00105     _cs = 0;
00106     _spi.write(0xA1); // read dig_H1 reg
00107     cmd[0] = _spi.write(0);
00108     _cs = 1;
00109 
00110     _cs = 0;
00111     _spi.write(0xE1); // read dig_H regs
00112     for(int i = 0; i < 7; i++)
00113         cmd[1+i] = _spi.write(0);
00114     _cs = 1;
00115 
00116     dig_H1 = cmd[0];
00117     dig_H2 = (cmd[2] << 8) | cmd[1];
00118     dig_H3 = cmd[3];
00119     dig_H4 = (cmd[4] << 4) | (cmd[5] & 0x0f);
00120     dig_H5 = (cmd[6] << 4) | ((cmd[5]>>4) & 0x0f);
00121     dig_H6 = cmd[7];
00122 
00123     DEBUG_PRINT("dig_H = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_H1, dig_H2, dig_H3, dig_H4, dig_H5, dig_H6);
00124     DEBUG_PRINT("dig_H = %d, %d, %d, %d, %d, %d\n", dig_H1, dig_H2, dig_H3, dig_H4, dig_H5, dig_H6);
00125 }
00126 
00127 float BME280_SPI::getTemperature()
00128 {
00129     uint32_t temp_raw;
00130     float tempf;
00131     char cmd[3];
00132 
00133     _cs = 0;
00134     _spi.write(0xfa);
00135     for(int i = 0; i < 3; i++)
00136         cmd[i] = _spi.write(0);
00137     _cs = 1;
00138 
00139     temp_raw = (cmd[0] << 12) | (cmd[1] << 4) | (cmd[2] >> 4);
00140 
00141     int32_t temp;
00142 
00143     temp =
00144         (((((temp_raw >> 3) - (dig_T1 << 1))) * dig_T2) >> 11) +
00145         ((((((temp_raw >> 4) - dig_T1) * ((temp_raw >> 4) - dig_T1)) >> 12) * dig_T3) >> 14);
00146 
00147     t_fine = temp;
00148     temp = (temp * 5 + 128) >> 8;
00149     tempf = (float)temp;
00150 
00151     return (tempf/100.0f);
00152 }
00153 
00154 float BME280_SPI::getPressure()
00155 {
00156     uint32_t press_raw;
00157     float pressf;
00158     char cmd[3];
00159 
00160     _cs = 0;
00161     _spi.write(0xf7); // press_msb
00162     for(int i = 0; i < 3; i++)
00163         cmd[i] = _spi.write(0);
00164     _cs = 1;
00165 
00166     press_raw = (cmd[0] << 12) | (cmd[1] << 4) | (cmd[2] >> 4);
00167 
00168     int32_t var1, var2;
00169     uint32_t press;
00170 
00171     var1 = (t_fine >> 1) - 64000;
00172     var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6;
00173     var2 = var2 + ((var1 * dig_P5) << 1);
00174     var2 = (var2 >> 2) + (dig_P4 << 16);
00175     var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18;
00176     var1 = ((32768 + var1) * dig_P1) >> 15;
00177     if (var1 == 0) {
00178         return 0;
00179     }
00180     press = (((1048576 - press_raw) - (var2 >> 12))) * 3125;
00181     if(press < 0x80000000) {
00182         press = (press << 1) / var1;
00183     } else {
00184         press = (press / var1) * 2;
00185     }
00186     var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13))) >> 12;
00187     var2 = (((int32_t)(press >> 2)) * (int32_t)dig_P8) >> 13;
00188     press = (press + ((var1 + var2 + dig_P7) >> 4));
00189 
00190     pressf = (float)press;
00191     return (pressf/100.0f);
00192 }
00193 
00194 float BME280_SPI::getHumidity()
00195 {
00196     uint32_t hum_raw;
00197     float humf;
00198     char cmd[2];
00199 
00200     _cs = 0;
00201     _spi.write(0xfd); // hum_msb
00202     for(int i = 0; i < 2; i++)
00203         cmd[i] = _spi.write(0);
00204     _cs = 1;
00205 
00206     hum_raw = (cmd[0] << 8) | cmd[1];
00207 
00208     int32_t v_x1;
00209 
00210     v_x1 = t_fine - 76800;
00211     v_x1 =  (((((hum_raw << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1)) +
00212                ((int32_t)16384)) >> 15) * (((((((v_x1 * (int32_t)dig_H6) >> 10) *
00213                                             (((v_x1 * ((int32_t)dig_H3)) >> 11) + 32768)) >> 10) + 2097152) *
00214                                             (int32_t)dig_H2 + 8192) >> 14));
00215     v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * (int32_t)dig_H1) >> 4));
00216     v_x1 = (v_x1 < 0 ? 0 : v_x1);
00217     v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
00218 
00219     humf = (float)(v_x1 >> 12);
00220 
00221     return (humf/1024.0f);
00222 }