Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: How can I change which CC's my MIDI controller is sending AFTER the initial setup?

  1. #1

    How can I change which CC's my MIDI controller is sending AFTER the initial setup?

    I just built a MIDI CC controller using a Teensy 3.2. I copied the code that someone else had used and it uses the code below to assign which CC's the six potentiometers on my controller will send.

    // define pins and cc codes
    const int A_PINS = 6;
    const int ANALOG_PINS[A_PINS] = {A0, A1, A2, A3, A4, A5};
    const int CCID[A_PINS] = {11, 1, 4, 2, 1, 21};

    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];

    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[]{
    ///////////////////////////////////////////////////////////////////////////
    {ANALOG_PINS[1],true},
    {ANALOG_PINS[2],true},
    {ANALOG_PINS[3],true},
    {ANALOG_PINS[4],true},
    {ANALOG_PINS[5],true},
    {ANALOG_PINS[0],true},

    That works fine, but I'd like to have the ability to update the CC assignments to one of five predefined "sets" while the program is running. I have a selector switch wired up and it's working fine, but I don't know what command could be used to update the CC assignments for the 6 pots while the program is looping. I tried using CCID[A_PINS] = {11, 1, 4, 2, 1, 21}; and that caused an error*, so I'm thinking that command may only work during setup. Any help will be greatly appreciated!


    * ERROR:
    Arduino: 1.8.13 (Windows 10), TD: 1.53, Board: "Teensy 3.2 / 3.1, MIDI, 96 MHz (overclock), Faster, US English"

    CCID[A_PINS] = {11, 11, 11, 1, 1, 11};
    ^
    C:\Users\Family Dell 2016\Documents\Arduino\MIDI_Controller_V5_with-5Banks\MIDI_Controller_V5_with-5Banks.ino:99:17: error: cannot convert '<brace-enclosed initializer list>' to 'const int' in assignment

    Error compiling for board Teensy 3.2 / 3.1.

  2. #2
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    298
    @LikeToBuildStuff:

    You are essentially correct that the line that you attempted to "reuse" is only used to set things up. The line that you pointed out is a variable declaration (CCID[A_PINS]) for an array named CCID that contains integers (int), with the number of elements defined by A_PINS. This declaration of CCID includes an initializer (= {11, 1, 4, 2, 1, 21}), which means that it is filled with those particular known values at the startup of your program. In addition, this particular variable declaration includes the syntax (const) which specifies that the contents of the array are not allowed to change while your program is running.

    So, reading from left to right, your variable declaration statement says the following:

    This is an unchanging array which contains 6 integers, & the values of the integers will be 11, 1, 4, 2, 1, 21, where 11 will be stored in the first element of the array (CCID[0]), 1 will be stored in the second element of the array (CCID[1]), etc. with 21 stored in the last element of the array (CCID[5]).

    The simplest way to expand what you have is to turn the CCID array of pins into a 2-dimensional array. You can change what you have to the following (this is written with the assumption that you will have 3 sets of pin definitions . . . change this as appropriate):

    Code:
    const int A_PINS = 6;
    const int CC_SETS = 3;
    const int CCID[CC_SETS, A_PINS] = {{11, 1, 4, 2, 1, 21}, {12, 2, 5, 3, 2, 22}, {13, 3, 6, 4, 3, 23}};
    This definition & initializer will cause the values for the first set to be set to 11, 1, 4, 2, 1, & 21, the second set to 12, 2, 5, 3, 2, 22, & the third set to 13, 3, 6, 4, 3, 23. Of course, you will need to substitute the appropriate values for your desired CC messages for each set.

    Now, in your program, lets say you have a variable called "pin" that keeps track of which pin you are reading, & you have a variable called "set" which keeps track of which set of CC definitions that you want to use. So, with use of these variables, for example, if you want to use the first set of pin definitions & reference the CC for the third pin, you'll set "set = 0;", along with "pin = 2;". Then, using these settings, you would reference CCID[set, pin] to get the appropriate CC value for the intended analog pin.

    Hope this helps. Feel free to ask more questions . . .

    Mark J Culross
    KD5RXT

  3. #3
    Quote Originally Posted by kd5rxt-mark View Post
    @LikeToBuildStuff:

    Hope this helps. Feel free to ask more questions . . .

    Mark J Culross
    KD5RXT
    Mark - thank you so much for the thorough and clear response. I think I understand your suggestions and tried to implement them in my program, but I'm getting another error so I must have some syntax incorrect. I've copied my entire program below so that you can see what I've done. Sorry for all the 1's and 11's - they are not the final CC values I will use but will make it easier to check my controller is responding correctly. Thanks again for your help!

    #include <Bounce.h>

    ///////////////////////////////////////////////////////////////////////////
    // define how many pots are active up to number of available analog inputs
    #define analogInputs 6
    //////////////////////////////////////////////////////////////////////////


    // define arrays for input values and lagged input values
    int inputAnalog[analogInputs];
    int iAlag[analogInputs];
    // define array of cc values
    int ccValue[analogInputs];
    // include the ResponsiveAnalogRead library
    #include <ResponsiveAnalogRead.h>

    // Define variables for Rotary Switch function (used to define one of 5 CC sets)
    int RotNewState;
    int Pin1State;
    int Pin3State;
    int Pin4State;
    int Pin7State;


    ///////////////////////////////////////////////////////////////////////////
    // define pins and cc codes
    const int A_PINS = 6;
    const int ANALOG_PINS[A_PINS] = {A0, A1, A2, A3, A4, A5};
    const int CC_SETS = 5;
    const int CCID[CC_SETS, A_PINS] = {{11,11,11,1,1,11},{11,11,1,11,1,11},{11,1,11,11,1 ,11},{1,11,11,11,1,11},{11,11,11,11,1,1}};
    ///////////////////////////////////////////////////////////////////////////

    // //////// REFERENCE INFO /////////////////////////////////////////////
    // Four sliders left-to-right are A3, A2, A1, A0, A5. Footpedal is A4
    //0=bank, 1=mod, 2=Breath, 7=Vol, 8=Bal, 10=pan, 4=foot, 11=Expr, 21=Vib 64=pedal
    /////////////////////////////////////////////////////////////////////////

    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];

    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[]{
    ///////////////////////////////////////////////////////////////////////////
    {ANALOG_PINS[1],true},
    {ANALOG_PINS[2],true},
    {ANALOG_PINS[3],true},
    {ANALOG_PINS[4],true},
    {ANALOG_PINS[5],true},
    {ANALOG_PINS[0],true},
    ///////////////////////////////////////////////////////////////////////////
    };

    // the setup routine runs once when you press reset:
    void setup() {
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);

    // Define Input pins (from 5-position Rotary Switch)
    pinMode (1,INPUT);
    pinMode (3,INPUT);
    pinMode (4,INPUT);
    pinMode (7,INPUT);

    }

    void loop(){

    // MIDI Controllers should discard incoming MIDI messages.
    while (usbMIDI.read()) {
    // read & ignore incoming messages
    }


    // Determine the state of the 4 pins coming from the rotary switch
    Pin1State=digitalRead(1);
    Pin3State=digitalRead(3);
    Pin4State=digitalRead(4);
    Pin7State=digitalRead(7);

    // Deduce the "CC Set" selected on the Rotary Switch and store in variable "RotNewState";
    if (Pin3State==HIGH && Pin7State==HIGH){
    RotNewState=1;
    }
    if (Pin4State==HIGH && Pin7State==HIGH){
    RotNewState=2;
    }
    if (Pin4State==HIGH && Pin7State==LOW){
    RotNewState=3;
    }
    if (Pin1State==HIGH && Pin4State==HIGH){
    RotNewState=4;
    }
    if (Pin1State==HIGH && Pin4State==LOW){
    RotNewState=5;
    }


    // Serial.println(RotNewState); //was used to check function of determining rotary switch position -> worked fine.

    }

    // update the ResponsiveAnalogRead object every loop
    for (int i=0;i<A_PINS;i++){
    analog[i].update();
    // if the repsonsive value has change, print out 'changed'
    if(analog[i].hasChanged()) {
    data[i] = analog[i].getValue()>>3;
    if (data[i] != dataLag[i]){
    dataLag[i] = data[i];
    usbMIDI.sendControlChange(CCID[RotNewState,i], data[i], 1);
    }
    }
    }
    }


    *********** ERROR RECEIVED ****************

    C:\Users\Family Dell 2016\Documents\Arduino\MIDI_Controller_V7_with-5CCsets\MIDI_Controller_V7_with-5CCsets.ino:31:23: error: expected ']' before ',' token
    const int CCID[CC_SETS, A_PINS] = {{11,11,11,1,1,11},{11,11,1,11,1,11},{11,1,11,11,1 ,11},{1,11,11,11,1,11},{11,11,11,11,1,1}};
    ^
    C:\Users\Family Dell 2016\Documents\Arduino\MIDI_Controller_V7_with-5CCsets\MIDI_Controller_V7_with-5CCsets.ino:31:31: error: expected initializer before ']' token
    const int CCID[CC_SETS, A_PINS] = {{11,11,11,1,1,11},{11,11,1,11,1,11},{11,1,11,11,1 ,11},{1,11,11,11,1,11},{11,11,11,11,1,1}};
    ^
    Error compiling for board Teensy 3.2 / 3.1.

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,753
    The syntax for the two-dimensional array is wrong. It should be this:
    Code:
    const int CCID[CC_SETS][A_PINS] = {{11,11,11,1,1,11},{11,11,1,11,1,11},{11,1,11,11,1 ,11},{1,11,11,11,1,11},{11,11,11,11,1,1}};
    Similarly, the reference to the array should be like this:
    Code:
    usbMIDI.sendControlChange(CCID[RotNewState][i], data[i], 1);
    Pete

  5. #5
    Quote Originally Posted by el_supremo View Post
    The syntax for the two-dimensional array is wrong. It should be this:
    Code:
    const int CCID[CC_SETS][A_PINS] = {{11,11,11,1,1,11},{11,11,1,11,1,11},{11,1,11,11,1 ,11},{1,11,11,11,1,11},{11,11,11,11,1,1}};
    Similarly, the reference to the array should be like this:
    Code:
    usbMIDI.sendControlChange(CCID[RotNewState][i], data[i], 1);
    Pete
    Pete - Thanks very much for the prompt reply. I made the two syntax changes you suggested and that part of the code no longer causes errors, however I am now getting the errors below. I'm a bit puzzled since that part of the code worked fine before I made CCID an array (ie, when I just had one set of CC assignments). Any suggestions for what could be wrong now will be much appreciated.

    *************** NEW ERROR ******************
    C:\Users\Family Dell 2016\Documents\Arduino\MIDI_Controller_V8_with-5CCsets\MIDI_Controller_V8_with-5CCsets.ino:103:25: error: 'i' does not name a type
    for (int i=0;i<A_PINS;i++){
    ^
    C:\Users\Family Dell 2016\Documents\Arduino\MIDI_Controller_V8_with-5CCsets\MIDI_Controller_V8_with-5CCsets.ino:114:1: error: expected declaration before '}' token
    }
    ^
    Error compiling for board Teensy 3.2 / 3.1.

  6. #6
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    298
    LikeToBuildStuff:

    Dang it !! Sorry, I wasn't at my primary PC when I typed my first reply. I'll use the excuse that I'm old & something else, but I'm having trouble remembering what the other thing is . . . oh yeah, forgetful !! I'm forgetful, so that's my excuse for the poor syntax . . . I was in a rush to help, but I really should have actually tested what I typed before I hit the send button. Nothing like posting suggestions that cause more errors instead of less !! Thanks to Pete for jumping in to provide corrections !!

    When you post code, it helps if the code is surrounded with CODE tags (just click the "#" in the bar of icons right above the text composition window here on the forum, then paste your code between the two tags). Also, for your own benefit, if you're using the Arduino IDE, you can use CTRL-T to auto (re)format the code with indentations, etc. That will make it much easier for you (& others as well) to read. Definitely don't take these suggestions as any kind of criticism . . . I applaud you for diving into this with both feet !!

    Here's a slightly updated version of the code that you posted earlier (reformatted) . . . it looks like you had one too many closing braces (}) . . . the closing brace right before the for loop was removed in the code below:

    Code:
    #include <Bounce.h>
    
    ///////////////////////////////////////////////////////////////////////////
    // define how many pots are active up to number of available analog inputs
    #define analogInputs 6
    //////////////////////////////////////////////////////////////////////////
    
    
    // define arrays for input values and lagged input values
    int inputAnalog[analogInputs];
    int iAlag[analogInputs];
    // define array of cc values
    int ccValue[analogInputs];
    // include the ResponsiveAnalogRead library
    #include <ResponsiveAnalogRead.h>
    
    // Define variables for Rotary Switch function (used to define one of 5 CC sets)
    int RotNewState;
    int Pin1State;
    int Pin3State;
    int Pin4State;
    int Pin7State;
    
    
    ///////////////////////////////////////////////////////////////////////////
    // define pins and cc codes
    const int A_PINS = 6;
    const int ANALOG_PINS[A_PINS] = {A0, A1, A2, A3, A4, A5};
    const int CC_SETS = 5;
    const int CCID[CC_SETS][A_PINS] = {{11, 11, 11, 1, 1, 11}, {11, 11, 1, 11, 1, 11}, {11, 1, 11, 11, 1 , 11}, {1, 11, 11, 11, 1, 11}, {11, 11, 11, 11, 1, 1}};
    ///////////////////////////////////////////////////////////////////////////
    
    // //////// REFERENCE INFO /////////////////////////////////////////////
    // Four sliders left-to-right are A3, A2, A1, A0, A5. Footpedal is A4
    //0=bank, 1=mod, 2=Breath, 7=Vol, 8=Bal, 10=pan, 4=foot, 11=Expr, 21=Vib 64=pedal
    /////////////////////////////////////////////////////////////////////////
    
    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];
    
    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[] {
       ///////////////////////////////////////////////////////////////////////////
       {ANALOG_PINS[1], true},
       {ANALOG_PINS[2], true},
       {ANALOG_PINS[3], true},
       {ANALOG_PINS[4], true},
       {ANALOG_PINS[5], true},
       {ANALOG_PINS[0], true},
       ///////////////////////////////////////////////////////////////////////////
    };
    
    // the setup routine runs once when you press reset:
    void setup() {
       // initialize serial communication at 9600 bits per second:
       Serial.begin(9600);
    
       // Define Input pins (from 5-position Rotary Switch)
       pinMode (1, INPUT);
       pinMode (3, INPUT);
       pinMode (4, INPUT);
       pinMode (7, INPUT);
    
    }
    
    void loop() {
    
       // MIDI Controllers should discard incoming MIDI messages.
       while (usbMIDI.read()) {
          // read & ignore incoming messages
       }
    
    
       // Determine the state of the 4 pins coming from the rotary switch
       Pin1State = digitalRead(1);
       Pin3State = digitalRead(3);
       Pin4State = digitalRead(4);
       Pin7State = digitalRead(7);
    
       // Deduce the "CC Set" selected on the Rotary Switch and store in variable "RotNewState";
       if (Pin3State == HIGH && Pin7State == HIGH) {
          RotNewState = 1;
       }
       if (Pin4State == HIGH && Pin7State == HIGH) {
          RotNewState = 2;
       }
       if (Pin4State == HIGH && Pin7State == LOW) {
          RotNewState = 3;
       }
       if (Pin1State == HIGH && Pin4State == HIGH) {
          RotNewState = 4;
       }
       if (Pin1State == HIGH && Pin4State == LOW) {
          RotNewState = 5;
       }
    
    
       // Serial.println(RotNewState); //was used to check function of determining rotary switch position -> worked fine.
    
    
    
       // update the ResponsiveAnalogRead object every loop
       for (int i = 0; i < A_PINS; i++) {
          analog[i].update();
          // if the repsonsive value has change, print out 'changed'
          if (analog[i].hasChanged()) {
             data[i] = analog[i].getValue() >> 3;
             if (data[i] != dataLag[i]) {
                dataLag[i] = data[i];
                usbMIDI.sendControlChange(CCID[RotNewState][i], data[i], 1);
             }
          }
       }
    }
    Keep at it . . . you're almost there !!

    Good luck & have fun !!

    Mark J Culross
    KD5RXT
    Last edited by kd5rxt-mark; 03-06-2021 at 03:16 AM. Reason: corrected wording

  7. #7
    Thank you, Mark! Everything works perfectly now.

    And I appreciate your helpful suggestions for formatting and posting code. It's so nice that there are folks like you and Pete willing to help solve issues like this.

    [One last thing in case others want to re-use any of this code. I had to make my variable "RotNewState" go from 0 to 4 (rather than from 1 to 5) in order for everything to work correctly when sending MIDI CC's.]

    Here is my final code with all corrections and formatting;
    Code:
    #include <Bounce.h>
    
    ///////////////////////////////////////////////////////////////////////////
    // define how many pots are active up to number of available analog inputs
    #define analogInputs 6
    //////////////////////////////////////////////////////////////////////////
    
    
    // define arrays for input values and lagged input values
    int inputAnalog[analogInputs];
    int iAlag[analogInputs];
    // define array of cc values
    int ccValue[analogInputs];
    // include the ResponsiveAnalogRead library
    #include <ResponsiveAnalogRead.h>
    
    // Define variables for Rotary Switch function (used to define one of 5 CC sets)
    int RotNewState;
    int Pin1State;
    int Pin3State;
    int Pin4State;
    int Pin7State;
    
    
    ///////////////////////////////////////////////////////////////////////////
    // define pins and cc codes
    const int A_PINS = 6;
    const int ANALOG_PINS[A_PINS] = {A0, A1, A2, A3, A4, A5};
    const int CC_SETS = 5;
    const int CCID[CC_SETS][A_PINS] = {{11, 11, 11, 1, 1, 11}, {11, 11, 1, 11, 1, 11}, {11, 1, 11, 11, 1 , 11}, {1, 11, 11, 11, 1, 11}, {11, 11, 11, 11, 1, 1}};
    ///  1's and 11's are for testing the controller only.  Update to desired CC's in final version 
    ///////////////////////////////////////////////////////////////////////////
    
    // //////// REFERENCE INFO /////////////////////////////////////////////
    // Four sliders left-to-right are A3, A2, A1, A0, A5. Footpedal is A4
    //0=bank, 1=mod, 2=Breath, 7=Vol, 8=Bal, 10=pan, 4=foot, 11=Expr, 21=Vib 64=pedal
    /////////////////////////////////////////////////////////////////////////
    
    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];
    
    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[] {
      ///////////////////////////////////////////////////////////////////////////
      {ANALOG_PINS[1], true},
      {ANALOG_PINS[2], true},
      {ANALOG_PINS[3], true},
      {ANALOG_PINS[4], true},
      {ANALOG_PINS[5], true},
      {ANALOG_PINS[0], true},
      ///////////////////////////////////////////////////////////////////////////
    };
    
    // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    
      // Define Input pins (from 5-position Rotary Switch)
      pinMode (1, INPUT);
      pinMode (3, INPUT);
      pinMode (4, INPUT);
      pinMode (7, INPUT);
    
    }
    
    void loop() {
    
      // MIDI Controllers should discard incoming MIDI messages.
      while (usbMIDI.read()) {
        // read & ignore incoming messages
      }
    
    
      // Determine the state of the 4 pins coming from the rotary switch
      Pin1State = digitalRead(1);
      Pin3State = digitalRead(3);
      Pin4State = digitalRead(4);
      Pin7State = digitalRead(7);
    
      // Deduce the "CC Set" selected on the Rotary Switch and store in variable "RotNewState";
      if (Pin3State == HIGH && Pin7State == HIGH) {
        RotNewState = 0;
      }
      if (Pin4State == HIGH && Pin7State == HIGH) {
        RotNewState = 1;
      }
      if (Pin4State == HIGH && Pin7State == LOW) {
        RotNewState = 2;
      }
      if (Pin1State == HIGH && Pin4State == HIGH) {
        RotNewState = 3;
      }
      if (Pin1State == HIGH && Pin4State == LOW) {
        RotNewState = 4;
      }
    
    
      // Serial.println(RotNewState); //was used to check function of determining rotary switch position -> worked fine.
    
    
    
      // update the ResponsiveAnalogRead object every loop
      for (int i = 0; i < A_PINS; i++) {
        analog[i].update();
        // if the repsonsive value has change, print out 'changed'
        if (analog[i].hasChanged()) {
          data[i] = analog[i].getValue() >> 3;
          if (data[i] != dataLag[i]) {
            dataLag[i] = data[i];
            usbMIDI.sendControlChange(CCID[RotNewState][i], data[i], 1);
          }
        }
      }
    }

  8. #8
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    298
    Glad I could help in a small way. Pete & others kindly helped me when I first got started with Teensy, so I try to pay my appreciation forward to others in a similar way whenever I can.

    Mark J Culross
    KD5RXT

  9. #9
    Junior Member
    Join Date
    Jul 2021
    Posts
    6

    Another newbie i'm afraid

    Hello my question is exactly the same as "Like to build stuff" how to change cc number after programing Teensy.

    I've made a 3 fader box with the code below but I would like CC numbers to be such that they can be changed by the user with a web ui or something similar.

    Any help would be gratefully received.

    Thanks Nick


    #include <Bounce.h>

    ///////////////////////////////////////////////////////////////////////////
    // define how many pots are active up to number of available analog inputs
    #define analogInputs 3
    //////////////////////////////////////////////////////////////////////////


    // define arrays for input values and lagged input values
    int inputAnalog[analogInputs];
    int iAlag[analogInputs];
    // define array of cc values
    int ccValue[analogInputs];
    // include the ResponsiveAnalogRead library
    #include <ResponsiveAnalogRead.h>


    ///////////////////////////////////////////////////////////////////////////
    // define pins and cc codes
    const int A_PINS = 3;
    const int ANALOG_PINS[A_PINS] = {A1, A2, A3};
    const int CCID[A_PINS] = {11, 1, 21};
    ///////////////////////////////////////////////////////////////////////////


    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];

    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[]{
    ///////////////////////////////////////////////////////////////////////////
    {ANALOG_PINS[0],true},
    {ANALOG_PINS[1],true},
    {ANALOG_PINS[2],true},
    ///////////////////////////////////////////////////////////////////////////
    };

    // the setup routine runs once when you press reset:
    void setup() {
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);
    }

    void loop(){
    // MIDI Controllers should discard incoming MIDI messages.
    while (usbMIDI.read()) {
    // read & ignore incoming messages
    }
    // update the ResponsiveAnalogRead object every loop
    for (int i=0;i<A_PINS;i++){
    analog[i].update();
    // if the repsonsive value has change, print out 'changed'
    if(analog[i].hasChanged()) {
    data[i] = analog[i].getValue()>>3;
    if (data[i] != dataLag[i]){
    dataLag[i] = data[i];
    usbMIDI.sendControlChange(CCID[i], data[i], 1);
    }
    }
    }
    }





    Quote Originally Posted by kd5rxt-mark View Post
    Glad I could help in a small way. Pete & others kindly helped me when I first got started with Teensy, so I try to pay my appreciation forward to others in a similar way whenever I can.

    Mark J Culross
    KD5RXT

  10. #10
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,753
    I've added some code which allows the CC number to be changed by using the serial monitor to enter the index of the CC to be changed and the CC number - e.g. 0 17
    It's not exactly a web UI but it shows the basics of what's required to change an entry in the array (including removing 'const' from the array declaration).
    The code compiles for a T3.2 but is untested.

    Code:
    #include <Bounce.h>
    
    ///////////////////////////////////////////////////////////////////////////
    // define how many pots are active up to number of available analog inputs
    #define analogInputs 3
    //////////////////////////////////////////////////////////////////////////
    
    
    // define arrays for input values and lagged input values
    int inputAnalog[analogInputs];
    int iAlag[analogInputs];
    // define array of cc values
    int ccValue[analogInputs];
    // include the ResponsiveAnalogRead library
    #include <ResponsiveAnalogRead.h>
    
    
    ///////////////////////////////////////////////////////////////////////////
    // define pins and cc codes
    const int A_PINS = 3;
    const int ANALOG_PINS[A_PINS] = {A1, A2, A3};
    //>>> Removed const
    int CCID[A_PINS] = {11, 1, 21};
    ///////////////////////////////////////////////////////////////////////////
    
    ///////////////////////////////////////////////////////////////////////////
    //>>>
    // declarations for string input from the serial monitor
    #define MAX_BUF 128
    char inbuf[MAX_BUF];
    // Index of next character to be stored in inbuf
    char b_idx = 0;
    // separators for strtok
    char sep[] = " ,";
    // token from strtok
    char *token;
    ///////////////////////////////////////////////////////////////////////////
    
    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];
    
    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[] {
    ///////////////////////////////////////////////////////////////////////////
      {ANALOG_PINS[0],true},
      {ANALOG_PINS[1],true},
      {ANALOG_PINS[2],true},
    ///////////////////////////////////////////////////////////////////////////
    };
    
    // the setup routine runs once when you press reset:
    void setup()
    {
    // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    }
    
    void loop()
    {
    // MIDI Controllers should discard incoming MIDI messages.
      while (usbMIDI.read()) {
    // read & ignore incoming messages
      }
    // update the ResponsiveAnalogRead object every loop
      for (int i=0; i<A_PINS; i++) {
        analog[i].update();
    // if the repsonsive value has change, print out 'changed'
        if(analog[i].hasChanged()) {
          data[i] = analog[i].getValue()>>3;
          if (data[i] != dataLag[i]) {
            dataLag[i] = data[i];
            usbMIDI.sendControlChange(CCID[i], data[i], 1);
          }
        }
      }
    ///////////////////////////////////////////////////////////////////////////
    //>>>
    // Handle input from serial monitor
      while(Serial.available() > 0) {
        char c;
        c = Serial.read();
        if(c != '\n') {
          inbuf[b_idx++] = c;
          if(b_idx >= MAX_BUF) {
            // The line is WAY too long. Throw it away
            b_idx = 0;
            continue;
          }
          continue;
        }
        // We have a linefeed. Parse the command
        // The line should be just two numbers
        // (any more than that will be ignored).
        // The first number is the index of the CC
        // to be changed and therefore must be positive
        // and less than A_PINS
        // The second number is the new value of the
        // CC number and therefore the number must be
        // positive and less than 128.
        // replace the linefeed with NULL
        inbuf[--b_idx] = 0;
        // reset the index ready for the next line
        b_idx = 0;
        // Get the first number
        token = strtok(inbuf,sep);
        if(token == NULL) {
          Serial.printf("ERROR: Input string is empty\n");
          break;
        }
        int cc_idx = atoi(token);
        // Is it valid?
        if(cc_idx < 0 || cc_idx >= A_PINS) {
          Serial.printf("ERROR: Invalid CC index '%d'\n",cc_idx);
          break;
        }
    
        // Now get the CC number
        token = strtok(inbuf,sep);
        if(token == NULL) {
          Serial.printf("ERROR: Second number is missing\n");
          break;
        }
        int cc_num = atoi(token);
        // Is the CC number valid?
        if(cc_num < 0 || cc_num > 127) {
          Serial.printf("ERROR: Invalid CC number '%d'\n",cc_num);
          break;
        }
        // Store the new CC number
        CCID[cc_idx] = cc_num;
      }
    ///////////////////////////////////////////////////////////////////////////
    }
    Pete

  11. #11
    Junior Member
    Join Date
    Jul 2021
    Posts
    6
    Hello Pete

    That is very generous of you to write that code for me.

    The sort of GUI I had in mind was one like this which I think relies on sys ex commands.

    Click image for larger version. 

Name:	faderbox gui.jpg 
Views:	29 
Size:	31.4 KB 
ID:	25337

    Can my sketch be modified to respond to commands from this Gui?

    I've tried to attach the code from this HTML page.

    Thanks again for your help.

    Nick

    Quote Originally Posted by el_supremo View Post
    I've added some code which allows the CC number to be changed by using the serial monitor to enter the index of the CC to be changed and the CC number - e.g. 0 17
    It's not exactly a web UI but it shows the basics of what's required to change an entry in the array (including removing 'const' from the array declaration).
    The code compiles for a T3.2 but is untested.

    Code:
    #include <Bounce.h>
    
    ///////////////////////////////////////////////////////////////////////////
    // define how many pots are active up to number of available analog inputs
    #define analogInputs 3
    //////////////////////////////////////////////////////////////////////////
    
    
    // define arrays for input values and lagged input values
    int inputAnalog[analogInputs];
    int iAlag[analogInputs];
    // define array of cc values
    int ccValue[analogInputs];
    // include the ResponsiveAnalogRead library
    #include <ResponsiveAnalogRead.h>
    
    
    ///////////////////////////////////////////////////////////////////////////
    // define pins and cc codes
    const int A_PINS = 3;
    const int ANALOG_PINS[A_PINS] = {A1, A2, A3};
    //>>> Removed const
    int CCID[A_PINS] = {11, 1, 21};
    ///////////////////////////////////////////////////////////////////////////
    
    ///////////////////////////////////////////////////////////////////////////
    //>>>
    // declarations for string input from the serial monitor
    #define MAX_BUF 128
    char inbuf[MAX_BUF];
    // Index of next character to be stored in inbuf
    char b_idx = 0;
    // separators for strtok
    char sep[] = " ,";
    // token from strtok
    char *token;
    ///////////////////////////////////////////////////////////////////////////
    
    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS];
    
    // ititialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[] {
    ///////////////////////////////////////////////////////////////////////////
      {ANALOG_PINS[0],true},
      {ANALOG_PINS[1],true},
      {ANALOG_PINS[2],true},
    ///////////////////////////////////////////////////////////////////////////
    };
    
    // the setup routine runs once when you press reset:
    void setup()
    {
    // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    }
    
    void loop()
    {
    // MIDI Controllers should discard incoming MIDI messages.
      while (usbMIDI.read()) {
    // read & ignore incoming messages
      }
    // update the ResponsiveAnalogRead object every loop
      for (int i=0; i<A_PINS; i++) {
        analog[i].update();
    // if the repsonsive value has change, print out 'changed'
        if(analog[i].hasChanged()) {
          data[i] = analog[i].getValue()>>3;
          if (data[i] != dataLag[i]) {
            dataLag[i] = data[i];
            usbMIDI.sendControlChange(CCID[i], data[i], 1);
          }
        }
      }
    ///////////////////////////////////////////////////////////////////////////
    //>>>
    // Handle input from serial monitor
      while(Serial.available() > 0) {
        char c;
        c = Serial.read();
        if(c != '\n') {
          inbuf[b_idx++] = c;
          if(b_idx >= MAX_BUF) {
            // The line is WAY too long. Throw it away
            b_idx = 0;
            continue;
          }
          continue;
        }
        // We have a linefeed. Parse the command
        // The line should be just two numbers
        // (any more than that will be ignored).
        // The first number is the index of the CC
        // to be changed and therefore must be positive
        // and less than A_PINS
        // The second number is the new value of the
        // CC number and therefore the number must be
        // positive and less than 128.
        // replace the linefeed with NULL
        inbuf[--b_idx] = 0;
        // reset the index ready for the next line
        b_idx = 0;
        // Get the first number
        token = strtok(inbuf,sep);
        if(token == NULL) {
          Serial.printf("ERROR: Input string is empty\n");
          break;
        }
        int cc_idx = atoi(token);
        // Is it valid?
        if(cc_idx < 0 || cc_idx >= A_PINS) {
          Serial.printf("ERROR: Invalid CC index '%d'\n",cc_idx);
          break;
        }
    
        // Now get the CC number
        token = strtok(inbuf,sep);
        if(token == NULL) {
          Serial.printf("ERROR: Second number is missing\n");
          break;
        }
        int cc_num = atoi(token);
        // Is the CC number valid?
        if(cc_num < 0 || cc_num > 127) {
          Serial.printf("ERROR: Invalid CC number '%d'\n",cc_num);
          break;
        }
        // Store the new CC number
        CCID[cc_idx] = cc_num;
      }
    ///////////////////////////////////////////////////////////////////////////
    }
    Pete
    Attached Files Attached Files

  12. #12
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,753
    Sorry, I can't help with that. I've done practically nothing with Teensy related to interacting with a web page.

    Pete

  13. #13
    Junior Member
    Join Date
    Jul 2021
    Posts
    6
    Hi Pete
    I'm sorry I'm pretty clueless about this.

    Using the code you kindly wrote for me can I write something in a terminal window and send it to the teensy? to change the CC settings.

    Thanks Nick




    Quote Originally Posted by el_supremo View Post
    Sorry, I can't help with that. I've done practically nothing with Teensy related to interacting with a web page.

    Pete

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,110
    Quote Originally Posted by n.tracker View Post
    Hi Pete
    I'm sorry I'm pretty clueless about this.

    Using the code you kindly wrote for me can I write something in a terminal window and send it to the teensy? to change the CC settings.

    Thanks Nick
    Looking at the code this:
    Code:
    // Handle input from serial monitor
      while(Serial.available() > 0) {
    Will take Terminal or Serial Monitor input from the USB Serial port and act on it to change the values as indicated.

  15. #15
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,753
    To expand a bit on what @defragster wrote: When that code is run, the USB port on the Teensy will appear as a COM port on the PC. You don't have to have the serial monitor on that COM port. A terminal emulator will work just as well as long as it is configured to add a linefeed at the end of each line. If you can write your web UI to talk to the COM port, it will work as well.

    Pete

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •