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

Thread: Teensy Midi Controller Project Advice/Journal

  1. #26
    Yes that sounds right. There are many extraeneous pieces in the initial code that I think would make sense to be removed. I am still re reading everything and making sense of what is happening. It is starting to piece together in my mind.

    What we really need is for the timer to load the bank with 5 unique CCs. And have 5 sets of unique CC codes. So in result I could Have 25 presets.

    I could use this very well I think.

  2. #27
    So button 0 is help for 2 seconds or even for one second it loads the bank with CC 1,2,3,4 and 5.
    hold button 1 and it loads the bank with 6,7,8,9,and 10 and so on right?

  3. #28
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    Oh... and they don't have to toggle OFF and ON. It's easier if they don't

    We can send the same CC message every time if the DAW is treating CC messages more like program changes.

    Or we can toggle the accompanying value between OFF (0) and ON (127).

  4. #29
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    Quote Originally Posted by briandtinker View Post
    So button 0 is help for 2 seconds or even for one second it loads the bank with CC 1,2,3,4 and 5.
    hold button 1 and it loads the bank with 6,7,8,9,and 10 and so on right?
    Yeah something like that. The numbers are in arrays and can be whatever you like but there would be five sets of them.

    No clue if that's anything that would be beneficial.

    At that point LEDs or a 7-segment display to say which set is active might be in order.

  5. #30
    Ok so that is good for the bank system.
    the thought to add onto this would be individual controls per preset. so another bank of 5-10 switches.

    The array for these switches and the LED text for printout is loaded when the specific bank number is selected.

    So example if we are in bank 3 and select switch 2 that will be CC 12 andwhen pressed can load switches 6-10 with led printouts and codes in an array.

  6. #31
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    I just meant five banks of five might get confusing if you can't tell which bank you've selected.

    An LED above the switch could tell the user which bank is active.
    Another (of a different color) could do the same for which switches are active assuming you have toggled behaviour and switches can be 'off' or 'on' independently.



    Let's leave off on displaying the info back to the user for now...

  7. #32
    yeah leds would be nice. i can see this controller being set up very specifically for what I would need it for.

    Can you program multiple events for when a switch is pressed? i.e. send a CC code and also load the array?

  8. #33
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    Quote Originally Posted by oddson View Post
    I suggest we take the A/B bank example from my first post here and change it as follows:

    Note on/off becomes CC 127/0
    Send CC only on releasing the [s]witch (risingEdge) and only if timer is below 2000 mS
    Reset timer on fallingEdge - start counting the timer only when a switch is down
    If timer > 2000 mS when risingEdge is detected then toggle mode/bank and do not send CC for the button pressed

    FYI - with this scheme we could make it so it changes mode if ANY button is held for >2000ms.

    If this sounds OK to you let me know and I'll make a version with these changes later tonight.
    Sorry I guess I forgot about your project the other day.

    Here's a version that changes mode if any button is held for more than two seconds.
    Code:
    #include <Bounce.h>
    
    //**********CONSTANTS**********
    const int BOUNCE_TIME = 25; // fine tune if the buttons need more/less time
    const int LEDPIN = 13; // Upper BANK indicator LED 
    const int DIGITAL_PINS = 5; // size of the PINS array (no longer includes toggle button!)
    const int PINS[DIGITAL_PINS] = {0,1,2,3,4}; // set pin numbers of swtiches
    const int channel = 1;
    const int ONvalue = 127; // arbitrary 'on' value for D2 of CC message
    const int OFFvalue = 0; // arbitrary 'off' value for D2 of CC message
    const int resetThreshold = 2000; /// mS hold to change bank
    
    const byte CC[][DIGITAL_PINS] = {
      {60,61,62,63,64},
      {80,81,82,83,84},
    }; // this is the banks by switches matrix of CC values for the bank system
    
    //**********VARIABLES/LIBRARY OBJECTS**********
    int bank = 0; // this is the bank variable to be toggled
    boolean CCstate[DIGITAL_PINS]; // array of current CC on/off toggle state
    boolean timerOn; // timer toggle memory tracks whether a new fallingEdge was heard since the last rising; used in bank switching
    
    Bounce btn[] = {
      Bounce(PINS[0], BOUNCE_TIME),
      Bounce(PINS[1], BOUNCE_TIME),
      Bounce(PINS[2], BOUNCE_TIME),
      Bounce(PINS[3], BOUNCE_TIME),
      Bounce(PINS[4], BOUNCE_TIME),
      };
    elapsedMillis toggleReset; // mS clock counter to reset on contact/risgingEdge()
    
    //**********SETUP**********
    void setup() {
      //Serial.begin(9600);
      for (int i = 0;i<DIGITAL_PINS;i++){
        pinMode(PINS[i], INPUT_PULLUP);
      }
      pinMode(LEDPIN, OUTPUT);
    }
    
    //**********LOOP**********
    void loop() {
      for (int i = 0;i<DIGITAL_PINS;i++){ // loop through each object in the BOUNCE arrray for the note switches (no longer includes TOGGLE)
        btn[i].update();
        if (btn[i].fallingEdge()) {
          timerOn = true ;
          toggleReset = 0;
        }
        if (btn[i].risingEdge()) {
          if(toggleReset<resetThreshold){
            if (CCstate[i]){ 
              usbMIDI.sendControlChange(CC[bank][i], ONvalue, channel); 
            }else{
              usbMIDI.sendControlChange(CC[bank][i], OFFvalue, channel);  
            }
            CCstate[i] = !CCstate[i] ; //toggle state memory
            timerOn = false ; //turn off timer (resets each cycle)
          }
        }
        if (timerOn && (toggleReset>resetThreshold)){
          toggleReset = 0;
          bank = !bank;
          digitalWrite(LEDPIN, bank); // visual feedback for ALT bank selection
        }
      }
    }
    It toggles the LED as well as the state (currently set to the internal pin but you can power an external LED on your front-panel to indicate you are in alternate mode).

    If you keep holding it keeps toggling -- which is good I think since if you accidentally hold too long you just keep holding to correct and release when the LED is in the correct state.

    As indicated this one only sends the CC messages after you release and then toggles the second byte of data to OFF and ON (0 and 127 as the code is now).

  9. #34
    Quote Originally Posted by oddson View Post
    Sorry I guess I forgot about your project the other day.

    Here's a version that changes mode if any button is held for more than two seconds.
    Code:
    #include <Bounce.h>
    
    //**********CONSTANTS**********
    const int BOUNCE_TIME = 25; // fine tune if the buttons need more/less time
    const int LEDPIN = 13; // Upper BANK indicator LED 
    const int DIGITAL_PINS = 5; // size of the PINS array (no longer includes toggle button!)
    const int PINS[DIGITAL_PINS] = {0,1,2,3,4}; // set pin numbers of swtiches
    const int channel = 1;
    const int ONvalue = 127; // arbitrary 'on' value for D2 of CC message
    const int OFFvalue = 0; // arbitrary 'off' value for D2 of CC message
    const int resetThreshold = 2000; /// mS hold to change bank
    
    const byte CC[][DIGITAL_PINS] = {
      {60,61,62,63,64},
      {80,81,82,83,84},
    }; // this is the banks by switches matrix of CC values for the bank system
    
    //**********VARIABLES/LIBRARY OBJECTS**********
    int bank = 0; // this is the bank variable to be toggled
    boolean CCstate[DIGITAL_PINS]; // array of current CC on/off toggle state
    boolean timerOn; // timer toggle memory tracks whether a new fallingEdge was heard since the last rising; used in bank switching
    
    Bounce btn[] = {
      Bounce(PINS[0], BOUNCE_TIME),
      Bounce(PINS[1], BOUNCE_TIME),
      Bounce(PINS[2], BOUNCE_TIME),
      Bounce(PINS[3], BOUNCE_TIME),
      Bounce(PINS[4], BOUNCE_TIME),
      };
    elapsedMillis toggleReset; // mS clock counter to reset on contact/risgingEdge()
    
    //**********SETUP**********
    void setup() {
      //Serial.begin(9600);
      for (int i = 0;i<DIGITAL_PINS;i++){
        pinMode(PINS[i], INPUT_PULLUP);
      }
      pinMode(LEDPIN, OUTPUT);
    }
    
    //**********LOOP**********
    void loop() {
      for (int i = 0;i<DIGITAL_PINS;i++){ // loop through each object in the BOUNCE arrray for the note switches (no longer includes TOGGLE)
        btn[i].update();
        if (btn[i].fallingEdge()) {
          timerOn = true ;
          toggleReset = 0;
        }
        if (btn[i].risingEdge()) {
          if(toggleReset<resetThreshold){
            if (CCstate[i]){ 
              usbMIDI.sendControlChange(CC[bank][i], ONvalue, channel); 
            }else{
              usbMIDI.sendControlChange(CC[bank][i], OFFvalue, channel);  
            }
            CCstate[i] = !CCstate[i] ; //toggle state memory
            timerOn = false ; //turn off timer (resets each cycle)
          }
        }
        if (timerOn && (toggleReset>resetThreshold)){
          toggleReset = 0;
          bank = !bank;
          digitalWrite(LEDPIN, bank); // visual feedback for ALT bank selection
        }
      }
    }
    It toggles the LED as well as the state (currently set to the internal pin but you can power an external LED on your front-panel to indicate you are in alternate mode).

    If you keep holding it keeps toggling -- which is good I think since if you accidentally hold too long you just keep holding to correct and release when the LED is in the correct state.

    As indicated this one only sends the CC messages after you release and then toggles the second byte of data to OFF and ON (0 and 127 as the code is now).

    Ok so understanding the way you wrote it in mode when when I hit and release switch 0 it will send CC 60 and then in mode 2 when i hit switch 0 it will send code 80.

    Upon toggling mode with long press an LED will show the alternate mode.

    Questions:

    1) which switch is the long press to activate the toggled mode?
    2) can there be more than one alternate bank? i.e. array loaded depending on which switch is the long hold toggle activator?

  10. #35
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    1) Right now they all work as mode switch. If any fallingEdge() (contact) is detected the timer variable is set and the counter starts incrementing (technically the reset that would otherwise happen every cycle is bypassed and so the elapsedMillis variable is allowed to increment). If there is no risingEdge() (release) detected after 2000 mS (the value in resetThreshold) then the mode is toggled and the counter reset. If a risingEdge() is detected prior to that amount of time elapsing then the CC message for that switch in the current mode is sent.

    2) Yes... it would be fairly simple to make bank an integer and to set it's value based on which switch triggered the fallingEdge that started the counter. And if you want feedback the simplest would be to make LEDPIN into an array and use the bank value as an index to track which should be on.

  11. #36
    Quote Originally Posted by oddson View Post
    1) Right now they all work as mode switch. If any fallingEdge() (contact) is detected the timer variable is set and the counter starts incrementing (technically the reset that would otherwise happen every cycle is bypassed and so the elapsedMillis variable is allowed to increment). If there is no risingEdge() (release) detected after 2000 mS (the value in resetThreshold) then the mode is toggled and the counter reset. If a risingEdge() is detected prior to that amount of time elapsing then the CC message for that switch in the current mode is sent.

    2) Yes... it would be fairly simple to make bank an integer and to set it's value based on which switch triggered the fallingEdge that started the counter. And if you want feedback the simplest would be to make LEDPIN into an array and use the bank value as an index to track which should be on.
    ok this actually sounds amazingly flexible because it would give me very quick access to 25 different codes

  12. #37
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    It will be Wednesday next week before I'll have time at my Teensy setup so until then coding will be guesswork on a text editor.

    But I believe the five-mode option is as simple as expanding the CC array to be five by five and to set bank to 'i' instead of toggling it between 1 and 0 with bank = !bank;

    Now it will pick the mode based on the index of the switch you are holding down instead of just toggling; with very little coding change.

    Code:
    #include <Bounce.h>
    
    //**********CONSTANTS**********
    const int BOUNCE_TIME = 25; // fine tune if the buttons need more/less time
    const int LEDPIN = 13; // Upper BANK indicator LED 
    const int DIGITAL_PINS = 5; // size of the PINS array (no longer includes toggle button!)
    const int PINS[DIGITAL_PINS] = {0,1,2,3,4}; // set pin numbers of swtiches
    const int channel = 1;
    const int ONvalue = 127; // arbitrary 'on' value for D2 of CC message
    const int OFFvalue = 0; // arbitrary 'off' value for D2 of CC message
    const int resetThreshold = 2000; /// mS hold to change bank
    
    const byte CC[][DIGITAL_PINS] = {
      {60,61,62,63,64},
      {65,66,67,68,69},
      {70,71,72,73,74},
      {75,76,77,78,79},
      {80,81,82,83,84},
      {85,86,87,88,89}
    }; // this is the banks by switches matrix of CC values for the bank system
    
    //**********VARIABLES/LIBRARY OBJECTS**********
    int bank = 0; // this is the bank variable to be toggled
    boolean CCstate[DIGITAL_PINS]; // array of current CC on/off toggle state
    boolean timerOn; // timer toggle memory tracks whether a new fallingEdge was heard since the last rising; used in bank switching
    
    Bounce btn[] = {
      Bounce(PINS[0], BOUNCE_TIME),
      Bounce(PINS[1], BOUNCE_TIME),
      Bounce(PINS[2], BOUNCE_TIME),
      Bounce(PINS[3], BOUNCE_TIME),
      Bounce(PINS[4], BOUNCE_TIME),
      };
    elapsedMillis toggleReset; // mS clock counter to reset on contact/risgingEdge()
    
    //**********SETUP**********
    void setup() {
      //Serial.begin(9600);
      for (int i = 0;i<DIGITAL_PINS;i++){
        pinMode(PINS[i], INPUT_PULLUP);
      }
      pinMode(LEDPIN, OUTPUT);
    }
    
    //**********LOOP**********
    void loop() {
      for (int i = 0;i<DIGITAL_PINS;i++){ // loop through each object in the BOUNCE arrray for the note switches (no longer includes TOGGLE)
        btn[i].update();
        if (btn[i].fallingEdge()) {
          timerOn = true ;
          toggleReset = 0;
        }
        if (btn[i].risingEdge()) {
          if(toggleReset<resetThreshold){
            if (CCstate[i]){ 
              usbMIDI.sendControlChange(CC[bank][i], ONvalue, channel); 
            }else{
              usbMIDI.sendControlChange(CC[bank][i], OFFvalue, channel);  
            }
            CCstate[i] = !CCstate[i] ; //toggle state memory
            timerOn = false ; //turn off timer (resets each cycle)
          }
        }
        if (timerOn && (toggleReset>resetThreshold)){
          toggleReset = 0;
          bank = i;
          //digitalWrite(LEDPIN, bank); // turn off for now...
        }
      }
    }
    So then you have the display issue. The LED is disabled for now.

  13. #38
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Vancouver Canada
    Posts
    684
    Quote Originally Posted by oddson View Post
    ... it would be fairly simple to make bank an integer and to set it's value based on which switch triggered the fallingEdge that started the counter. And if you want feedback the simplest would be to make LEDPIN into an array and use the bank value as an index to track which should be on.
    It is the risingEdge which selects the bank. The fallingEdge of any button starts the counter.

    There is only one counter so it will be reset if a second button is pressed while one is already down and (I think) the first to rise (be released) after passing the the threshold that will select the mode.

    In normal operation it won't matter but just in case you were trying to follow the logic.

    You might want to reduce the timing threshold to 1500 or even 1000 as holding two seconds seems very long.

  14. #39
    Quote Originally Posted by oddson View Post
    It is the risingEdge which selects the bank. The fallingEdge of any button starts the counter.

    There is only one counter so it will be reset if a second button is pressed while one is already down and (I think) the first to rise (be released) after passing the the threshold that will select the mode.

    In normal operation it won't matter but just in case you were trying to follow the logic.

    You might want to reduce the timing threshold to 1500 or even 1000 as holding two seconds seems very long.
    Ok so I can reduce the timing. Can the code be setup so that the bank selected after the timer is based on which pin is the rising edge? so if rising edge is pin 0 load Array A and is risingedge is pin 1 load array B and if risingedge is pin 2 load Array C?


    As far as constructing the components. For LEDs do I need resistors in the signal chain?

    I have just the board with pins in it. How would you recommend connecting the switches and leds to the pins on the board? Are there some specific kinds of connectors? Or should I just use breadboard or something like that?

Posting Permissions

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