Last updated: 13/09/18
This is an absolut minimal Midi monitor, using a Teensy 3.6 from pjrc and an OLED display SSD1351 from adafruit.
Thanks to the Teensy midi library the software is a piece of cake.
The circuits are basically the standard midi circuits.
3 | 220Ω (R1-R3) |
1 | 10kΩ; (R4) |
1 | 15kΩ (R5) |
2 | 100nF (C1, C3) |
1 | 10µF (C2) |
1 | 1N4148 |
1 | 6N137 |
1 | Teensy 3.6 |
1 | SSD1351 128x128 16-bit colour 1.5" |
3 | Midi Jack |
2 | pin header 4pol |
You have to install the SSD1351 and the gfx libraries from adafruit (Sketch-Include Library-Manage Libraries...).
Here is the sketch:
/***************************************************
midi monitor
weigu.lu
****************************************************/
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <SPI.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// Display OLED 128x128 1.5" SSD1351 Adafruit
#define cs 24
#define rst 25
#define dc 26
#define sclk 27
#define mosi 28
#define BLACK 0x0000 // Color definitions
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
Adafruit_SSD1351 disp = Adafruit_SSD1351(cs, dc, mosi, sclk, rst);
uint16_t time = millis();
char buf[10];
void setup(void) {
Serial.begin(9600);
Serial.print("hello!");
disp.begin();
Serial.println("init");
disp.setRotation(3); //0 no rotation, 1=90, 2=180, 3=270 clockwise.
time = millis() - time;
Serial.println(time, DEC);
delay(100);
greetingText();
Serial.println("done");
delay(1000);
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
MIDI.setHandleControlChange(handleControlChange);
MIDI.setHandleSystemExclusive(handleSystemExclusive);
MIDI.setHandlePitchBend(handlePitchBend);
MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop() {
MIDI.read();
}
// Greeting Text for 3 seconds
void greetingText() {
disp.fillScreen(BLACK);
delay(200);
disp.fillScreen(BLACK);
delay(1000);
disp.setTextColor(YELLOW);
disp.setTextSize(2);
disp.setCursor(40, 20);
disp.print("MIDI");
disp.setCursor(20, 50);
disp.print("MONITOR");
disp.setCursor(40, 80);
disp.print("V1.0");
disp.setCursor(10, 120);
disp.setTextSize(1);
disp.setTextColor(GREEN);
disp.print("by weigu.lu");
delay(2000);
disp.setTextColor(WHITE,BLACK);
disp.setTextSize(1);
disp.fillScreen(BLACK);
}
void handleNoteOn(byte channel, byte pitch, byte velocity) {
disp.setCursor(0, 8);
disp.print("Note On: ");
sprintf(buf, "%2d", channel);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%3d", pitch);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%3d", velocity);
disp.print(buf);
}
void handleNoteOff(byte channel, byte pitch, byte velocity) {
disp.setCursor(0, 16);
disp.print("Note Of: ");
sprintf(buf, "%2d", channel);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%3d", pitch);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%3d", velocity);
disp.print(buf);
}
void handlePitchBend(byte channel, int bend) {
disp.setCursor(0, 32);
disp.print("PBend: ");
sprintf(buf, "%2d", channel);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%5d", bend);
disp.print(buf);
}
void handleControlChange(byte channel, byte number, byte value) {
disp.setCursor(0, 48);
disp.print("Cchange: ");
sprintf(buf, "%2d", channel);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%3d", number);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%4d", value);
disp.print(buf);
}
void handleSystemExclusive(byte * array, unsigned size) {
disp.setCursor(0, 64);
disp.print("SysEx: ");
sprintf(buf, "%5d", *array);
disp.print(*array);
disp.print(buf);
disp.print(" ");
sprintf(buf, "%3d", size);
disp.print(buf);
disp.print(" ");
disp.print(size);
}