Some Arduino code advice please - Midi bass pedal project.

Started by anotherjim, October 22, 2018, 04:37:42 PM

Previous topic - Next topic

anotherjim

So, I've been working on hacking this project...
https://www.instructables.com/id/Build-MIDI-Bass-Pedals-for-About-150/
...and extended it to add midi channel select, octave switching and a velocity adjustment pot.
This all works, but is a little clunky.
I'm having trouble finding the best place in the main loop to update the octave and velocity setting. The midi channel isn't a problem, that is set in the setup code, as I can't see any reason to change it during use.
As it is, it only updates after a key on-off. I put the Velocity and octave calls at the end of the main key scan routine as I thought it wouldn't interfere with play timing, but is there a better place?
BTW, I don't want to change too much -  it is working!

Here's the main loop...
void loop() {
    // Main Loop
    byte byte1;
    byte byte2;
    byte byte3;
    int value;
    //

    // Look for bass pedal key events
    for (int i = 0; keys[i].pin != 0; ++i)
    {
      value = digitalRead(keys[i].pin);
      if (keys[i].debounce == 0) // Key has been off
      {
        if (value == LOW)       // Key is now on
        {
          noteOn(keys[i].midiKey + keyOffset);      // Send the MIDI note on message
          keys[i].keySent = keys[i].midiKey + keyOffset;
          keys[i].debounce = DEBOUNCE;  // Set the note off debounce counter
        }
      }
      else                      // Key has been on
      {
        if (value == HIGH)      // Key has gone off
        {
          if (--keys[i].debounce == 0) // If Key has remained off for DEBOUNCE scans,
            noteOff(keys[i].keySent); // In case the offset has changed, send MIDI off for the right note
        }
        else                    // Key has not gone off
          keys[i].debounce = DEBOUNCE;  // Reset debounce counter in case we got
        // a small number of key off scans
        octave();
        Velocity();
      }
    }
  }


...and here's the whole thing...
//Arduino midi 13note bass pedals cobbled by Jim Yale from...
//https://www.instructables.com/id/Build-MIDI-Bass-Pedals-for-About-150/
//Changed pin usuage to suit smaller Diecimila to Uno types. This is working on a Freeduino clone with ATmega168.
//Added midi channel select via dip switches on startup. Selected by diode gate when pin13 is high.
//Added octave select rotary switch using 3bit diode coding to pins A0 to A2. Only values 0 to 5 used.
//Added velocity pot on pin A3.
#define DEBOUNCE 1000

struct key
{
  int pin;
  int midiKey;
  int debounce;
  int keySent;
};
// pin usage changed from original Mega board.
struct key keys[] =
{
  { 2, 24, 0, 0 },  // C Low
  { 3, 25, 0, 0 },  // Db
  { 4, 26, 0, 0 },  // D
  { 5, 27, 0, 0 },  // Eb
  { 6, 28, 0, 0 },  // E
  { 7, 29, 0, 0 },  // F
  { 8, 30, 0, 0 },  // Gb
  { 9, 31, 0, 0 },  // G
  { 10, 32, 0, 0 },  // Ab
  { 11, 33, 0, 0 },  // A
  { 12, 34, 0, 0 },  // Bb
  { A5, 35, 0, 0 },  // B
  { A4, 36, 0, 0 },  // C High

  { 0, 0, 0, 0 }     // end of list marker
};

