openi2c
Version:
This library is a set of cross platform drivers for common I2C devices.
62 lines (50 loc) • 2.15 kB
text/typescript
import * as i2c from 'i2c-bus';
import { sleep } from '../../utils';
import { debug } from '../../debug';
import { Module } from '../Module';
const defaultConfig = {
// Module Registers
ADDRESS: 0x40,
MODE1: 0x00,
PRESCALE: 0xfe,
LED0_ON_L: 0x06,
LED0_ON_H: 0x07,
LED0_OFF_L: 0x08,
LED0_OFF_H: 0x09,
// Library Defaults
frequency: 50
}
type Config = typeof defaultConfig;
export class PCA9685 extends Module<Config> {
constructor(busNumber: number = 0, address: number = defaultConfig.ADDRESS, config: Partial<Config> = defaultConfig) {
super(busNumber, address, config);
}
async init() {
await this.setFrequency(this.config.frequency);
}
async setDutyCycle(channel: number, dutyCycle: number): Promise<void> {
dutyCycle = Math.min(1, Math.max(0, dutyCycle)); // Clamp to [0,1]
this.debug.log(`Set duty cycle for channel ${channel} to ${dutyCycle}`);
await this.setPWM(channel, 0, Math.round(dutyCycle * 4095));
}
async setFrequency(freq: number) {
this.debug.log(`Set PWM frequency to ${freq} Hz`);
const prescale = Math.round(25000000 / (4096 * freq)) - 1;
await this.bus.writeByte(this.address, this.config.MODE1, 0x10); // sleep
await this.bus.writeByte(this.address, this.config.PRESCALE, prescale); // set frequency prescaler
// Does it need to sleep?
await sleep(1);
await this.bus.writeByte(this.address, this.config.MODE1, 0x80); // wake up
await sleep(1);
}
async setPWM(channel: number, on: number, off: number) {
this.debug.log(`Set PWM for channel ${channel} to ${on} to ${off}`);
await Promise.all([
this.bus.writeByte(this.address, this.config.LED0_ON_L + 4 * channel, on & 0xff),
this.bus.writeByte(this.address, this.config.LED0_ON_H + 4 * channel, on >> 8),
this.bus.writeByte(this.address, this.config.LED0_OFF_L + 4 * channel, off & 0xff),
this.bus.writeByte(this.address, this.config.LED0_OFF_H + 4 * channel, off >> 8)
]);
}
}
export const config = defaultConfig;