How to send MIDI patch change messages

Hi Everyone,

I have recently got into the world of Arduino MIDI, and need some help understanding MIDI patch changes.

I have successfully made the nano controllers on Notes and Volts both with buttons and pots tweaking Daves sketch. I would now like to send MIDI patch changes via buttons. Each switch would be a set PC .

I have tried to search but couldn't find anything other than sequential PC modes.

Any help would be greatfully received

Cheers

If you post the code you currently have working then we can probably help. But most people will not go searching round the internet in the hope of finding whatever it is that you have.

A patch change message is just another MIDI message, there's nothing special about it except it's only 2 bytes not 3. If you're searching for information it is officially known as a Program Control message.

Steve

It is supported in my MIDI Control-Surface library:
Ex.16.SelectorPC

[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]Control_Surface[/color][/b][color=#434f54].[/color][color=#000000]h[/color][color=#434f54]>[/color] [color=#434f54]// Include the library[/color]

[color=#434f54]// Patch Selector selecting patches 1, 2, 3 or 4, [/color]
[color=#434f54]// increment patch number with button connected to pin 11, [/color]
[color=#434f54]// decrement patch number with button connected to pin 12[/color]
[color=#000000]SelectorPC[/color] [color=#000000]sel[/color][color=#000000]([/color] [color=#000000]{[/color] [color=#000000]1[/color][color=#434f54],[/color] [color=#000000]2[/color][color=#434f54],[/color] [color=#000000]3[/color][color=#434f54],[/color] [color=#000000]4[/color] [color=#000000]}[/color][color=#434f54],[/color] [color=#000000]{[/color] [color=#000000]11[/color][color=#434f54],[/color] [color=#000000]12[/color] [color=#000000]}[/color] [color=#000000])[/color][color=#000000];[/color] 

[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color][color=#000000]}[/color] [color=#434f54]// Nothing to set up[/color]

[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#434f54]// Refresh the control surface, send a Program Change [/color]
  [color=#434f54]// event when the patch number changes[/color]
  [b][color=#d35400]Control_Surface[/color][/b][color=#434f54].[/color][color=#d35400]refresh[/color][color=#000000]([/color][color=#000000])[/color][color=#000000];[/color] 
[color=#000000]}[/color]

If you just want to manually send Program/Patch change messages, read this:
Arduino MIDI

Pieter

Thank you so much for all the input. Apologies for delay in getting back. I did post earlier but obviously didn't upload.

I read through the midi doc and sort of get it however as I am very new to this still not sure how to implement it with the sketch I am using.

I have done the bank one and it works great - many thanks but I just need a few favourites switches if that makes sense.

I am away from pc at present but will upload the code I have been editing

Cheers

#include <MIDI.h>
#include "Controller.h"

/*************************************************************
MIDI CONTROLLER

by Notes and Volts

Version 1.2 Arduino UNO ONLY!
*************************************************************/

MIDI_CREATE_DEFAULT_INSTANCE();

//************************************************************
//SET THE NUMBER OF CONTROLS USED***********************
//************************************************************
//---How many buttons are connected directly to pins?---------
byte NUMBER_BUTTONS = 0;
//---How many potentiometers are connected directly to pins?--
byte NUMBER_POTS = 0;
//---How many buttons are connected to a multiplexer?---------
byte NUMBER_MUX_BUTTONS = 0;
//---How many potentiometers are connected to a multiplexer?--
byte NUMBER_MUX_POTS = 0;
//************************************************************

//ANY MULTIPLEXERS? (74HC4067)*********************************
//MUX address pins must be connected to Arduino UNO pins 2,3,4,5
//A0 = PIN2, A1 = PIN3, A2 = PIN4, A3 = PIN5
//*******************************************************************
//Mux NAME (OUTPUT PIN, , How Many Mux Pins?(8 or 16) , Is It Analog?);

//Mux M1(10, 16, false); //Digital multiplexer on Arduino pin 10
//Mux M2(A5, 8, true); //Analog multiplexer on Arduino analog pin A0
//*******************************************************************

//DEFINE DIRECTLY CONNECTED POTENTIOMETERS*********************
//Pot (Pin Number, Command, CC Control, Channel Number)
//Command parameter is for future use

//Pot PO1(A0, 0, 1, 1);
//Pot PO2(A1, 0, 10, 1);
//Pot PO3(A2, 0, 22, 1);
//Pot PO4(A3, 0, 118, 1);
//Pot PO5(A4, 0, 30, 1);
//Pot PO6(A5, 0, 31, 1);
//*******************************************************************
//Add pots used to array below like this-> Pot POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6};
Pot POTS[] {};
//
*****************************************************************

//DEFINE DIRECTLY CONNECTED BUTTONS****************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
//** Command parameter 0=NOTE 1=CC 2=Toggle CC **

//Button BU1(2, 0, 60, 1, 5 );
//Button BU2(3, 0, 61, 1, 5 );
//Button BU3(4, 0, 62, 1, 5 );
//Button BU4(5, 0, 63, 1, 5 );
//Button BU5(6, 0, 64, 1, 5 );
//Button BU6(7, 0, 65, 1, 5 );
//Button BU7(8, 1, 64, 1, 5 );
//Button BU8(9, 2, 64, 1, 5 );
//*******************************************************************
//Add buttons used to array below like this-> Button BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8};
Button BUTTONS[] {};
//
*****************************************************************

//DEFINE BUTTONS CONNECTED TO MULTIPLEXER**********************
//Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
//** Command parameter 0=NOTE 1=CC 2=Toggle CC **

//Button MBU1(M1, 0, 0, 70, 1, 5);
//Button MBU2(M1, 1, 1, 71, 1, 5);
//Button MBU3(M1, 2, 2, 72, 1, 5);
//Button MBU4(M1, 3, 0, 73, 1, 5);
//Button MBU5(M1, 4, 0, 74, 1, 5);
//Button MBU6(M1, 5, 0, 75, 1, 5);
//Button MBU7(M1, 6, 0, 76, 1, 5);
//Button MBU8(M1, 7, 0, 77, 1, 5);
//Button MBU9(M1, 8, 0, 78, 1, 5);
//Button MBU10(M1, 9, 0, 79, 1, 5);
//Button MBU11(M1, 10, 0, 80, 1, 5);
//Button MBU12(M1, 11, 0, 81, 1, 5);
//Button MBU13(M1, 12, 0, 82, 1, 5);
//Button MBU14(M1, 13, 0, 83, 1, 5);
//Button MBU15(M1, 14, 0, 84, 1, 5);
//Button MBU16(M1, 15, 0, 85, 1, 5);
//*******************************************************************
////Add multiplexed buttons used to array below like this-> Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
Button *MUXBUTTONS[] {};

//*******************************************************************

//DEFINE POTENTIOMETERS CONNECTED TO MULTIPLEXER****************
//Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
//Command parameter is for future use

//Pot MPO1(M2, 0, 0, 1, 1);
//Pot MPO2(M2, 1, 0, 7, 1);
//Pot MPO3(M2, 2, 0, 50, 1);
//Pot MPO4(M2, 3, 0, 55, 2);
//Pot MPO5(M2, 4, 0, 50, 1);
//Pot MPO6(M2, 5, 0, 55, 2);
//Pot MPO7(M2, 6, 0, 50, 1);
//Pot MPO8(M2, 7, 0, 55, 2);
//Pot MPO9(M2, 8, 0, 50, 1);
//Pot MPO10(M2, 9, 0, 55, 2);
//Pot MPO11(M2, 10, 0, 50, 1);
//Pot MPO12(M2, 11, 0, 55, 2);
//Pot MPO13(M2, 12, 0, 50, 1);
//Pot MPO14(M2, 13, 0, 55, 2);
//Pot MPO15(M2, 14, 0, 50, 1);
//Pot MPO16(M2, 15, 0, 55, 2);
//*******************************************************************
//Add multiplexed pots used to array below like this-> Pot MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
Pot MUXPOTS[] {};
//
*****************************************************************

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

void loop() {
if (NUMBER_BUTTONS != 0) updateButtons();
if (NUMBER_POTS != 0) updatePots();
if (NUMBER_MUX_BUTTONS != 0) updateMuxButtons();
if (NUMBER_MUX_POTS != 0) updateMuxPots();
}

//*****************************************************************
void updateButtons() {

// Cycle through Button array
for (int i = 0; i < NUMBER_BUTTONS; i = i + 1) {
byte message = BUTTONS*->getValue();*

  • // Button is pressed*
  • if (message == 0) {*
    _ switch (BUTTONS*->Bcommand) {_
    _
    case 0: //Note*_
    MIDI.sendNoteOn(BUTTONS_->Bvalue, 127, BUTTONS*->Bchannel);
    break;
    case 1: //CC*

    MIDI.sendControlChange(BUTTONS->Bvalue, 127, BUTTONS*->Bchannel);
    break;
    case 2: //Toggle*

    if (BUTTONS*->Btoggle == 0) {
    MIDI.sendControlChange(BUTTONS->Bvalue, 127, BUTTONS->Bchannel);
    BUTTONS->Btoggle = 1;
    }
    else if (BUTTONS->Btoggle == 1) {
    MIDI.sendControlChange(BUTTONS->Bvalue, 0, BUTTONS->Bchannel);
    BUTTONS->Btoggle = 0;
    }
    break;
    }
    }
    // Button is not pressed*

    * if (message == 1) {
    switch (BUTTONS->Bcommand) {
    case 0:
    MIDI.sendNoteOff(BUTTONS->Bvalue, 0, BUTTONS->Bchannel);
    break;
    case 1:
    MIDI.sendControlChange(BUTTONS->Bvalue, 0, BUTTONS->Bchannel);
    break;
    }
    }
    }
    }
    //
    void updateMuxButtons() {
    // Cycle through Mux Button array

    for (int i = 0; i < NUMBER_MUX_BUTTONS; i = i + 1) {
    MUXBUTTONS->muxUpdate();

    byte message = MUXBUTTONS->getValue();

    // Button is pressed

    if (message == 0) {

    switch (MUXBUTTONS->Bcommand) {

    case 0: //Note

    MIDI.sendNoteOn(MUXBUTTONS->Bvalue, 127, MUXBUTTONS->Bchannel);

    break;

    case 1: //CC

    MIDI.sendControlChange(MUXBUTTONS->Bvalue, 127, MUXBUTTONS->Bchannel);

    break;

    case 2: //Toggle

    if (MUXBUTTONS->Btoggle == 0) {

    MIDI.sendControlChange(MUXBUTTONS->Bvalue, 127, MUXBUTTONS->Bchannel);

    MUXBUTTONS->Btoggle = 1;

    }

    else if (MUXBUTTONS->Btoggle == 1) {

    MIDI.sendControlChange(MUXBUTTONS->Bvalue, 0, MUXBUTTONS->Bchannel);

    MUXBUTTONS->Btoggle = 0;

    }

    break;

    }

    }

    // Button is not pressed

    if (message == 1) {

    switch (MUXBUTTONS->Bcommand) {

    case 0:

    MIDI.sendNoteOff(MUXBUTTONS->Bvalue, 0, MUXBUTTONS->Bchannel);

    break;

    case 1:

    MIDI.sendControlChange(MUXBUTTONS->Bvalue, 0, MUXBUTTONS->Bchannel);

    break;

    * }
    }
    }
    }
    //***********************************************************************
    void updatePots() {
    for (int i = 0; i < NUMBER_POTS; i = i + 1) {
    byte potmessage = POTS->getValue();
    if (potmessage != 255) MIDI.sendControlChange(POTS->Pcontrol, potmessage, POTS->Pchannel);
    }
    }
    //***********************************************************************
    void updateMuxPots() {
    for (int i = 0; i < NUMBER_MUX_POTS; i = i + 1) {
    MUXPOTS->muxUpdate();
    byte potmessage = MUXPOTS->getValue();
    if (potmessage != 255) MIDI.sendControlChange(MUXPOTS->Pcontrol, potmessage, MUXPOTS->Pchannel);
    }
    }*_

Please use code tags. Your code is completely unreadable, and array indices were removed by the forum.

What's wrong with the code I posted?

If I understand your question correctly, you want to do something like
this?
(Try the 5 blue buttons to change the patch number.)

And please specify what in that code works and what exactly it is that you want to do differently. Just saying "Done the bank one" and "want a few favourites switches" isn't providing any useful information.

Steve

Apologies for the confusion. Ignore what I have done previous as that controller works as required - 8 knobs and 8 switchrs controlling midi cc via nano.

I am looking to build a 6 swith foot controller sending midi PC messages.

So

Switch 1 sends PC 12
Switch 2 sends PC 37
Switch 3 sends PC 49

etc

No increments just each button does only that specific PC - sort of like instant access switching.

The link you posted lookd good but unfortunately it is almost unreadable on my phone so will check later.

Thanks for your patience so far I do appteciate it

Then you can do something like this:

Code:

---



```
#include <Control_Surface.h> // Include the library

// Patch Selector selecting patches 12, 37, 49, 50, 51, 52
// when buttons on pins  2, 3, 4, 5, 6, 7 are pressed, respectively
SelectorPC sel( { 12, 37, 49, 50, 51, 52 }, { 2, 3, 4, 5, 6, 7 } );

void setupcolor=#000000[/color] {} // Nothing to set up

void loopcolor=#000000[/color] {
  // Refresh the control surface, send a Program Change
  // event when the patch number changes
  Control_Surface.refreshcolor=#000000[/color];
}
```

|

That looks pretty much it ! :smiley:

Will try it later today and report back but thank you so much for your perserverance.

Just got back in now and tried uploading to the nano - unfortunately no joy as keep getting errors uploading.

I added the control surface to the library but still not happening. I am sure I just need to disable the encoder doc but at present no ideas on how to do that .

error code is

Arduino: 1.8.5 (Windows 7), Board: "Arduino Nano, ATmega328P"

In file included from C:\Users\Laptop\Documents\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:16:0,

from C:\Users\Laptop\Documents\Arduino\sketch_apr22b\sketch_apr22b.ino:1:

C:\Users\Laptop\Documents\Arduino\libraries\Control-Surface-master\src/./MIDI_Outputs/RotaryEncoder.h:5:21: fatal error: Encoder.h: No such file or directory

#include <Encoder.h>

^

compilation terminated.

exit status 1
Error compiling for board Arduino Nano.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Also how do I set the MIDI channel with the script from Pieter? Or is it omni - which would be fine.

Cheers

I'm sorry, I didn't find the time to include the installation instructions yet. You have to install the PJRC Encoder library.
(Even if you don't use it, sadly. It's a problem that I'm working on, should be fixed soon.)

The channel is 1 by default. I didn't add code to set the channel yet, will do so tonight or tomorrow.

cheers thats great.

Don't worry about the midi channel 1 is fine this end

Works perfectly - huge thanks for your support.

It transmits on channel 16 by the way - is there anyway I can change this?

Also I would like to add a potentiometer transmitting cc11, and possibly a switch doing cc11 too ie pot does the whole 0-127 and button fixed at 63, is this a simple copy and past from another sketch?

Cheers