@@ -40,15 +40,14 @@ BME280::BME280( void )
4040
4141 // Select interface mode
4242 settings.commInterface = I2C_MODE; // Can be I2C_MODE, SPI_MODE
43+
4344 // Select address for I2C. Does nothing for SPI
4445 settings.I2CAddress = 0x77 ; // Ignored for SPI_MODE
46+
4547 // Select CS pin for SPI. Does nothing for I2C
4648 settings.chipSelectPin = 10 ;
47- settings.runMode = 0 ;
48- settings.tempOverSample = 0 ;
49- settings.pressOverSample = 0 ;
50- settings.humidOverSample = 0 ;
5149
50+ settings.runMode = 0 ;
5251}
5352
5453
@@ -63,13 +62,14 @@ BME280::BME280( void )
6362// ****************************************************************************//
6463uint8_t BME280::begin ()
6564{
65+ delay (2 ); // Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
66+
6667 // Check the settings structure values to determine how to setup the device
67- uint8_t dataToWrite = 0 ; // Temporary variable
6868 switch (settings.commInterface )
6969 {
7070
7171 case I2C_MODE:
72- Wire. begin ();
72+ if (_i2cPort != 0 ) _i2cPort-> begin ();
7373 break ;
7474
7575 case SPI_MODE:
@@ -125,30 +125,141 @@ uint8_t BME280::begin()
125125 calibration.dig_H5 = ((int16_t )((readRegister (BME280_DIG_H5_MSB_REG) << 4 ) + ((readRegister (BME280_DIG_H4_LSB_REG) >> 4 ) & 0x0F )));
126126 calibration.dig_H6 = ((int8_t )readRegister (BME280_DIG_H6_REG));
127127
128- // Set the oversampling control words.
129- // config will only be writeable in sleep mode, so first insure that.
130- writeRegister (BME280_CTRL_MEAS_REG, 0x00 );
128+ settings.runMode = 3 ; // 3, Normal mode
129+ settings.tStandby = 0 ; // 0, 0.5ms
130+ settings.filter = 0 ; // 0, filter off
131+
132+ setPressureOverSample (1 ); // Default
133+ setHumidityOverSample (1 ); // Default
134+ setTempOverSample (1 ); // Default
135+
136+ setMode (MODE_NORMAL); // Go!
131137
132- // Set the config word
133- dataToWrite = (settings.tStandby << 0x5 ) & 0xE0 ;
134- dataToWrite |= (settings.filter << 0x02 ) & 0x1C ;
135- writeRegister (BME280_CONFIG_REG, dataToWrite);
138+ return (readRegister (BME280_CHIP_ID_REG)); // Should return 0x60
139+ }
140+
141+ // Begin comm with BME280 over I2C
142+ bool BME280::beginI2C (TwoWire &wirePort)
143+ {
144+ _i2cPort = &wirePort;
145+ _i2cPort->begin (); // The caller can begin their port and set the speed. We just confirm it here otherwise it can be hard to debug.
136146
137- // Set ctrl_hum first, then ctrl_meas to activate ctrl_hum
138- dataToWrite = settings.humidOverSample & 0x07 ; // all other bits can be ignored
139- writeRegister (BME280_CTRL_HUMIDITY_REG, dataToWrite);
147+ settings.commInterface = I2C_MODE;
148+ // settings.I2CAddress = 0x77; //We assume user has set the I2C address using setI2CAddress()
140149
141- // set ctrl_meas
142- // First, set temp oversampling
143- dataToWrite = (settings.tempOverSample << 0x5 ) & 0xE0 ;
144- // Next, pressure oversampling
145- dataToWrite |= (settings.pressOverSample << 0x02 ) & 0x1C ;
146- // Last, set mode
147- dataToWrite |= (settings.runMode ) & 0x03 ;
148- // Load the byte
149- writeRegister (BME280_CTRL_MEAS_REG, dataToWrite);
150+ if (begin () == 0x60 ) return (true ); // Begin normal init with these settings. Should return chip ID of 0x60
151+ return (false );
152+ }
153+
154+ // Set the mode bits in the ctrl_meas register
155+ // Mode 00 = Sleep
156+ // 01 and 10 = Forced
157+ // 11 = Normal mode
158+ void BME280::setMode (uint8_t mode)
159+ {
160+ if (mode > 0b11 ) mode = 0 ; // Error check. Default to sleep mode
150161
151- return readRegister (0xD0 );
162+ uint8_t controlData = readRegister (BME280_CTRL_MEAS_REG);
163+ controlData &= ~( (1 <<1 ) | (1 <<0 ) ); // Clear the mode[1:0] bits
164+ controlData |= mode; // Set
165+ writeRegister (BME280_CTRL_MEAS_REG, controlData);
166+ }
167+
168+ // Gets the current mode bits in the ctrl_meas register
169+ // Mode 00 = Sleep
170+ // 01 and 10 = Forced
171+ // 11 = Normal mode
172+ uint8_t BME280::getMode ()
173+ {
174+ uint8_t controlData = readRegister (BME280_CTRL_MEAS_REG);
175+ return (controlData & 0b11111100 ); // Mask out all but bits 1 and 0
176+ }
177+
178+ // Set the temperature oversample value
179+ // 0 turns off temp sensing
180+ // 1 to 16 are valid over sampling values
181+ void BME280::setTempOverSample (uint8_t overSampleAmount)
182+ {
183+ overSampleAmount = checkSampleValue (overSampleAmount); // Error check
184+
185+ uint8_t originalMode = getMode (); // Get the current mode so we can go back to it at the end
186+
187+ setMode (MODE_SLEEP); // Config will only be writeable in sleep mode, so first go to sleep mode
188+
189+ // Set the osrs_t bits (7, 6, 5) to overSampleAmount
190+ uint8_t controlData = readRegister (BME280_CTRL_MEAS_REG);
191+ controlData &= ~( (1 <<7 ) | (1 <<6 ) | (1 <<5 ) ); // Clear bits 765
192+ controlData |= overSampleAmount << 5 ; // Align overSampleAmount to bits 7/6/5
193+ writeRegister (BME280_CTRL_MEAS_REG, controlData);
194+
195+ setMode (originalMode); // Return to the original user's choice
196+ }
197+
198+ // Set the pressure oversample value
199+ // 0 turns off pressure sensing
200+ // 1 to 16 are valid over sampling values
201+ void BME280::setPressureOverSample (uint8_t overSampleAmount)
202+ {
203+ overSampleAmount = checkSampleValue (overSampleAmount); // Error check
204+
205+ uint8_t originalMode = getMode (); // Get the current mode so we can go back to it at the end
206+
207+ setMode (MODE_SLEEP); // Config will only be writeable in sleep mode, so first go to sleep mode
208+
209+ // Set the osrs_p bits (4, 3, 2) to overSampleAmount
210+ uint8_t controlData = readRegister (BME280_CTRL_MEAS_REG);
211+ controlData &= ~( (1 <<4 ) | (1 <<3 ) | (1 <<2 ) ); // Clear bits 432
212+ controlData |= overSampleAmount << 2 ; // Align overSampleAmount to bits 4/3/2
213+ writeRegister (BME280_CTRL_MEAS_REG, controlData);
214+
215+ setMode (originalMode); // Return to the original user's choice
216+ }
217+
218+ // Set the humidity oversample value
219+ // 0 turns off humidity sensing
220+ // 1 to 16 are valid over sampling values
221+ void BME280::setHumidityOverSample (uint8_t overSampleAmount)
222+ {
223+ overSampleAmount = checkSampleValue (overSampleAmount); // Error check
224+
225+ uint8_t originalMode = getMode (); // Get the current mode so we can go back to it at the end
226+
227+ setMode (MODE_SLEEP); // Config will only be writeable in sleep mode, so first go to sleep mode
228+
229+ // Set the osrs_h bits (2, 1, 0) to overSampleAmount
230+ uint8_t controlData = readRegister (BME280_CTRL_HUMIDITY_REG);
231+ controlData &= ~( (1 <<2 ) | (1 <<1 ) | (1 <<0 ) ); // Clear bits 2/1/0
232+ controlData |= overSampleAmount << 0 ; // Align overSampleAmount to bits 2/1/0
233+ writeRegister (BME280_CTRL_HUMIDITY_REG, controlData);
234+
235+ setMode (originalMode); // Return to the original user's choice
236+ }
237+
238+ // Validates an over sample value
239+ // Allowed values are 0 to 16
240+ // These are used in the humidty, pressure, and temp oversample functions
241+ uint8_t BME280::checkSampleValue (uint8_t userValue)
242+ {
243+ switch (userValue)
244+ {
245+ case (0 ): break ; // Valid
246+ case (1 ): break ; // Valid
247+ case (2 ): break ; // Valid
248+ case (4 ): break ; // Valid
249+ case (8 ): break ; // Valid
250+ case (16 ): break ; // Valid
251+ default :
252+ userValue = 1 ; // Default to 1x
253+ break ; // Good
254+ }
255+ return (userValue);
256+ }
257+
258+ // Set the global setting for the I2C address we want to communicate with
259+ // Default is 0x77
260+ void BME280::setI2CAddress (uint8_t address)
261+ {
262+ settings.I2CAddress = address; // Set the I2C address for this device
152263}
153264
154265// Strictly resets. Run .begin() afterwards
@@ -191,11 +302,25 @@ float BME280::readFloatPressure( void )
191302
192303}
193304
305+ // Sets the internal variable _referencePressure so the
306+ void BME280::setReferencePressure (float refPressure)
307+ {
308+ _referencePressure = rePressure;
309+ }
310+
311+ // Return the local reference pressure
312+ float BME280::getReferencePressure ()
313+ {
314+ return (_referencePressure);
315+ }
316+
317+
318+
194319float BME280::readFloatAltitudeMeters ( void )
195320{
196321 float heightOutput = 0 ;
197322
198- heightOutput = ((float )-45846.2 )*(pow (((float )readFloatPressure ()/(float )101325 ), 0.190263 ) - (float )1 );
323+ heightOutput = ((float )-45846.2 )*(pow (((float )readFloatPressure ()/(float )_referencePressure ), 0.190263 ) - (float )1 );
199324 return heightOutput;
200325
201326}
@@ -287,15 +412,15 @@ void BME280::readRegisterRegion(uint8_t *outputPointer , uint8_t offset, uint8_t
287412 {
288413
289414 case I2C_MODE:
290- Wire. beginTransmission (settings.I2CAddress );
291- Wire. write (offset);
292- Wire. endTransmission ();
415+ _i2cPort-> beginTransmission (settings.I2CAddress );
416+ _i2cPort-> write (offset);
417+ _i2cPort-> endTransmission ();
293418
294419 // request bytes from slave device
295- Wire. requestFrom (settings.I2CAddress , length);
296- while ( (Wire. available ()) && (i < length)) // slave may send less than requested
420+ _i2cPort-> requestFrom (settings.I2CAddress , length);
421+ while ( (_i2cPort-> available ()) && (i < length)) // slave may send less than requested
297422 {
298- c = Wire. read (); // receive a byte as character
423+ c = _i2cPort-> read (); // receive a byte as character
299424 *outputPointer = c;
300425 outputPointer++;
301426 i++;
@@ -332,14 +457,14 @@ uint8_t BME280::readRegister(uint8_t offset)
332457 switch (settings.commInterface ) {
333458
334459 case I2C_MODE:
335- Wire. beginTransmission (settings.I2CAddress );
336- Wire. write (offset);
337- Wire. endTransmission ();
460+ _i2cPort-> beginTransmission (settings.I2CAddress );
461+ _i2cPort-> write (offset);
462+ _i2cPort-> endTransmission ();
338463
339- Wire. requestFrom (settings.I2CAddress , numBytes);
340- while ( Wire. available () ) // slave may send less than requested
464+ _i2cPort-> requestFrom (settings.I2CAddress , numBytes);
465+ while ( _i2cPort-> available () ) // slave may send less than requested
341466 {
342- result = Wire. read (); // receive a byte as a proper uint8_t
467+ result = _i2cPort-> read (); // receive a byte as a proper uint8_t
343468 }
344469 break ;
345470
@@ -375,10 +500,10 @@ void BME280::writeRegister(uint8_t offset, uint8_t dataToWrite)
375500 {
376501 case I2C_MODE:
377502 // Write the byte
378- Wire. beginTransmission (settings.I2CAddress );
379- Wire. write (offset);
380- Wire. write (dataToWrite);
381- Wire. endTransmission ();
503+ _i2cPort-> beginTransmission (settings.I2CAddress );
504+ _i2cPort-> write (offset);
505+ _i2cPort-> write (dataToWrite);
506+ _i2cPort-> endTransmission ();
382507 break ;
383508
384509 case SPI_MODE:
0 commit comments