Planning for midi preset box - First project

Hey, this is my first Arduino project. I have spent the last few weeks reading and watching every Arduino tutorial I could find. I was hoping to get some help on what boards/shields/etc I should need to move forward. Everything that I pull up on the subject is for real time midi controllers. My project will use midi, but it will need to store midi data that can be triggered by one event.

It is for a preset box to be used in between a footswitch that sends PCs and effects pedals that only accept CC's for every control.

Here is my goal:

Midi preset/patch box

It will accept incoming midi PCs. Those incoming PCs will then trigger specific event that will send Midi data out . A similar example of this would be the Midi Solutions Event Processor - MIDI Solutions Event Processor Plus; 32 Event MIDI Event Processor. The event processor only allows for up to 32 settings to be sent at once. I would like to be able to send up to 100 midi messages at once.

The box will have two footswitches that will scroll between banks. There will be a two digit numeric display that will show the current bank. The banks will determine which midi code will be chosen depending on the PC that is received.
For example, the incoming PC messages will always be on CH 1 and will be numbers are 1 through 14. Bank 1 would have 14 presets that could be drawn from it. Bank 2 would have 14 different presets that would still be triggered by CH1 PC 1 through 14. And so on.

It will have an external LCD display. With every preset that is pulled up, I would like to have a name that shows up on the display. The display could also be used to program the midi presets.

I would like to eventually move away from using a computer to program the midi presets and instead have it all included in the preset box. I would program and name every midi channel in Arduino to make it more user friendly. I would use the LCD display to show the data.
For example, if I were to edit Preset 1, I could assign it's incoming trigger as Bank 1 > Ch 1 > PC 1. I could name it as Effect 1. When Effect 1 is triggered by PC 1, CH1 on Bank 1, it would send all of the midi CC data that is programmed into that preset. Instead of programming everything on the preset box as midi data, I would like to make it more user friendly for on the fly programming. For example, my chorus effect will be on Ch 2. If I wanted to adjust the Feedback on the unit, I would need to adjust CC#12(MSB), CC#44(LSB) 0 - 16384. Instead of going in there and entering that specific midi data every time, I would just want it to show go from Chorus > Feedback > Value (-100 through 100) in a menu system.

An perfect example of this all is the Strymon multieffects boxes menu system - TimeLine Multi Delay - Strymon

I would want to be able to dump all preset info into a file to save as a backup.

What to purchase to get started?

Will the Arduino Uno be the best board for this?
What would I use to store all of the midi data that is used? Does the Uno have enough memory or should I use the Arduino to pull up data that is stored in another source?
I've seen many different Midi shields, most designed for controllers. Is there one that will work for me on this project and make my life easier?
Are there any specific parts of this project that will make it more difficult than it needs to be?

Thank you!!

That's... a lot for a first project.
What have you done so far? Did you ever send MIDI with arduino?
Arduino Uno will be fine, but if money and space is not a problem I would go with the mega. More inputs, more memory.
You want the presets to be saved even if you poweroff the arduino? Then you save the data into EEPROM. Uno has 1024 bytes and the mega has 4kB. You can use a SD card too, the sd shield is about 4usd or so...
MIDI with arduino can't be easier. I wouldn't even buy a Shield. Midi input is just an optocoupler and 2 or 3 resistors plus a diode. Midi ouput is just the midi jack with a resistor.
You can make a dump with MIDI sysex.
For a first project IMO the "hard" part would be the preset thingy.

Thank you!

Yeah, I always get myself a bit in over my head whenever I start something. I have a difficult time motivating myself to learn unless I have a real use for it. I will probably start small and slowly build up to it. But I want to make sure I'm buying parts that don't eventually need to be replaced as I move on.

I do have a lot of analog electronics experience. To give an idea, I've built over 100 effects pedals, 6 guitar amplifiers, patch and routing systems, recording preamps, compressors, etc. However, I'm quickly learning that digital is a completely different thing all together.

Money and space aren't a huge issue. Unless it's extreme. To pull this by buying separate available midi products I would be looking at a lot more money. The Mega is in stock at Mouser, so it's an easy purchase for me - http://www.mouser.com/ProductDetail/Arduino/A000067/?qs=sGAEpiMZZMt0re6d%252b2Rx9v%252bc%252bQEIaOW9

I had thought about using an SD card or flash drive. It would make it very convenient to save backups. The rig will be going on tour, so if there were an issue with the data, I could keep a couple cards/drives handy.

If I get stumped on the preset part, I may just figure out a way to integrate the Midi Solutions Event Processor into my rig. Instead of having a preset system built in, I would use the Arduino to change banks by switching the Channel from 1 to whatever was selected. The LCD side seems pretty straight forward. Instead of a menu system, it would just be a display to show the preset name.

facon:
Thank you!

Yeah, I always get myself a bit in over my head whenever I start something. I have a difficult time motivating myself to learn unless I have a real use for it. I will probably start small and slowly build up to it. But I want to make sure I'm buying parts that don't eventually need to be replaced as I move on.

I do have a lot of analog electronics experience. To give an idea, I've built over 100 effects pedals, 6 guitar amplifiers, patch and routing systems, recording preamps, compressors, etc. However, I'm quickly learning that digital is a completely different thing all together.

Money and space aren't a huge issue. Unless it's extreme. To pull this by buying separate available midi products I would be looking at a lot more money. The Mega is in stock at Mouser, so it's an easy purchase for me - http://www.mouser.com/ProductDetail/Arduino/A000067/?qs=sGAEpiMZZMt0re6d%252b2Rx9v%252bc%252bQEIaOW9

