Push-button to change MIDI channel

Hey guys!!

So, I´ve been building a MIDI console to controle DAW with arduino uno. I have a code that already works but in a predetermined channel. As I would like to have more functionalities from the console than the UNO can give me; I mean I´m limited in 5 analog pins, so I could only use 5 faders and I would like to be able to use them in more than 5 tracks. One solution would be to change the channel and re-assign the potentiometer in that channel to other track. So, is there a simple way that I could assign a push-button to change the MIDI channels once pushed (e.g. pushed once --> channel 2; push again --> 3 and then go back to 1) so I could re-assign the potentiometers and re-use the same code? I mean re-use in the sense that I want the buttons and pots to work exactly in the same way in the other channels. I only want to have more "banks". Is that clear?

Well the code is as follows:

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

const int NButtons = 4;
const int button[NButtons] = {2,3,4,5};
int buttonCState[NButtons] = {0};
int buttonPState[NButtons] = {0};

const int NPots = 1;
const int pot[NPots] = {A0};
int potCState[NPots] = {0};
int potPState[NPots] = {0};
int potVar = 0;

byte midiCh = 1;
byte note = 36;
byte cc = 1;

int TIMEOUT = 300;
int varThreshold = 4;
boolean potMoving = true;
unsigned long pTime[NPots] = {0};
unsigned long timer[NPots] = {0};

void setup () {

MIDI.begin();
//Serial Connection
Serial.begin(115200);
//Initialize Digital Pins as inputs
for (int i=0; i<NButtons; i++){
pinMode(button*, INPUT_PULLUP);*

  • }*
    // pinMode(button[3], INPUT); //pino 13

  • //Initialize Analog Pins as inputs*

  • for (int i=0; i<NPots; i++){*
    _ pinMode(pot*, INPUT);_
    _
    }*_

}
void loop () {

* for (int i=0; i<NButtons; i++) {*
buttonCState = digitalRead(button*);*
* }*
* buttonCState[12] = !buttonCState[12];*

* for (int i=0; i<NButtons; i++) {*
if (buttonCState != buttonPState*) {*
_ if(buttonCState == LOW) {
MIDI.sendNoteOn(note+i, 127, midiCh);

buttonPState = buttonCState*;*
* }
else {
MIDI.sendNoteOn(note+i, 0, midiCh);_

buttonPState _= buttonCState;
}
}*_

* }*

* for (int i=0; i<NPots; i++) { // le todas entradas analogicas utilizadas*
potCState = analogRead(pot*);*
* }*

* for (int i=0; i<NPots; i++) {*
potVar = abs(potCState - potPState*);*
* if (potVar >= varThreshold) { *
_ pTime = millis();
* }_
timer _= millis() - pTime;
if (timer < TIMEOUT) {
potMoving = true;
}
else {
potMoving = false;
}
if (potMoving == true) {
MIDI.sendControlChange(cc+i, map(potCState, 0, 1023, 0, 127), midiCh);_

potPState _= potCState;
}
}*_

}[/quote]
Many thanks in advance!
Marcos

That code doesn't compile. It is NOT using 5 faders and it will need a fair amount of change before it can. And I don't believe that it works with 4 buttons either.

Whoever wrote seems to have no real idea of how arrays work. I'd get the existing code sorted out before trying to add anything new to it.

Steve

Hi,

I still need to change for 4 faders, but with one and 4 buttons it worked just fine. It is compiling in my pc. Anyways, any idea on how to add the midi channel changer?

Thanks

If you can really get the code that you posted to compile without errors and work with 4 buttons then you can already work miracles. There's nothing I can possibly teach you.

Steve

It is compiling in my pc

Copy it back from your post above then try compiling it

If only you had used code tags instead of quote tags ...

UKHeliBob:
If only you had used code tags instead of quote tags ...

In fact even no tags at all is better than quote tags, I can still hit the Quote link (how ironic!) and recover the original from the message editor. Quote tags dont't leave that option, because the forum software removes nested quotes.

I removed some slashes to not over crowed the post. Here is the original though. It is still with only one potentiometer but that is easy to change. So, any ideas in how I can assign a button for changing the MIDI channels? I'm looking for that so I can have something like banks in the DAW. I believe there should be an easy solution for it but as I'm really new to this I cannot figure it out yet!

Sorry for the confusion of the code :wink:

There it goes again:

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

/////////////////////////////////////////////

const int NButtons = 4;
const int button[NButtons] = {2,3,4,5};
int buttonCState[NButtons] = {0};
int buttonPState[NButtons] = {0};

/////////////////////////////////////////////

const int NPots = 1;
const int pot[NPots] = {A0};
int potCState[NPots] = {0};
int potPState[NPots] = {0};
int potVar = 0;

/////////////////////////////////////////////

byte midiCh = 1;
byte note = 36;
byte cc = 1;

/////////////////////////////////////////////

int TIMEOUT = 300;
int varThreshold = 4;
boolean potMoving = true;
unsigned long pTime[NPots] = {0};
unsigned long timer[NPots] = {0};

/////////////////////////////////////////////

void setup () {

//Start midi connection
MIDI.begin();
//Serial Connection
Serial.begin(115200);
//Initialize Digital Pins as inputs
for (int i=0; i<NButtons; i++){
pinMode(button*, INPUT_PULLUP);*

  • }*
    // pinMode(button[3], INPUT); //pino 13

  • //Initialize Analog Pins as inputs*

  • for (int i=0; i<NPots; i++){*
    _ pinMode(pot*, INPUT);_
    _
    }*_

}
void loop () {

* for (int i=0; i<NButtons; i++) {*
buttonCState = digitalRead(button*);*
* }*
* buttonCState[12] = !buttonCState[12];*

* for (int i=0; i<NButtons; i++) {*
if (buttonCState != buttonPState*) {*
_ if(buttonCState == LOW) {
MIDI.sendNoteOn(note+i, 127, midiCh);_

buttonPState = buttonCState*;*
* }*
* else {*
* MIDI.sendNoteOn(note+i, 0, midiCh);*

buttonPState = buttonCState*;*
* }*
* }*

* }*
* ////////////////////////////////////////////////////////////////////////////////////////*
* for (int i=0; i<NPots; i++) {*
potCState = analogRead(pot*);*
* }*

* for (int i=0; i<NPots; i++) {*
potVar = abs(potCState - potPState*);*
* if (potVar >= varThreshold) { *
_ pTime = millis();
* }_
timer _= millis() - pTime;
if (timer < TIMEOUT) {
potMoving = true;
}
else {
potMoving = false;
}
if (potMoving == true) {
MIDI.sendControlChange(cc+i, map(potCState, 0, 1023, 0, 127), midiCh);_

potPState _= potCState;
}
}*_

}
I just tested and it compiles :wink:
Thanks in advance again!!

Would it work if I add this to the code:

const int buttonUPPin = 1;
const int buttonDOWNPin = 2;

..

const byte = maxCH = 16;
const byte = minCH = 1;
byte midiCh = minCH; // *Canal midi a ser utilizado

...

void setup () {

...

}

