openi2c
Version:
This library is a set of cross platform drivers for common I2C devices.
189 lines (188 loc) • 8.81 kB
JavaScript
"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;