-
-
Save narioinc/bfa3dc62255b0747ab75dfcee88c244f to your computer and use it in GitHub Desktop.
Espruino BME280 module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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