Trouble with MIDI controller code (2)

Five months ago, I started this topic here about the code for the midi controller I was building and got help especially from PieterP, who presented me the Control Surface library he maintains. After all of this months, I put all the hardware and enclosure together and started working on the code. I got the 16 button matrix working as I expected and managed to make the 8 pots working too, but not how I want. I would like to make them ready (predefined) to control a specific group of parameters in my daw as I plug the midi, just like the button matrix, instead of having to map them everytime I open the daw, how can I do that?.
The other thing Im having difficulties on making it work is the button ladder, I've tried I few things on the code without success and I don't understand what I need to do to make it work.
Any help would be much appreciated.

#include <Control_Surface.h> // Include the Control Surface library
 
USBMIDI_Interface midi; // Instantiate a MIDI over USB interface.

int RX1_PIN= 0;   
int TX0_PIN= 1;
int BLUEL= A10;
//int BLUER= A10;
//int WHITE= A10;
//int GREEN= A10;
//int RED= A10;
//int YELLOW= A10;

// Transpose up to 2 octaves down or up (steps of 12 semitones = 1 octave)
Transposer<-2, +2> transposer{10};


// The note numbers corresponding to the buttons in the matrix   

const AddressMatrix<4, 4> addresses = {{
    { 36,  37,  38,  39 },
    { 40,  41,  42,  43 },
    { 44,  45,  46,  47 },
    { 48,  49,  50,  51 },
}};

 
Bankable::NoteButtonMatrix<4, 4> buttonmatrix = {
  
  transposer,   // determines the offset
  
  {5, 7, 14, 15}, // row pins
  {3, 2, 0, 1},   // column pins

  addresses,    // address matrix
  
  CHANNEL_1,    // channel and cable number
};


// Instantiate a CCPotentiometer object
CCPotentiometer potentiometers[] = {
  {A3,                                   // Analog pin connected to potentiometer
  {MIDI_CC::Channel_Volume, CHANNEL_1}}, // Channel volume of channel 1
  {A2,
  {MIDI_CC::General_Purpose_Controller_2, CHANNEL_2}},
  {A1,
  {MIDI_CC::General_Purpose_Controller_3, CHANNEL_3}},
  {A0,
  {MIDI_CC::General_Purpose_Controller_4, CHANNEL_4}},
  {A9,
  {MIDI_CC::General_Purpose_Controller_5, CHANNEL_5}},
  {A8,
  {MIDI_CC::General_Purpose_Controller_6, CHANNEL_6}},
  {A7,
  {MIDI_CC::General_Purpose_Controller_7, CHANNEL_7}},
  {A6,
  {MIDI_CC::General_Purpose_Controller_8, CHANNEL_8}},
};
//CCPotentiometer potentiometers[] = {
  //{A3, 0X07},
  //{A2, 0X08},
  //{A1, 0X0A},
  //{A0, 0X0C},
  //{A9, 0X0D},
  //{A8, 0X10},
  //{A7, 0X11},
  //{A6, 0X12}, 
//};
 

void setup() {
  Control_Surface.begin(); // Initialize Control Surface

}
 
void loop() {
  Control_Surface.loop(); // Update the Control Surface
    //if (BLUEL) {
    // You can set the transposition using transposer.select(i),
    // where i is the index of the octave to select: i = 0 is
    // the lowest octave (-2 in this case), i = 1 is the second
    // octave (-1 here), i = 2 is the third octave (no transposition
    // here) etc.
    //transposer.select(-2); // selects transposition of -2
    //}
    //if (BLUER) {
    //transposer.select (2);
    //}

//Control_Surface.sendNoteOn(0x5E, 127); // default channel 1
//Control_Surface.sendNoteOff(0x5E, 127);
//Control_Surface.sendNoteOff({0x5E, CHANNEL_10}, 127); // specific channel


}

This sounds like a problem with your DAW. Control Surface just reads the position of the potentiometers and sends it over MIDI to the address you specified in your Arduino code. The DAW is responsible for mapping that position and the address to a meaningful action within the software.

The library doesn't have a predefined class for button ladders. You'll have to measure the analog value yourself, map each range to a button, and then send the necessary MIDI messages. Have a look at the following examples:

Thank you! Good you pointed that.. Since I dont fully understand what I am doing and I am learning as I go, I thought the problem was on "my" code. After searching more about it, I found here, that its possible to create a script for my own control surface and with a little bit of trial and error between the script and the arduino code, I made it work as I want it.

I am using 6 buttons and 7 1K resistors for the button ladder, 2 of them will be for transposing octaves and the other 4 will be for stop, play, rec and loop, everything pluged into 1 analog pin. How can I do that? How can I measure the analog values and map it to the buttons?

Use e.g. the analogReadSerial example that comes with the IDE to determine which analogue value belongs to which button.

Next you can add the logic to detect which button was pressed. An example for 5 buttons here: Arduino_LCD_KeyPad_Shield__SKU__DFR0009_-DFRobot, adjust to your needs.

Okay, I've tried this, but I only get 2 values. On the first two buttons I got a value of 510 and on the other four buttons I got 681, when nothing is being pressed I got 1023. I've simulate the same setup on a breadboard and I got one different value for each button (511, 682, 767, 819, 853, 877) Its probably a circuit issue, right?

It was a circuit issue. I had to make some changes on the stripboard layout and now I have quite stable values (i guess), like the ones I mentioned above. Now, I've been trying to make the code work with the help of the examples above and some videos about multiple buttons on a single analog pin , but I not understanding the logic of how I can incorporate those values into the control surface functions. Can someone help me with that please?

Post your best attempt.

Did you have a look at the Send-MIDI-Notes example I referred to earlier?

Yes. Here I was able to import the code to the Arduino without errors, but it makes all pots and button matrix stop working.

// Include the Control Surface library
#include <Control_Surface.h>

// Instantiate a MIDI over USB interface. 
USBMIDI_Interface midi;

int RX1_PIN= 0;   
int TX0_PIN= 1;

int value = analogRead(A10);
#define OctaveL
#define OctaveR
#define Stop 
#define Play
#define Rec
#define Loop



 
// Transpose up to 2 octaves down or up (steps of 12 semitones = 1 octave)
Transposer<-2, +2> transposer{10}; 


// The note numbers corresponding to the buttons in the matrix   
const AddressMatrix<4, 4> addresses = {{
    { 36,  37,  38,  39 },
    { 40,  41,  42,  43 },
    { 44,  45,  46,  47 },
    { 48,  49,  50,  51 },
}};

 
Bankable::NoteButtonMatrix<4, 4> buttonmatrix = {
  
  transposer,   // determines the offset
  
  {5, 7, 14, 15}, // row pins
  {3, 2, 0, 1},   // column pins

  addresses,    // address matrix
  
  CHANNEL_1,    // channel and cable number
};


// Instantiate a CCPotentiometer object
CCPotentiometer potentiometers[] = {
  {A3,                                   // Analog pin connected to potentiometer
  {MIDI_CC::Sound_Controller_1, CHANNEL_1}}, // Channel volume of channel 1
  {A2,
  {MIDI_CC::Sound_Controller_2, CHANNEL_1}},
  {A1,
  {MIDI_CC::Sound_Controller_3, CHANNEL_1}},
  {A0,
  {MIDI_CC::Sound_Controller_4, CHANNEL_1}},
  {A9,
  {MIDI_CC::Sound_Controller_5, CHANNEL_1}},
  {A8,
  {MIDI_CC::Sound_Controller_6, CHANNEL_1}},
  {A7,
  {MIDI_CC::Sound_Controller_7, CHANNEL_1}},
  {A6,
  {MIDI_CC::Sound_Controller_8, CHANNEL_1}},
};
//CCPotentiometer potentiometers[] = {
  //{A3, 0X07},
  //{A2, 0X08},
  //{A1, 0X0A},
  //{A0, 0X0C},
  //{A9, 0X0D},
  //{A8, 0X10},
  //{A7, 0X11},
  //{A6, 0X12}, 
//};
 

void setup() {
  Control_Surface.begin(); // Initialize Control Surface
  
}
 
void loop() {
  Control_Surface.loop(); // Update the Control Surface

 int value = analogRead(A10);
 if (value > 0 && value < 512) return OctaveL;
 else if (value > 512 && value < 682) return OctaveR;
 else if (value > 682 && value < 768) return Stop;
 else if (value > 768 && value < 820) return Play;
 else if (value > 820 && value < 854) return Rec;
 else if (value > 854 && value < 877) return Loop;

  if ("OctaveL") {
    // You can set the transposition using transposer.select(i),
    // where i is the index of the octave to select: i = 0 is
    // the lowest octave (-2 in this case), i = 1 is the second
    // octave (-1 here), i = 2 is the third octave (no transposition
    // here) etc.
  transposer.select(-2); // selects transposition of -2
  }
  if ("OctaveL") {
  transposer.select(-1);
  }
    

//Control_Surface.sendNoteOn(0x5E, 127); // default channel 1
//Control_Surface.sendNoteOff(0x5E, 127);
//Control_Surface.sendNoteOff({0x5E, CHANNEL_10}, 127); // specific channel


}

Any help would be appreciated.

You're not defining anything, you should probably be using an enum, never use macros for constants.

Why are you returning from the loop function? Move this code to a separate function that returns the enum value.

This is always true, a string literal evaluates to true.

You are selecting the wrong transposition here, you cannot select negative values. To select octave -2, you do transposer.select(0), as explained in the comment.

It might be useful to have a look at an introductory C++ tutorial, it should clear up many of the problems with your code.

Thank you for the help and for pointing what I was doing wrong.
I corrected the last two notes you made and tried to implement the enum and the function that returns the enum value, but I didn't do it successfully. The attempt I think is close is the one below but I am not understanding what I am doing wrong.

enum buttons 
{

  OctaveL, OctaveR, Stop, Play, Rec, Loop

};

void buttons() {

int value = analogRead(A10);


 if (value > 0 && value < 512) 
  return OctaveL;
 else if (value > 512 && value < 682) 
  return OctaveR;
 else if (value > 682 && value < 768) 
  return Stop;
 else if (value > 768 && value < 820) 
 return Play;
 else if (value > 820 && value < 854) 
  return Rec;
 else if (value > 854 && value < 877) 
  return Loop;
  
}

The only way I am being able to get the transposition work, is when I attribute the values on the enum, but by doing this the transposition is working by default and the button ladder are still not getting recognized on my DAW as MIDI. Also I found that by doing this, the part of the code that is creating the function to returns the enum value is being useless, which conformes me that is incorrect.

enum buttons 
{
  OctaveL = 0 < 512, OctaveR = 512 < 682, Stop = 682 < 768, Play = 768 < 820, Rec = 820 < 854, Loop = 854 < 877

};

First of all, you cannot have an enum and a function with the same name.

You're trying to return a value, but the return type of your function is "void". Your return type should be the enumeration type, here buttons (which is not a great name, consider ButtonState or something like that, and rename the function to getButtonState()).

This doesn't make any sense, it'll result in all enumerator values being 1.

Given the type of mistakes in your code, I'd highly recommend taking a structured course/tutorial/book about introductory C++ programming, the trial-and-error approach is not an efficient way to learn how to code.

You are right, this approach of trial-and-error is really not efficient and is making me "waste" a lot of time. I started already taking a course and with your help I managed to get everything working how I wanted (besides the two transposition buttons), but Im not sure if this is the most efficient way of doing it, since I couldn't make the enum work.


#include <Control_Surface.h>

USBMIDI_Interface midi;

int RX1_PIN= 0;   
int TX0_PIN= 1;

// Transpose up to 2 octaves down or up (steps of 12 semitones = 1 octave)
Transposer<-2, +2> transposer{12}; 

