Arduino Pro Micro not running code

Hi there,

Very new to the world of Arduino and programming in general so please do go gentle with me!

I've got an Arduino Pro Micro (was listed on eBay actually as an Arduino Pro Micro Leonardo, not sure if that was right or not though?) and I've placed a very very simple (told you I'm a beginner!) programme on there to basically play a scale of notes out via MIDI.

This all works fine if I use a USB lead to power the board but now I want to power the board via a PSU so that I can use the USB socket on the board as a MIDI input for the project I'm attempting.

I therefore attached a 5V PSU to the RAW and GND pins of the Arduino board (also tried the VCC pin for positive but had read that RAW is best incase the PSU isn't regulated. Pretty sure it is a regulated supply but tried both pins anyway.)

Powering the board up in this way makes the red power LED on the board come on however the programme doesn't run (or perhaps something else is going on) and I can tell as for each note that plays in the programme I made the board flash the TX / RX LEDs alternatively however these never light up and no MIDI is being sent from the board.

Basically is there something I'm missing as this is a really really simple hookup or at least I thought it was going to be!

I really thought I'd just be able to power up the board using a PSU (5V) and everything would power up and run just like it did when the board was plugged in by using the USB lead instead.

Please could someone tell me what rookie mistake I've made as I'm not finding much on the internet about how to power them up other than by using the USB socket which I can't do as I need that to plug my MIDI device into.

Many thanks in advance for any help with this. I'm sure it's going to be something really silly that I'm missing (hoping it is anyway!) so any help anyone can pass my way would be greatly appreciated.

Best wishes,

Mark

Sorry for the quick addendum but just noticed that even if I power up the board using the USB socket just to a USB power brick then again the power LED lights up but nothing 'seems' to run on the board.

As soon as I power the board up by plugging it into my computer then it runs fine!

What am I missing here? Why would it run fine when plugged into the computer but not a USB supply plugged into the wall?

It's almost as though the board is reliant on the computer for it to work which seems rather odd to me?

Thanks,

Mark

Some points

The RAW voltage should be 1V higher than Vcc; see Pro Micro & Fio V3 Hookup Guide - learn.sparkfun.com. So feeding 5V into the RAW input is not the way to go although it might work (possibly unreliable).

Sketches for boards with native USB (like yours) often have a line like below

while(!Serial);

Your program will not get furter than that if there is no terminal program open at the other side (e.g. Serial Monitor on your PC). So if you show your sketch, we might be able to check that out; please make sure to post it between [code] and [/code].

Hi sterretje,

Thanks for the pointers there. I didn't know about that voltage thing so will give that a go.

The programme does also make use of serial messages so I will try commenting those out and seeing if that fixes things.

Thank you so much for the pointers. Unfortunately can't try right away but once I've tried these out later on will post back with if I've had success or not.

Many thanks,

Mark

I'm back but unfortunately still having problems :frowning:

I tried commenting out all the serial parts so that they wouldn't have any effect on the running of the code and also then just tried running it from a USB lead in a standard USB PSU but still nothing :frowning:
When I say nothing I mean that the power LED lights up but then the TX LED doesn't light up showing it sending any MIDI information. When I said above that I'd programmed that LED to light up I could have sworn it was code I'd placed into the sketch but appears it's nothing I put in there and it just lights up anyway however it's not lighting up and no MIDI is being sent :frowning:

My code is here below and I really hope I'm being silly here and missing something drastically easy as my head is pounding now :frowning:

/*
 * MIDIUSB_test.ino
 *
 */ 

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  // Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
//  Serial.println("Sending note on");
  noteOn(0, 48, 64);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 48, 64);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);

//  Serial.println("Sending note on");
  noteOn(0, 50, 68);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 50, 68);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
  
//  Serial.println("Sending note on");
  noteOn(0, 52, 72);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 52, 72);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
  
//  Serial.println("Sending note on");
  noteOn(0, 53, 76);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 53, 76);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);

//  Serial.println("Sending note on");
  noteOn(0, 55, 80);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 55, 80);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);

//  Serial.println("Sending note on");
  noteOn(0, 57, 84);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 57, 84);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);

//  Serial.println("Sending note on");
  noteOn(0, 59, 88);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 59, 88);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);

//  Serial.println("Sending note on");
  noteOn(0, 60, 92);   // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);
//  Serial.println("Sending note off");
  noteOff(0, 60, 92);  // Channel 0, middle C, normal velocity
  MidiUSB.flush();
  delay(200);

  // controlChange(0, 10, 65); // Set the value of controller 10 on channel 0 to 65
}

Thanks so much for all the help with this as it really is very much appreciated.

Best wishes,

Mark

Okay I'm looking around now and guessing that the reason it's not working is the fact that it's utilising the MIDIUSB library and it's waiting for a USB connection but obviously isn't getting one from my Piano for whatever reason when plugged into the USB to Host port.

This is getting quite frustrating as what I'm looking at building is a MIDI controlled LED strip for my piano where basically you have a strip of LEDs above the keys and when you press a key on the piano the LEDs above that key light up.

I need to be able to have the MIDI coming out of the piano go both into my computer (currently doing that via a standard MIDI cable into a MIDI interface and into the computer - all working fine) so that I can record the MIDI performance and also somehow have that same MIDI output going into the Arduino at the same time so that it can read which notes I've pressed and then do its magic (I'll definitely be needing help with that bit I'm sure!) to light up the LED strip in the correct way.

I was hoping therefore to be able to plug the USB to Host connector from the back of the piano into the Arduino to get a MIDI input to the Arduino in that way however now to completely scupper everything I've learnt that my piano has to be set to either use the USB port for MIDI or the standard MIDI connectors. It can't output on both at the same time unfortunately so I need to find some way of taking the MIDI out from the standard MIDI connector on the piano and have that go to both my computer AND to the Arduino at the same time so that I can both record the MIDI performance into Logic Pro and also have the Arduino able to read the notes being played and then light up the correct LEDs.

I'm thinking due to this now that I will have to have the Arduino plugged in via the USB port on the computer (which is fine if it needs to be that way) but don't know how I can get the MIDI from the piano to go to both the computer (it's already going there via a MIDI interface) and also the Arduino?

Is there some clever way of routing the MIDI that's being seen by the computer and sending it on to the Arduino maybe?

Many thanks for any help with this.

Best wishes,

Mark

That got a bit complicated to read but it looks like what you need is a device called a “MIDI splitter”. They are readily available and not expensive and route the MIDI signal from one output device to several receiving devices.

Steve

slipstick:
That got a bit complicated to read but it looks like what you need is a device called a "MIDI splitter". They are readily available and not expensive and route the MIDI signal from one output device to several receiving devices.

Steve

My apologies. I admit that I've always had a problem with being a little too verbose.
I actually think I've managed to fix that part of the problem now though using an application for Mac called Hairless MidiSerial. I'm now able to mirror the MIDI signals that are coming into the computer from the MIDI interface and get them to go into the Arduino so (I believe) I now have success with that part! Hoping I'm not talking too soon on that one of course!
I'm currently testing it all out with the standard MIDIUSB_read example that comes with the MIDIUSB library :

/*
 * MIDIUSB_test.ino
 *
 * Created: 4/6/2015 10:47:08 AM
 * Author: gurbrinder grewal
 * Modified by Arduino LLC (2015)
 */ 

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {
      Serial.print("Received: ");
      Serial.print(rx.header, HEX);
      Serial.print("-");
      Serial.print(rx.byte1, HEX);
      Serial.print("-");
      Serial.print(rx.byte2, HEX);
      Serial.print("-");
      Serial.println(rx.byte3, HEX);    
 
    
    }
  } while (rx.header != 0);
}

and this seems to be working well and is printing out information to the serial monitor but I was wondering if there's a way to actually output the note name (i.e. C3) instead of the weird information it's giving me at the moment?

Received: 9-90-3C-20
Received: 9-90-3C-0

My guess is that's for NoteOn and NoteOff information but I'd love to be able to see it as note names if that's possible?
I just want to see that the Arduino is able to keep up with what I'm playing first and then can hopefully move on to learning how to get the notes that are arriving at the Arduino to be converted into lighting up an LED strip. Very small steps for me though as I'm literally just keeping my head above the water at the moment! :smiley:
Thanks for any more help anyone can throw my way.
Best wishes,
Mark

Digging through the library, I do not see a direct method. Looking at noteOn() and noteOff() in the examples

  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};

So it looks like pitch is the 3rd value in the header. You can create a lookup table like

// a lookup table to convert pitch to text
char lut[][4] =
{
  "A0",
  "B0b",
  "B0",
  "C1",
  "D1b",
};

You will have to complete it; above is based on pitchToNote.h in the library. Note that the text is limited to 3 (!!) characters.

Next you can write a function that takes the pitch as an argument and returns an entry from the lookup table.

/*
  convert a pitch to text
  In:
    pitch (21 .. 108)
  Returns:
    note as text; NULL if invalid pitch passed
*/
char* pitchToText(byte pitch)
{
  // check against lowest pitch
  if (pitch < 21)
  {
    Serial.println("Invalid pitch (1)");
    return NULL;
  }
  // check against highest pitch
  if (pitch < 108)
  {
    Serial.println("Invalid pitch (2)");
    return NULL;
  }

  // first 20 are not used
  byte index = pitch - 21;

  // check in case the LUT is not fully populated
  if (index > sizeof(lut) / sizeof(lut[0]))
  {
    Serial.println("Invalid pitch (lookup table too small)");
    return NULL;
  }

  return lut[index];
}

And you can use it like

  // get note as text from pitch
  char *note = pitchToText(rx.header[2]);
  // if a valid pitch
  if (note != NULL)
  {
    Serial.println(note);
  }

I hope that this gives you the idea.

Note 1: not tested
Note 2: it’s advisable to move the lookup table to PROGMEM so it does not chew away valuable RAM.

Thank you so much for the code above. Unfortunately I’m not really sure what it all means and I did have a go at placing it into my current script but I’m getting errors and don’t have the foggiest what they mean I’m afraid :frowning:

My code so far is :

/*
 * MIDIUSB_test.ino
 *
 * Created: 4/6/2015 10:47:08 AM
 * Author: gurbrinder grewal
 * Modified by Arduino LLC (2015)
 */ 

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}


// a lookup table to convert pitch to text
char lut[][4] =
{
"A0",
"B0b",
"B0",
"C1",
"D1b",
"D1",
"E1b",
"E1",
"F1",
"G1b",
"G1",
"A1b",
"A1",
"B1b",
"B1",
"C2",
"D2b",
"D2",
"E2b",
"E2",
"F2",
"G2b",
"G2",
"A2b",
"A2",
"B2b",
"B2",
"C3",
"D3b",
"D3",
"E3b",
"E3",
"F3",
"G3b",
"G3",
"A3b",
"A3",
"B3b",
"B3",
"C4",
"D4b",
"D4",
"E4b",
"E4",
"F4",
"G4b",
"G4",
"A4b",
"A4",
"B4b",
"B4",
"C5",
"D5b",
"D5",
"E5b",
"E5",
"F5",
"G5b",
"G5",
"A5b",
"A5",
"B5b",
"B5",
"C6",
"D6b",
"D6",
"E6b",
"E6",
"F6",
"G6b",
"G6",
"A6b",
"A6",
"B6b",
"B6",
"C7",
"D7b",
"D7",
"E7b",
"E7",
"F7",
"G7b",
"G7",
"A7b",
"A7",
"B7b",
"B7",
"C8",
};

/*
  convert a pitch to text
  In:
    pitch (21 .. 108)
  Returns:
    note as text; NULL if invalid pitch passed
*/
char* pitchToText(byte pitch)
{
  // check against lowest pitch
  if (pitch < 21)
  {
    Serial.println("Invalid pitch (1)");
    return NULL;
  }
  // check against highest pitch
  if (pitch < 108)
  {
    Serial.println("Invalid pitch (2)");
    return NULL;
  }

  // first 20 are not used
  byte index = pitch - 21;

  // check in case the LUT is not fully populated
  if (index > sizeof(lut) / sizeof(lut[0]))
  {
    Serial.println("Invalid pitch (lookup table too small)");
    return NULL;
  }

  return lut[index];
}



void loop() {
  
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {
      Serial.print("Received: ");
      Serial.print(rx.header, HEX);
      Serial.print("-");
      Serial.print(rx.byte1, HEX);
      Serial.print("-");
      Serial.print(rx.byte2, HEX);
      Serial.print("-");
      Serial.println(rx.byte3, HEX);    

  // get note as text from pitch
  char *note = pitchToText(rx.header[2]);
  // if a valid pitch
  if (note != NULL)
  {
    Serial.println(note);
  }
 
    
    }
  } while (rx.header != 0);
}

but I’m getting an error that says :

/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino: In function 'void noteOn(byte, byte, byte)':
/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino:18:42: warning: narrowing conversion of '(int)(144 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
                                     ~~~~~^~~~~~~~~
/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino: In function 'void noteOff(byte, byte, byte)':
/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino:23:43: warning: narrowing conversion of '(int)(128 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
                                      ~~~~~^~~~~~~~~
/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino: In function 'void controlChange(byte, byte, byte)':
/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino:37:41: warning: narrowing conversion of '(int)(176 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
                                    ~~~~~^~~~~~~~~
/Volumes/Documents/Documents/Work/Film Scores/Arduino Pro Micro Test/MIDIUSB_read/MIDIUSB_read.ino: In function 'void loop()':
MIDIUSB_read:188:39: error: invalid types 'uint8_t {aka unsigned char}[int]' for array subscript
   char *note = pitchToText(rx.header[2]);
                                       ^
exit status 1
invalid types 'uint8_t {aka unsigned char}[int]' for array subscript

None of which means anything to me :frowning: Don’t suppose anyone could tell me what any of that means and how I can go about fixing it?

Many thanks.

Best wishes,

Mark

Check your serial prints but I don't think the pitch is in rx.header.

char *note = pitchToText(rx.header[2]);

Instead of that try using (rx.byte2) i.e.

char *note = pitchToText(rx.byte2);

That looks more likely but I haven't used that library for a while. Also you should really check to see if what you're reading is a NoteOn or NoteOff message because there are loads of other MIDI messages that don't have the same format/information.

Steve

Hi Steve,

Many thanks for the code above. I did try exchanging that line for the one you posted and whilst there are no compilation errors it comes up with this in the Serial Monitor instead :

19:15:52.720 -> Invalid pitch (2)
19:15:52.909 -> Invalid pitch (2)

The first line is the NoteOn information and the second the NoteOff information.
Not too sure how to fix that though?

Many thanks,

Mark

In the pitch lookup if (pitch < 108) should be if (pitch > 108). Pitches LESS than 108 are valid, it’s pitches MORE then 108 that aren’t.

You really need to make an attempt to understand the code that people are giving you otherwise you’re not learning anything and there’s a real danger that we’ll get bored with writing your code for you.

Steve

Thanks slipstick for that correction. My mistake :frowning: