From 72490644bb97599d94a6394e839529b2d0d66c11 Mon Sep 17 00:00:00 2001 From: Satoru Takagi Date: Wed, 13 Dec 2023 18:53:54 +0900 Subject: [PATCH] Added drivers for ICM20948, LTR390, SGP40, and TSL2591. Now all sensors of WAVESHARE20471 can be used. --- README.md | 4 + packages/ICM20948/.gitignore | 1 + packages/ICM20948/ICM20948.js | 589 ++++++++++++++++++++++++++++ packages/ICM20948/package.json | 23 ++ packages/ICM20948/rollup.config.mjs | 8 + packages/LTR390/.gitignore | 1 + packages/LTR390/LTR390.js | 97 +++++ packages/LTR390/package.json | 23 ++ packages/LTR390/rollup.config.mjs | 8 + packages/SGP40/.gitignore | 1 + packages/SGP40/SGP40.js | 140 +++++++ packages/SGP40/package.json | 23 ++ packages/SGP40/rollup.config.mjs | 8 + packages/TSL2591/.gitignore | 1 + packages/TSL2591/TSL2591.js | 144 +++++++ packages/TSL2591/package.json | 23 ++ packages/TSL2591/rollup.config.mjs | 8 + 17 files changed, 1102 insertions(+) create mode 100755 packages/ICM20948/.gitignore create mode 100755 packages/ICM20948/ICM20948.js create mode 100755 packages/ICM20948/package.json create mode 100755 packages/ICM20948/rollup.config.mjs create mode 100755 packages/LTR390/.gitignore create mode 100755 packages/LTR390/LTR390.js create mode 100755 packages/LTR390/package.json create mode 100755 packages/LTR390/rollup.config.mjs create mode 100755 packages/SGP40/.gitignore create mode 100755 packages/SGP40/SGP40.js create mode 100755 packages/SGP40/package.json create mode 100755 packages/SGP40/rollup.config.mjs create mode 100755 packages/TSL2591/.gitignore create mode 100755 packages/TSL2591/TSL2591.js create mode 100755 packages/TSL2591/package.json create mode 100755 packages/TSL2591/rollup.config.mjs diff --git a/README.md b/README.md index 7c133e1..e6cfc64 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ - [@chirimen/grove-oled-display](https://www.jsdelivr.com/package/npm/@chirimen/grove-oled-display) - [@chirimen/grove-touch](https://www.jsdelivr.com/package/npm/@chirimen/grove-touch) - [@chirimen/htu21d](https://www.jsdelivr.com/package/npm/@chirimen/htu21d) +- [@chirimen/ICM20948](https://www.jsdelivr.com/package/npm/@chirimen/ICM20948) - [@chirimen/ina219](https://www.jsdelivr.com/package/npm/@chirimen/ina219) +- [@chirimen/LTR390](https://www.jsdelivr.com/package/npm/@chirimen/LTR390) - [@chirimen/mlx90614](https://www.jsdelivr.com/package/npm/@chirimen/mlx90614) - [@chirimen/mpu6050](https://www.jsdelivr.com/package/npm/@chirimen/mpu6050) - [@chirimen/mpu6500](https://www.jsdelivr.com/package/npm/@chirimen/mpu6500) @@ -38,9 +40,11 @@ - [@chirimen/s11059](https://www.jsdelivr.com/package/npm/@chirimen/s11059) - [@chirimen/scd40](https://www.jsdelivr.com/package/npm/@chirimen/scd40) - [@chirimen/seesaw](https://www.jsdelivr.com/package/npm/@chirimen/seesaw) +- [@chirimen/SGP40](https://www.jsdelivr.com/package/npm/@chirimen/SGP40) - [@chirimen/sht30](https://www.jsdelivr.com/package/npm/@chirimen/sht30) - [@chirimen/tca9548a](https://www.jsdelivr.com/package/npm/@chirimen/tca9548a) - [@chirimen/tcs34725](https://www.jsdelivr.com/package/npm/@chirimen/tcs34725) +- [@chirimen/TSL2591](https://www.jsdelivr.com/package/npm/@chirimen/TSL2591) - [@chirimen/veml6070](https://www.jsdelivr.com/package/npm/@chirimen/veml6070) - [@chirimen/vl53l0x](https://www.jsdelivr.com/package/npm/@chirimen/vl53l0x) - [@chirimen/vl53l1x](https://www.jsdelivr.com/package/npm/@chirimen/vl53l1x) diff --git a/packages/ICM20948/.gitignore b/packages/ICM20948/.gitignore new file mode 100755 index 0000000..652bb1b --- /dev/null +++ b/packages/ICM20948/.gitignore @@ -0,0 +1 @@ +/index.js diff --git a/packages/ICM20948/ICM20948.js b/packages/ICM20948/ICM20948.js new file mode 100755 index 0000000..064f1ed --- /dev/null +++ b/packages/ICM20948/ICM20948.js @@ -0,0 +1,589 @@ +// ICM20948 driver for WebI2C +// https://www.waveshare.com/wiki/Environment_Sensor_HAT +// の +// https://files.waveshare.com/upload/b/bc/Environment_Sensor_HAT_Code.7z +// をベースに移植 +// 2023/12/13 Ported by Satoru Takagi + +var ICM20948 = function (i2cPort, slaveAddress) { + this.I2C_ADD_ICM20948 = 0x68; + if (!slaveAddress) { + slaveAddress = this.I2C_ADD_ICM20948; + } + this.i2cPort = i2cPort; + this.i2cSlave = null; + this.slaveAddress = slaveAddress; + + // consts + this.Gyro = [0, 0, 0]; + this.Accel = [0, 0, 0]; + this.Mag = [0, 0, 0]; + this.pitch = 0.0; + this.roll = 0.0; + this.yaw = 0.0; + this.pu8data = [0, 0, 0, 0, 0, 0, 0, 0]; + this.U8tempX = [0, 0, 0, 0, 0, 0, 0, 0, 0]; + this.U8tempY = [0, 0, 0, 0, 0, 0, 0, 0, 0]; + this.U8tempZ = [0, 0, 0, 0, 0, 0, 0, 0, 0]; + this.GyroOffset = [0, 0, 0]; + this.Ki = 1.0; + this.Kp = 4.5; + this.q0 = 1.0; + this.q1 = 0.0; + this.q2 = 0.0; + this.q3 = 0.0; + this.angles = [0.0, 0.0, 0.0]; + this.true = 0x01; + this.false = 0x00; + // define ICM-20948 Device I2C address + this.I2C_ADD_ICM20948_AK09916 = 0x0c; + this.I2C_ADD_ICM20948_AK09916_READ = 0x80; + this.I2C_ADD_ICM20948_AK09916_WRITE = 0x00; + // define ICM-20948 Register + // user bank 0 register + this.REG_ADD_WIA = 0x00; + this.REG_VAL_WIA = 0xea; + this.REG_ADD_USER_CTRL = 0x03; + this.REG_VAL_BIT_DMP_EN = 0x80; + this.REG_VAL_BIT_FIFO_EN = 0x40; + this.REG_VAL_BIT_I2C_MST_EN = 0x20; + this.REG_VAL_BIT_I2C_IF_DIS = 0x10; + this.REG_VAL_BIT_DMP_RST = 0x08; + this.REG_VAL_BIT_DIAMOND_DMP_RST = 0x04; + this.REG_ADD_PWR_MIGMT_1 = 0x06; + this.REG_VAL_ALL_RGE_RESET = 0x80; + this.REG_VAL_RUN_MODE = 0x01; // Non low-power mode + this.REG_ADD_LP_CONFIG = 0x05; + this.REG_ADD_PWR_MGMT_1 = 0x06; + this.REG_ADD_PWR_MGMT_2 = 0x07; + this.REG_ADD_ACCEL_XOUT_H = 0x2d; + this.REG_ADD_ACCEL_XOUT_L = 0x2e; + this.REG_ADD_ACCEL_YOUT_H = 0x2f; + this.REG_ADD_ACCEL_YOUT_L = 0x30; + this.REG_ADD_ACCEL_ZOUT_H = 0x31; + this.REG_ADD_ACCEL_ZOUT_L = 0x32; + this.REG_ADD_GYRO_XOUT_H = 0x33; + this.REG_ADD_GYRO_XOUT_L = 0x34; + this.REG_ADD_GYRO_YOUT_H = 0x35; + this.REG_ADD_GYRO_YOUT_L = 0x36; + this.REG_ADD_GYRO_ZOUT_H = 0x37; + this.REG_ADD_GYRO_ZOUT_L = 0x38; + this.REG_ADD_EXT_SENS_DATA_00 = 0x3b; + this.REG_ADD_REG_BANK_SEL = 0x7f; + this.REG_VAL_REG_BANK_0 = 0x00; + this.REG_VAL_REG_BANK_1 = 0x10; + this.REG_VAL_REG_BANK_2 = 0x20; + this.REG_VAL_REG_BANK_3 = 0x30; + + // user bank 1 register + // user bank 2 register + this.REG_ADD_GYRO_SMPLRT_DIV = 0x00; + this.REG_ADD_GYRO_CONFIG_1 = 0x01; + this.REG_VAL_BIT_GYRO_DLPCFG_2 = 0x10; // bit[5:3] + this.REG_VAL_BIT_GYRO_DLPCFG_4 = 0x20; // bit[5:3] + this.REG_VAL_BIT_GYRO_DLPCFG_6 = 0x30; // bit[5:3] + this.REG_VAL_BIT_GYRO_FS_250DPS = 0x00; // bit[2:1] + this.REG_VAL_BIT_GYRO_FS_500DPS = 0x02; // bit[2:1] + this.REG_VAL_BIT_GYRO_FS_1000DPS = 0x04; // bit[2:1] + this.REG_VAL_BIT_GYRO_FS_2000DPS = 0x06; // bit[2:1] + this.REG_VAL_BIT_GYRO_DLPF = 0x01; // bit[0] + this.REG_ADD_ACCEL_SMPLRT_DIV_2 = 0x11; + this.REG_ADD_ACCEL_CONFIG = 0x14; + this.REG_VAL_BIT_ACCEL_DLPCFG_2 = 0x10; // bit[5:3] + this.REG_VAL_BIT_ACCEL_DLPCFG_4 = 0x20; // bit[5:3] + this.REG_VAL_BIT_ACCEL_DLPCFG_6 = 0x30; // bit[5:3] + this.REG_VAL_BIT_ACCEL_FS_2g = 0x00; // bit[2:1] + this.REG_VAL_BIT_ACCEL_FS_4g = 0x02; // bit[2:1] + this.REG_VAL_BIT_ACCEL_FS_8g = 0x04; // bit[2:1] + this.REG_VAL_BIT_ACCEL_FS_16g = 0x06; // bit[2:1] + this.REG_VAL_BIT_ACCEL_DLPF = 0x01; // bit[0] + + // user bank 3 register + this.REG_ADD_I2C_SLV0_ADDR = 0x03; + this.REG_ADD_I2C_SLV0_REG = 0x04; + this.REG_ADD_I2C_SLV0_CTRL = 0x05; + this.REG_VAL_BIT_SLV0_EN = 0x80; + this.REG_VAL_BIT_MASK_LEN = 0x07; + this.REG_ADD_I2C_SLV0_DO = 0x06; + this.REG_ADD_I2C_SLV1_ADDR = 0x07; + this.REG_ADD_I2C_SLV1_REG = 0x08; + this.REG_ADD_I2C_SLV1_CTRL = 0x09; + this.REG_ADD_I2C_SLV1_DO = 0x0a; + + // define ICM-20948 Register end + + // define ICM-20948 MAG Register + this.REG_ADD_MAG_WIA1 = 0x00; + this.REG_VAL_MAG_WIA1 = 0x48; + this.REG_ADD_MAG_WIA2 = 0x01; + this.REG_VAL_MAG_WIA2 = 0x09; + this.REG_ADD_MAG_ST2 = 0x10; + this.REG_ADD_MAG_DATA = 0x11; + this.REG_ADD_MAG_CNTL2 = 0x31; + this.REG_VAL_MAG_MODE_PD = 0x00; + this.REG_VAL_MAG_MODE_SM = 0x01; + this.REG_VAL_MAG_MODE_10HZ = 0x02; + this.REG_VAL_MAG_MODE_20HZ = 0x04; + this.REG_VAL_MAG_MODE_50HZ = 0x05; + this.REG_VAL_MAG_MODE_100HZ = 0x08; + this.REG_VAL_MAG_MODE_ST = 0x10; + // define ICM-20948 MAG Register end + + this.MAG_DATA_LEN = 6; +}; + +ICM20948.prototype = { + sleep: function (ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }, + init: async function () { + this.i2cSlave = await this.i2cPort.open(this.slaveAddress); + + this._address = this.slaveAddress; + var bRet = await this.icm20948Check(); //Initialization of the device multiple times after power on will result in a return error + await this.sleep(500); //We can skip this detection by delaying it by 500 milliseconds + // user bank 0 register + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); + await this._write_byte( + this.REG_ADD_PWR_MIGMT_1, + this.REG_VAL_ALL_RGE_RESET + ); + await this.sleep(100); + await this._write_byte(this.REG_ADD_PWR_MIGMT_1, this.REG_VAL_RUN_MODE); + // user bank 2 register + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_2); + await this._write_byte(this.REG_ADD_GYRO_SMPLRT_DIV, 0x07); + await this._write_byte( + this.REG_ADD_GYRO_CONFIG_1, + this.REG_VAL_BIT_GYRO_DLPCFG_6 | + this.REG_VAL_BIT_GYRO_FS_1000DPS | + this.REG_VAL_BIT_GYRO_DLPF + ); + await this._write_byte(this.REG_ADD_ACCEL_SMPLRT_DIV_2, 0x07); + await this._write_byte( + this.REG_ADD_ACCEL_CONFIG, + this.REG_VAL_BIT_ACCEL_DLPCFG_6 | + this.REG_VAL_BIT_ACCEL_FS_2g | + this.REG_VAL_BIT_ACCEL_DLPF + ); + // user bank 0 register + this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); + await this.sleep(100); + await this.GyroOffsetF(); + await this.MagCheck(); + await this.WriteSecondary( + this.I2C_ADD_ICM20948_AK09916 | this.I2C_ADD_ICM20948_AK09916_WRITE, + this.REG_ADD_MAG_CNTL2, + this.REG_VAL_MAG_MODE_20HZ + ); + }, + + Gyro_Accel_Read: async function () { + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); + var data = await this._read_block(this.REG_ADD_ACCEL_XOUT_H, 12); + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_2); + this.Accel[0] = (data[0] << 8) | data[1]; + this.Accel[1] = (data[2] << 8) | data[3]; + this.Accel[2] = (data[4] << 8) | data[5]; + this.Gyro[0] = ((data[6] << 8) | data[7]) - this.GyroOffset[0]; + this.Gyro[1] = ((data[8] << 8) | data[9]) - this.GyroOffset[1]; + this.Gyro[2] = ((data[10] << 8) | data[11]) - this.GyroOffset[2]; + if (this.Accel[0] >= 32767) { + //Solve the problem that Python shift will not overflow + this.Accel[0] = this.Accel[0] - 65535; + } else if (this.Accel[0] <= -32767) { + this.Accel[0] = this.Accel[0] + 65535; + } + if (this.Accel[1] >= 32767) { + this.Accel[1] = this.Accel[1] - 65535; + } else if (this.Accel[1] <= -32767) { + this.Accel[1] = this.Accel[1] + 65535; + } + if (this.Accel[2] >= 32767) { + this.Accel[2] = this.Accel[2] - 65535; + } else if (this.Accel[2] <= -32767) { + this.Accel[2] = this.Accel[2] + 65535; + } + if (this.Gyro[0] >= 32767) { + this.Gyro[0] = this.Gyro[0] - 65535; + } else if (this.Gyro[0] <= -32767) { + this.Gyro[0] = this.Gyro[0] + 65535; + } + if (this.Gyro[1] >= 32767) { + this.Gyro[1] = this.Gyro[1] - 65535; + } else if (this.Gyro[1] <= -32767) { + this.Gyro[1] = this.Gyro[1] + 65535; + } + if (this.Gyro[2] >= 32767) { + this.Gyro[2] = this.Gyro[2] - 65535; + } else if (this.Gyro[2] <= -32767) { + this.Gyro[2] = this.Gyro[2] + 65535; + } + }, + + MagRead: async function () { + var counter = 20; + while (counter > 0) { + await this.sleep(10); + await this.icm20948ReadSecondary( + this.I2C_ADD_ICM20948_AK09916 | this.I2C_ADD_ICM20948_AK09916_READ, + this.REG_ADD_MAG_ST2, + 1 + ); + if ((this.pu8data[0] & 0x01) != 0) { + break; + } + counter -= 1; + } + if (counter != 0) { + for (var i = 0; i < 8; i++) { + await this.icm20948ReadSecondary( + this.I2C_ADD_ICM20948_AK09916 | this.I2C_ADD_ICM20948_AK09916_READ, + this.REG_ADD_MAG_DATA, + this.MAG_DATA_LEN + ); + this.U8tempX[i] = (this.pu8data[1] << 8) | this.pu8data[0]; + this.U8tempY[i] = (this.pu8data[3] << 8) | this.pu8data[2]; + this.U8tempZ[i] = (this.pu8data[5] << 8) | this.pu8data[4]; + } + this.Mag[0] = + (this.U8tempX[0] + + this.U8tempX[1] + + this.U8tempX[2] + + this.U8tempX[3] + + this.U8tempX[4] + + this.U8tempX[5] + + this.U8tempX[6] + + this.U8tempX[7]) / + 8; + this.Mag[1] = + -( + this.U8tempY[0] + + this.U8tempY[1] + + this.U8tempY[2] + + this.U8tempY[3] + + this.U8tempY[4] + + this.U8tempY[5] + + this.U8tempY[6] + + this.U8tempY[7] + ) / 8; + this.Mag[2] = + -( + this.U8tempZ[0] + + this.U8tempZ[1] + + this.U8tempZ[2] + + this.U8tempZ[3] + + this.U8tempZ[4] + + this.U8tempZ[5] + + this.U8tempZ[6] + + this.U8tempZ[7] + ) / 8; + } + if (this.Mag[0] >= 32767) { + //Solve the problem that Python shift will not overflow + this.Mag[0] = this.Mag[0] - 65535; + } else if (this.Mag[0] <= -32767) { + this.Mag[0] = this.Mag[0] + 65535; + } + if (this.Mag[1] >= 32767) { + this.Mag[1] = this.Mag[1] - 65535; + } else if (this.Mag[1] <= -32767) { + this.Mag[1] = this.Mag[1] + 65535; + } + if (this.Mag[2] >= 32767) { + this.Mag[2] = this.Mag[2] - 65535; + } else if (this.Mag[2] <= -32767) { + this.Mag[2] = this.Mag[2] + 65535; + } + }, + + icm20948ReadSecondary: async function (u8I2CAddr, u8RegAddr, u8Len) { + var u8Temp = 0; + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_3); //swtich bank3 + await this._write_byte(this.REG_ADD_I2C_SLV0_ADDR, u8I2CAddr); + await this._write_byte(this.REG_ADD_I2C_SLV0_REG, u8RegAddr); + await this._write_byte( + this.REG_ADD_I2C_SLV0_CTRL, + this.REG_VAL_BIT_SLV0_EN | u8Len + ); + + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); //swtich bank0 + + u8Temp = await this._read_byte(this.REG_ADD_USER_CTRL); + u8Temp |= this.REG_VAL_BIT_I2C_MST_EN; + await this._write_byte(this.REG_ADD_USER_CTRL, u8Temp); + await this.sleep(10); + u8Temp &= ~this.REG_VAL_BIT_I2C_MST_EN; + await this._write_byte(this.REG_ADD_USER_CTRL, u8Temp); + + for (var i = 0; i < u8Len; i++) { + this.pu8data[i] = await this._read_byte( + this.REG_ADD_EXT_SENS_DATA_00 + i + ); + } + + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_3); //swtich bank3 + + u8Temp = await this._read_byte(this.REG_ADD_I2C_SLV0_CTRL); + u8Temp &= ~(this.REG_VAL_BIT_I2C_MST_EN & this.REG_VAL_BIT_MASK_LEN); + await this._write_byte(this.REG_ADD_I2C_SLV0_CTRL, u8Temp); + + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); //swtich bank0 + }, + + WriteSecondary: async function (u8I2CAddr, u8RegAddr, u8data) { + var u8Temp = 0; + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_3); //swtich bank3 + await this._write_byte(this.REG_ADD_I2C_SLV1_ADDR, u8I2CAddr); + await this._write_byte(this.REG_ADD_I2C_SLV1_REG, u8RegAddr); + await this._write_byte(this.REG_ADD_I2C_SLV1_DO, u8data); + await this._write_byte( + this.REG_ADD_I2C_SLV1_CTRL, + this.REG_VAL_BIT_SLV0_EN | 1 + ); + + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); //swtich bank0 + + u8Temp = await this._read_byte(this.REG_ADD_USER_CTRL); + u8Temp |= this.REG_VAL_BIT_I2C_MST_EN; + await this._write_byte(this.REG_ADD_USER_CTRL, u8Temp); + await this.sleep(10); + u8Temp &= ~this.REG_VAL_BIT_I2C_MST_EN; + await this._write_byte(this.REG_ADD_USER_CTRL, u8Temp); + + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_3); //swtich bank3 + + u8Temp = await this._read_byte(this.REG_ADD_I2C_SLV0_CTRL); + u8Temp &= ~(this.REG_VAL_BIT_I2C_MST_EN & this.REG_VAL_BIT_MASK_LEN); + await this._write_byte(this.REG_ADD_I2C_SLV0_CTRL, u8Temp); + + await this._write_byte(this.REG_ADD_REG_BANK_SEL, this.REG_VAL_REG_BANK_0); //swtich bank0 + }, + + GyroOffsetF: async function () { + var s32TempGx = 0; + var s32TempGy = 0; + var s32TempGz = 0; + for (var i = 0; i < 32; i++) { + await this.Gyro_Accel_Read(); + s32TempGx += this.Gyro[0]; + s32TempGy += this.Gyro[1]; + s32TempGz += this.Gyro[2]; + await this.sleep(10); + } + this.GyroOffset[0] = s32TempGx >> 5; + this.GyroOffset[1] = s32TempGy >> 5; + this.GyroOffset[2] = s32TempGz >> 5; + }, + + _read_byte: async function (cmd) { + return await this.i2cSlave.read8(cmd); + }, + _read_block: async function (reg, length) { + await this.i2cSlave.writeByte(reg); + return await this.i2cSlave.readBytes(length); + }, + _read_u16: async function (cmd) { + var LSB = await this.i2cSlave.read8(cmd); + var MSB = await this.i2cSlave.read8(cmd + 1); + return (MSB << 8) + LSB; + }, + + _write_byte: async function (cmd, val) { + await this.i2cSlave.write8(cmd, val); + }, + + imuAHRSupdata: function (gx, gy, gz, ax, ay, az, mx, my, mz) { + var norm = 0.0; + var hx = 0, + hy = 0, + hz = 0, + bx = 0, + bz = 0.0; + var vx = 0, + vy = 0, + vz = 0, + wx = 0, + wy = 0, + wz = 0.0; + var exInt = 0, + eyInt = 0, + ezInt = 0.0; + var ex = 0, + ey = 0, + ez = 0.0; + var halfT = 0.024; + /** + global q0 + global q1 + global q2 + global q3 + **/ + var q0q0 = this.q0 * this.q0; + var q0q1 = this.q0 * this.q1; + var q0q2 = this.q0 * this.q2; + var q0q3 = this.q0 * this.q3; + var q1q1 = this.q1 * this.q1; + var q1q2 = this.q1 * this.q2; + var q1q3 = this.q1 * this.q3; + var q2q2 = this.q2 * this.q2; + var q2q3 = this.q2 * this.q3; + var q3q3 = this.q3 * this.q3; + + norm = 1 / Math.sqrt(ax * ax + ay * ay + az * az); + ax = ax * norm; + ay = ay * norm; + az = az * norm; + + norm = (1 / Math.sqrt(mx * mx + my * my + mz * mz)); + mx = mx * norm; + my = my * norm; + mz = mz * norm; + + // compute reference direction of flux + hx = + 2 * mx * (0.5 - q2q2 - q3q3) + + 2 * my * (q1q2 - q0q3) + + 2 * mz * (q1q3 + q0q2); + hy = + 2 * mx * (q1q2 + q0q3) + + 2 * my * (0.5 - q1q1 - q3q3) + + 2 * mz * (q2q3 - q0q1); + hz = + 2 * mx * (q1q3 - q0q2) + + 2 * my * (q2q3 + q0q1) + + 2 * mz * (0.5 - q1q1 - q2q2); + bx = Math.sqrt(hx * hx + hy * hy); + bz = hz; + + // estimated direction of gravity and flux (v and w) + vx = 2 * (q1q3 - q0q2); + vy = 2 * (q0q1 + q2q3); + vz = q0q0 - q1q1 - q2q2 + q3q3; + wx = 2 * bx * (0.5 - q2q2 - q3q3) + 2 * bz * (q1q3 - q0q2); + wy = 2 * bx * (q1q2 - q0q3) + 2 * bz * (q0q1 + q2q3); + wz = 2 * bx * (q0q2 + q1q3) + 2 * bz * (0.5 - q1q1 - q2q2); + + // error is sum of cross product between reference direction of fields and direction measured by sensors + ex = ay * vz - az * vy + (my * wz - mz * wy); + ey = az * vx - ax * vz + (mz * wx - mx * wz); + ez = ax * vy - ay * vx + (mx * wy - my * wx); + + if (ex != 0.0 && ey != 0.0 && ez != 0.0) { + exInt = exInt + ex * this.Ki * halfT; + eyInt = eyInt + ey * this.Ki * halfT; + ezInt = ezInt + ez * this.Ki * halfT; + + gx = gx + this.Kp * ex + exInt; + gy = gy + this.Kp * ey + eyInt; + gz = gz + this.Kp * ez + ezInt; + } + + this.q0 = this.q0 + (-this.q1 * gx - this.q2 * gy - this.q3 * gz) * halfT; + this.q1 = this.q1 + (this.q0 * gx + this.q2 * gz - this.q3 * gy) * halfT; + this.q2 = this.q2 + (this.q0 * gy - this.q1 * gz + this.q3 * gx) * halfT; + this.q3 = this.q3 + (this.q0 * gz + this.q1 * gy - this.q2 * gx) * halfT; + + norm = + 1 / + Math.sqrt( + this.q0 * this.q0 + + this.q1 * this.q1 + + this.q2 * this.q2 + + this.q3 * this.q3 + ); + this.q0 = this.q0 * norm; + this.q1 = this.q1 * norm; + this.q2 = this.q2 * norm; + this.q3 = this.q3 * norm; + }, + + icm20948Check: async function () { + var bRet = false; + if (this.REG_VAL_WIA == (await this._read_byte(this.REG_ADD_WIA))) { + bRet = true; + } + return bRet; + }, + + MagCheck: async function () { + await this.icm20948ReadSecondary( + this.I2C_ADD_ICM20948_AK09916 | this.I2C_ADD_ICM20948_AK09916_READ, + this.REG_ADD_MAG_WIA1, + 2 + ); + if ( + this.pu8data[0] == this.REG_VAL_MAG_WIA1 && + this.pu8data[1] == this.REG_VAL_MAG_WIA2 + ) { + var bRet = true; + return bRet; + } + }, + + CalAvgValue: function () { + var MotionVal = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; + MotionVal[0] = this.Gyro[0] / 32.8; + MotionVal[1] = this.Gyro[1] / 32.8; + MotionVal[2] = this.Gyro[2] / 32.8; + MotionVal[3] = this.Accel[0]; + MotionVal[4] = this.Accel[1]; + MotionVal[5] = this.Accel[2]; + MotionVal[6] = this.Mag[0]; + MotionVal[7] = this.Mag[1]; + MotionVal[8] = this.Mag[2]; + return MotionVal; + }, + + getdata: async function () { + await this.Gyro_Accel_Read(); + await this.MagRead(); + + var MotionVal = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; + MotionVal = this.CalAvgValue(); + await this.sleep(100); + await this.imuAHRSupdata( + MotionVal[0] * 0.0175, + MotionVal[1] * 0.0175, + MotionVal[2] * 0.0175, + MotionVal[3], + MotionVal[4], + MotionVal[5], + MotionVal[6], + MotionVal[7], + MotionVal[8] + ); + + var pitch = + Math.asin(-2 * this.q1 * this.q3 + 2 * this.q0 * this.q2) * 57.3; + var roll = + Math.atan2( + 2 * this.q2 * this.q3 + 2 * this.q0 * this.q1, + -2 * this.q1 * this.q1 - 2 * this.q2 * this.q2 + 1 + ) * 57.3; + var yaw = + Math.atan2( + -2 * this.q1 * this.q2 - 2 * this.q0 * this.q3, + 2 * this.q2 * this.q2 + 2 * this.q3 * this.q3 - 1 + ) * 57.3; + + return [ + roll, + pitch, + yaw, + this.Accel[0], + this.Accel[1], + this.Accel[2], + this.Gyro[0], + this.Gyro[1], + this.Gyro[2], + this.Mag[0], + this.Mag[1], + this.Mag[2], + ]; + }, +}; + +export default ICM20948; diff --git a/packages/ICM20948/package.json b/packages/ICM20948/package.json new file mode 100755 index 0000000..7a18f04 --- /dev/null +++ b/packages/ICM20948/package.json @@ -0,0 +1,23 @@ +{ + "name": "@chirimen/ICM20948", + "version": "1.0.0", + "description": "Driver for ICM20948 with WebI2C", + "main": "index.js", + "module": "ICM20948.js", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/chirimen-oh/chirimen-drivers.git", + "directory": "packages/ICM20948" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "rollup -c --bundleConfigAsCjs", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "rollup": "^4.0.0" + } +} diff --git a/packages/ICM20948/rollup.config.mjs b/packages/ICM20948/rollup.config.mjs new file mode 100755 index 0000000..1a87644 --- /dev/null +++ b/packages/ICM20948/rollup.config.mjs @@ -0,0 +1,8 @@ +export default { + input: "ICM20948.js", + output: { + file: "index.js", + format: "umd", + name: "ICM20948" + } +}; diff --git a/packages/LTR390/.gitignore b/packages/LTR390/.gitignore new file mode 100755 index 0000000..652bb1b --- /dev/null +++ b/packages/LTR390/.gitignore @@ -0,0 +1 @@ +/index.js diff --git a/packages/LTR390/LTR390.js b/packages/LTR390/LTR390.js new file mode 100755 index 0000000..0fc3559 --- /dev/null +++ b/packages/LTR390/LTR390.js @@ -0,0 +1,97 @@ +// LTR390 driver for WebI2C +// https://www.waveshare.com/wiki/Environment_Sensor_HAT +// の +// https://files.waveshare.com/upload/b/bc/Environment_Sensor_HAT_Code.7z +// をベースに移植 +// 2023/12/13 Ported by Satoru Takagi + +var LTR390 = function (i2cPort, slaveAddress) { + if (!slaveAddress) { + slaveAddress = 0x53; + } + this.i2cPort = i2cPort; + this.i2cSlave = null; + this.slaveAddress = slaveAddress; + + // consts + this.LTR390_MAIN_CTRL = 0x00; // Main control register + this.LTR390_MEAS_RATE = 0x04; // Resolution and data rate + this.LTR390_GAIN = 0x05; // ALS and UVS gain range + this.LTR390_PART_ID = 0x06; // Part id/revision register + this.LTR390_MAIN_STATUS = 0x07; // Main status register + this.LTR390_ALSDATA = 0x0d; // ALS data lowest byte, 3 byte + this.LTR390_UVSDATA = 0x10; // UVS data lowest byte, 3 byte + this.LTR390_INT_CFG = 0x19; // Interrupt configuration + this.LTR390_INT_PST = 0x1a; // Interrupt persistance config + this.LTR390_THRESH_UP = 0x21; // Upper threshold, low byte, 3 byte + this.LTR390_THRESH_LOW = 0x24; // Lower threshold, low byte, 3 byte + + //ALS/UVS measurement resolution, Gain setting, measurement rate + this.RESOLUTION_20BIT_TIME400MS = 0x00; + this.RESOLUTION_19BIT_TIME200MS = 0x10; + this.RESOLUTION_18BIT_TIME100MS = 0x20; //default + this.RESOLUTION_17BIT_TIME50MS = 0x3; + this.RESOLUTION_16BIT_TIME25MS = 0x40; + this.RESOLUTION_13BIT_TIME12_5MS = 0x50; + this.RATE_25MS = 0x0; + this.RATE_50MS = 0x1; + this.RATE_100MS = 0x2; // default + this.RATE_200MS = 0x3; + this.RATE_500MS = 0x4; + this.RATE_1000MS = 0x5; + this.RATE_2000MS = 0x6; + + // measurement Gain Range. + this.GAIN_1 = 0x0; + this.GAIN_3 = 0x1; // default + this.GAIN_6 = 0x2; + this.GAIN_9 = 0x3; + this.GAIN_18 = 0x4; +}; + +LTR390.prototype = { + sleep: function (ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }, + init: async function () { + this.i2cSlave = await this.i2cPort.open(this.slaveAddress); + + this.sensID = await this.Read_Byte(this.LTR390_PART_ID); + // console.log("ID =" ,this.sensID) + if (this.sensID != 0xb2) { + console.error("read ID error!,Check the hardware... ID:", this.sensID); + return; + } + await this.Write_Byte(this.LTR390_MAIN_CTRL, 0x0a); // UVS in Active Mode + await this.Write_Byte( + this.LTR390_MEAS_RATE, + this.RESOLUTION_20BIT_TIME400MS | this.RATE_2000MS + ); // Resolution=18bits, Meas Rate = 100ms + await this.Write_Byte(this.LTR390_GAIN, this.GAIN_3); // Gain Range=3. + // await this.Write_Byte(this.LTR390_INT_CFG, 0x34) // UVS_INT_EN=1, Command=0x34 + // await this.Write_Byte(this.LTR390_GAIN, GAIN_3) // Resolution=18bits, Meas Rate = 100ms + }, + + Read_Byte: async function (cmd) { + return await this.i2cSlave.read8(cmd); + }, + + Write_Byte: async function (cmd, val) { + await this.i2cSlave.write8(cmd, val); + }, + + UVS: async function (self) { + // this.Write_Byte(LTR390_MAIN_CTRL, 0x0A) // UVS in Active Mode + var Data1 = await this.Read_Byte(this.LTR390_UVSDATA); + var Data2 = await this.Read_Byte(this.LTR390_UVSDATA + 1); + var Data3 = await this.Read_Byte(this.LTR390_UVSDATA + 2); + var uv = (Data3 << 16) | (Data2 << 8) | Data1; + // var UVS = Data3*65536+Data2*256+Data1 + // console.log("UVS = ", UVS) + return uv; + }, +}; + +export default LTR390; diff --git a/packages/LTR390/package.json b/packages/LTR390/package.json new file mode 100755 index 0000000..320caf5 --- /dev/null +++ b/packages/LTR390/package.json @@ -0,0 +1,23 @@ +{ + "name": "@chirimen/LTR390", + "version": "1.0.0", + "description": "Driver for LTR390 with WebI2C", + "main": "index.js", + "module": "LTR390.js", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/chirimen-oh/chirimen-drivers.git", + "directory": "packages/LTR390" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "rollup -c --bundleConfigAsCjs", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "rollup": "^4.0.0" + } +} diff --git a/packages/LTR390/rollup.config.mjs b/packages/LTR390/rollup.config.mjs new file mode 100755 index 0000000..0cc6a34 --- /dev/null +++ b/packages/LTR390/rollup.config.mjs @@ -0,0 +1,8 @@ +export default { + input: "LTR390.js", + output: { + file: "index.js", + format: "umd", + name: "LTR390" + } +}; diff --git a/packages/SGP40/.gitignore b/packages/SGP40/.gitignore new file mode 100755 index 0000000..652bb1b --- /dev/null +++ b/packages/SGP40/.gitignore @@ -0,0 +1 @@ +/index.js diff --git a/packages/SGP40/SGP40.js b/packages/SGP40/SGP40.js new file mode 100755 index 0000000..2d58dd3 --- /dev/null +++ b/packages/SGP40/SGP40.js @@ -0,0 +1,140 @@ +// SGP40 driver for WebI2C +// https://www.waveshare.com/wiki/Environment_Sensor_HAT +// の +// https://files.waveshare.com/upload/b/bc/Environment_Sensor_HAT_Code.7z +// をベースに移植 +// 2023/12/13 Ported by Satoru Takagi + +var SGP40 = function (i2cPort, slaveAddress) { + if (!slaveAddress) { + slaveAddress = 0x59; + } + this.i2cPort = i2cPort; + this.i2cSlave = null; + this.slaveAddress = slaveAddress; + this.ch0 = null; + this.ch1 = null; + + // CONSTS + this.SGP40_CMD_FEATURE_SET = [0x20, 0x2f]; + this.SGP40_CMD_MEASURE_TEST = [0x28, 0x0e]; + this.SGP40_CMD_SOFT_RESET = [0x00, 0x06]; + this.SGP40_CMD_HEATER_OFF = [0x36, 0x15]; + this.SGP40_CMD_MEASURE_RAW = [0x26, 0x0f]; + this.CRC_TABLE = [ + 0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46, 67, + 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109, 134, + 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168, 197, + 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235, 61, 12, + 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19, 126, 79, + 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80, 187, 138, + 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149, 248, 201, 154, + 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214, 122, 75, 24, 41, + 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84, 57, 8, 91, 106, 253, + 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23, 252, 205, 158, 175, 56, + 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210, 191, 142, 221, 236, 123, + 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145, 71, 118, 37, 20, 131, 178, + 225, 208, 254, 207, 156, 173, 58, 11, 88, 105, 4, 53, 102, 87, 192, 241, + 162, 147, 189, 140, 223, 238, 121, 72, 27, 42, 193, 240, 163, 146, 5, 52, + 103, 86, 120, 73, 26, 43, 188, 141, 222, 239, 130, 179, 224, 209, 70, 119, + 36, 21, 59, 10, 89, 104, 255, 206, 157, 172, + ]; + this.WITHOUT_HUM_COMP = [0x26, 0x0f, 0x80, 0x00, 0xa2, 0x66, 0x66, 0x93]; // default Temperature=25 Humidity=50 + this.WITH_HUM_COMP = [0x26, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; //Manual input +}; + +SGP40.prototype = { + sleep: function (ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }, + init: async function () { + this.i2cSlave = await this.i2cPort.open(this.slaveAddress); + // feature set 0x3220 + await this.write(this.SGP40_CMD_FEATURE_SET); + await this.sleep(250); + var Rbuf = await this.Read(); +// console.log("feature set:", (Math.floor(Rbuf[0]) << 8) | Rbuf[1]); + if (((Math.floor(Rbuf[0]) << 8) | Rbuf[1]) != 0x3220) { + console.error("Self test failed"); + return; + } + + // Self Test 0xD400 + await this.write(this.SGP40_CMD_MEASURE_TEST); + await this.sleep(250); + var Rbuf = await this.Read(); +// console.log("Self Test :", (Math.floor(Rbuf[0]) << 8) | Rbuf[1]); + if (((Math.floor(Rbuf[0]) << 8) | Rbuf[1]) != 0xd400) { + //0x4B00 is failed,0xD400 pass + console.error("Self test failed"); + return; + } + }, + + Read: async function () { + await this.i2cSlave.writeByte(this.slaveAddress); + var ans = await this.i2cSlave.readBytes(3); + return ans; + }, + + write: async function (cmd) { +// await this.i2cSlave.write16(cmd); + await this.i2cSlave.writeBytes(cmd); + }, + + write_block: async function (cmd) { +// console.log("write_block:", cmd); + await this.i2cSlave.writeBytes(cmd); + }, + + raw: async function () { +// console.log("raw"); + await this.write_block(this.WITHOUT_HUM_COMP); + await this.sleep(250); + var Rbuf = await this.Read(); +// console.log("raw:",Rbuf); + return (Math.floor(Rbuf[0]) << 8) | Rbuf[1]; + }, + + measureRaw: async function (temperature, humidity) { +// console.log("measureRaw"); + var h = (humidity * 0xffff) / 100; + var paramh_h = (h >> 8); + var paramh_l = (h & 0xff); + var crch = this.__crc(paramh_h, paramh_l); + + var t = ((temperature + 45) * 0xffff) / 175; + var paramt_h = (t >> 8); + var paramt_l = (t & 0xff); + var crct = this.__crc(paramt_h, paramt_l); + + this.WITH_HUM_COMP[2] = paramh_h; + this.WITH_HUM_COMP[3] = paramh_l; + this.WITH_HUM_COMP[4] = Math.floor(crch); + this.WITH_HUM_COMP[5] = paramt_h; + this.WITH_HUM_COMP[6] = paramt_l; + this.WITH_HUM_COMP[7] = Math.floor(crct); + //console.log("WITH_HUM_COMP:", this.WITH_HUM_COMP); + await this.write_block(this.WITH_HUM_COMP); + + await this.sleep(500); + var Rbuf = await this.Read(); +// console.log(Rbuf); + return (Math.floor(Rbuf[0]) << 8) | Rbuf[1]; + }, + + __crc: function (msb, lsb) { + var crc = 0xff; + crc ^= msb; + crc = this.CRC_TABLE[crc]; + if (lsb) { + crc ^= lsb; + crc = this.CRC_TABLE[crc]; + } + return crc; + }, +}; + +export default SGP40; diff --git a/packages/SGP40/package.json b/packages/SGP40/package.json new file mode 100755 index 0000000..5507e57 --- /dev/null +++ b/packages/SGP40/package.json @@ -0,0 +1,23 @@ +{ + "name": "@chirimen/SGP40", + "version": "1.0.0", + "description": "Driver for SGP40 with WebI2C", + "main": "index.js", + "module": "SGP40.js", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/chirimen-oh/chirimen-drivers.git", + "directory": "packages/SGP40" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "rollup -c --bundleConfigAsCjs", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "rollup": "^4.0.0" + } +} diff --git a/packages/SGP40/rollup.config.mjs b/packages/SGP40/rollup.config.mjs new file mode 100755 index 0000000..d5f2d7b --- /dev/null +++ b/packages/SGP40/rollup.config.mjs @@ -0,0 +1,8 @@ +export default { + input: "SGP40.js", + output: { + file: "index.js", + format: "umd", + name: "SGP40" + } +}; diff --git a/packages/TSL2591/.gitignore b/packages/TSL2591/.gitignore new file mode 100755 index 0000000..652bb1b --- /dev/null +++ b/packages/TSL2591/.gitignore @@ -0,0 +1 @@ +/index.js diff --git a/packages/TSL2591/TSL2591.js b/packages/TSL2591/TSL2591.js new file mode 100755 index 0000000..56816ed --- /dev/null +++ b/packages/TSL2591/TSL2591.js @@ -0,0 +1,144 @@ +// TSL2591 driver for WebI2C +// https://www.waveshare.com/wiki/Environment_Sensor_HAT +// https://www.waveshare.com/wiki/TSL25911_Light_Sensor +// の +// https://files.waveshare.com/upload/b/bc/Environment_Sensor_HAT_Code.7z +// をベースに移植 +// TSL25911FN == TSL2591 +// 2023/12/13 Ported by Satoru Takagi + +var TSL2591 = function (i2cPort, slaveAddress) { + if (!slaveAddress) { + slaveAddress = 0x29; + } + this.i2cPort = i2cPort; + this.i2cSlave = null; + this.slaveAddress = slaveAddress; + this.ch0 = null; + this.ch1 = null; + + // CONSTS + this.COMMAND_BIT = (0xA0); + this.ENABLE_REGISTER = (0x00); + this.ENABLE_POWERON = (0x01); + this.ENABLE_POWEROFF = (0x00); + this.ENABLE_AEN = (0x02); + this.ENABLE_AIEN = (0x10); + this.ENABLE_SAI = (0x40); + this.ENABLE_NPIEN = (0x80); + + this.CONTROL_REGISTER = (0x01); + this.SRESET = (0x80); + + this.AILTL_REGISTER = (0x04); + this.AILTH_REGISTER = (0x05); + this.AIHTL_REGISTER = (0x06); + this.AIHTH_REGISTER = (0x07); + this.NPAILTL_REGISTER = (0x08); + this.NPAILTH_REGISTER = (0x09); + this.NPAIHTL_REGISTER = (0x0A); + this.NPAIHTH_REGISTER = (0x0B); + + this.PERSIST_REGISTER = (0x0C); + + this.ID_REGISTER = (0x12); + + this.STATUS_REGISTER = (0x13); + + this.CHAN0_LOW = (0x14); + this.CHAN0_HIGH = (0x15); + this.CHAN1_LOW = (0x16); + this.CHAN1_HIGH = (0x17); + + this.LUX_DF = 408.0; + this.LUX_COEFB = 1.64; + this.LUX_COEFC = 0.59; + this.LUX_COEFD = 0.86; + + this.LOW_AGAIN = (0X00);//Low gain (1x) + this.MEDIUM_AGAIN = (0X10);//Medium gain (25x) + this.HIGH_AGAIN = (0X20);//High gain (428x) + this.MAX_AGAIN = (0x30);//Max gain (9876x) + + this.ATIME_100MS = (0x00);//100 millis #MAX COUNT 36863 + this.ATIME_200MS = (0x01);//200 millis #MAX COUNT 65535 + this.ATIME_300MS = (0x02);//300 millis + this.ATIME_400MS = (0x03);//400 millis + this.ATIME_500MS = (0x04);//500 millis + this.ATIME_600MS = (0x05);//600 millis + + this.MAX_COUNT_100MS = (36863) ;// 0x8FFF + this.MAX_COUNT = (65535) ;// 0xFFFF + this.INI_PIN = 23; +}; + +TSL2591.prototype = { + sleep: function (ms) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); + }, + init: async function () { + this.i2cSlave = await this.i2cPort.open(this.slaveAddress); + this.ID = await this.Read_Byte(this.ID_REGISTER); + if(this.ID != 0x50){ + console.error(`invalid ID : ${this.ID}`); + return; + } + await this.Write_Byte(this.ENABLE_REGISTER, this.ENABLE_AIEN | this.ENABLE_POWERON | this.ENABLE_AEN | this.ENABLE_NPIEN); + this.IntegralTime = this.ATIME_200MS; + this.Gain = this.MEDIUM_AGAIN; + await this.Write_Byte(this.CONTROL_REGISTER, this.IntegralTime | this.Gain) + await this.Write_Byte(this.PERSIST_REGISTER, 0x01) + var atime = 100.0 * this.IntegralTime + 100.0; + var again = 1.0; + if (this.Gain == this.MEDIUM_AGAIN){ + again = 25.0; + } else if (this.Gain == this.HIGH_AGAIN){ + again = 428.0; + } else if( this.Gain == this.MAX_AGAIN){ + again = 9876.0; + } + this.Cpl = (atime * again) / this.LUX_DF; + }, + + Read_Byte: async function(Addr){ + var Addr = (this.COMMAND_BIT | Addr) & 0xFF; + var ans = await this.i2cSlave.read8(Addr); + return ans; + }, + Write_Byte: async function(Addr, val){ + var Addr = (this.COMMAND_BIT | Addr) & 0xFF; + await this.i2cSlave.write8(Addr, val); + }, + + Read_2Channel: async function(){ + var CH0L = await this.Read_Byte(this.CHAN0_LOW); + var CH0H = await this.Read_Byte(this.CHAN0_LOW + 1); + var CH1L = await this.Read_Byte(this.CHAN0_LOW + 2); + var CH1H = await this.Read_Byte(this.CHAN0_LOW + 3); + var full = (CH0H << 8)|CH0L; + var ir = (CH1H << 8)|CH1L; + return [full,ir]; + }, + + Lux: async function(){ + var status = await this.Read_Byte(0x13); + if(status & 0x10){ + // console.log ('soft goto interrupt'); + await this.Write_Byte(0xE7, 0x13); + } + + var [full, ir] = await this.Read_2Channel(); + if (full == 0xFFFF || ir == 0xFFFF){ + console.error('Numerical overflow!'); + return; + } + + var lux = ((full-ir) * (1.00 - (ir/full))) / this.Cpl; + return lux + }, + +}; + +export default TSL2591; diff --git a/packages/TSL2591/package.json b/packages/TSL2591/package.json new file mode 100755 index 0000000..ceff0ec --- /dev/null +++ b/packages/TSL2591/package.json @@ -0,0 +1,23 @@ +{ + "name": "@chirimen/TSL2591", + "version": "1.0.0", + "description": "Driver for TSL2591 with WebI2C", + "main": "index.js", + "module": "TSL2591.js", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/chirimen-oh/chirimen-drivers.git", + "directory": "packages/TSL2591" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "rollup -c --bundleConfigAsCjs", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "rollup": "^4.0.0" + } +} diff --git a/packages/TSL2591/rollup.config.mjs b/packages/TSL2591/rollup.config.mjs new file mode 100755 index 0000000..e07e420 --- /dev/null +++ b/packages/TSL2591/rollup.config.mjs @@ -0,0 +1,8 @@ +export default { + input: "TSL2591.js", + output: { + file: "index.js", + format: "umd", + name: "TSL2591" + } +};