Midi Send Note - Error spotting!?

Status
Not open for further replies.

marl

Member
Hey Folks,

my Midi device receives no notes from my Teensy whereas serialprint.ln displays the midi values correctly - can you please help me to find the error!?


Midi Port Connections:
Midi Port 5 is connected to Pin 1 of my Teensy LC using a 47 Ohm resistor.
Midi Port 2 is connected to GND.
Midi Port 4 is connected to 3.3 V of my Teensy LC using a 47 Ohm resistor.

Tools: USB Type is set to MIDI; CPU speed is set to 48 MHz.

The Scale is chosen through A1.
The Note that should be sent through the midi port is chosen through A0.
The Note should be kept until another one is chosen. -> SerialPrint.ln displays this as wanted, but the Midi device does not get this notes!



Here's the main part of my code:

Code:
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12,11,5,4,2,3);



void setup() {
  // put your setup code here, to run once:
  MIDI.begin();
   Serial.begin(31250);
 
   // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);

  // include reverse switch 
    pinMode(16, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:

// The pot on A1 selects which of the 20 scales we pull notes from
int whichScale = (analogRead(A1) * 20) / 1024;
const int *theChosenScale = Scales[whichScale];
int theChosenScalesLength = ScaleLength[whichScale];

char theChosenScaleName = (*Scales_Names[whichScale]);





// The pot on A0 selects a note from the chosen scale
int whichNoteOfScale = (analogRead(A0) * theChosenScalesLength) / 1024;


// If the switch is set to reverse, reverse the direction of the sequence
if (digitalRead(16) == HIGH) {

    const int theNote = theChosenScale[((theChosenScalesLength - 1) - whichNoteOfScale)];
    lcd.setCursor(6, 1);
    //print that the Scale is in reverse mode
    lcd.print("Reverse");
    lcd.setCursor(0, 0);
  lcd.print(whichScale);
   lcd.setCursor(6, 0);
  lcd.print(theChosenScaleName);
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the note being played:
  lcd.print(theNote);
  MIDI.sendNoteOn(theNote, 127, 1);

Serial.println(theNote);
} else {

    const int theNote = theChosenScale[whichNoteOfScale];
    lcd.setCursor(6, 1);
    //print that the Scale is in normal mode
    lcd.print("Normal ");
    lcd.setCursor(0, 0);
  lcd.print(whichScale);
   lcd.setCursor(6, 0);
  lcd.print(theChosenScaleName);
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
    MIDI.sendNoteOn(theNote, 127, 1);

Serial.println(theNote);
}

Do you have any ideas where the problem is?
Thanks in advance,
Marl
 
I'm not a midi expert, but it seems that you are confounding a few things. When you set the USB type to midi, that means that you want to transmit midi over USB. In that case, you would use usbMidi.sendNoteOn etc. But you obviously wired a serial midi interface to pin 1 of your Teensy LC and you included the "classic" MIDI.begin() and so on, thus it should basically work if you added an include statement for MIDI.h. Unfortunately, your code seems to be incomplete, thus I can't do a quick copy/paste into my IDE for testing.

Basically, it is always a good idea to break down things to diagnose problems one by one. Take one of the known working Midi example sketches and check (best with an oscilloscope on pin1) if midi messages are sent. Then, modify/extend the code to send your own midi messages. After that is working, you might add the LCD stuff.
 
Thanks for your prompt reply!

Enclosed you find the complete code. I already included Midi.h etc, but nervertheless it doesn't work so far.

Any ideas?

Code:
// include the library code:
#include <LiquidCrystal.h>
#include <MIDI.h>


        

int const numPins = 2; //  number of analog inputs 
int analogPins[] = {  
  0,1   // which analog pins to use
};
// the MIDI channel number to send messages
const int channel = 1;


// *********************************
// SCALE INFORMATION:
// *********************************

  // *** A Major ***    COUNT: 0
 const int Amaj0[] = {57,59,61,62,64,66,68,69};
 const char Amaj0_Names[] = {'A6', 'B6', 'C#6', 'C6', 'E6', 'F#6', 'G#6', 'A7'};

  // *** A Major 1***    COUNT: 1
const int Amaj1[] = {69,71,73,74,76,78,80,81};
const char Amaj1_Names[] = {'A7', 'B7', 'C#7', 'C7', 'E7', 'F#7', 'G#7', 'A8'};

  // *** B Major ***    COUNT: 2
const int Bmaj0[] = {59,61,63,64,66,68,70,71};
const char Bmaj0_Names[] = {'B6', 'C#6', 'D#6', 'E6', 'F#6', 'G#6', 'A#7', 'B7'};

  // *** B Major 1***    COUNT: 3
const int Bmaj1[] = {71,73,75,76,78,80,82,83};
const char Bmaj1_Names[] = {'B7', 'C#7', 'D#7', 'E7', 'F#7', 'G#7', 'A#8', 'B8'};

  // *** C Major ***    COUNT: 4
const int Cmaj0[] = {60,62,64,65,67,69,71,72};
const char Cmaj0_Names[] = {'C6', 'D6', 'E6', 'F6', 'G6', 'A7', 'B7', 'C7'};
 
  // *** C Major 1 ***    COUNT: 5
const int Cmaj1[] = {72,74,76,77,79,81,83,84};
const char Cmaj1_Names[] = {'C7', 'D7', 'E7', 'F7', 'G7', 'A8', 'B8', 'C8'};

  // *** D Major ***    COUNT: 6
const int Dmaj0[] = {62,64,66,67,69,71,73,74};
const char Dmaj0_Names[] = {'D6', 'E6', 'F#6', 'G6', 'A7', 'B7', 'C#7', 'D7'};

  // *** D Major 1***    COUNT: 7
const int Dmaj1[] = {74,76,78,79,81,83,85,86};
const char Dmaj1_Names[] = {'D7', 'E7', 'F#7', 'G7', 'A8', 'B8', 'C#8', 'D8'};

  // *** E Major ***    COUNT: 8
const int Emaj0[] = {64,66,68,69,71,73,75,76};
const char Emaj0_Names[] = {'E6', 'F#6', 'G#6', 'A7', 'B7', 'C#7', 'D#7', 'E7'};

 // *** E Major 1***    COUNT: 9
const int Emaj1[] = {76,78,80,81,83,85,87,88};
const char Emaj1_Names[] = {'E7', 'F#7', 'G#7', 'A8', 'B8', 'C#8', 'D#8', 'E8'};

  // *** F Major ***    COUNT: 10
const int Fmaj0[] = {65,67,69,70,72,74,76,77};
const char Fmaj0_Names[] = {'F6', 'G6', 'A7', 'A#7', 'C7', 'D7', 'E7', 'F7'};

  // *** F Major 1***    COUNT: 11
const int Fmaj1[] = {77,79,81,82,84,86,88,89};
const char Fmaj1_Names[] = {'F7', 'G7', 'A8', 'A#8', 'C8', 'D8', 'E8', 'F8'};

  // *** G Major ***    COUNT: 12 
const int Gmaj0[] = {55,57,59,60,62,64,66,67};
const char Gmaj0_Names[] = {'G5', 'A6', 'B6', 'C6', 'D6', 'E6', 'F#6', 'G6'};

  // *** G Major 1***    COUNT: 13 
const int Gmaj1[] = {67,69,71,72,74,76,78,79};
const char Gmaj1_Names[] = {'G6', 'A7', 'B7', 'C7', 'D7', 'E7', 'F#7', 'G7'};

  // *** G Mixolydian***    COUNT: 14 
const int Gmix[] = {81,83,84,86,88,89,79,81};
const char Gmix_Names[] = {'A8', 'B8', 'C8', 'D8', 'E8', 'F8', 'G7', 'A8'};

  // *** Pentatonic***    COUNT: 15
const int Pent[] = {0,2,4,7,9};
const char Pent_Names[] = {'C0', 'D0', 'E0', 'G0', 'A0'};

  // *** Pentatonic 8***    COUNT: 16
const int Pent8[] = {84,86,88,91,93};
const char Pent8_Names[] = {'C8', 'D8', 'E8', 'G8', 'A9'};

  // *** Blues***    COUNT: 17
const int Blue[] = {0,2,3,4,5,7,9,10,11};
const char Blue_Names[] = {'C0', 'D0', 'D#', 'E0', 'F0', 'G0', 'A2', 'A#2','B2'};

  // *** Bluz 10***    COUNT: 18
const int Bluz[] = {108,110,111,112,113,115,117,118,119};
const char Bluz_Names[] = {'C10', 'D10', 'D#10', 'E10', 'F10', 'G10', 'A11', 'A#11','B11'};

  // *** Phrygian 5***    COUNT: 19
const int Phry5[] = {48,49,51,53,55,56,58};
const char Phry5_Names[] = {'C5', 'C#5', 'D#5', 'F5', 'G5', 'G#5', 'A#6'};
     
// **********************************************
// ******* END OF SCALE INFORMATION ********
// **********************************************

const int *Scales[] = {Amaj0, Amaj1, Bmaj0, Bmaj1, Cmaj0, Cmaj1, Dmaj0, Dmaj1, Emaj0, Emaj1, Fmaj0, Fmaj1, Gmaj0, Gmaj1, Gmix, Pent, Pent8, Blue, Bluz, Phry5};

const int ScaleLength[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 9, 9, 7};
const char *Scale_Names[] = {"Amaj0_Names", "Amaj1_Names", "Bmaj0_Names", "Bmaj1_Names", "Cmaj0_Names", "Cmaj1_Names", "Dmaj0_Names", "Dmaj1_Names", "Emaj0_Names", "Emaj1_Names", "Fmaj0_Names", "Fmaj1_Names", "Gmaj0_Names", "Gmaj1_Names", "Gmix_Names", "Pent_Names", "Pent8_Names", "Blue_Names", "Bluz_Names", "Phry5_Names"};

const char *Scales_Names[] = {"Amaj0", "Amaj1", "Bmaj0", "Bmaj1", "Cmaj0", "Cmaj1", "Dmaj0", "Dmaj1", "Emaj0", "Emaj1", "Fmaj0", "Fmaj1", "Gmaj0", "Gmaj1", "Gmix", "Pent", "Pent8", "Blue", "Bluz", "Phry5"};


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12,11,5,4,2,3);



void setup() {
  // put your setup code here, to run once:
  MIDI.begin();
   Serial.begin(31250);
 
   // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);

  // include reverse switch 
    pinMode(16, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:

// The pot on A1 selects which of the 20 scales we pull notes from
int whichScale = (analogRead(A1) * 20) / 1024;
const int *theChosenScale = Scales[whichScale];
int theChosenScalesLength = ScaleLength[whichScale];

char theChosenScaleName = (*Scales_Names[whichScale]);





// The pot on A0 selects a note from the chosen scale
int whichNoteOfScale = (analogRead(A0) * theChosenScalesLength) / 1024;


// If the switch is set to reverse, reverse the direction of the sequence
if (digitalRead(16) == HIGH) {

    const int theNote = theChosenScale[((theChosenScalesLength - 1) - whichNoteOfScale)];
    lcd.setCursor(6, 1);
    //print that the Scale is in reverse mode
    lcd.print("Reverse");
    lcd.setCursor(0, 0);
  lcd.print(whichScale);
   lcd.setCursor(6, 0);
  lcd.print(theChosenScaleName);
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the note being played:
  lcd.print(theNote);
  MIDI.sendNoteOn(theNote, 127, 1);

Serial.println(theNote);
} else {

    const int theNote = theChosenScale[whichNoteOfScale];
    lcd.setCursor(6, 1);
    //print that the Scale is in normal mode
    lcd.print("Normal ");
    lcd.setCursor(0, 0);
  lcd.print(whichScale);
   lcd.setCursor(6, 0);
  lcd.print(theChosenScaleName);
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
    MIDI.sendNoteOn(theNote, 127, 1);

Serial.println(theNote);
}





}

Thanks in advance!
 
Serial is the USB serial, the UART port connected to pins 0 and 1 is Serial1.
So probably you should use
Code:
Serial1.begin(31250);
to initialize the MIDI serial port baudrate.
 
Did you test your hardware first with something like Paul's test sketch?:
Code:
#include <MIDI.h>

const int channel = 1;

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (note=10; note <= 127; note++) {
    MIDI.sendNoteOn(note, 100, channel);
    delay(200);
    MIDI.sendNoteOff(note, 100, channel);
  }
  delay(2000);
}
...and try channel = 0 (omni-mode) just to make sure you're device isn't listening to the wrong channel.
 
Last edited:
Did you test your hardware first with something like Paul's test sketch?:
Code:
#include <MIDI.h>

Thanks for all your answers and suggestions - up to now nothing worked.

I even tried Paul's Test Sketch with channel 0 and channel 1 - nothing.

So the problem seems to be within the hardware:

Basically my set up is ok, isn't it?

[QUOTE]Midi Port Connections:
Midi Port 5 is connected to Pin 1 of my Teensy LC using a 47 Ohm resistor.
Midi Port 2 is connected to GND.
Midi Port 4 is connected to 3.3 V of my Teensy LC using a 47 Ohm resistor.[/QUOTE]

What is the best way to ckeck if there are midi signals on the midi out port?

Thanks again!
 
Double check you have 4 and 5 correct on the DIN
Make sure you are on Pin 1 and not Pin 0 (or other).


What is the best way to ckeck if there are midi signals on the midi out port?
do you have a logic probe to make sure pin 1 is sending?

If Paul's code won't run I'd say it means your connections are not right or there is a physical problem with the Teensy (which is pretty rare unless you've abused it).

can anyone else look over marl's connection notes and ensure that is correct?
 
Last edited:
Thanks once again!

After soldering a completely new DIN port to my teensy, Paul's test sketch now works perfectly.

My sketch doesn't work. I can upload it to my teensy but I do not get notes played on my Midi device!

So the problem now seems to be within my code but I don't know where?!

Any more ideas?
 
Basically, it is always a good idea to break down things to diagnose problems one by one.

I even tried the enclosed more basic code to create and send notes.

As in my longer code, I still get the chosen notes displayed through serial.println - so the whole process of creating and choosing notes works - BUT there are no notes being played on my Midi device!?

Hopefully you can help me to find the error in my code!

Thanks in advance

Code:
#include <MIDI.h>

const int channel = 1;





// *********************************
// SCALE INFORMATION:
// *********************************

 // *** A Major ***    COUNT: 0
 const int Amaj0[] = {57,59,61,62,64,66,68,69};
 const char *Amaj0_Names[] = {"A6", "B6", "C#6", "C6", "E6", "F#6", "G#6", "A7"};

  // *** A Major 1***    COUNT: 1
const int Amaj1[] = {69,71,73,74,76,78,80,81};
const char *Amaj1_Names[] = {"A7", "B7", "C#7", "C7", "E7", "F#7", "G#7", "A8"};

  // *** B Major ***    COUNT: 2
const int Bmaj0[] = {59,61,63,64,66,68,70,71};
const char *Bmaj0_Names[] = {"B6", "C#6", "D#6", "E6", "F#6", "G#6", "A#7", "B7"};

  // *** B Major 1***    COUNT: 3
const int Bmaj1[] = {71,73,75,76,78,80,82,83};
const char *Bmaj1_Names[] = {"B7", "C#7", "D#7", "E7", "F#7", "G#7", "A#8", "B8"};

  // *** C Major ***    COUNT: 4
const int Cmaj0[] = {60,62,64,65,67,69,71,72};
const char *Cmaj0_Names[] = {"C6", "D6", "E6", "F6", "G6", "A7", "B7", "C7"};
 
  // *** C Major 1 ***    COUNT: 5
const int Cmaj1[] = {72,74,76,77,79,81,83,84};
const char *Cmaj1__Names[] = {"C7", "D7", "E7", "F7", "G7", "A8", "B8", "C8"};

  // *** D Major ***    COUNT: 6
const int Dmaj0[] = {62,64,66,67,69,71,73,74};
const char *Dmaj0_Names[] = {"D6", "E6", "F#6", "G6", "A7", "B7", "C#7", "D7"};

  // *** D Major 1***    COUNT: 7
const int Dmaj1[] = {74,76,78,79,81,83,85,86};
const char *Dmaj1_Names[] = {"D7", "E7", "F#7", "G7", "A8", "B8", "C#8", "D8"};

  // *** E Major ***    COUNT: 8
const int Emaj0[] = {64,66,68,69,71,73,75,76};
const char *Emaj0_Names[] = {"E6", "F#6", "G#6", "A7", "B7", "C#7", "D#7", "E7"};

 // *** E Major 1***    COUNT: 9
const int Emaj1[] = {76,78,80,81,83,85,87,88};
const char *Emaj1_Names[] = {"E7", "F#7", "G#7", "A8", "B8", "C#8", "D#8", "E8"};

  // *** F Major ***    COUNT: 10
const int Fmaj0[] = {65,67,69,70,72,74,76,77};
const char *Fmaj0_Names[] = {"F6", "G6", "A7", "A#7", "C7", "D7", "E7", "F7"};

  // *** F Major 1***    COUNT: 11
const int Fmaj1[] = {77,79,81,82,84,86,88,89};
const char *Fmaj1_Names[] = {"F7", "G7", "A8", "A#8", "C8", "D8", "E8", "F8"};

  // *** G Major ***    COUNT: 12 
const int Gmaj0[] = {55,57,59,60,62,64,66,67};
const char *Gmaj0_Names[] = {"G5", "A6", "B6", "C6", "D6", "E6", "F#6", "G6"};

  // *** G Major 1***    COUNT: 13 
const int Gmaj1[] = {67,69,71,72,74,76,78,79};
const char *Gmaj1_Names[] = {"G6", "A7", "B7", "C7", "D7", "E7", "F#7", "G7"};

  // *** G Mixolydian***    COUNT: 14 
const int Gmix[] = {81,83,84,86,88,89,79,81};
const char *Gmix_Names[] = {"A8", "B8", "C8", "D8", "E8", "F8", "G7", "A8"};

  // *** Pentatonic***    COUNT: 15
const int Pent[] = {0,2,4,7,9};
const char *Pent_Names[] = {"C", "D", "E", "G", "A"};

  // *** Pentatonic 8***    COUNT: 16
const int Pent8[] = {84,86,88,91,93};
const char *Pent8_Names[] = {"C8", "D8", "E8", "G8", "A9"};

  // *** Blues***    COUNT: 17
const int Blue[] = {0,2,3,4,5,7,9,10,11};
const char *Blue_Names[] = {"C", "D", "D#", "E", "F", "G", "A2", "A#2","B2"};

  // *** Bluz 10***    COUNT: 18
const int Bluz[] = {108,110,111,112,113,115,117,118,119};
const char *Bluz_Names[] = {"C10", "D10", "D#10", "E10", "F10", "G10", "A11", "A#11","B11"};

  // *** Phrygian 5***    COUNT: 19
const int Phry5[] = {48,49,51,53,55,56,58};
const char *Phry5_Names[] = {"C5", "C#5", "D#5", "F5", "G5", "G#5", "A#6"};
     
// **********************************************
// ******* END OF SCALE INFORMATION ********
// **********************************************
const int *Scales[] = {Amaj0, Amaj1, Bmaj0, Bmaj1, Cmaj0, Cmaj1, Dmaj0, Dmaj1, Emaj0, Emaj1, Fmaj0, Fmaj1, Gmaj0, Gmaj1, Gmix, Pent, Pent8, Blue, Bluz, Phry5};

const int ScaleLength[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 9, 9, 7};



void setup() {
  MIDI.begin();
  Serial.begin(31250);
}

void loop() {

// The pot on A1 selects which of the 20 scales we pull notes from
int whichScale = (analogRead(A1) * 20) / 1024;
const int *theChosenScale = Scales[whichScale];
int theChosenScalesLength = ScaleLength[whichScale];



// The pot on A0 selects a note from the chosen scale
int whichNoteOfScale = (analogRead(A0) * theChosenScalesLength) / 1024;
int theNote = theChosenScale[whichNoteOfScale];
MIDI.sendNoteOn(theNote, 100, channel);
Serial.println(theNote);
}
 
I'd suggest a systematic or scientific diagnosing approach. Instead of immediately "jumping" from a simple and working example code towards something which is ways more complex, including arrays, analogReads, scaling and all that, I'd slowly start from the working example and add the complexity step by step, always checking if it works still or not.
This one was working, isn't it?
Code:
#include <MIDI.h>

const int channel = 1;

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (note=10; note <= 127; note++) {
    MIDI.sendNoteOn(note, 100, channel);
    delay(200);
    MIDI.sendNoteOff(note, 100, channel);
  }
  delay(2000);
}

Next step would be trying to cycle not through note numbers in the loop, but picking these from an array and cycling through that:
Code:
#include <MIDI.h>

const int channel = 1;
const int m_index = 16;
const int melody[m_index] = {60,60,67,67,69,69,67,67,65,65,64,64,62,62,60,60};

void setup() {
  MIDI.begin();
}

void loop() {
  int idx, note;
  for (idx=0; idx < m_index; idx++) {
    note = melody[idx];
    MIDI.sendNoteOn(note, 100, channel);
    delay(200);
    MIDI.sendNoteOff(note, 100, channel);
  }
  delay(2000);
}

... and if that works, you might add analogRead for 1 potentiometer to use the latter scaled down to 0...15 to pick values out of the melody array, and so on. Step by step. Slowly and systematically!
 
....where is noteoff and shouldn't there be something to slow the loop down? (Like in Theremingenieur's example!)

Looks like it would fire thousands of noteon() and flood the target's midi buffer to me.
 
Thanks Oddson and thanks to everyone being involved. IT WORKS!

....where is noteoff and shouldn't there be something to slow the loop down?
This really solved the problem:)

Code:
if (theNote != OldNote) {
MIDI.sendNoteOn(theNote, 127, channel);
Serial.println(theNote);
}
else {
  MIDI.sendNoteOff(theNote, 127, channel);
}
OldNote = theNote;
}

Thanks,
Marl
 
Status
Not open for further replies.
Back
Top