int keyOffset = 12; //octave setting
int keyVelocity = 127;  //max velocity
int MidiChannel = 0;
int NoteOnCd = 0x90;
int NoteOffCd = 0x80;
int PotVal = 100;
int PotPin = 3;
void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);  //Set pin13 to read midi channel data
  // Enable pedal key inputs
  for (int i = 0; keys[i].pin != 0; ++i)
  {
    pinMode(keys[i].pin, INPUT_PULLUP);
  }
  //Use A0 to A4 to read 4 bit midi channel switches
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  if (digitalRead(A0) == HIGH) {
    MidiChannel += 1;
  }
  if (digitalRead(A1) == HIGH) {
    MidiChannel += 2;
  }
  if (digitalRead(A2) == HIGH) {
    MidiChannel += 4;
  }
  if (digitalRead(A3) == HIGH) {
    MidiChannel += 8;
  }
  //Construct midi note on & off messages for selected channel
  NoteOnCd |= MidiChannel;
  NoteOffCd |= MidiChannel;
  delay(500);
  digitalWrite(13, LOW);    //Deselect channel switches.
  //start serial with midi baudrate 31250
  Serial.begin(31250);
  octave();   //initialise selected octave
  Velocity();   //Initialise velocity pot value
  //End of setup, functions follow.
  //
}
  void Midi_Send(byte cmd, byte data1, byte data2)
  {
    Serial.write(cmd);
    Serial.write(data1);
    Serial.write(data2);
  }

  void noteOn(int midiKey)
  {
    Midi_Send(NoteOnCd, midiKey, keyVelocity);
  }

  void noteOff(int midiKey)
  {
    Midi_Send(NoteOffCd, midiKey, keyVelocity);
  }
  void octave()
  {
    keyOffset = 0;
    pinMode(13, OUTPUT);
    digitalWrite(13, LOW);
    if (digitalRead(A0) == HIGH) {
      keyOffset += 1;
    }
    if (digitalRead(A1) == HIGH) {
      keyOffset += 2;
    }
    if (digitalRead(A2) == HIGH) {
      keyOffset += 4;
    }
    keyOffset *= 12;
  }
  void Velocity() {
    PotVal = analogRead(PotPin) / 8;
    keyVelocity = (keyVelocity + PotVal) / 2;
  }
  //End of functions, main loop follows
  //
  void loop() {
    // Main Loop
    byte byte1;
    byte byte2;
    byte byte3;
    int value;
    //

    // Look for bass pedal key events
    for (int i = 0; keys[i].pin != 0; ++i)
    {
      value = digitalRead(keys[i].pin);
      if (keys[i].debounce == 0) // Key has been off
      {
        if (value == LOW)       // Key is now on
        {
          noteOn(keys[i].midiKey + keyOffset);      // Send the MIDI note on message
          keys[i].keySent = keys[i].midiKey + keyOffset;
          keys[i].debounce = DEBOUNCE;  // Set the note off debounce counter
        }
      }
      else                      // Key has been on
      {
        if (value == HIGH)      // Key has gone off
        {
          if (--keys[i].debounce == 0) // If Key has remained off for DEBOUNCE scans,
            noteOff(keys[i].keySent); // In case the offset has changed, send MIDI off for the right note
        }
        else                    // Key has not gone off
          keys[i].debounce = DEBOUNCE;  // Reset debounce counter in case we got
        // a small number of key off scans
        octave();
        Velocity();
      }
    }
  }


potul


potul

One thing you can do is remove the Ocatve() and Velocity() call from the for statement. you can have them run only once in a loop and it should be fine. These only need to be sampled when you move a pot,...so you could setup an interrupt as well.

On the other hand, I see you are not initializing your keys debounce to DEBOUNCE, but to zero. So first time you press a kay the debounce counter will not be properly set.

deadastronaut

cool project....love a bit of rush. 8)

i have an old roland fc100 mkii i could hack one day for a very crude version..

look forward to the demo... 8)
https://www.youtube.com/user/100roberthenry
https://deadastronaut.wixsite.com/effects

chasm reverb/tremshifter/faze filter/abductor II delay/timestream reverb/dreamtime delay/skinwalker hi gain dist/black triangle OD/ nano drums/space patrol fuzz//

anotherjim

