Skip to content

Instantly share code, notes, and snippets.

@AlexanderBrevig
Created April 10, 2015 10:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AlexanderBrevig/e04fbeb19402d5f5d8f7 to your computer and use it in GitHub Desktop.
Save AlexanderBrevig/e04fbeb19402d5f5d8f7 to your computer and use it in GitHub Desktop.
Espruino BME280 module
var C = {
regCalibStart: 0x88,
regChipID: 0xd0,
regReset: 0xe0,
regCalibStart2: 0xe1,
regCtrlHum: 0xf2,
regStatus: 0xf3,
regCtrlMeas: 0xf4,
regConfig: 0xf5,
regMeasurementsStart: 0xf,
// address of BME280 on the MOD-1022 board
addrBME280: 0x76
};
function BME280(i2cInstance) {
this.i2c = i2cInstance;
this.compParams = {
compArray: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
compStruct: {
dig_T1: 0,
dig_T2: 0,
dig_T3: 0,
dig_P1: 0,
dig_P2: 0,
dig_P3: 0,
dig_P4: 0,
dig_P5: 0,
dig_P6: 0,
dig_P7: 0,
dig_P8: 0,
dig_P9: 0,
dig_H1: 0,
dig_H2: 0,
dig_H3: 0,
dig_H4: 0,
dig_H5: 0,
dig_H6: 0
}
};
this.t_fine = 0;
this.adc_t = 0;
this.adc_p = 0;
this.adc_h = 0;
}
BME280.prototype.compensateTDecimal = function(adc_T) {
var var1, var2, T;
var1 = ((adc_T) / 16384.0 - (this.compParams.compStruct.dig_T1) / 1024.0) * (this.compParams.compStruct.dig_T2);
var2 = (((adc_T) / 131072.0 - (this.compParams.compStruct.dig_T1) / 8192.0) *
((adc_T) / 131072.0 - (this.compParams.compStruct.dig_T1) / 8192.0)) * (this.compParams.compStruct.dig_T3);
this.t_fine = (var1 + var2);
T = (var1 + var2) / 5120.0;
return T;
};
// Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
// this.t_fine carries fine temperature as global value
BME280.prototype.compensateTIntegral = function(adc_T) {
var var1, var2, T;
var1 = ((((adc_T >> 3) - (this.compParams.compStruct.dig_T1 << 1))) * (this.compParams.compStruct.dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - (this.compParams.compStruct.dig_T1)) * ((adc_T >> 4) - (this.compParams.compStruct.dig_T1))) >> 12) * (this.compParams.compStruct.dig_T3)) >> 14;
this.t_fine = var1 + var2;
T = (this.t_fine * 5 + 128) >> 8;
return T;
};
// Returns pressure in Pa as var. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
BME280.prototype.compensatePDecimal = function(adc_P) {
var var1, var2, p;
var1 = (this.t_fine / 2.0) - 64000.0;
var2 = var1 * var1 * (this.compParams.compStruct.dig_P6) / 32768.0;
var2 = var2 + var1 * (this.compParams.compStruct.dig_P5) * 2.0;
var2 = (var2 / 4.0) + ((this.compParams.compStruct.dig_P4) * 65536.0);
var1 = ((this.compParams.compStruct.dig_P3) * var1 * var1 / 524288.0 + (this.compParams.compStruct.dig_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0) * (this.compParams.compStruct.dig_P1);
if (var1 === 0.0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576.0 - adc_P;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;
var1 = (this.compParams.compStruct.dig_P9) * p * p / 2147483648.0;
var2 = p * (this.compParams.compStruct.dig_P8) / 32768.0;
p = p + (var1 + var2 + (this.compParams.compStruct.dig_P7)) / 16.0;
return p;
};
// Returns pressure in Pa as unsigned 32 bit integer. Output value of “96386” equals 96386 Pa = 963.86 hPa
BME280.prototype.compensatePIntegral = function(adc_P) {
var var1, var2;
var p;
var1 = ((this.t_fine) >> 1) - 64000;
var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * (this.compParams.compStruct.dig_P6);
var2 = var2 + ((var1 * (this.compParams.compStruct.dig_P5)) << 1);
var2 = (var2 >> 2) + ((this.compParams.compStruct.dig_P4) << 16);
var1 = (((this.compParams.compStruct.dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + (((this.compParams.compStruct.dig_P2) * var1) >> 1)) >> 18;
var1 = ((((32768 + var1)) * (this.compParams.compStruct.dig_P1)) >> 15);
if (var1 === 0) {
return 0; // avoid exception caused by division by zero
}
p = ((((1048576) - adc_P) - (var2 >> 12))) * 3125;
if (p < 0x80000000) {
p = (p << 1) / (var1);
} else {
p = (p / var1) * 2;
}
var1 = ((this.compParams.compStruct.dig_P9) * ((((p >> 3) * (p >> 3)) >> 13))) >> 12;
var2 = (((p >> 2)) * (this.compParams.compStruct.dig_P8)) >> 13;
p = (p + ((var1 + var2 + this.compParams.compStruct.dig_P7) >> 4));
return p;
};
// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
BME280.prototype.compensatePIntegralWide = function(adc_P) {
var var1, var2, p;
var1 = (this.t_fine) - 128000;
var2 = var1 * var1 * this.compParams.compStruct.dig_P6;
var2 = var2 + ((var1 * this.compParams.compStruct.dig_P5) << 17);
var2 = var2 + ((this.compParams.compStruct.dig_P4) << 35);
var1 = ((var1 * var1 * this.compParams.compStruct.dig_P3) >> 8) + ((var1 * this.compParams.compStruct.dig_P2) << 12);
var1 = ((((1) << 47) + var1)) * (this.compParams.compStruct.dig_P1) >> 33;
if (var1 === 0) {
return 0;
}
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = ((this.compParams.compStruct.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = ((this.compParams.compStruct.dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + ((this.compParams.compStruct.dig_P7) << 4);
return p;
};
// Returns humidity in %rH as as var. Output value of “46.332” represents 46.332 %rH
BME280.prototype.compensateHDecimal = function(adc_H) {
var var_H;
var_H = ((this.t_fine) - 76800.0);
var_H = (this.adc_H - ((this.compParams.compStruct.dig_H4) * 64.0 + (this.compParams.compStruct.dig_H5) / 16384.0 * var_H)) * ((this.compParams.compStruct.dig_H2) / 65536.0 * (1.0 + (this.compParams.compStruct.dig_H6) / 67108864.0 * var_H * (1.0 + (this.compParams.compStruct.dig_H3) / 67108864.0 * var_H)));
var_H = var_H * (1.0 - (this.compParams.compStruct.dig_H1) * var_H / 524288.0);
if (var_H > 100.0) {
var_H = 100.0;
} else if (var_H < 0.0) {
var_H = 0.0;
}
return var_H;
};
// Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
// Output value of “47445” represents 47445/1024 = 46.333 %RH
BME280.prototype.compensateHIntegral = function(adc_H) {
var v_x1_u32r;
v_x1_u32r = (this.t_fine - (76800));
v_x1_u32r = (((((adc_H << 14) - ((this.compParams.compStruct.dig_H4) << 20) - ((this.compParams.compStruct.dig_H5) * v_x1_u32r)) + (16384)) >> 15) * (((((((v_x1_u32r * (this.compParams.compStruct.dig_H6)) >> 10) * (((v_x1_u32r * (this.compParams.compStruct.dig_H3)) >> 11) + (32768))) >> 10) + (2097152)) * (this.compParams.compStruct.dig_H2) + 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * (this.compParams.compStruct.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 (v_x1_u32r >> 12);
};
BME280.prototype.getTemperature = function() {
return this.compensateTIntegral(this.adc_t) / 100;
};
BME280.prototype.getTemperatureMostAccurate = function() {
return this.compensateTDecimal(this.adc_t);
};
BME280.prototype.getHumidity = function() {
return this.compensateHIntegral(this.adc_h) / 1024;
};
BME280.prototype.getHumidityMostAccurate = function() {
return this.compensateHDecimal(this.adc_h);
};
BME280.prototype.getPressure = function() {
return this.compensatePIntegral(this.adc_p) / 100;
};
BME280.prototype.getPressureMoreAccurate = function() {
return this.compensatePIntegralWide(this.adc_p) / 256 / 100;
};
BME280.prototype.getPressureMostAccurate = function() {
return this.compensatePDecimal(this.adc_p) / 100;
};
BME280.prototype.writeStandbyTime = function(t_sb) {
var conf;
conf = this.readRegister(C.regConfig);
conf = conf & 0b00011111;
conf = conf | (t_sb << 5);
this.writeRegister(C.regConfig, conf);
};
BME280.prototype.writeFilterCoefficient = function(fc) {
var conf;
conf = this.readRegister(C.regConfig);
conf = conf & 0b11100011;
conf = conf | (fc << 2);
this.writeRegister(C.regConfig, conf);
};
BME280.prototype.writeOversamplingPressure = function(os) {
var ctrlMeas;
ctrlMeas = this.readRegister(regCtrlMeas);
ctrlMeas = ctrlMeas & 0b11100011;
ctrlMeas = ctrlMeas | (os << 2);
this.writeRegister(regCtrlMeas, ctrlMeas);
};
// We want to change osrs_t which is bits 7,6,5
BME280.prototype.writeOversamplingTemperature = function(os) {
var ctrlMeas;
ctrlMeas = this.readRegister(C.regCtrlMeas);
ctrlMeas = ctrlMeas & 0b00011111;
ctrlMeas = ctrlMeas | (os << 5);
this.writeRegister(regCtrlMeas, ctrlMeas);
};
// We want to change osrs_h which is bits 2,1,0 - there are no other bits though, so we can just se it.
BME280.prototype.writeOversamplingHumidity = function(os) {
this.writeRegister(C.regCtrlHum, os);
};
BME280.prototype.readCompensationParams = function() {
var count;
var regE5, regE6, result;
this.i2c.writeTo(C.addrBME280, C.regCalibStart);
result = this.i2c.readFrom(C.addrBME280, 24);
for (count = 0; count < 28; count++) {
this.compParams.compArray[count] = result[count];
}
this.compParams.compStruct.dig_H1 = this.readRegister(0xA1);
this.i2c.writeTo(C.addrBME280, C.regCalibStart2);
result = this.i2c.readFrom(C.addrBME280, 7);
this.compParams.compStruct.dig_H2 = result[0];
this.compParams.compStruct.dig_H2 |= result[1] << 8;
this.compParams.compStruct.dig_H3 = result[2];
this.compParams.compStruct.dig_H4 = result[3] << 4;
regE5 = result[4];
this.compParams.compStruct.dig_H4 |= regE5 & 0b00001111;
this.compParams.compStruct.dig_H5 = regE5 >> 4;
regE6 = result[5];
this.compParams.compStruct.dig_H5 |= regE6 << 4;
this.compParams.compStruct.dig_H6 = result[6];
};
BME280.prototype.this.readRegister = function(reg) {
var result;
this.i2c.writeTo(C.addrBME280, reg);
result = this.i2c.readFrom(C.addrBME280, 1);
return result;
};
BME280.prototype.writeRegister = function(reg, data) {
//TODO: verify
this.i2c.writeTo(C.addrBME280, [reg, data]);
};
BME280.prototype.readMeasurements = function() {
var data[8];
var count;
this.i2c.writeTo(C.addrBME280, C.regMeasurementsStart);
result = this.i2c.readFrom(C.addrBME280, 8);
for (count = 0; count < 8; count++) {
data[count] = result[count];
}
this.adc_h = data[hum_lsb];
this.adc_h |= data[hum_msb] << 8;
this.adc_t = data[temp_xlsb] >> 4;
this.adc_t |= data[temp_lsb] << 4;
this.adc_t |= data[temp_msb] << 12;
this.adc_p = data[press_xlsb] >> 4;
this.adc_p |= data[press_lsb] << 4;
this.adc_p |= data[press_msb] << 12;
};
BME280.prototype.writeMode = function(m) {
var ctrlMeas;
ctrlMeas = this.readRegister(C.regCtrlMeas);
ctrlMeas = ctrlMeas & 0b11111100;
ctrlMeas = ctrlMeas | m;
this.writeRegister(C.regCtrlMeas, C.ctrlMeas);
};
BME280.prototype.readChipId = function() {
return this.readRegister(C.regChipID); // Status is hidden in here
};
BME280.prototype.readCtrlMeas = function() {
return this.readRegister(C.regCtrlMeas); // Status is hidden in here
};
BME280.prototype.isMeasuring = function() {
return (this.readRegister(C.regStatus) & 0b00001000);
};
BME280.prototype.doingIMUpdate = function() {
return (this.readRegister(C.regStatus) & 0b00000001);
};
/** This is 'exported' so it can be used with `I2C1.setup({scl:pin, sda:pin, bitrate:100000}); var bme = require('BME280.js').connect(I2C1);` */
exports.connect = function(i2cInstance) {
return new BME280(i2cInstance);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment