I’ve breadboarded a MIDI in circuit with a Nano and am running a sketch that listens for MIDI messages and prints them out. It uses SoftwareSerial for MIDI so it can write diagnostics to the serial monitor with hardware serial. Or it can be set up to use hardware serial for MIDI and write no diagnostics; it flashes an LED when it sees a MIDI message of the type or types I specify.
And I’m getting garbage.
I’m using this for MIDI In:
The worse problem is with the Arturia Keystep. If I just play keys manually it does fine. But if I put it in arp mode and hold down one key to get a single-note “arpeggio”, I get this (where “Clock tick” means it’s seen 24 Clock messages):
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
08:56:15.317 -> Type = 255 d1 0 d2 0
08:56:16.282 -> NoteOn MIDI note 74 channel 1 velocity 128
08:56:16.349 -> NoteOn MIDI note 74 channel 1 velocity 64
08:56:17.309 -> Clock tick
08:56:17.309 -> Type = 255 d1 0 d2 0
08:56:18.303 -> NoteOn MIDI note 74 channel 1 velocity 128
08:56:18.337 -> NoteOn MIDI note 74 channel 1 velocity 64
08:56:19.298 -> Clock tick
08:56:20.294 -> NoteOn MIDI note 41 channel 1 velocity 128
08:56:20.327 -> NoteOn MIDI note 74 channel 1 velocity 64
08:56:21.287 -> Clock tick
I get pairs of note events per 24 Clock events mostly, as expected, but they’re both NoteOn instead of one on and one off, and the note is usually the correct one, 74, but not always. There also are a lot of System Reset messages (Type 255). Occasionally also there are some random Control Change messages.
Is the Keystep really doing this? I don’t think so, because if I plug it into my Mother-32 all I hear is the same note over and over, on and off, as expected.
This occurs even at the lowest tempo, somewhere around 40 beats per minute.
With another keyboard, my M-Audio MIDI keyboard, plugged in, if I press a key and then do nothing (not touching the keyboard), I get:
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
At intervals of roughly once a minute, one or more Control Change messages. Almost always with a 93 as either the first or the second data byte.
Note that this keyboard does send Active Sense messages (which my sketch sees but doesn’t print out). I’m thinking these may be somehow corrupted Active Sense messages.
With diagnostic messages turned off and using hardware serial to listen to the MIDI, the LED lights up about once a minute, so I infer the same thing is happening. Therefore this does not appear to be a Software Serial issue or to do with serial output bogging things down.
I have the same issues using an H11L1 optoisolator (different pinout and pullup resistor). I’ve changed the MIDI cable, no change. I’ve tried two Nanos, both clones from Tayda, one brand new, no change.
I’m out of ideas. Do you have any?
Here’s the sketch:
/*
Listen for MIDI messages (on soft serial pin) and write
diagnostics (on hard serial)
CC0 Rich Holmes Feb 2020
*/
#define DO_PRINT 1 // Print events (requires software serial)
#define HSERIAL 0 // 1 for hardware serial, 0 for software
#define TELL_NOTEON 1
#define TELL_NOTEOFF 1
#define TELL_PITCHBEND 1
#define TELL_CC 1
#define TELL_CLOCK 24 // Every nth clock
#define TELL_OTHER 1
#define TELL_ACTIVE 0 // Every nth active sense
#define LED_TELL 10
#include <MIDI.h>
#if HSERIAL==1
MIDI_CREATE_DEFAULT_INSTANCE();
#else
#define MIDI_RX 6 // <--- connect the optocoupler to this pin
#define MIDI_TX 7
unsigned long led_time = 0;
#include <SoftwareSerial.h>
SoftwareSerial midiSerial(MIDI_RX, MIDI_TX);
MIDI_CREATE_INSTANCE(SoftwareSerial, midiSerial, MIDI);
#endif
void setup()
{
#if HSERIAL==0
Serial.begin(9600);
#endif
MIDI.begin(MIDI_CHANNEL_OMNI);
pinMode(LED_TELL, OUTPUT);
digitalWrite(LED_TELL, LOW);
led_time = 0;
}
void loop()
{
int type, noteMsg, velocity, channel, d1, d2, led_on;
static unsigned int clock_count = 0;
static unsigned int active_count = 0;
if (led_time > 0 && millis() - led_time > 300)
{
digitalWrite(LED_TELL, LOW);
led_time = 0;
}
led_on = 0;
if (MIDI.read()) {
byte type = MIDI.getType();
switch (type) {
case midi::NoteOn:
#if TELL_NOTEON>0
led_on = 1;
#if DO_PRINT > 0
noteMsg = MIDI.getData1();
channel = MIDI.getChannel();
velocity = MIDI.getData2();
Serial.print ("NoteOn");
Serial.print (" MIDI note ");
Serial.print (noteMsg+21);
Serial.print (" channel ");
Serial.print (channel);
Serial.print (" velocity ");
Serial.println (velocity);
#endif
#endif
break;
case midi::NoteOff:
#if TELL_NOTEOFF>0
led_on = 1;
#if DO_PRINT > 0
noteMsg = MIDI.getData1();
channel = MIDI.getChannel();
Serial.print ("NoteOff");
Serial.print (" MIDI note ");
Serial.print (noteMsg+21);
Serial.print (" channel ");
Serial.println (channel);
#endif
#endif
break;
case midi::PitchBend:
#if TELL_PITCHBEND>0
led_on = 1;
#if DO_PRINT > 0
d1 = MIDI.getData1();
d2 = MIDI.getData2(); // d2 from 0 to 127, mid point = 64
Serial.print ("PitchBend");
Serial.print (" d1 ");
Serial.print (d1);
Serial.print (" d2 ");
Serial.println (d2);
#endif
#endif
break;
case midi::ControlChange:
#if TELL_CC
led_on = 1;
#if DO_PRINT > 0
d1 = MIDI.getData1();
d2 = MIDI.getData2(); // From 0 to 127
Serial.print ("ControlChange");
Serial.print (" d1 ");
Serial.print (d1);
Serial.print (" d2 ");
Serial.println (d2);
#endif
#endif
break;
case midi::Clock:
#if TELL_CLOCK>0
led_on = 1;
#if DO_PRINT > 0
if (clock_count == 0)
Serial.println ("Clock tick");
clock_count++;
if (clock_count == TELL_CLOCK)
clock_count = 0;
#endif
#endif
break;
case midi::ActiveSensing:
#if TELL_ACTIVE>0
led_on = 1;
#if DO_PRINT > 0
if (active_count == 0)
Serial.println ("ActiveSensing");
active_count++;
if (active_count == TELL_CLOCK)
active_count = 0;
#endif
#endif
break;
default:
#if TELL_OTHER>0
led_on = 1;
#if DO_PRINT > 0
d1 = MIDI.getData1();
d2 = MIDI.getData2();
Serial.print ("Type = ");
Serial.print (type);
Serial.print (" d1 ");
Serial.print (d1);
Serial.print (" d2 ");
Serial.println (d2);
#endif
#endif
}
if (led_on > 0)
{ digitalWrite(LED_TELL, HIGH);
led_time = millis();
}
}
}