I didn't write the pedal key scan. And I've only just spotted the debounce countdown part
if (--keys.debounce == 0)
The original author appears to have been troubled by contact bounce at note-off.
My Farfisa pedal board has the same type of coil spring contacts the original projects Conn board has and simply grounds an Arduino input pin when a pedal is pressed. A difference with mine is they are changeover contacts which break the path to ground for the next highest note so enforcing monophonic low note priority. I don't think that's such a significant difference although the code is capable of polyphonic operation.

If I was doing it from scratch, I might have had the settings scanned in the main loop and dealt with note commands from pin-change interrupts.

I guess I just want to hide the time my extra functions take by fitting them into the debounce time -  which I have reduced anyway, and I think could be reduced further.

Potul,
As it is, I have to play a key twice to hear a setting change. Not the end of the world for bass pedals as you set them up and leave them be apart from stomping notes.
QuoteOn the other hand, I see you are not initializing your keys debounce to DEBOUNCE, but to zero. So first time you press a kay the debounce counter will not be properly set.
What I see is the debounce value of zero in the keys array is used to show the note has played and debounced - so initially is zero. After note-off it gets set to DEBOUNCE and counts back down toward zero. It don't debounce a note-on.

I'll try moving the added settings into the main loop, but note that I make no attempt to debounce those.
Otherwise, I don't mind if I have to play a note to enable new settings if it keeps it simple, but it might have been better to put them right after sending the midi note-off for that.

anotherjim

Rob, it ain't no Moog Taurus - yet. Obviously, midi only pedals can only do exactly what you might expect and only sound like what you drive with them.
Unlike the Instructable project, I think the cost for me will be Zero. The organ that donated the pedals was free, I've had the Arduino board on a shelf for years and the rest is bits I have in stock. I'm not using a midi shield, just a buffered midi output to a 5pin din socket.
I am thinking of putting some kind of basic bass synth on board. One thing that bugs me about all the commercial midi bass pedals is that they are very expensive considering they can't make a sound themselves.

Ben N

I thought about doing something like this with just soft momentary switches in a long enclosure, like a McMillen 12 Step.
  • SUPPORTER

anotherjim

Sometimes my brain tells me to do things without telling me why ;)
Apparently, I needed to keep pin13 free during a note_on period, so I can't have settings checked then, it depends on the pin13 level to select between either the 4 midi channel dip switches or the octave rotary switch and velocity pot to the 4 input pins A0 to A3.
Now it plays a tone out of pin 13 using the Arduino tone() function for the duration a key is pressed. I've chosen the highest octave supported which is a top C of 4186Hz. A counter chip will be used to reduce that to bass frequencies and maybe a little waveshaping from higher octaves. The on-board synth will have separate octave selection from the midi side, but there won't, as far as can see, be any way to allow fine-tuning of its pitch. I don't foresee wanting to tune it away from concert pitch myself.

I've moved the octave/velocity stuff to pretty much the same place only sooner -  right after the noteOff command. Adding the tone function turned out to be really simple thanks to the keys table structure used.

So I think that's it for now until a build thread when I've sussed out the hardware synth part. I haven't yet drawn up the additional circuits - midi out, switches & pot selection, but if someone wants to get going with this themselves, let me know and I'll draw it up for digital consumption.

For now, here's the current state with the Tone function...
//Arduino midi 13note bass pedals cobbled by Jim Yale from...
//https://www.instructables.com/id/Build-MIDI-Bass-Pedals-for-About-150/
//Changed pin usuage to suit smaller Diecimila to Uno types. This is working on a Freeduino clone with ATmega168.
//Added midi channel select via dip switches on startup. Selected by diode gate when pin13 is high.
//Added octave select rotary switch using 3bit diode coding to pins A0 to A2. Only values 0 to 5 used.
//Added velocity pot on pin A3.
//Add tone generator for onboard synth using pin13 and Tone command
#define DEBOUNCE 500

struct key
{
  int pin;
  int midiKey;
  int debounce;
  int keySent;
  int toneFreq;
};
// pin usage changed from original Mega board.
struct key keys[] =
{
  { 2, 24, 0, 0, 2093 },  // C Low
  { 3, 25, 0, 0, 2217 },  // Db
  { 4, 26, 0, 0, 2349 },  // D
  { 5, 27, 0, 0, 2489 },  // Eb
  { 6, 28, 0, 0, 2637 },  // E
  { 7, 29, 0, 0, 2794 },  // F
  { 8, 30, 0, 0, 2960 },  // Gb
  { 9, 31, 0, 0, 3136 },  // G
  { 10, 32, 0, 0, 3322 },  // Ab
  { 11, 33, 0, 0, 3520 },  // A
  { 12, 34, 0, 0, 3729 },  // Bb
  { A5, 35, 0, 0, 3951 },  // B
  { A4, 36, 0, 0, 4186 },  // C High

  { 0, 0, 0, 0 }     // end of list marker
};

int keyOffset = 12; //octave setting
int keyVelocity = 127;  //max velocity
int MidiChannel = 0;
int NoteOnCd = 0x90;
int NoteOffCd = 0x80;
int PotVal = 100;
int PotPin = 3;
void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);  //Set pin13 to read midi channel data
  // Enable pedal key inputs
  for (int i = 0; keys[i].pin != 0; ++i)
  {
    pinMode(keys[i].pin, INPUT_PULLUP);
  }
  //Use A0 to A4 to read 4 bit midi channel switches
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  if (digitalRead(A0) == HIGH) {
    MidiChannel += 1;
  }
  if (digitalRead(A1) == HIGH) {
    MidiChannel += 2;
  }
  if (digitalRead(A2) == HIGH) {
    MidiChannel += 4;
  }
  if (digitalRead(A3) == HIGH) {
    MidiChannel += 8;
  }
  //Construct midi note on & off messages for selected channel
  NoteOnCd |= MidiChannel;
  NoteOffCd |= MidiChannel;
  delay(500);
  digitalWrite(13, LOW);    //Deselect channel switches.
  //start serial with midi baudrate 31250
  Serial.begin(31250);
  octave();   //initialise selected octave
  Velocity();   //Initialise velocity pot value
  //End of setup, functions follow.
  //
}
void Midi_Send(byte cmd, byte data1, byte data2)
{
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
}

void noteOn(int midiKey)
{
  Midi_Send(NoteOnCd, midiKey, keyVelocity);
}

void noteOff(int midiKey)
{
  Midi_Send(NoteOffCd, midiKey, keyVelocity);
}
void octave()
{
  keyOffset = 0;
  digitalWrite(13, LOW);
  if (digitalRead(A0) == HIGH) {
    keyOffset += 1;
  }
  if (digitalRead(A1) == HIGH) {
    keyOffset += 2;
  }
  if (digitalRead(A2) == HIGH) {
    keyOffset += 4;
  }
  keyOffset *= 12;
}
void Velocity() {
  digitalWrite(13, LOW);
  PotVal = analogRead(PotPin) / 8;
  keyVelocity = (keyVelocity + PotVal) / 2;
}
//End of functions, main loop follows
//
void loop() {
  // Main Loop
  byte byte1;
  byte byte2;
  byte byte3;
  int value;
  //

  // Look for bass pedal key events
  for (int i = 0; keys[i].pin != 0; ++i)
  {
    value = digitalRead(keys[i].pin);
    if (keys[i].debounce == 0) // Key has been off
    {
      if (value == LOW)       // Key is now on
      {
        noteOn(keys[i].midiKey + keyOffset);      // Send the MIDI note on message
       tone(13, keys[i].toneFreq);
        keys[i].keySent = keys[i].midiKey + keyOffset;
        keys[i].debounce = DEBOUNCE;  // Set the note off debounce counter
      }
    }
    else                      // Key has been on
    {
      if (value == HIGH)      // Key has gone off
      {
        if (--keys[i].debounce == 0) // If Key has remained off for DEBOUNCE scans,
          noteOff(keys[i].keySent); // In case the offset has changed, send MIDI off for the right note
       noTone(13);
        octave();
        Velocity();
      }
      else                    // Key has not gone off
        keys[i].debounce = DEBOUNCE;  // Reset debounce counter in case we got
      // a small number of key off scans
    }
  }
}



