DEV Community

Paul Diggle
Paul Diggle

Posted on • Updated on

How to create a Launchpad Mini digital clock using Node.js

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.

Image description

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

Step 2: Execute the program

  • Execute the project with npx ts-node src/application/console.ts

Select a port (running on Raspberry Pi)

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);
};
Enter fullscreen mode Exit fullscreen mode

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.

Grid Layout

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.

Image description

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)