🔍

How to make a standalone MIDI controller from your Arduino to send stuff to your Browser :)

Make MIDI Keyboard of your Arduino

Arduino Code to make a full MIDI Keyboard out of the controller 🙂 – This needs the „MIDIUSB“ Library installed!

/*
 * MIDIUSB_test.ino
 *
 * Created: 4/6/2015 10:47:08 AM
 * Author: gurbrinder grewal
 * Modified by Arduino LLC (2015)
 */ 

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

// ---------------------------------------------
// ---------------------------------------------
// ---------------------------------------------


void setup() {

}


void loop() {
 
    //-----------------------------------------------------
    // just for fun : send 66 control changes to computer
   for(int i=0;i<=66;i++){
    
      controlChange(0, i,   int(abs(sin(millis()*.0001*(i*.66+1)))*127)  ); // Set the value of controller 10 on channel 0 to 65
   
    }
    //-----------------------------------------------------
    //pick a random note and trigger it with random velocity
    
    int random_note = int( random()*127 ); 
    int random_vel = int( random()*127 ); 
    
    // send  note
    noteOn(0, random_note, random_vel);   // Channel 0, middle C, normal velocity
      
    MidiUSB.flush();
    delay(20);

     // send noteoff (release)
    noteOff(0, random_note, random_vel);   // Channel 0, middle C, normal velocity
      
    MidiUSB.flush();
    delay(20);
}

Code for p5.js to visualize midi input

THIS ONLY WORKS IN CHROME OR EQUIVALENT

midi_magic.js

function midiInit(){
  
  // check for existence of method
  if (navigator.requestMIDIAccess) console.log('This browser supports WebMIDI!')
  else console.log('WebMIDI is not supported in this browser.')

  // ask for MIDI access
  navigator.requestMIDIAccess()
    .then(onMIDISuccess, onMIDIFailure);
}

function onMIDISuccess(midiAccess) {
  // console.log(midiAccess)
  const midi = midiAccess
  const inputs = midi.inputs.values()
  const input = inputs.next()
  console.log(input)
  input.value.onmidimessage = onMIDIMessage
}

function onMIDIMessage(message) {
  const data = message.data // [command/channel, note, velocity]

  const cmd = data[0] >> 4
  channel = data[0] & 0xf
  type = data[0] & 0xf0
  note = data[1]
  velocity = data[2]

  // 248 is midi clock - how to turn it off?? (in op-z app maybe?)
  if (data[0] != 248) {
    //console.log("MIDI data: ", data)
  }

     
 // console.log(type);

  switch (type) {
    case 144: // noteOn message type (always 144 no matter what channel)
      noteOn(channel, note, velocity)
      break
    case 128: //noteOff message type (always 128)
      noteOff(channel, note, velocity)
      break
    case 176: // command change
      controlChange(channel, note, velocity);
      break
  }
}
  
  function controlChange(c, n, v) {
    
    // console.log(c + " = " + n + " = " + v);
    
      axis[n] = int(v);
    
  }

function noteOn(channel, note, velocity) {
  
  notes[note] = velocity;
  
}

function noteOff(channel, note, velocity) {
    notes[note] = 0;
}


function onMIDIFailure(e) {
  console.log('Could not access your MIDI devices: ', e)
}

sketch.js

let axis = [66];
let notes = [128];

function setup() {
  createCanvas(windowWidth, windowHeight);

  midiInit();
}

function initAxis() {
  for (let i = 0; i < axis.length; i++) {
    axis[i] = 1;
  }

  for (let i = 0; i < notes.length; i++) {
    notes[i] = 1;
  }
}

function drawAxis() {
  let wdiv = width / axis.length;
  let hdiv = (height * 0.66) / 127;

  for (let i = 0; i < axis.length; i++) {
    stroke(0);
    fill(255);
    rect(i * wdiv, 0, wdiv, axis[i] * hdiv);
  }
}

function drawNotes() {
  let wdiv = width / notes.length;
  let hdiv = (height * 0.33) / 127;

  for (let i = 0; i < notes.length; i++) {
    stroke(0);
    fill(255);
    rect(i * wdiv, height * 0.66, wdiv, int(notes[i] * hdiv));
  }
}

function draw() {
  background(0, 6);
  drawAxis();
  drawNotes();
}

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="midi_magic.js"></script>
    <script src="sketch.js"></script>
  </body>
</html>