potul

Quote from: anotherjim on October 23, 2018, 06:24:05 AM

As it is, I have to play a key twice to hear a setting change. Not the end of the world for bass pedals as you set them up and leave them be apart from stomping notes.
QuoteOn the other hand, I see you are not initializing your keys debounce to DEBOUNCE, but to zero. So first time you press a kay the debounce counter will not be properly set.
What I see is the debounce value of zero in the keys array is used to show the note has played and debounced - so initially is zero. After note-off it gets set to DEBOUNCE and counts back down toward zero. It don't debounce a note-on.

I'll try moving the added settings into the main loop, but note that I make no attempt to debounce those.
Otherwise, I don't mind if I have to play a note to enable new settings if it keeps it simple, but it might have been better to put them right after sending the midi note-off for that.

I think you have a couple of misunderstandings on how the code and MIDI work.

1-MIDI velocity is not a dynamic parameter (like a CC code). It's transmitted only at the note ON event, and cannot be changed further until you send a new note-ON event. So there is no way to change velocity of a note while it gets played, unless you use CC codes (that could change the volume, not the note velocity). Same will apply for the octave setting. Octave changes will only take effect on the notes you play AFTER chaging octaves.

2-The for loop that checks for switches is not stopping anywhere during the note-on... it's free running. This means that there is no sense on adding the velocity/octave check sooner or later in the loop. In fact, as I suggested, you could place it completely out of the for loop, and it would still work, and probably better because the arduino would not need read in/outs and ADC so frequently. The only thing that velocity() and octave() functions are doing is reading the pot and the switches you use to configure velocity and octave and storing the result in some variables. And you are not changing this at a high khz speed, so there is no sense on checking this every millisecond.

Regarding the DEBOUNCE, you are right... I didn't understand correctly how the debouncing works.



anotherjim

You may be right about putting the settings at the top of the loop (or end), they will only be read after each complete key scan if there's no debounce outstanding, but...
Quotethere is no sense on checking this every millisecond.
I didn't think it was, but read my reasons below,

Well, I think I do understand velocity. The reasons I want to control that instead of channel volume are...

The midi device being played already has volume control.
I don't want to get on the floor to change that volume.
The pedals are not velocity sensitive and aren't going to be.
Some synths use velocity for all kinds of parameters and a fixed value of velocity may not suit. It would be tedious to reprogram the patches to change that.
Some devices only respond to velocity over midi and have fixed maximum velocity buttons/keys, then it needs to transmit high velocity to match.
There is only one analogue read pin free and velocity won the draw.

And yeh, I know velocity is buried in the note on & off message and must be pre-ordained.

...Now this part of the scan loop,
       if (--keys[i].debounce == 0) // If Key has remained off for DEBOUNCE scans,
          noteOff(keys[i].keySent); // In case the offset has changed, send MIDI off for the right note
       noTone(13);
        octave();
        Velocity();

I thought it...
Decrements the array debounce element that "i" is pointing to.
If it hasn't got the debounce element to zero, there is no "else" to this "if", it should decrement again until debounce is zero.
Only then does it command note off and my extra functions.
Therefore, I reckon those functions operate once only during a note-off command. Admittedly, they aren't re-using debounce time either.

I do agree, it might as well be reading settings at the top (or bottom) of the main loop. It should only see them once after every full scan.



potul

I must admit you are starting to lose me here....

what is the problem you have then on the velocity response?


anotherjim

