The Launchpad Mini is a MIDI controller with 8x8 buttons that can be used to trigger clips, play notes, and control various software applications. One fun project you can do with the Launchpad Mini is to turn it into a digital clock. This project uses NodeJS and the midi-stream npm package to communicate with the device.
In this blog post, I will outline the steps I took and problems I encountered.
Test the clock for yourself
Before we get started, make sure you have the following:
- A Launchpad Mini device
- NodeJS installed on your computer
Step 1: Setting up the project
- Clone the Launchpad Clock repo
- Install the project with
npm install
Step 2: Execute the program
- Execute the project with
npx ts-node src/application/console.ts
Building the clock
To start, I began by setting up a series of tests to ensure that I could successfully illuminate the individual buttons. From there, I developed a basic JavaScript application to explore concepts such as colour mapping and data mapping from the launchpad to a grid.
var MidiStream = require("midi-stream");
//https://www.youtube.com/watch?v=JatNuVsbsEQ
var duplex = MidiStream("Launchpad Mini");
duplex.write([176, 0, 0]); //clear all
//duplex.pipe(duplex);
duplex.on("data", function (data) {
console.log(data);
//console.log(mapToGrid(data[1]));
//buttons across top 104 - 111
//botton down right 8,24,40,56,72,88,104,120
play(mapToGrid(data[1]).row, mapToGrid(data[1]).col, randomVelocity());
});
const play = (row, col, velocity, delay) => {
var note = mapToMidi(row, col);
setTimeout(() => {
duplex.write([144, note, velocity]);
}, delay || 0);
};
const mapToGrid = (data) => {
const row = Math.floor(data / 16);
const col = data % 8;
return { row, col };
};
const mapToMidi = (row, col) => {
return row * 16 + col;
};
const randomVelocity = () => {
return Math.floor(Math.random() * 100);
};
When configuring a button on the MIDI interface, an array of values is sent to specify the desired behavior. For instance, stream.write([176,0,0])
may be used to turn a button off, while stream.write([144,0,3])
would turn it on. The first value in the array indicates the desired state, with 176 indicating "switch off" and 144 indicating "switch on." The second value corresponds to the specific button being configured, and while it took a bit of experimentation to fully grasp the mapping between numbers and buttons, I eventually got the hang of it. Finally, the third value specifies the colour of the button, and again, some testing was necessary to understand the relationship between values and colours.
The codebase was loosely designed with the hexagonal architecture in mind, featuring three primary components:
Application - This component is responsible for starting the clock application.
Domain - Here, the domain objects manage the bulk of the application's functionality.
Infrastructure - Finally, the infrastructure component handles external entities, such as the low-level code for the Launchpad Mini.
Of all the unit tests, the GridManager tests were the most vital. These tests validated that the grid correctly maps to the MIDI call, ensuring proper operation of the clock.
In summary, this project was an enjoyable endeavour that allowed me to breathe new life into an old device. I've even gone so far as to install the application on a Raspberry Pi, where it runs 24/7 and serves as a stylish and functional decoration for my desk.
Top comments (0)