Help adding switch to MIDI Controller

Hi
I am building a MIDI Controller with 8 pots and a switch. I can get the pots working but would like to add a switch so all the pots change their controller numbers when the switch is on.

See attached code. Any help would be great.

EDIT: I am using and Arduino Mega Rev3 with HIDUINO.

MIDI_Controller_Test.ino (4.23 KB)

Please read this:-
How to use this forum
Because your post is not posting code in the best way here.

Take this array

int controllers[NUMBER_OF_ANALOG_INPUTS] = { 
  0xE, 0x4A, 0x47, 0x46, 0x49, 0x4B, 0x4C, 0x48
};

And add an extra 8 entries on the end of the alternate controller numbers you want to use.

Then change this line:-

msg.data1   = controllers[i];
// to this line
msg.data1   = controllers[i+shift];

Then make a global variable called shift.
Wire your shift switch between the chosen input and ground and set that pin to be an input with the pull up resistors enabled.
Then in the loop function read the value of shift pin and if it is high set the "shift" variable to 8 otherwise set it to zero.

Thank you, I understand your first instructions...

int controllers[NUMBER_OF_ANALOG_INPUTS] = { 
  0xE, 0x4A, 0x47, 0x46, 0x49, 0x4B, 0x4C, 0x48, 0xF, 0x11, 0x12, 0x13, 0x4D, 0x4E, 0x4F, 0x10
};

and

msg.data1   = controllers[i+shift];

But not the

make a global variable called shift.

Can you give an example of the shift variable and the loop function syntax? I have a switch on pin 11.

Global variable called shift. Outside of any function write

int shift =0;

In the setup function write

pinMode(11,INPUT_PULLUP);

In the loop function write

if(digitalRead(11) == LOW){
   shift = 8;
}
else {
   shift = 0;
}

I have a switch on pin 11.

Remove any pull up or down resistors you might have there.

I guess from these questions you did not write that code yourself, it would have been good to know that first.

Grumpy_Mike:
I guess from these questions you did not write that code yourself, it would have been good to know that first.

Thank you, sorry yes I have copied code from various instructables but got stuck on the switch syntax.

The code is almost working but I'm getting a lot of noise on the MIDI monitor. Can you check if I have pasted the loop syntax correctly?

void loop() // The loop keeps on repeating forever.
{
  t_midiMsg msg;                                     // create a variable 'msg' of data type 't_midiMsg' we just created
  for(int i = 0; i < NUMBER_OF_ANALOG_INPUTS; i++){  // Repeat this procedure for every analog input.

    analogVal[i] = analogRead(i+A0)/8;               // The resolution of the Arduino's ADC is 10 bit, and the MIDI message has only 7 bits, 10 - 7 = 3, so we divide by 2^3, or 8.
    if(analogVal[i] != analogOld[i]){                // Only send the value, if it is a different value than last time.
      msg.status = CC;                               // Controll Change
      msg.status = msg.status | CHANNEL-1;           // Channels are zero based (0 = ch1, and F = ch16). Bitwise or to add the status message and channel together: 
                                                    /* status     = 0bssss0000 
                                                     * channel    = 0b0000cccc 
                                                     * | ------------------ (bitwise or)
                                                     * msg.status = 0bsssscccc       
                                                     */
      msg.data1   = controllers[i+shift];             // Get the controller number from the array above.
      msg.data2   = analogVal[i];                    // Get the value of the analog input from the analogVal array.
      Serial.write((uint8_t *)&msg, sizeof(msg));    // Send the MIDI message.
      analogOld[i] = analogVal[i];                   // Put the analog values in the array for old analog values, so we can compare the new values with the previous ones.
      delay(10);                                     // Wait for 10ms, so it doesn't flood the computer with MIDI-messages
     if(digitalRead(11) == LOW){
       shift = 8;
        }
      else {
        shift = 0;
        }
    }
  }

}

Can you check if I have pasted the loop syntax correctly?

Yes it looks correct. Although it would be much better if you would have positioned it at the start of the loop function, instead of doing it each time you read one of the inputs.