Well, actually the problems were my worries. But as we've discussed it, I've got more confident on what the original code does. A worry was that octave could change during note-on then note-off would have no effect - however, the code saves the midi note actually sent in the array to use for the note-off when the time comes. Which is pretty smart I think.
Anyway, now I've got the tone going I can work on the hardware synth bit, which is where the big fun is for me - I hate coding, although I get an urge to have a go every few years.

ElectricDruid

Have you got a gate output from the MIDI code? If so, if you've got a basic square wave tone and a gate, you're basically there.

If you can get the tone to a higher octave, you can add octave dividers to produce different wave shapes (by mixing octaves - many string synths did this for their "ramp" waves, actually a staircase wave built of squares of different octaves). You could also have a sub-octave built in, which would be good for a bass synth - a la SH101. In which case, take another tip from Roland and AND two squares together to get a 25% pulse wave. It was always my favourite of the three sub-octave options on the '101.

Then add a filter and and VCA and an envelope for each triggered by that Gate pulse I mentioned for tone and dynamic control. That's the easy bit, in some ways, unless you want to start designing your own envelopes and filters. There are certainly enough designs out there to start with. Check out the Frequency Central Raging Bull for a classic Moog Taurus option (schematics are linked on the page):

http://www.frequencycentral.co.uk/?page_id=1361

(Full disclosure - as many here know, Rick and I did a load of stuff together, including this project - his design, my PCB layout.)

BTW, totally understand that the synth hardware part is the fun part. Coding is a drag by comparison, but sometimes it's a necessary evil to make cool stuff happen!


anotherjim

Hey Tom, there's so many possible choices, I'll have to choose the easy way...
Uses parts I have.
Uses parts that will physically fit
Uses existing power supply - 9v & 5v.
Essential it has synth bass and "almost just the fundamental" organ bass tones.

There's no spare output, so no gate. I'll make one from the tone being there or not, guitar synth fashion. Actually, the Farfisa pedals have a separate common "gate" contact bus, but that would be too easy.
At the moment I'm looking at a 4046 thing like the EDP Gnat running after a 4024 divider. Promising, but I haven't built gate & s&h into it yet. Sounds very like a second oscillator with the VCO mixed with a divider octave.
Anyway, if that's turns out good enough, then another Gnat trick, the VCO CV is buffered and used to set the limit of a ramp generator that's reset & timed by the square wave. Roland Juno DCO worked similarly. Then pulse wave follows easy.


anotherjim

As the hardware for the project grinds close to completion, I got around to tweaking the Arduino code to suit it better. The Tone function missed a new note on unless it had definitely ended and debounced.  the previous note off. I think that was the polyphonic nature of the original midi only project allowing a new note on before the last note off. The Tone function is monophonic in this case, so a noTone command to end the last one could happen after the new tone command.

I now have an almost complete rewrite of the main loop. This seems to be working fine and allows faster playing than a 13 note foot pedalboard can really make use of. Hopefully, after some tweaks to the synth circuits and some cosmetic touches, I'll present the build with circuits and the required evidence in a new thread nearby.

Here's the currently installed code...
//Arduino midi 13note bass pedals cobbled together by Jim Yale and inspired by...
//https://www.instructables.com/id/Build-MIDI-Bass-Pedals-for-About-150/
//Changed pin usuage to suit smaller Diecimila to Uno types. This is working on a Freeduino clone with ATmega168.
//Code rewrite to suit monophonic operation and additional features.
//MIDI shield not used only TX pin used for hardware MIDI output.
//Added midi channel select via dip switches only during startup. Selected by diode gating when pin13 is high.
//Added octave select rotary switch using 3bit diode coding to pins A0 to A2. Only values 0 to 5 used. Only available when pin13 is low.
//Added velocity pot on pin A3.
//Add tone generator for onboard synth using pin13 and Tone command. Settings cannot be checked while tone sounds.

struct key
{
  int pin;
  int midiKey;
  int toneFreq;
};
// pin usage changed from original Mega board.
//Array used for key scan.
struct key keys[] =
{
  { 2, 24, 2093 },  // C Low. Values here used when key scan i = 0
  { 3, 25, 2217 },  // C#
  { 4, 26, 2349 },  // D
  { 5, 27, 2489 },  // D#
  { 6, 28, 2637 },  // E
  { 7, 29, 2794 },  // F
  { 8, 30, 2960 },  // F#
  { 9, 31, 3136 },  // G
  { 10, 32, 3322 },  // G#
  { 11, 33, 3520 },  // A
  { 12, 34, 3729 },  // A#
  { A5, 35, 3951 },  // B
  { A4, 36, 4186 },  // C High. Values here used when key scan i = 12
  { 0, 0, 0,}        // End of array. Key scan ends when pin value of 0 found.
};

int keyOffset = 12; //octave setting
int keyVelocity = 127;  //max velocity
int MidiChannel = 0;
int NoteOnCd = 0x90;
int NoteOffCd = 0x80;
int PotVal = 100;
int PotPin = 3;
void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);  //Set pin13 to read midi channel data
  // Enable pedal key inputs
  for (int i = 0; keys[i].pin != 0; ++i)
  {
    pinMode(keys[i].pin, INPUT_PULLUP);
  }
  //Use A0 to A4 to read 4 bit midi channel switches
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  if (digitalRead(A0) == HIGH) {
    MidiChannel += 1;
  }
  if (digitalRead(A1) == HIGH) {
    MidiChannel += 2;
  }
  if (digitalRead(A2) == HIGH) {
    MidiChannel += 4;
  }
  if (digitalRead(A3) == HIGH) {
    MidiChannel += 8;
  }
  //Construct midi note on & off messages for selected channel
  NoteOnCd |= MidiChannel;
  NoteOffCd |= MidiChannel;
  delay(500);
  digitalWrite(13, LOW);    //Deselect channel switches.
  //start serial with midi baudrate 31250
  Serial.begin(31250);
  octave();   //initialise selected octave
  Velocity();   //Initialise velocity pot value
  //End of setup, functions follow.
  //
}
void Midi_Send(byte cmd, byte data1, byte data2)
{
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
}

void noteOn(int midiKey)
{
  Midi_Send(NoteOnCd, midiKey, keyVelocity);
}

void noteOff(int midiKey)
{
  Midi_Send(NoteOffCd, midiKey, keyVelocity);
}
void octave()
{
  keyOffset = 0;
  digitalWrite(13, LOW);
  if (digitalRead(A0) == HIGH) {
    keyOffset += 1;
  }
  if (digitalRead(A1) == HIGH) {
    keyOffset += 2;
  }
  if (digitalRead(A2) == HIGH) {
    keyOffset += 4;
  }
  keyOffset *= 12;
}
void Velocity() {
  digitalWrite(13, LOW);
  PotVal = analogRead(PotPin) / 8;
  keyVelocity = (keyVelocity + PotVal) / 2;
}
//End of functions, main loop follows
//
void loop() {
  // Main Loop
  byte byte1;
  byte byte2;
  byte byte3;
  int value;
  //
  // Scan pedal keys
  for (int i = 0; keys[i].pin != 0; ++i)
  {
    value = digitalRead(keys[i].pin);
    if (value == LOW)       // Key pointed to by i is on
    {
      noteOn(keys[i].midiKey + keyOffset);      // Send the MIDI note on message
      tone(13, keys[i].toneFreq);               //Play tone for synth
      delay(20);                                //Wait out any contact bouncing before looking for note off
      do                                        //Look for note off
      {
        value = digitalRead(keys[i].pin);
      }
      while (value == LOW);                     //Note off contact is defined by pull-up - it cannot bounce down hence no debounce.
      noteOff(keys[i].midiKey + keyOffset);     //Send MIDI note off
      noTone(13);                               //End synth tone
    }

  }
  octave();   //Update octave setting
  Velocity();   //Update velocity value
}