I had thought about using an SD card or flash drive. It would make it very convenient to save backups. The rig will be going on tour, so if there were an issue with the data, I could keep a couple cards/drives handy.

If I get stumped on the preset part, I may just figure out a way to integrate the Midi Solutions Event Processor into my rig. Instead of having a preset system built in, I would use the Arduino to change banks by switching the Channel from 1 to whatever was selected. The LCD side seems pretty straight forward. Instead of a menu system, it would just be a display to show the preset name.

Well it's good to have a good electronics background...
It's not hard to write data to the SD card with the library.
You'll only need to figure out how to read it and that the potentiometers and button don't interfiere... It's just a matter of checking if the pots/switches changed it's state. If they didn't change, keep reading from SD or EEPROM, if they changed, real the actual value of the pot/switch

I've built a box just like what you describe and the Arduino will likely run out of memory ( I did once I added an lcd). I used the MIDI library originally, but later moved to not using it. Mine also plays MIDI files from SD and sends MIDI clock. I am using a Mega now.

Here's a link to my original code, which is just the MIDI 'event processor'.

Here's the code. I simply map notes to do stuff like Program Changes. I'm controlling a sequencer. Also, a Note On with zero volume is the same as Note off (if you don't already know).

#include <MIDI.h>
/*
8/9/13: 

Things this sketch does: 
------------------------------------
1. Program change up/down
  a.  note 60 is up, note 62 is down

2. "Mute"  parts 1-7b (sets the volume to zero)
  a.  note 64 is part 1
  b.  note 66 is part 2
  c.  note 68 is part 3
  d.  note 70 is part 4
  e.  note 72 is part 5
  f.  note 74 is part 6
  g.  note 76 is part 6a
  h.  note 78 is part 6b
  i.  note 79 is part 7a
  j.  note 80 is part 7b


TO DO:
----------------------------
1.  Start/stop via trigger pad

if note X is received
sendRealTime (Start/Stop)? 

2.  MIDI file reader/send out, get sync...

 */
byte P = 0;  //program or patch number
byte M1 = 0;  //mute for part 1 off
byte M2 = 0;  //mute for part 2 off
byte M3 = 0;  //mute for part 3 off
byte M4 = 0;  //mute for part 4 off
byte M5 = 0;  //mute for part 5 off
byte M6a = 0;  //mute for part 6a off
byte M6b = 0;  //mute for part 6b off
byte M7a = 0;  //mute for part 7a off
byte M7b = 0;  //mute for part 7b off

void HandleClock() {

  //do stuff ?

}

void HandleNoteOn (byte channel, byte note, byte velocity){
  //if note X is sent, send program change control to go up
  //todo: 
  if (note == 60 and velocity >0){   //need to get the actual note number that I'll assign */
    if (P == 127){
      P=0;
      MIDI.sendProgramChange(P,10);
    }
    else
    {
      P++;
      MIDI.sendProgramChange(P,10);
    }
  }

  //if note Y is sent, send program change control to go down
  if (note == 62 and velocity>0){  //need to get the actual note number that I'll assign
    if (P== 0){
      P=127;
      MIDI.sendProgramChange(P,10);
    }
    else {
      P--;
      MIDI.sendProgramChange(P,10);
    }
  }

  //if note Z is sent, send nrpn to set volume to zero (part mute)
//mute for part 1
  if (note == 64 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M1==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,1,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M1=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,1,10);
      MIDI.sendControlChange(06,120,10);
      M1=0;
    }
  }
  
  
   //mute for part 2
  
   if (note == 66 and velocity>0) { 
    if (M2==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,9,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 2
      //need to toggle it
      M2=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,9,10);
      MIDI.sendControlChange(06,120,10);
      M2=0;
    }
  }

  //mute for part 3
     if (note == 68 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M3==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,17,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 3
      //need to toggle it
      M3=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,17,10);
      MIDI.sendControlChange(06,120,10);
      M3=0;
    }
  }
  //mute for part 4
     if (note == 70 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M4==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,25,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M4=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,25,10);
      MIDI.sendControlChange(06,120,10);
      M4=0;
    }
  }
  //mute for part 5
     if (note == 72 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M5==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,33,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M5=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,33,10);
      MIDI.sendControlChange(06,120,10);
      M5=0;
    }
  }
  //mute for 6a
     if (note == 74 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M6a==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,41,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M6a=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,41,10);
      MIDI.sendControlChange(06,120,10);
      M6a=0;
    }
  }
  //mute for 6b
     if (note == 76 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M6b==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,49,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M6b=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,49,10);
      MIDI.sendControlChange(06,120,10);
      M6b=0;
    }
  }
  //mute for 7a
     if (note == 78 and velocity>0) { 
    //use sendcontrolchange? to mute part 1 only
    if (M7a==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,57,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M7a=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,57,10);
      MIDI.sendControlChange(06,120,10);
      M7a=0;
    }
  }
  //mute for 7b
     if (note == 80 and velocity>0) { 
    if (M7b==0) {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,65,10);
      MIDI.sendControlChange(06,0,10);  //sets level to zero, for part 1
      //need to toggle it
      M7b=1;
    }
    else {
      MIDI.sendControlChange(99,5,10);
      MIDI.sendControlChange(98,65,10);
      MIDI.sendControlChange(06,120,10);
      M7b=0;
    }
  }

  //done.
}

void setup() {

  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.turnThruOff();
  MIDI.setHandleNoteOn(HandleNoteOn);
  MIDI.sendProgramChange(P,10);
   MIDI.setHandleClock ( HandleClock );

}

void loop () {

  MIDI.read(); //is there incoming MIDI?


}

Awesome. Thanks for posting that!