// The note numbers corresponding to the buttons in the matrix   
const AddressMatrix<4, 4> addresses = {{
    { 36,  37,  38,  39 },
    { 40,  41,  42,  43 },
    { 44,  45,  46,  47 },
    { 48,  49,  50,  51 },
}};

Bankable::NoteButtonMatrix<4, 4> buttonmatrix = {
  transposer,   // determines the offset
  {5, 7, 14, 15}, // row pins
  {3, 2, 0, 1},   // column pins
  addresses,    // address matrix
  CHANNEL_1,    // channel and cable number
};

// Instantiate a CCPotentiometer object
CCPotentiometer potentiometers[] = {
  {A3,                                   // Analog pin connected to potentiometer
  {MIDI_CC::Sound_Controller_1, CHANNEL_1}}, // Channel volume of channel 1
  {A2,
  {MIDI_CC::Sound_Controller_2, CHANNEL_1}},
  {A1,
  {MIDI_CC::Sound_Controller_3, CHANNEL_1}},
  {A0,
  {MIDI_CC::Sound_Controller_4, CHANNEL_1}},
  {A9,
  {MIDI_CC::Sound_Controller_5, CHANNEL_1}},
  {A8,
  {MIDI_CC::Sound_Controller_6, CHANNEL_1}},
  {A7,
  {MIDI_CC::Sound_Controller_7, CHANNEL_1}},
  {A6,
  {MIDI_CC::Sound_Controller_8, CHANNEL_1}},
};
 

void setup() {
 
  Control_Surface.begin(); // Initialize Control Surface
  Serial.begin(9600);
 
}


void loop() {
  Control_Surface.loop(); // Update the Control Surface
  int value = analogRead(A10);
  Serial.println(value);
  
 if (value > 0 && value < 512){  //OCTAVE DOW
  transposer.select(1);
  delay (150);
 }
 
 else if (value > 513 && value < 682){  // OCTAVE UP
  transposer.select(3);
  delay (150);
 }
 
  else if (value > 690 && value < 768){ // PLAY
  Control_Surface.sendCC(0x12, 127); // default channel 1
  Control_Surface.sendCC(0x12, 127); // General_Purpose_Controller_3 = 0x12
  delay (250);
  }
  
 else if (value > 769 && value < 820){ // STOP
  Control_Surface.sendCC(0x13, 127); // default channel 1
  Control_Surface.sendCC(0x13, 127); // General_Purpose_Controller_4 = 0x13
  delay (250);
 }
 
 else if (value > 840 && value < 854){ // REC
  Control_Surface.sendCC(0x50, 127); // default channel 1
  Control_Surface.sendCC(0x50, 127); // General_Purpose_Controller_5 = 0x50
  delay (250);
 }
 
 else if (value > 855 && value < 877){ // LOOP
  Control_Surface.sendCC(0x51, 127); // default channel 1
  Control_Surface.sendCC(0x51, 127); // General_Purpose_Controller_6 = 0x51
  delay (250);
 }

 }

The transposition buttons are currently transposing only to a specific lower/higher octave and there is no way to get back to the central octave. I found this example and test it on a breadboard with a simple circuit and it worked great.

#include <Control_Surface.h>
 
USBMIDI_Interface midi;
 
// Transposer that transposes one octave (12 semitones) at a time,
// from 0 to +5 octaves.
Transposer<0, +5> transposer(12);
 
// Push button on pin 2 to transpose up, pin 3 to transpose down.
IncrementDecrementSelector<6> selector = {transposer, {2, 3}};
 
using namespace MIDI_Notes;
Bankable::NoteButton notebutton = {
  transposer,      // bank/transposer
  8,               // pin
  {72, CHANNEL_1}, // address/note
  127,             // velocity
};
 
void setup() {
  selector.invert(); // normally closed button
  Control_Surface.begin();
}
 
void loop() {
  Control_Surface.loop();
}

The problem is when I try it on my build. Since I am using a resistor ladder for this buttons and I have analogue values to identify them and I dont know what do put on the transposer pins.
How can make it work?

Thanks for your help!