void loop () {

//testar pins
if(digitalRead(buttonUPPin) == LOW) {
midiCh++;
if(midCh > maxCH) {
midCh = minCH;
}
}
if(digitalRead(buttonDOWNPin) == LOW) {
midiCh--;
if(midCh < minCH) {
midCh = maxCH;
}
}

Thanks!

From post #6

I just tested and it compiles :wink:

The code as it appears in your post doesn't !

Why not just use code tags ? It is what they were designed for, after all.

So exactly what compiler are you using that will compile that stuff? It definitely isn't the standard Arduino IDE.

It must be an odd compiler if it allows you to assign the result of a single digitalRead to a complete array. And it lets you do a digitalRead() of an array of button pins in one statement. E.g.

const int button[NButtons] = {2, 3, 4, 5};
int buttonCState[NButtons] = {0};
....

    buttonCState = digitalRead(button);

and that's just one of the many obvious errors.

Steve

Here it is a new one. It does compile on mine (arduino software). I guess it should work, no?

Sorry for the confusion!

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

/////////////////////////////////////////////

const int buttonUPPin = 6;
const int buttonDOWNPin = 7;
const int NButtons = 4; 
const int button[NButtons] = {2,3,4,5}; 
int buttonCState[NButtons] = {0}; 
int buttonPState[NButtons] = {0}; 

/////////////////////////////////////////////

const int NPots = 1; 
const int pot[NPots] = {A0}; 
int potCState[NPots] = {0}; 
int potPState[NPots] = {0}; 
int potVar = 0; 

/////////////////////////////////////////////

const byte maxCH = 16;
const byte minCH = 1;
byte midiCh = minCH; // *Canal midi a ser utilizado
byte note = 36; 
byte cc = 1; 

/////////////////////////////////////////////

int TIMEOUT = 300; 
int varThreshold = 4; 
boolean potMoving = true; 
unsigned long pTime[NPots] = {0}; 
unsigned long timer[NPots] = {0}; 

/////////////////////////////////////////////

void setup () {

  //Start midi connection
  MIDI.begin();
  //Serial Connection
  Serial.begin(115200);
  //Initialize Digital Pins as inputs
  for (int i=0; i<NButtons; i++){
    pinMode(button[i], INPUT_PULLUP);
  }
 // pinMode(button[3], INPUT); //pino 13
  
  //Initialize Analog Pins as inputs
  for (int i=0; i<NPots; i++){
    pinMode(pot[i], INPUT);
  }
  

}

void loop () {

  //testar pins
  if(digitalRead(buttonUPPin) == LOW) {
    midiCh++;
    if(midiCh > maxCH) {
      midiCh = minCH;
    }
  }
  if(digitalRead(buttonDOWNPin) == LOW) {
    midiCh--;
    if(midiCh < minCH) {
      midiCh = maxCH;
    }
  }
 
  for (int i=0; i<NButtons; i++) {
    buttonCState[i] = digitalRead(button[i]);
  }
  buttonCState[12] = !buttonCState[12]; 

  
  for (int i=0; i<NButtons; i++) {

    if (buttonCState[i] != buttonPState[i]) {

      if(buttonCState[i] == LOW) {     
        MIDI.sendNoteOn(note+i, 127, midiCh); 
  
        buttonPState[i] = buttonCState[i];
      }
      else {
        MIDI.sendNoteOn(note+i, 0, midiCh); 
        
        buttonPState[i] = buttonCState[i];
      }
    }
    
  }

  ////////////////////////////////////////////////////////////////////////////////////////

  for (int i=0; i<NPots; i++) { 
    potCState[i] = analogRead(pot[i]);
  }

    
  for (int i=0; i<NPots; i++) {

    potVar = abs(potCState[i] - potPState[i]); 

    if (potVar >= varThreshold) {  
      pTime[i] = millis(); 
    }
    timer[i] = millis() - pTime[i]; 
    if (timer[i] < TIMEOUT) { 
      potMoving = true;
    }
    else {
      potMoving = false;
    }

    if (potMoving == true) { 
      MIDI.sendControlChange(cc+i, map(potCState[i], 0, 1023, 0, 127), midiCh); 
      potPState[i] = potCState[i]; 
    }
  }
  
}

So the code you twice insisted compiled for you and worked didn't really compile at all let alone work? It's not easy helping some people.

Anyway the new code is better. However while it might compile

  buttonCState[12] = !buttonCState[12];

will cause you problems. That's only a 4 element array so writing outside it to the "13th" element will sooner or later create chaos.

Also for your channel change you should really be looking at when the buttons change state i.e. go from off to on, so that one push of the button changes channel by 1. As you have it now if you hold a button down for a second or two it will cycle through the channel numbers, ending up who knows where. Have a look at the IDE example 02.Digital / StateChangeDetection" for some ideas.

Steve

Thanks Steve,

what about

for (int i = 0; i < NButtons; i++) {

    buttonCState[i] = digitalRead(buttonPin[i]);

        if (i == pin13index) {
          buttonCState[i] = !buttonCState[i]; //inverts pin 13 because it has a pull down resistor instead of a pull up
        }

About the channel change, as is each click won't reflect changing 1 channel up or down? It will depend on the time pressed?

Thanks

The code you've previously posted doesn't use pin 13 for anything. The button[] array uses pins 2,3,4,5 and there is no buttonPin[] array. So what is the point of that bit of code?

Channel change, why not just try it? Add a serial.print of midiCh and see what you get. But if you remember that loop() keeps on looping round (fast!) and every time it loops if the button is still pressed it will change midiCh again you can probably work it out.

Steve