UNPKG

openi2c

Version:

This library is a set of cross platform drivers for common I2C devices.

189 lines (188 loc) 8.81 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ak8963 = exports.AK8963 = void 0; const i2c = __importStar(require("i2c-bus")); const utils_1 = require("../../utils"); const BaseDevice_1 = require("../BaseDevice"); // AK8963 Map exports.AK8963 = { ADDRESS: 0x0C, WHO_AM_I: 0x00, // should return 0x48, WHO_AM_I_RESPONSE: 0x48, INFO: 0x01, ST1: 0x02, // data ready status bit 0 XOUT_L: 0x03, // data XOUT_H: 0x04, YOUT_L: 0x05, YOUT_H: 0x06, ZOUT_L: 0x07, ZOUT_H: 0x08, ST2: 0x09, // Data overflow bit 3 and data read error status bit 2 CNTL: 0x0A, // Power down (0000), single-measurement (0001), self-test (1000) and Fuse ROM (1111) modes on bits 3:0 ASTC: 0x0C, // Self test control I2CDIS: 0x0F, // I2C disable ASAX: 0x10, // Fuse ROM x-axis sensitivity adjustment value ASAY: 0x11, // Fuse ROM y-axis sensitivity adjustment value ASAZ: 0x12, ST1_DRDY_BIT: 0, ST1_DOR_BIT: 1, CNTL_MODE_OFF: 0x00, // Power-down mode CNTL_MODE_SINGLE_MEASURE: 0x01, // Single measurement mode CNTL_MODE_CONTINUE_MEASURE_1: 0x02, // Continuous measurement mode 1 - Sensor is measured periodically at 8Hz CNTL_MODE_CONTINUE_MEASURE_2: 0x06, // Continuous measurement mode 2 - Sensor is measured periodically at 100Hz CNTL_MODE_EXT_TRIG_MEASURE: 0x04, // External trigger measurement mode CNTL_MODE_SELF_TEST_MODE: 0x08, // Self-test mode CNTL_MODE_FUSE_ROM_ACCESS: 0x0F, // Fuse ROM access mode DEFAULT_CALIBRATION: { offset: { x: 0, y: 0, z: 0 }, scale: { x: 1, y: 1, z: 1 } } }; class ak8963 extends BaseDevice_1.BaseDevice { constructor(config = {}) { super(); this._config = Object.assign({ // device: '/dev/i2c-0', bus: 0, ak_address: exports.AK8963.ADDRESS, scaleValues: false, magCalibration: exports.AK8963.DEFAULT_CALIBRATION }, config); this.address = this._config.ak_address; } initialize() { return __awaiter(this, void 0, void 0, function* () { this.bus = i2c.openSync(this._config.bus).promisifiedBus(); yield (0, utils_1.sleep)(100); const buffer = yield this.getIDDevice(); if (buffer & exports.AK8963.WHO_AM_I_RESPONSE) { this.getSensitivityAdjustmentValues(); yield (0, utils_1.sleep)(100); this.setCNTL(exports.AK8963.CNTL_MODE_CONTINUE_MEASURE_2); } else { this.debug.log('ERROR', 'AK8963: Device ID is not equal to 0x' + exports.AK8963.WHO_AM_I_RESPONSE.toString(16) + ', device value is 0x' + buffer.toString(16)); } }); } getMagAttitude() { return __awaiter(this, void 0, void 0, function* () { // Get the actual data const buffer = yield this.readBytes(exports.AK8963.XOUT_L, 6); const cal = this._config.magCalibration; // For some reason when we read ST2 (Status 2) just after reading byte, this ensures the // next reading is fresh. If we do it before without a pause, only 1 in 15 readings will // be fresh. The setTimeout ensures this read goes to the back of the queue, once all other // computation is done. process.nextTick(() => this.readByte(exports.AK8963.ST2)); return [ ((buffer.readInt16LE(0) * this.asax) - cal.offset.x) * cal.scale.x, ((buffer.readInt16LE(2) * this.asay) - cal.offset.y) * cal.scale.y, ((buffer.readInt16LE(4) * this.asaz) - cal.offset.z) * cal.scale.z ]; }); } printSettings() { return __awaiter(this, void 0, void 0, function* () { const MODE_LST = { 0: '0x00 (Power-down mode)', 1: '0x01 (Single measurement mode)', 2: '0x02 (Continuous measurement mode 1: 8Hz)', 6: '0x06 (Continuous measurement mode 2: 100Hz)', 4: '0x04 (External trigger measurement mode)', 8: '0x08 (Self-test mode)', 15: '0x0F (Fuse ROM access mode)' }; this.debug.log('INFO', 'Magnetometer (Compass):'); this.debug.log('INFO', '--> i2c address: 0x' + this._config.ak_address.toString(16)); this.debug.log('INFO', '--> Device ID: 0x' + (yield this.getIDDevice()).toString(16)); this.debug.log('INFO', '--> Mode: ' + MODE_LST[(yield this.getCNTL()) & 0x0F]); this.debug.log('INFO', '--> Scalars:'); this.debug.log('INFO', ' --> x: ' + this.asax); this.debug.log('INFO', ' --> y: ' + this.asay); this.debug.log('INFO', ' --> z: ' + this.asaz); }); } /** * Get the Sensitivity Adjustment values. These were set during manufacture and allow us to get the actual H values * from the magnetometer. */ getSensitivityAdjustmentValues() { return __awaiter(this, void 0, void 0, function* () { if (!this._config.scaleValues) { this.asax = 1; this.asay = 1; this.asaz = 1; return; } // Need to set to Fuse mode to get valid values from this. var currentMode = yield this.getCNTL(); this.setCNTL(exports.AK8963.CNTL_MODE_FUSE_ROM_ACCESS); yield (0, utils_1.sleep)(100); // Get the ASA* values this.asax = (((yield this.readByte(exports.AK8963.ASAX)) - 128) * 0.5 / 128 + 1); this.asay = (((yield this.readByte(exports.AK8963.ASAY)) - 128) * 0.5 / 128 + 1); this.asaz = (((yield this.readByte(exports.AK8963.ASAZ)) - 128) * 0.5 / 128 + 1); // Return the mode we were in before this.setCNTL(currentMode); }); } getCNTL() { return __awaiter(this, void 0, void 0, function* () { return yield this.readByte(exports.AK8963.CNTL); }); } /** * CNTL_MODE_OFF: 0x00, // Power-down mode * CNTL_MODE_SINGLE_MEASURE: 0x01, // Single measurement mode * CNTL_MODE_CONTINUE_MEASURE_1: 0x02, // Continuous measurement mode 1 * CNTL_MODE_CONTINUE_MEASURE_2: 0x06, // Continuous measurement mode 2 * CNTL_MODE_EXT_TRIG_MEASURE: 0x04, // External trigger measurement mode * CNTL_MODE_SELF_TEST_MODE: 0x08, // Self-test mode * CNTL_MODE_FUSE_ROM_ACCESS: 0x0F // Fuse ROM access mode */ setCNTL(mode) { return __awaiter(this, void 0, void 0, function* () { return yield this.writeByte(exports.AK8963.CNTL, mode); }); } getIDDevice() { return __awaiter(this, void 0, void 0, function* () { return yield this.readByte(exports.AK8963.WHO_AM_I); }); } getDataReady() { return __awaiter(this, void 0, void 0, function* () { return yield this.readBit(exports.AK8963.ST1, exports.AK8963.ST1_DRDY_BIT); }); } } exports.ak8963 = ak8963;