...so what was wrong with your initial attempts?
Glad to see your having success now.
I am not entirely sure but I re-did the breadboard several times. All the components (resistors, diode, opto) were all ok but I think it was something to have to do with ground. I forgot that the DIN connectors have two front metal pins that were also on the ground line. Perhaps that was the cause. I took that out of the re-factoring and the circuit worked.
Code:
Hints:
Modulo division by 12 on MIDI notes gives you an zero-based array index for note names from C to B
e.g.
noteName = names[note%12]
You can even have one array for sharp names and one for flats and then de-reference the name based on whether the key sig. has flats or not.
I have problems with BPM conversions every time... but the crucial thing the inversion from a duration to a rate:
mSec/beat = x
Sec/beat = 1/1000*x
Min/beat = 1/60*1/1000*x
BPM = 60000 / (ms/Beat)
I.e. - Invert the duration and scale by the time factor.
Thank you so much for these hints - in researching the note names I've found some examples that are in line with your hint but I am not entirely sure how to incorporate them into my sketch just yet. In the MIDI sniffer sketch I am using, there are two switch cases for NoteOff and NoteOn that return the Note #:
Code:
case midi::NoteOff :
{
Serial.print("NoteOff, chan: ");
Serial.print(MIDI.getChannel());
Serial.print(" Note#: ");
Serial.print(MIDI.getData1());
Serial.print(" Vel#: ");
Serial.println(MIDI.getData2());
}
break;
case midi::NoteOn :
{
uint8_t vel;
Serial.print("NoteOn, chan: ");
Serial.print(MIDI.getChannel());
Serial.print(" Note#: ");
Serial.print(MIDI.getData1());
Serial.print(" Vel#: ");
vel = MIDI.getData2();
Serial.print(vel);
if (vel == 0)
{
Serial.print(" *Implied off*");
}
Serial.println();
}
break;
If I understand correctly:
Code:
MIDI.getData1();
MIDI.getData2();
are what return the 2 data bytes of the received MIDI message? So I need to use the MIDI note# data pulled from MIDI.getData1(?) and take it a step further. This seems similar to your method:
Code:
// https://forum.pjrc.com/threads/43924-convert-midi-note-to-note-name
String noteName[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
int MidiNoteName;
int noteOctave;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Start");
delay(100);
int i;
for (i=0; i<=127; i++) {
noteOctave = i/12;
MidiNoteName = i%12;
Serial.println("Note: "+String(i)+" "+String(noteName[MidiNoteName])+" "+String(noteName[MidiNoteName])+String(noteOctave));
delay(50);
}
delay(200);
}
With regards to the BPM conversions, the MIDI sniffer sketch I am using as a guide uses the MsTimer2 library: https://github.com/sparkfun/MIDI_Shi...DI-sniffer.ino
To calculate the BPM as you describe, would I need to use MIDI.setHandleClock(handleClock) in addition to MsTimer library or would that be redundant? If I understand correctly these switch cases are displaying the clock byte values:
Code:
case midi::Clock :
{
clock_ticks++;
Serial.print("Clock ");
Serial.println(clock_ticks);
}
break;
case midi::Start :
{
clock_ticks = 0;
Serial.println("Starting");
}
break;
case midi::Stop :
{
old_clock_ticks = clock_ticks;
Serial.println("Stopping");
}
break;