UNPKG

sensor-htu21d

Version:

Library to read out a HTU21d humidity/temperature sensor connected via I2C. It depends on the "i2c-bus" library and is tested on a Raspberry Pi 3.

155 lines (128 loc) 3.98 kB
const i2c = require('i2c-bus'); const events = require('events'); const util = require('util'); const HTU21_ADDRESS = 0x40; const HTU21_CMD_TRIGGER_TEMP_MEAS_HOLD = 0xe3; const HTU21_CMD_TRIGGER_HUM_MEAS_HOLD = 0xe5; const HTU21_CMD_TRIGGER_TEMP_MEAS_NO_HOLD = 0xf3; const HTU21_CMD_TRIGGER_HUM_MEAS_NO_HOLD = 0xf5; const HTU21_CMD_WRITE_USER_REGISTER = 0xe6; const HTU21_CMD_READ_USER_REGISTER = 0xe7; const HTU21_CMD_SOFT_RESET = 0xfe; //console.log("start of program"); let delay = (ms) => { return new Promise( (resolve) => { setTimeout(() => resolve(), ms); }) }; let bufferToTemperature= (buf) => { let tRaw = (buf[0] << 8) + (buf[1] & 0xfc); let temperature = (tRaw*175.72/65536)-46.85; return temperature.toFixed(2); }; let bufferToHumidity = (buf) => { let hRaw = (buf[0] << 8) + (buf[1] & 0xf0); let humidity = (hRaw*125.0/65536)-6.0; return humidity.toFixed(2); }; let sendByte = (i2cDev, byte) => { return new Promise( (resolve) => { i2cDev.sendByte(0x40, byte, (err) => { resolve(); }); }); }; let readBuffer = (i2cDev, buffer) => { return new Promise( (resolve) => { i2cDev.i2cRead(0x40, 3, buffer, (err, bytesRead, buffer) => { resolve(); }); }); }; var crc8 = (buffer) => { var poly = 0x98800000; var reg = (buffer[0]<<24 | buffer[1]<<16 | buffer[2]<<8); var shift = 0; for (shift=0; shift<24; shift++) { if (reg & 0x80000000) reg ^= poly; reg <<= 1; } } let verifyBuffer = (buffer) => { if (buffer[0] == 0 && buffer[1] == 0) { return "open circuit condition"; } else if (buffer[0] == 0xff && buffer[1] == 0xff) { return "short circuit condition"; } else if (crc8(buffer)) { return "crc error"; } }; let verifyTemperture = (buffer) => { if (buffer[1] & 0b11 != 0b00) { return "invalid temperature data"; } }; let verifyHumidity = (buffer) => { if (buffer[1] & 0b11 != 0b10) { return "invalid humidity data"; } }; var Htu21d = function(i2cNr, period) { util.inherits(Htu21d, events.EventEmitter); this.i2cNr = i2cNr; this.period = period; this.timer = null; this.data = { temperature: null, humidity: null }; this.i2cBus = i2c.open(this.i2cNr, (err) => { if (err) { console.log("Error opening I2C bus ", err); this.emit('error', err); } }); this.readout = async () => { try { let buf = Buffer.alloc(3); await sendByte(this.i2cBus, HTU21_CMD_TRIGGER_TEMP_MEAS_NO_HOLD); await delay(100); await readBuffer(this.i2cBus, buf); (err) = verifyTemperture(buf); (err) = verifyBuffer(buf); if (err) { this.emit('error', "error reading temperature"); return; } let temperature = bufferToTemperature(buf); await sendByte(this.i2cBus, HTU21_CMD_TRIGGER_HUM_MEAS_NO_HOLD); await delay(100); await readBuffer(this.i2cBus, buf); let humidity = bufferToHumidity(buf); (err) = verifyTemperture(buf); (err) = verifyBuffer(buf); if (err) { this.emit('error', "error reading humidity"); return; } if (buf[1] & 0b11 != 0b10) { this.emit('error', 'invalid humidity data'); } this.data.temperature = Number(temperature); this.data.humidity = Number(humidity); this.emit('readout-complete', this.data); } catch (error) { this.emit('error', error); console.log(error); } }; this.start = () => { this.timer = setInterval(this.readout, this.period); }; this.stop = () => { clearInterval(this.timer); this.i2cBus.closeSync(); }; } module.exports = Htu21d;