How do I Calibrate BME280 Readings

I am using Sparkfun BME280 sample code to read the BME280 and my Altitude is off for my location. My location was verified by actual location and GPS location The BME280 is reading 40ft low.

I have attached the code:

BME280 Arduino and Teensy example
Marshall Taylor @ SparkFun Electronics
May 20, 2015

This sketch configures the BME280 to read all measurements.  The sketch also
displays the BME280's physical memory and what the driver perceives the
calibration words to be.

Uses Wire.h for I2C operation
Uses SPI.h for SPI operation

Development environment specifics:
Arduino IDE 1.6.4
Teensy loader 1.23

This code is released under the [MIT License](
Please review the file included with this example. If you have any questions 
or concerns with licensing, please contact
Distributed as-is; no warranty is given.

#include <stdint.h>
#include "SparkFunBME280.h"
//Library allows either I2C or SPI, so include both.
#include "Wire.h"
//#include "SPI.h"

//Global sensor object
BME280 mySensor;

void setup()
	//***Driver settings********************************//
	//commInterface can be I2C_MODE or SPI_MODE
	//specify chipSelectPin using arduino pin names
	//specify I2C address.  Can be 0x77(default) or 0x76
	//For I2C, enable the following and disable the SPI section
	mySensor.settings.commInterface = I2C_MODE;
	mySensor.settings.I2CAddress = 0x76;
	//For SPI enable the following and dissable the I2C section
	//mySensor.settings.commInterface = SPI_MODE;
	//mySensor.settings.chipSelectPin = 10;

	//***Operation settings*****************************//
	//renMode can be:
	//  0, Sleep mode
	//  1 or 2, Forced mode
	//  3, Normal mode
	mySensor.settings.runMode = 3; //Normal mode
	//tStandby can be:
	//  0, 0.5ms
	//  1, 62.5ms
	//  2, 125ms
	//  3, 250ms
	//  4, 500ms
	//  5, 1000ms
	//  6, 10ms
	//  7, 20ms
	mySensor.settings.tStandby = 0;
	//filter can be off or number of FIR coefficients to use:
	//  0, filter off
	//  1, coefficients = 2
	//  2, coefficients = 4
	//  3, coefficients = 8
	//  4, coefficients = 16
	mySensor.settings.filter = 0;
	//tempOverSample can be:
	//  0, skipped
	//  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
	mySensor.settings.tempOverSample = 1;

	//pressOverSample can be:
	//  0, skipped
	//  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
    mySensor.settings.pressOverSample = 1;
	//humidOverSample can be:
	//  0, skipped
	//  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
	mySensor.settings.humidOverSample = 1;
	Serial.print("Program Started\n");
	Serial.print("Starting BME280... result of .begin(): 0x");
	//Calling .begin() causes the settings to be loaded
	delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
	Serial.println(mySensor.begin(), HEX);

	Serial.print("Displaying ID, reset and ctrl regs\n");
	Serial.print("ID(0xD0): 0x");
	Serial.println(mySensor.readRegister(BME280_CHIP_ID_REG), HEX);
	Serial.print("Reset register(0xE0): 0x");
	Serial.println(mySensor.readRegister(BME280_RST_REG), HEX);
	Serial.print("ctrl_meas(0xF4): 0x");
	Serial.println(mySensor.readRegister(BME280_CTRL_MEAS_REG), HEX);
	Serial.print("ctrl_hum(0xF2): 0x");
	Serial.println(mySensor.readRegister(BME280_CTRL_HUMIDITY_REG), HEX);


	Serial.print("Displaying all regs\n");
	uint8_t memCounter = 0x80;
	uint8_t tempReadData;
	for(int rowi = 8; rowi < 16; rowi++ )
		Serial.print(rowi, HEX);
		for(int coli = 0; coli < 16; coli++ )
			tempReadData = mySensor.readRegister(memCounter);
			Serial.print((tempReadData >> 4) & 0x0F, HEX);//Print first hex nibble
			Serial.print(tempReadData & 0x0F, HEX);//Print second hex nibble
			Serial.print(" ");
	Serial.print("Displaying concatenated calibration words\n");
	Serial.print("dig_T1, uint16: ");
	Serial.print("dig_T2, int16: ");
	Serial.print("dig_T3, int16: ");
	Serial.print("dig_P1, uint16: ");
	Serial.print("dig_P2, int16: ");
	Serial.print("dig_P3, int16: ");
	Serial.print("dig_P4, int16: ");
	Serial.print("dig_P5, int16: ");
	Serial.print("dig_P6, int16: ");
	Serial.print("dig_P7, int16: ");
	Serial.print("dig_P8, int16: ");
	Serial.print("dig_P9, int16: ");
	Serial.print("dig_H1, uint8: ");
	Serial.print("dig_H2, int16: ");
	Serial.print("dig_H3, uint8: ");
	Serial.print("dig_H4, int16: ");
	Serial.print("dig_H5, int16: ");
	Serial.print("dig_H6, uint8: ");

void loop()
	//Each loop, take a reading.
	//Start with temperature, as that data is needed for accurate compensation.
	//Reading the temperature updates the compensators of the other functions
	//in the background.

	Serial.print("Temperature: ");
	Serial.print(mySensor.readTempC(), 2);
	Serial.println(" degrees C");

	Serial.print("Temperature: ");
	Serial.print(mySensor.readTempF(), 2);
	Serial.println(" degrees F");

	Serial.print("Pressure: ");
	Serial.print(mySensor.readFloatPressure(), 2);
	Serial.println(" Pa");

	Serial.print("Altitude: ");
	Serial.print(mySensor.readFloatAltitudeMeters(), 2);

	Serial.print("Altitude: ");
	Serial.print(mySensor.readFloatAltitudeFeet(), 2);

	Serial.print("%RH: ");
	Serial.print(mySensor.readFloatHumidity(), 2);
	Serial.println(" %");


An unadjusted error of 40 feet is perfectly acceptable.

The altitude determined by a barometer depends on the reference (sea level) pressure, and due to weather changes, can go up and down by hundreds of feet in a day. The sea level reference has to be adjusted nearly every day.

Since the sea level reference pressure is not in the code you posted, it must be in the library.

I am working on being able to see Relative Air Density etc. Would getting the more accurate conditions be better via a gps module that then can get longitude, latitude, altitude and weather?

Is there Arduino code out there for the gps module to do that without wifi connections.

Not sure how the drag racing meters accurately do it but I don't think it is from gps or wifi. It must some kind of correction factor for sea level.

The BME280 measures absolute air pressure.

It is factory calibrated, but you can do better by comparing the measurements with those obtained from a professional quality barometer, and calculating an improved scale and offset factor to apply to the BME280 data.