99 lines
2.7 KiB
JavaScript

const Gpio = require('onoff').Gpio;
const i2c = require('i2c-bus');
const MAX9744_I2CADDR = 0x4b;
const MAX_VOLUME = 63;
const MIN_VOLUME = 0;
const VOLUME_STEPS = 1;
let currentVolume = MIN_VOLUME;
let i2c1;
async function readVolume() {
const rBuf = Buffer.alloc(1);
const data = await i2c1.i2cRead(MAX9744_I2CADDR, rBuf.length, rBuf);
return data.buffer.readUInt8();
}
async function writeVolume(volume) {
const wBuf = Buffer.from([volume]);
await i2c1.i2cWrite(MAX9744_I2CADDR, wBuf.length, wBuf);
console.log("Volume set: ", volume);
}
async function increaseVolume() {
console.log("Increasing volume");
currentVolume = currentVolume < MAX_VOLUME - VOLUME_STEPS ? currentVolume + VOLUME_STEPS : MAX_VOLUME;
await writeVolume(currentVolume);
}
async function decreaseVolume() {
console.log("Decreasing volume");
currentVolume = currentVolume > MIN_VOLUME + VOLUME_STEPS ? currentVolume - VOLUME_STEPS : MIN_VOLUME;
await writeVolume(currentVolume);
}
async function handleButtonTick(button) {
console.log("Handling button tick");
if(button.active) {
await button.action();
button.cycles++;
let timeout = 1400 - (button.cycles * 200);
if(timeout < 200) {
timeout = 200;
}
button.watcher = setTimeout(async () => {
await handleButtonTick(button);
}, timeout);
} else if(button.watcher) {
clearTimeout(button.watcher);
button.cycles = 0;
}
}
const buttons = {
volumeUp: {pin: 17, gpio: null, active: false, watcher: null, action: increaseVolume, cycles: 0},
volumeDown: {pin: 27, gpio: null, active: false, watcher: null, action: decreaseVolume, cycles: 0}
};
function watchButton(button) {
button.gpio.watch(async (err, value) => {
if(err) {
button.active = false;
if(button.watcher) {
clearInterval(button.watcher);
button.cycles = 0;
}
console.error(err);
} else {
if (value === 1) {
button.active = true;
await handleButtonTick(button);
} else {
button.active = false;
if(button.watcher) {
clearInterval(button.watcher);
}
}
}
});
}
function initButton(button) {
button.gpio = new Gpio(button.pin, 'in', 'both', { activeLow: true});
watchButton(button);
}
async function main() {
try {
i2c1 = await i2c.openPromisified(1);
currentVolume = await readVolume();
initButton(buttons.volumeUp);
initButton(buttons.volumeDown);
} catch (err) {
console.error(err);
}
}
main();