UNPKG

node-anemometer

Version:

Measuring the wind speed with an anemometer

246 lines (245 loc) 8.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PCF8583 = void 0; const i2c_bus_1 = require("i2c-bus"); const constants_1 = require("./constants"); const utilities_1 = require("./utilities"); /** * Represents a PCF8583 real-time clock module. * This class provides methods to interact with the PCF8583 module over I2C. */ class PCF8583 { address; bus; i2cOptions; wire = null; /** * Creates an instance of PCF8583. * * @param address The I2C address of the PCF8583 module. * @param bus The I2C bus number. */ constructor(address, bus, i2cOptions) { this.address = address; this.bus = bus; this.i2cOptions = i2cOptions; } /** * Indicates whether the I2C connection is currently open. * * @readonly * @returns `true` if the connection is open, otherwise `false`. */ get isOpen() { return this.wire !== null; } /* * ========================================== * Private functions * ========================================== */ /** * Writes an array of bytes to the specified register. * * @param register The register address to write to. * @param bytes The array of bytes to write. * @returns A promise that resolves when the write operation is complete. * @throws If the I2C connection is not open. * @throws If the write operation fails. */ async i2cWriteBytes(register, bytes) { const buff = Buffer.from(bytes); return new Promise((resolve, reject) => { if (!this.wire) { return reject(new Error('Open a connection before you can access the bus!')); } this.wire.writeI2cBlock(this.address, register, buff.length, buff, (err) => { if (err) { return reject(err); } resolve(); }); }); } /** * Reads an array of bytes from the specified register. * * @param register The register address to read from. * @param length The number of bytes to read. * @returns A promise that resolves with the read bytes as a Buffer. * @throws If the I2C connection is not open. * @throws If the read operation fails. */ async i2cReadBytes(register, length) { const buff = Buffer.alloc(length); return await new Promise((resolve, reject) => { if (!this.wire) { return reject(new Error('Open a connection before you can access the bus!')); } this.wire.readI2cBlock(this.address, register, buff.length, buff, (err, _bytesRead, buffer) => { if (err) { return reject(err); } resolve(buffer); }); }); } /** * Reads a single byte from the specified register. * * @param offset The register address to read from. * @returns A promise that resolves with the read byte value. * @throws If the I2C connection is not open. * @throws If the read operation fails. */ async i2cReadRegister(offset) { return (await this.i2cReadBytes(offset, 1))[0]; } /** * Writes a single byte to the specified register. * * @param offset The register address to write to. * @param value The byte value to write. * @returns A promise that resolves when the write operation is complete. * @throws If the I2C connection is not open. * @throws If the write operation fails. */ async i2cWriteRegister(offset, value) { await this.i2cWriteBytes(offset, [value]); } /* * ========================================== * Public functions * ========================================== */ /** * Opens the I2C connection to the PCF8583 module. * * @returns Resolves when the connection is successfully opened. * @throws If the i2c connection is already opened. */ async open() { if (this.wire) { throw new Error('Connection already open.'); } this.wire = await new Promise((resolve, reject) => { resolve((0, i2c_bus_1.open)(this.bus, this.i2cOptions ?? { forceAccess: false }, (err) => { if (err) { reject(err); } })); }); } /** * Closes the I2C connection to the PCF8583 module and stops the clock. * * @returns Resolves when the connection is successfully closed. * @throws If the i2c connection is already closed. */ async close() { if (!this.wire) { throw new Error('Connection already closed.'); } this.wire = await new Promise((resolve, reject) => { this.wire.close((err) => { if (err) { reject(err); } }); resolve(null); }); } /** * Starts the clock on the PCF8583 module. * * @returns A promise that resolves when the clock is started. * @throws If the I2C connection is not open. * @throws If the start operation fails. */ async start() { let control = await this.i2cReadRegister(constants_1.LOCATION_CONTROL); control &= 0x7f; await this.i2cWriteRegister(constants_1.LOCATION_CONTROL, control); } /** * Stops the clock on the PCF8583 module. * * @returns A promise that resolves when the clock is stopped. * @throws If the I2C connection is not open. * @throws If the stop operation fails. */ async stop() { let control = await this.i2cReadRegister(constants_1.LOCATION_CONTROL); control |= 0x80; await this.i2cWriteRegister(constants_1.LOCATION_CONTROL, control); } /** * Resets the PCF8583 module to its default values. * * @returns Resolves when the module is successfully reset. */ async reset() { await this.i2cWriteBytes(constants_1.LOCATION_CONTROL, [ 0x04, // 00 control/status (alarm enabled by default) 0x00, // 01 set hundreds-of-seconds 0x00, // 02 set second 0x00, // 03 set minute 0x00, // 04 set hour (24h format) 0x01, // 05 set day 0x01, // 06 set month 0x00, // 07 set timer 0x00, // 08 set alarm control 0x00, // 09 set alarm hundreds-of-seconds 0x00, // 0A set alarm second 0x00, // 0B set alarm minute 0x00, // 0C set alarm hour 0x01, // 0D set alarm day 0x01, // 0E set alarm month 0x00, // 0F set alarm timer 0x00, // 10 set year offset to 0 0x00 // 11 set last read value for year to 0 ]); } /** * Sets the clock mode of the PCF8583 module. * * @param mode The mode to set. * @returns Resolves when the mode is successfully set. */ async setMode(mode) { let control = await this.i2cReadRegister(constants_1.LOCATION_CONTROL); control = (control & ~0x30) | (mode & 0x30); await this.i2cWriteRegister(constants_1.LOCATION_CONTROL, control); } /** * Sets the counter value of the PCF8583 module. * * @param value The value to set in the counter. * @returns Resolves when the counter value is successfully set. */ async setCount(value) { if (value < 0 || value > 999999) { throw new Error(`Invalid value for counter: ${value}`); } await this.stop(); await this.i2cWriteBytes(constants_1.LOCATION_COUNTER, [ (0, utilities_1.byteToBCD)(value % 100), (0, utilities_1.byteToBCD)((value / 100) % 100), (0, utilities_1.byteToBCD)((value / 10000) % 100) ]); await this.start(); } /** * Retrieves the current counter value from the PCF8583 module. * * @returns Resolves with the current counter value. */ async getCount() { const read = await this.i2cReadBytes(constants_1.LOCATION_COUNTER, 3); let count = (0, utilities_1.bcdToByte)(read[0]); count += (0, utilities_1.bcdToByte)(read[1]) * 100; count += (0, utilities_1.bcdToByte)(read[2]) * 10000; return count; } } exports.PCF8583 = PCF8583;