using buttons in subroutine?

I have a line of code for sending midi note on/off messages that repeats with 8 different buttons, here's a cut down version

Button RECbutton = Button(2,PULLUP);

if(RECbutton.isPressed()) { MIDI.sendNoteOn(38,127,1); // record on delay(20); // debounce do { delay(20); } while(RECbutton.isPressed(); MIDI.sendNoteOn(38,0,1); // off

I thought about creating a subroutine

void wait (whichbutton) { delay(20); // debounce do { delay(20); } while(whichbutton.isPressed(); }

but how can I pass a button name into the subroutine? I don't think it's an integer!

I'm new to programming, so bear with me!

but how can I pass a button name into the subroutine? I don't think it's an integer!

You are right. It is not. However, you know it's type - Button. So, define the function to take an argument of type Button & (reference to Button).

void wait (Button &whichbutton)
{
      delay(20); // debounce
      do {
          delay(20);    
          }
       while(whichbutton.isPressed();  
}

However, if you have 8 button objects to manage, an array of Button objects is probably more appropriate. Then, the wait function would just need to know the index (an int) into the (global) array of Button objects.

Button buttons[8] = {
Button(2, PULLUP),
Button(3, PULLUP),
...
Button(9, PULLUP)
};

Use whatever pin numbers are appropriate.

Then, the wait function could look like:

void wait (int whichbutton)
{
      delay(20); // debounce
      do {
          delay(20);    
          }
       while(buttons[whichbutton].isPressed();  
}

The advantage of an array of buttons should be obvious, If not, consider that you could also have an array of notes that correspond to buttons: int notes[8] = {38, ?, ?, ?, ?, ?, ?, ?};

Then, the code snippet you posted could look like:

  if(buttons[n].isPressed())
      {
      MIDI.sendNoteOn(notes[n],127,1);  // record on
      delay(20); // debounce
      do {
          delay(20);    
         }
        while(buttons[n].isPressed();  
      MIDI.sendNoteOn(notes[n],0,1);  //  off

Where n is the button of interest. The could then be called in a for loop, with n as the loop variable.

Just for reference, the do/while statement executes the body of the statement, then checks the condition. Moving the while to the top, as in while(RECButton.isPressed()) { // Do nothing } means that no delay will occur if the switch is not pressed.

Also, getting rid of the delay in the while loop means that the note off command will be send as soon as the button is released, not as much as 20 milliseconds later.

For your application, the delay may not matter, but it's best to get in the habit of not using delay any more than is absolutely necessary.

Wow - lots to think about but it makes sense - I'm familiar with arrays through php. This should make the code much leaner! A really excellent reply - many thanks!!

OK, this code doesn’t seem to be working - anything obvious?

#include <MIDI.h>
#include <Button.h>

Button buttons[8] = {
Button(2, PULLUP), Button(3, PULLUP), Button(4, PULLUP), Button(5, PULLUP),
Button(6, PULLUP), Button(7, PULLUP), Button(8, PULLUP), Button(3, PULLUP),
};

int notes[8] = {38, 39, 40, 43, 38, 44, 48, 49};
int numswitches = 8;

void setup()
{
MIDI.begin(1);
//start serial with midi baudrate 31250 or 38400 for debugging
Serial.begin(31250);
Serial.flush();
}
void loop()
{
for (int n=0; n <= numswitches; n++)
{
if(buttons[n].isPressed())
{
MIDI.sendNoteOn(notes[n],127,1); // record on
do {
delay(20);
}
while(buttons[n].isPressed() );
MIDI.sendNoteOn(notes[n],0,1); // off
}
}
}

if(buttons[n].isPressed())
      {
         Serial.print("Switch ");
         Serial.print(n);
         Serial.println(" is pressed");
      MIDI.sendNoteOn(notes[n],127,1);  // record on

Add the three Serial.print() statements, and open the Serial Monitor. Each time a button is pressed, a message should appear.

No messages indicates a hardware problem. Messages but no notes means that there is a problem elsewhere.

Debugging is a matter of divide and conquer. Figure out where the problem isn't, and where it is is a smaller area.

The error was trying to access array entry numswitches[8] - the following works

for (int n=0; n <= (numswitches-1); n++)

I’ve also discovered that any serial.print statements are also interpreted by the midi device ;(

The script has come on greatly (see below). I’ve managed to add latched leds on certain switches, using these wonderful arrays and even thrown in a flashing init display :wink:

I don’t know if the for loop is the best method to determine which switches have associated leds, but it seems to work.

Next step, to read an expression pedal and use it to control feedback.

#include <MIDI.h>
#include <Button.h>

Button buttons[8] = {
Button(2, PULLUP), Button(3, PULLUP), Button(4, PULLUP), Button(5, PULLUP),
Button(6, PULLUP), Button(7, PULLUP), Button(8, PULLUP), Button(9, PULLUP),
};

int leds[5] = {15, 14, 18, 16, 17};
int ledswitches[5] = {0, 1, 2, 6, 7};
int ledstatus[5] = {0, 0, 0, 0, 0};
int notes[8] = {38, 39, 40, 43, 38, 44, 48, 49};
int numswitches = 8;
int numleds = 5;

void setup()
{
MIDI.begin(1);
// Serial.begin(38400); // debugging
Serial.begin(31250); // midi rate
Serial.flush();

// init display, just for fun
for (int m=0; m <= (numleds-1); m++) // go through led array
{
analogWrite(leds[m], 255); // light led
delay(250);
analogWrite(leds[m], 0); // kill led
}
}

void loop()
{
for (int n=0; n <= (numswitches-1); n++) // first in array is zero!
{
if(buttons[n].isPressed())
{
for (int m=0; m <= (numleds-1); m++) // go through led array
{
if (n == ledswitches[m]) // is switch one with an led?
{
if (ledstatus[m] == 0 )
{
analogWrite(leds[m], 255); // light led
ledstatus[m] = 1; // update status
}
else
{
ledstatus[m] = 0; // update status
analogWrite(leds[m], 0); // kill led
}
}
}
MIDI.sendNoteOn(notes[n],127,1); // send midi on
do {
delay(20);
}
while(buttons[n].isPressed() );
MIDI.sendNoteOn(notes[n],0,1); // send midi off
} // end if button is pressed
} // end of for loop
} // end of void loop

The error was trying to access array entry numswitches[8] - the following works
for (int n=0; n <= (numswitches-1); n++)

So would:

for(int n=0; n<numswitches; n++)

This is a problem:
int ledswitches[5] = {0, 1, 2, 6, 7};
Digital pins 0 and 1 are the serial pins. If your MIDI device is using Serial, you can’t use these pins for LEDs.

You are also using analogWrite to write to these pins, but of those 5 pins, only pin 6 is a PWM pin. If all you are doing is turning the LED on or off, you should be using digitalWrite().

Eight switches and five LEDs. I’m not seeing the relationship.

PaulS: int ledswitches[5] = {0, 1, 2, 6, 7}; Digital pins 0 and 1 are the serial pins. If your MIDI device is using Serial, you can't use these pins for LEDs. Eight switches and five LEDs. I'm not seeing the relationship.

the ledswitch array indicates which of the 8 switches need an led - the leds array indicates the actual output pins. There's bound to be a simpler way of coding, but it seems to work. This is my first proper arduino project, so a huge learning curve!

It's a bespoke arrangment for a specific item of musical hardware (echoplex looper) - some features, such as "record" or "half speed", need an LED to indicate the curent status. others, such as "undo" or next loop" don't. I also wanted to minimise the wiring! I've been using a behringer fcb1010, which is fully programmable, but it's also large, so I wanted a minimally sized unit. This is my mock-up, I need to learn about matrices to add another 4 switches.