Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 3 FirstFirst 1 2 3
Results 51 to 69 of 69

Thread: midi controller

  1. #51
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Back to square A, I don't know how to add pointometers to the buttons sketch (which is the only one that works with the chain selector). I would be happy to forget the lights for now and just add pots to the buttons.

  2. #52
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,165
    I finally get what the chain selector is after a quick search.

    What you need is another array that holds what value is sent with the CC message instead of just off and on.

    Then you can configure buttons on the same CC number but different values.

    I'll need some time at a compiler and I'm not near one currently.

    The other remaining issue is whether they latch or just fire the CC message when pressed and there is no OFF value sent and whether this is the same for all buttons or the behaviour of some buttons is still on-when-pressed or latching.

  3. #53
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Yea that makes sense, the other stuff is over my head.

  4. #54
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,165
    So each and every button sends a CC number and value, always the same and only on press and not on release?

    So not latching and not ON when pressed and OFF when released. All buttons. Correct?

  5. #55
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,165
    Code:
    /* bespoke code example
    
       By Leif Oddson
       https://forum.pjrc.com/threads/56935-midi-controller
    
     
    */
    
    
    //************LIBRARIES USED**************
    // include the ResponsiveAnalogRead library for analog smoothing
    #include <ResponsiveAnalogRead.h>
    // include the Bounce library for 'de-bouncing' switches -- removing electrical chatter as contacts settle
    #include <Bounce.h> 
    //usbMIDI.h library is added automatically when code is compiled as a MIDI device
    
    // ******CONSTANT VALUES******** 
    // customize code behaviour here!
    const int channel = 1; // MIDI channel
    const int A_PINS = 6; // number of Analog PINS
    const int D_PINS = 12; // number of Digital PINS
    
    // define the pins you want to use and the CC ID numbers on which to send them..
    const int ANALOG_PINS[A_PINS] = {A0,A1,A2,A3,A4,A5};
    const int CCID[A_PINS] = {21,22,23,24,25,26};
    
    // define the pins and notes for digital events
    const int DIGITAL_PINS[D_PINS] = {0,1,2,3,4,5,6,7,8,9,10,11};
    const int CCchainID[D_PINS] = {60,60,60,60,60,60,70,70,70,70,70,70};
    const int CCchainVal[D_PINS] = {0,25,50,75,100,127,0,25,50,75,100,127};
    const int BOUNCE_TIME = 7; // 5 ms is usually sufficient
    const boolean toggled = true;
    
    
    //******VARIABLES***********
    // a data array and a lagged copy to tell when MIDI changes are required
    byte data[A_PINS];
    byte dataLag[A_PINS]; // when lag and new are not the same then update MIDI CC value
    
    
    //************INITIALIZE LIBRARY OBJECTS**************
    // not sure if there is a better way... some way run a setup loop on global array??
    // use comment tags to comment out unused portions of array definitions
    
    // initialize the ReponsiveAnalogRead objects
    ResponsiveAnalogRead analog[]{
      {ANALOG_PINS[0],true},
      {ANALOG_PINS[1],true},
      {ANALOG_PINS[2],true},
      {ANALOG_PINS[3],true},
      {ANALOG_PINS[4],true},
      {ANALOG_PINS[5],true}/*,
      {ANALOG_PINS[6],true},
      {ANALOG_PINS[7],true},*/
    }; 
    
    // initialize the bounce objects 
    Bounce digital[] =   {
      Bounce(DIGITAL_PINS[0],BOUNCE_TIME), 
      Bounce(DIGITAL_PINS[1], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[2], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[3], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[4], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[5], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[6], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[7], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[8], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[9], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[10], BOUNCE_TIME),
      Bounce(DIGITAL_PINS[11], BOUNCE_TIME)
    }; 
    
    //************SETUP**************
    void setup() {
    // loop to configure input pins and internal pullup resisters for digital section
      for (int i=0;i<D_PINS;i++){
        pinMode(DIGITAL_PINS[i], INPUT_PULLUP);
      }
    }
    
    //************LOOP**************
    void loop() {
      // getAnalogData(); // commented out to avoid garbage MIDI until you are ready with the analog voltage dividers
      getDigitalData();
      while (usbMIDI.read()) {
         // controllers must call .read() to keep the queue clear even if they are not responding to MIDI
      }
    }
    
    
    //************ANALOG SECTION**************   uncomment call from loop to make active when you are ready!
    void getAnalogData(){  
      for (int i=0;i<A_PINS;i++){
        // update the ResponsiveAnalogRead object every loop
        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], channel);
          }
        }
      }
    }
    
    
    
    //************DIGITAL SECTION**************
    void getDigitalData(){
      for (int i=0;i<D_PINS;i++){
      digital[i].update();
        if (digital[i].fallingEdge()) {
          usbMIDI.sendControlChange(CCchainID[i],CCchainVal[i],channel);
        }
      }
    }
    Here's an example that compiled but I don't have a Teensy handy to even do breadboard testing.

    It's currently configured to support two sets of six buttons where each chain is a set of buttons and the second array holds the map points for the chain and the first array holds the two different CC numbers for the two chains.

  6. #56
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    For the lights? I would think press on latch. then unlatch when another button is pressed. The software seams to work with just note on note off. only problem is it also plays notes on the instruments as well. I'll have to try the code tomorrow. have a goodnight.

  7. #57
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Well it loads but, same as others, it only registers the first button on the chain selector. Only difference is before when I hit the second button while holding down the first it would change the first, now it does nothing. The first button says cc#60 When I use the buttons sketch it says note C3 #48 to F3 #53.
    Last edited by edrummer; 07-24-2019 at 03:49 PM.

  8. #58
    Junior Member
    Join Date
    Sep 2018
    Posts
    6
    Author of the MIDI Controller library here.

    Going back to the original post, to use multiple potentiometers and buttons, you would use something like this:

    Code:
    #include <MIDI_Controller.h>
    
    AnalogCC faders[] = {
        {A0, MIDI_CC::Channel_Volume, 1}, // Create a new instance of class 'AnalogCC' on pin A0, controller number 0x07 (channel volume), on MIDI channel 1.
        {A1, MIDI_CC::Channel_Volume, 2},
        {A2, MIDI_CC::Channel_Volume, 3},
        {A3, MIDI_CC::Channel_Volume, 4},
        {A4, MIDI_CC::Channel_Volume, 5},
        {A5, MIDI_CC::Channel_Volume, 6},
        {A6, MIDI_CC::Channel_Volume, 7},
        {A7, MIDI_CC::Channel_Volume, 8},
        // ...
    };
    
    DigitalCC buttons[] = {
        {2, 0x20, 1}, // Create a new instance of class 'DigitalCC' on pin 2, controller number 0x20, on MIDI channel 1.
        {3, 0x21, 1},
        {4, 0x22, 1},
        // ...
    }
    
    void setup() { }
    
    void loop() { // Refresh all inputs
        MIDI_Controller.refresh();
    }
    If it still doesn't work, could you please post the exact code you tried, settings used in the IDE, and the exact error messages. This will help me to fix the library if necessary.

    Thanks,
    Pieter

  9. #59
    Junior Member
    Join Date
    Sep 2018
    Posts
    6
    Thank you. I missed a semicolon right before "void setup () ..." (I posted this on mobile).

    If you add the semicolon after the bracket } before "void setup", does it compile?

  10. #60
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    This is making things to confusing, I have my breadboard set up for Odsons code, 6 buttons and 6 pots, If you want to contribute read the posts and understand where we are now or send something to try with that setup

  11. #61
    Junior Member
    Join Date
    Sep 2018
    Posts
    6
    The code I posted can be used with that setup.

    If you want the exact code, try this:

    Code:
    #include <MIDI_Controller.h>
    
    AnalogCC potentiometers[] = {
        {A0, MIDI_CC::Channel_Volume, 1}, // Create a new instance of class 'AnalogCC' on pin A0, controller number 0x07 (channel volume), on MIDI channel 1.
        {A1, MIDI_CC::Channel_Volume, 2},
        {A2, MIDI_CC::Channel_Volume, 3},
        {A3, MIDI_CC::Channel_Volume, 4},
        {A4, MIDI_CC::Channel_Volume, 5},
        {A5, MIDI_CC::Channel_Volume, 6},
    };
    
    DigitalCC buttons[] = {
        {2, 0x20, 1}, // Create a new instance of class 'DigitalCC' on pin 2, controller number 0x20, on MIDI channel 1.
        {3, 0x21, 1},
        {4, 0x22, 1},
        {5, 0x23, 1},
        {6, 0x24, 1},
        {7, 0x25, 1},
    };
    
    void setup() { }
    
    void loop() { // Refresh all inputs
        MIDI_Controller.refresh();
    }
    This code expects 6 potentiometers on pins A0-A5, and 6 switches between pins 2-7 and ground. If you have them connected to different pins, just change them in the code.

    The switches are debounced, and potentiometers are filtered.

  12. #62
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    It doesn't work with Ableton, nothing maps.

  13. #63
    Junior Member
    Join Date
    Sep 2018
    Posts
    6
    I'm sorry, without more information, I cannot possibly help you.

    Does it not send the correct MIDI messages, or does it not send any messages at all?

  14. #64
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,165
    Quote Originally Posted by edrummer View Post
    Well it loads but, same as others, it only registers the first button on the chain selector. Only difference is before when I hit the second button while holding down the first it would change the first, now it does nothing. The first button says cc#60 When I use the buttons sketch it says note C3 #48 to F3 #53.
    You have to configure it... and you're going to have to start trying to read the code.

    Forget the lights for now.

    My code should let you configure any number of pins to send any arbitrary CC message when buttons cofigured to pull the pin to ground when pressed.

    But you need to configure it and Abelton to work together and that assuming I've even figured out what you are trying to do (or trying to get me to do for you).

  15. #65
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,165
    Code:
      //************LOOP**************
    void loop() {
      // getAnalogData(); // commented out to avoid garbage MIDI until you are ready with the analog voltage dividers
      getDigitalData();
      while (usbMIDI.read()) {
         // controllers must call .read() to keep the queue clear even if they are not responding to MIDI
      }
    }
    ....and remove the two slashes to make the analog section work once you've sorted out the buttons. But only with the pot's in place.

  16. #66
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    you lost me, I don't know which code you're referring to or what to do with that snippet above

  17. #67
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    Could you at least just show me how to add 6 pots to this code?
    Code:
    /* Buttons to USB MIDI Example
    
       You must select MIDI from the "Tools > USB Type" menu
    
       To view the raw MIDI data on Linux: aseqdump -p "Teensy MIDI"
    
       This example code is in the public domain.
    */
    
    #include <Bounce.h>
    
    // the MIDI channel number to send messages
    const int channel = 1;
    
    // Create Bounce objects for each button.  The Bounce object
    // automatically deals with contact chatter or "bounce", and
    // it makes detecting changes very simple.
    Bounce button0 = Bounce(0, 5);
    Bounce button1 = Bounce(1, 5);  // 5 = 5 ms debounce time
    Bounce button2 = Bounce(2, 5);  // which is appropriate for good
    Bounce button3 = Bounce(3, 5);  // quality mechanical pushbuttons
    Bounce button4 = Bounce(4, 5);
    Bounce button5 = Bounce(5, 5);  // if a button is too "sensitive"
    Bounce button6 = Bounce(6, 5);  // to rapid touch, you can
    Bounce button7 = Bounce(7, 5);  // increase this time.
    Bounce button8 = Bounce(8, 5);
    Bounce button9 = Bounce(9, 5);
    Bounce button10 = Bounce(10, 5);
    Bounce button11 = Bounce(11, 5);
    
    void setup() {
      // Configure the pins for input mode with pullup resistors.
      // The pushbuttons connect from each pin to ground.  When
      // the button is pressed, the pin reads LOW because the button
      // shorts it to ground.  When released, the pin reads HIGH
      // because the pullup resistor connects to +5 volts inside
      // the chip.  LOW for "on", and HIGH for "off" may seem
      // backwards, but using the on-chip pullup resistors is very
      // convenient.  The scheme is called "active low", and it's
      // very commonly used in electronics... so much that the chip
      // has built-in pullup resistors!
      pinMode(0, INPUT_PULLUP);
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      pinMode(4, INPUT_PULLUP);
      pinMode(5, INPUT_PULLUP);
      pinMode(6, INPUT_PULLUP);  // Teensy++ 2.0 LED, may need 1k resistor pullup
      pinMode(7, INPUT_PULLUP);
      pinMode(8, INPUT_PULLUP);
      pinMode(9, INPUT_PULLUP);
      pinMode(10, INPUT_PULLUP);
      pinMode(11, INPUT_PULLUP); // Teensy 2.0 LED, may need 1k resistor pullup
    }
    
    void loop() {
      // Update all the buttons.  There should not be any long
      // delays in loop(), so this runs repetitively at a rate
      // faster than the buttons could be pressed and released.
      button0.update();
      button1.update();
      button2.update();
      button3.update();
      button4.update();
      button5.update();
      button6.update();
      button7.update();
      button8.update();
      button9.update();
      button10.update();
      button11.update();
    
      // Check each button for "falling" edge.
      // Send a MIDI Note On message when each button presses
      // Update the Joystick buttons only upon changes.
      // falling = high (not pressed - voltage from pullup resistor)
      //           to low (pressed - button connects pin to ground)
      if (button0.fallingEdge()) {
        usbMIDI.sendNoteOn(60, 99, channel);  // 60 = C4
      }
      if (button1.fallingEdge()) {
        usbMIDI.sendNoteOn(61, 99, channel);  // 61 = C#4
      }
      if (button2.fallingEdge()) {
        usbMIDI.sendNoteOn(62, 99, channel);  // 62 = D4
      }
      if (button3.fallingEdge()) {
        usbMIDI.sendNoteOn(63, 99, channel);  // 63 = D#4
      }
      if (button4.fallingEdge()) {
        usbMIDI.sendNoteOn(64, 99, channel);  // 64 = E4
      }
      if (button5.fallingEdge()) {
        usbMIDI.sendNoteOn(65, 99, channel);  // 65 = F4
      }
      if (button6.fallingEdge()) {
        usbMIDI.sendNoteOn(66, 99, channel);  // 66 = F#4
      }
      if (button7.fallingEdge()) {
        usbMIDI.sendNoteOn(67, 99, channel);  // 67 = G4
      }
      if (button8.fallingEdge()) {
        usbMIDI.sendNoteOn(68, 99, channel);  // 68 = G#4
      }
      if (button9.fallingEdge()) {
        usbMIDI.sendNoteOn(69, 99, channel);  // 69 = A5
      }
      if (button10.fallingEdge()) {
        usbMIDI.sendNoteOn(70, 99, channel);  // 70 = A#5
      }
      if (button11.fallingEdge()) {
        usbMIDI.sendNoteOn(71, 99, channel);  // 71 = B5
      }
    
      // Check each button for "rising" edge
      // Send a MIDI Note Off message when each button releases
      // For many types of projects, you only care when the button
      // is pressed and the release isn't needed.
      // rising = low (pressed - button connects pin to ground)
      //          to high (not pressed - voltage from pullup resistor)
      if (button0.risingEdge()) {
        usbMIDI.sendNoteOff(60, 0, channel);  // 60 = C4
      }
      if (button1.risingEdge()) {
        usbMIDI.sendNoteOff(61, 0, channel);  // 61 = C#4
      }
      if (button2.risingEdge()) {
        usbMIDI.sendNoteOff(62, 0, channel);  // 62 = D4
      }
      if (button3.risingEdge()) {
        usbMIDI.sendNoteOff(63, 0, channel);  // 63 = D#4
      }
      if (button4.risingEdge()) {
        usbMIDI.sendNoteOff(64, 0, channel);  // 64 = E4
      }
      if (button5.risingEdge()) {
        usbMIDI.sendNoteOff(65, 0, channel);  // 65 = F4
      }
      if (button6.risingEdge()) {
        usbMIDI.sendNoteOff(66, 0, channel);  // 66 = F#4
      }
      if (button7.risingEdge()) {
        usbMIDI.sendNoteOff(67, 0, channel);  // 67 = G4
      }
      if (button8.risingEdge()) {
        usbMIDI.sendNoteOff(68, 0, channel);  // 68 = G#4
      }
      if (button9.risingEdge()) {
        usbMIDI.sendNoteOff(69, 0, channel);  // 69 = A5
      }
      if (button10.risingEdge()) {
        usbMIDI.sendNoteOff(70, 0, channel);  // 70 = A#5
      }
      if (button11.risingEdge()) {
        usbMIDI.sendNoteOff(71, 0, channel);  // 71 = B5
      }
    
      // MIDI Controllers should discard incoming MIDI messages.
      // http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
      while (usbMIDI.read()) {
        // ignore incoming messages
      }
    }

  18. #68
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,165
    If I add pots to that code it will do what my original example code already does.

    My code at post 55 should work when configured. Unless I still don't understand chains and controlling with CC values.

    I don't know that you are up to programming with loops and arrays yet.

  19. #69
    Senior Member
    Join Date
    Feb 2018
    Posts
    154
    The code at #55 doesn't work with the chain selector. as I tried to explain in post #57. it only sends cc 60. I don't know what makes it work or where it differs from your code but the buttons code in #67 is the only one I've found that works with the chain selector and I've been searching for days. If I could just add some pots to that sketch I could get up and running. If you know how to add an analog section Please show me. I've been trying this also for days. You're right I am not up to programming with loops and arrays.

Posting Permissions

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