void loop()
{
  t_midiMsg msg;  // create a variable 'msg' of data type 't_midiMsg' we just created
  if(digitalRead(11) == LOW){
    shift = 8;
   }
  else {
  shift = 0;
  }

  for

I have copied code from various instructables

That explains why it is quite poor code. It is important to realise that the vast majority of instructiables articles are written by beginners who have little idea about electronics or writing code.

For example this line:-

delay(10);                                     // Wait for 10ms, so it doesn't flood the computer with MIDI-messages

Is total crap.

Now what do you mean by "noise" and how is this differing from what you had before. Noise has a very specific meaning in electronics and I doubt you mean what I understand as noise because in this context it doesn't make any sense.

before I put the shift code in I could clearly monitor which knob sent which controller number in the MIDI monitor software. But now it looks like the right CC are being sent and the switch is working but there is constant trasmitting of CC data all the time, like I am moving all the knobs all the time even when I am not touching them.

also had to change the number of analogue inputs to 16 or it wouldn't compile due to the extra controllers in the array...

#define NUMBER_OF_ANALOG_INPUTS  16 // NOTE: if you change this value, also change the controllers array, to match the number of inputs and the number of controllers.

#define CHANNEL 1 // Send all messages on channel 1.

/* The list with the corresponding controller numbers: for example, the values of the potentiometer on A0 will be sent as the first controller number in this list, A1 as the second, etc. */
int controllers[NUMBER_OF_ANALOG_INPUTS] = { 
  0xE, 0x4A, 0x47, 0x46, 0x49, 0x4B, 0x4C, 0x48, 0xF, 0x11, 0x12, 0x13, 0x4D, 0x4E, 0x4F, 0x10
};  

int analogVal[NUMBER_OF_ANALOG_INPUTS];  // We declare an array for the values from the analog inputs

int analogOld[NUMBER_OF_ANALOG_INPUTS]; // We declare an array for the previous analog values. 

int shift =0;

Arduino: 1.8.7 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

MIDI_Controller_Test:37:1: error: too many initializers for 'int [8]'
};
^
exit status 1
too many initializers for 'int [8]'

there is constant trasmitting of CC data all the time,

What you put in will not change that. Unless you have removed the delay( 10 ) line. I said it was crap because it is a very poor way of limiting the number of messages sent. But if you remove it then you will be constantly sending MIDI messages.

I think the problem is that you don't understand the code you have.

What proper code does is to compare the current reading from a pot with the reading of the last time you sent the pot's value as a MIDI message and only sends a MIDI message when it is different.

also had to change the number of analogue inputs to 16 or it wouldn't compile due to the extra controllers in the array...

Again rubbish code that array line should be

int controllers[] = {
  0xE, 0x4A, 0x47, 0x46, 0x49, 0x4B, 0x4C, 0x48, 0xF, 0x11, 0x12, 0x13, 0x4D, 0x4E, 0x4F, 0x10
};

The original code should never have had a line defining the number of bytes in that array.

Grumpy_Mike:
I think the problem is that you don't understand the code you have.

Thanks for being patient with me. After deleting the defining number of bytes in that array it now works - thanks!

There are various includes in the code that I assume refer to other files, are they needed? Given then requirements I have for this particlar project?

#include <RotaryEncoder.h>
#include <debug.h>
#include <interrupt_pins.h>
#include <sendMidi.h>
#include <DigitalLatch.h>
#include <Analog.h>
#include <Digital.h>
#include <direct_pin_read.h>
#include <interrupt_config.h>
#include <MIDI_controller.h>

I can't see you use them except the MIDI one, so it is safe to delete. If in doubt just comment them out and see if it compiles.

Thanks for your help Mike

yarsrev:
before I put the shift code in I could clearly monitor which knob sent which controller number in the MIDI monitor software. But now it looks like the right CC are being sent and the switch is working but there is constant trasmitting of CC data all the time, like I am moving all the knobs all the time even when I am not touching them.

Well stop transmitting the CC data all the time - only transmit when there's a change in value, that's
implicit in the MIDI spec.

MarkT:
Well stop transmitting the CC data all the time - only transmit when there's a change in value, that's
implicit in the MIDI spec.

As mentioned in reply #8

MarkT:
Well stop transmitting the CC data all the time - only transmit when there's a change in value, that's
implicit in the MIDI spec.

Thanks for that Mark, but the code now works perfectly, if there is a better way please give me an example of how to do it proporly and I will change it.

yarsrev:
Thanks for that Mark, but the code now works perfectly, if there is a better way please give me an example of how to do it proporly and I will change it.

StateChangeDetection is one of the example sketches...