I’m looking into building a MIDI to CV module — because everything I know of that’s commercially available fails to meet my needs one way or another — and decided I wanted to take a look at what my various MIDI controllers are actually sending. So I breadboarded a MIDI snooper.
Initially it was just a MIDI jack, an optoisolator with a few support components, and an Arduino Nano clone. The optoisolator I used was an H11L1. That’s the equivalent of the out-of-production PC-900, mentioned in the MIDI specification.
I wanted the Nano to write messages to the serial monitor, which is a problem because the MIDI input also needs serial I/O, and the Nano has only one serial channel in hardware. So I used the SofwareSerial library, which lets you choose any pair of digital pins to do serial I/O, for the MIDI. The script was simple: Listen for messages, pick out the types of interest, print them to the serial monitor. What could go wrong?
Well, with my Arturia Keystep plugged in, it seemed to work fine if I pressed keys — even rapid glissandi. But in sequencer or arpeggio mode, even at the slowest tempo, it all went south. An “arpeggio” with one key held down should give pairs of Note On / Note Off messages, with the same MIDI note each time, and Clock messages, of which the script would print one for every 24 that came in, and nothing else except some start and stop stuff. Instead:
08:55:59.308 -> ControlChange d1 54 d2 127 08:55:59.341 -> Type = 250 d1 0 d2 0 08:55:59.375 -> Clock tick 08:55:59.507 -> ControlChange d1 54 d2 0 08:56:01.296 -> Clock tick 08:56:02.291 -> NoteOn MIDI note 31 channel 1 velocity 128 08:56:02.358 -> NoteOn MIDI note 74 channel 1 velocity 64 08:56:03.319 -> Clock tick 08:56:03.319 -> Type = 255 d1 0 d2 0 08:56:04.280 -> NoteOn MIDI note 74 channel 1 velocity 128 08:56:04.347 -> NoteOn MIDI note 74 channel 1 velocity 64 08:56:05.307 -> Clock tick 08:56:06.302 -> NoteOn MIDI note 41 channel 1 velocity 128 08:56:06.335 -> Type = 255 d1 0 d2 0 08:56:07.296 -> Clock tick 08:56:07.328 -> NoteOn MIDI note 74 channel 1 velocity 144 08:56:08.289 -> NoteOn MIDI note 41 channel 1 velocity 128 08:56:08.323 -> NoteOn MIDI note 74 channel 1 velocity 64 08:56:09.284 -> Clock tick 08:56:09.317 -> Type = 255 d1 0 d2 0 08:56:10.278 -> NoteOn MIDI note 74 channel 1 velocity 128 08:56:10.345 -> NoteOn MIDI note 74 channel 1 velocity 64 08:56:11.307 -> Clock tick 08:56:12.301 -> NoteOn MIDI note 61 channel 1 velocity 128 08:56:12.334 -> NoteOn MIDI note 74 channel 1 velocity 64 08:56:13.296 -> Clock tick 08:56:14.290 -> NoteOn MIDI note 41 channel 1 velocity 128 08:56:14.356 -> NoteOn MIDI note 74 channel 1 velocity 64 08:56:15.317 -> Clock tick
Pairs of Note On messages, instead of Note On / Note Off, and frequently not the right note (74). Sometimes, though, there would be pairs of Note Off messages. And since plugging it into my Mother-32 resulted in it playing the same note, on and off, every time, I didn’t think the Keystep was actually sending such garbage.
And from my ancient M-Audio KeyStudio 25, with me just playing one note and then not touching anything:
08:42:37.362 -> ControlChange d1 93 d2 76 08:42:37.495 -> NoteOn MIDI note 56 channel 1 velocity 47 // key was pressed 08:42:37.627 -> NoteOff MIDI note 56 channel 1 08:43:33.648 -> ControlChange d1 93 d2 70 08:43:33.682 -> ControlChange d1 93 d2 67 08:43:33.715 -> ControlChange d1 93 d2 63 08:43:33.748 -> ControlChange d1 93 d2 60 08:43:33.781 -> ControlChange d1 93 d2 58 08:43:33.815 -> ControlChange d1 93 d2 57 08:43:33.848 -> ControlChange d1 93 d2 56 08:43:33.848 -> ControlChange d1 93 d2 55 08:43:37.891 -> ControlChange d1 93 d2 60 08:43:37.924 -> ControlChange d1 93 d2 62 08:43:37.957 -> ControlChange d1 93 d2 65 08:43:37.990 -> ControlChange d1 93 d2 69 08:43:38.024 -> ControlChange d1 101 d2 93 08:43:38.057 -> ControlChange d1 72 d2 93 08:43:38.057 -> ControlChange d1 73 d2 93 08:43:38.090 -> ControlChange d1 74 d2 93 08:43:39.383 -> ControlChange d1 75 d2 176 08:43:39.416 -> ControlChange d1 93 d2 76 08:43:57.145 -> ControlChange d1 93 d2 77 08:45:23.243 -> ControlChange d1 93 d2 78
Bursts of Control Change messages, once a minute or so. Not good!
First thing I tried was a different optoisolator, a 6N137. Which is very different from a 6N138, the other one mentioned in the MIDI spec, and which often gets used but in fact is slower than the MIDI spec calls for. The 6N137 is plenty fast.
But it didn’t change the results.
I changed the MIDI cable. (Never trust a cable.) I changed the Nano. Same thing.
Discussion on the LMNC Discourse group pointed the finger at SoftwareSerial, which has been specifically called out as too slow for MIDI. I was a little skeptical, because I’d also tried hard serial, not writing to the serial monitor but flashing an LED when an unexpected message showed up, and with my M-Audio plugged in that LED flashed once a minute or so. Entirely consistent with what the snooper had shown.
Well, maybe the KeyStudio was flaky and the KeyStep problems were due to SoftwareSerial. But how to snoop while using hardware serial for MIDI?
twinturbo made the obvious-in-retrospect suggestion of an OLED display. I had one around. All I’d have to do would be to change the script to print to that instead of the serial monitor. What could go wrong?
Several hours later I’d gotten it working to the point of seeing that with hardware serial listening to the Keystep I was in fact getting Note On / Note Off pairs with the correct note. But I wanted to improve my MIDI snooper and was having no luck. Strange and inconsistent things were happening, as if maybe the Nano didn’t have enough memory to do what needed to be done, or something was writing outside array bounds or using a bad pointer.
This morning JaggedNZ suggested using the u8g2 OLED library instead of the Adafruit library I’d been struggling with. They said they’d never had luck with the latter. I looked into it and discovered u8g2 has a class, U8log, which emulates an output terminal, scrolling old lines off the top to make room for new ones at the bottom — behavior I’d been bumblingly trying to code myself. I installed u8g2 and within maybe half an hour I had the snooper up and running:
There you are, alternating Note On and Note Off messages, all with the right note. As for the KeyStudio 25… still spewing random Control Change messages, all either 93 or more rarely 5. It turns out two of the pots on the KeyStudio are, for some reason, at present configured to send CC 5 or CC 93 messages. So it looks like some hardware problem is actually creating those.
But the MIDI snooper is working. It’s a very simple circuit, it could easily be built on a stripboard. And then a month from now I’d want to use it again and I would be utterly unable to find it. Maybe it’d be just easier to build it on a solderless breadboard when I need it, and dismantle it afterwards. Yes, I can keep track of individual optoisolators better than I can entire stripboard circuits.
I made a GitHub repo for the MIDI snooper, if you want to build one yourself.