Teensyduino for basic MIDI MAPPING in Ableton

Status
Not open for further replies.
Hi all,

I'm extremely new to all this.
Wanting to build a simple controller that creates ON/OFF style presses in Ableton. (for the time being)
For instance, hit a button and it turns on an effect via MIDI Mapping. Hit another button and it starts a sample, etc...
ALL of these demands can be mapped within Ableton, but it isn't quite working how I had hoped....

I'm using a Teensy 3.2 + teensyduino + the below sketch.

Thus far the code is working for a few mapping demands ( hitting the record and play button in a looper etc...)
but when i try to use it to turn on an effect it will only stay on WHILE the button is pressed and turns off when the button is un-pressed.

I'm not sure if all of that makes sense to you all. Thanks for any suggestions on how to modify the sketch. I just grabbed a sketch that seemed to make sense for the job from Instructables or something.
Thanks again for any help/and/or suggestions towards understanding the issue.


#include <Bounce.h>

//The number of push buttons
const int NUM_OF_BUTTONS = 8;

// the MIDI channel number to send messages
const int MIDI_CHAN = 1;

// Create Bounce objects for each button and switch. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
// 5 = 5 ms debounce time which is appropriate for good quality mechanical push buttons.
// If a button is too "sensitive" to rapid touch, you can increase this time.

//button debounce time
const int DEBOUNCE_TIME = 5;

Bounce buttons[NUM_OF_BUTTONS + 1] =
{
Bounce (0, DEBOUNCE_TIME),
Bounce (1, DEBOUNCE_TIME),
Bounce (2, DEBOUNCE_TIME),
Bounce (3, DEBOUNCE_TIME),
Bounce (4, DEBOUNCE_TIME),
Bounce (5, DEBOUNCE_TIME),
Bounce (6, DEBOUNCE_TIME),
Bounce (7, DEBOUNCE_TIME),
Bounce (8, DEBOUNCE_TIME)
};

const int MIDI_MODE_NOTES = 0;
const int MIDI_MODE_CCS = 1;

//Variable that stores the current MIDI mode of the device (what type of messages the push buttons send).
int midiMode = MIDI_MODE_NOTES;

//Arrays the store the exact note and CC messages each push button will send.
const int MIDI_NOTE_NUMS[NUM_OF_BUTTONS] = {40, 41, 42, 43, 36, 37, 38, 39};
const int MIDI_NOTE_VELS[NUM_OF_BUTTONS] = {110, 110, 110, 110, 110, 110, 110, 110};
const int MIDI_CC_NUMS[NUM_OF_BUTTONS] = {24, 25, 26, 27, 20, 21, 22, 23};
const int MIDI_CC_VALS[NUM_OF_BUTTONS] = {127, 127, 127, 127, 127, 127, 127, 127};

//==============================================================================
//==============================================================================
//==============================================================================
//The setup function. Called once when the Teensy is turned on or restarted

void setup()
{
// Configure the pins for input mode with pullup resistors.
// The buttons/switch connect from each pin to ground. When
// the button is pressed/on, the pin reads LOW because the button
// shorts it to ground. When released/off, 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!

for (int i = 0; i < NUM_OF_BUTTONS + 1; i++)
{
pinMode (i, INPUT_PULLUP);
}

}

//==============================================================================
//==============================================================================
//==============================================================================
//The loop function. Called over-and-over once the setup function has been called.

void loop()
{
//==============================================================================
// Update all the buttons/switch. 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.
for (int i = 0; i < NUM_OF_BUTTONS + 1; i++)
{
buttons.update();
}

//==============================================================================
// Check the status of each push button

for (int i = 0; i < NUM_OF_BUTTONS; i++)
{

//========================================
// Check each button for "falling" edge.
// Falling = high (not pressed - voltage from pullup resistor) to low (pressed - button connects pin to ground)

if (buttons[i + 1].fallingEdge())
{
//If in note mode send a MIDI note-on message.
//Else send a CC message.
if (midiMode == MIDI_MODE_NOTES)
usbMIDI.sendNoteOn (MIDI_NOTE_NUMS, MIDI_NOTE_VELS, MIDI_CHAN);
else
usbMIDI.sendControlChange (MIDI_CC_NUMS, MIDI_CC_VALS, MIDI_CHAN);
}

//========================================
// Check each button for "rising" edge
// Rising = low (pressed - button connects pin to ground) to high (not pressed - voltage from pullup resistor)

else if (buttons[i + 1].risingEdge())
{
//If in note mode send a MIDI note-off message.
//Else send a CC message with a value of 0.
if (midiMode == MIDI_MODE_NOTES)
usbMIDI.sendNoteOff (MIDI_NOTE_NUMS, 0, MIDI_CHAN);
else
usbMIDI.sendControlChange (MIDI_CC_NUMS, 0, MIDI_CHAN);
}

} //for (int i = 0; i < NUM_OF_BUTTONS; i++)

//==============================================================================
// Check the status of the toggle switch, and set the MIDI mode based on this.
if (buttons[0].fallingEdge())
{
midiMode = MIDI_MODE_NOTES;
}
else if (buttons[0].risingEdge())
{
midiMode = MIDI_MODE_CCS;
}

//==============================================================================
// MIDI Controllers should discard incoming MIDI messages.
// http://forum.pjrc.com/threads/24179-Teensy-3-Ableton-Analog-CC-causes-midi-crash
while (usbMIDI.read())
{
// ignoring incoming messages, so don't do anything here.
}

}
 
Wanting to build a simple controller that creates ON/OFF style presses in Ableton. (for the time being)
For instance, hit a button and it turns on an effect via MIDI Mapping. Hit another button and it starts a sample, etc...
ALL of these demands can be mapped within Ableton, but it isn't quite working how I had hoped....
ON/OFF buttons (toggles) are fundamentally different from firing note messages.

You need a variable to keep track of the current state (ON or OFF) so that when you detect a rising edge to know to reverse it. The falling edge, while in toggle mode, is generally ignored.
 
Last edited:
ON/OFF buttons (toggles) are fundamentally different from firing note messages.

You need a variable to keep track of the current state (ON or OFF) so that when you detect a rising edge to know to reverse it. The falling edge, while in toggle mode, is generally ignored.

I'm afraid all of that is pretty much gobbledigook to me. So... what would I need to do to solve my problem with the sketch code ? Could you perhaps provide what might need to be cut from my sketch or added to it ? Understand that all of this is extremely new to me so explaining things a bit clearer (long-winded/like I'm a 5 yr old) would be very helpful for my learning.

Thank you for the input !
 
Do you understand the code you've posted?
Not every line perhaps but have you read through it and tried to work out what's going on?
The code is heavily commented and should offer you a good start.
But if you really plan to work with Teensy you should work your way through the tutorials and get the basics before posting problems changing someone else code. :)





To make the toggle behaviour to be configurable for any given button (as you may still want some buttons to act as a momentary switch) you would add to the list of button array constant arrays:

const int MIDI_CC_TOGGLE[NUM_OF_BUTTONS] = {true,true,true,true,true,true,true,true};

And a variable array to store the current state of each button:


int midi_cc_state[NUM_OF_BUTTONS]={false,false,false,false,false,false,false,false} // initialized to OFF


Then you need to check whether the switch is in toggle mode in the logic under the fallingEdge and risingEdge sections of the code.

FallingEdge - switch is active and pulls the pin to LOW state:
If the toggle mode is set (MIDI_CC_TOGGLE is TRUE) and the current state of that switch is ON (midi_cc_state is TRUE) then we need to send the CC OFF message and set the state variable to match for next time. Otherwise the CC ON message is sent (including buttons not set to TRUE for toggle state) and the state variable is again set to match this OFF state.

Code:
  if (buttons[i + 1].fallingEdge()) {
    if (midiMode == MIDI_MODE_NOTES){
      usbMIDI.sendNoteOn (MIDI_NOTE_NUMS[i], MIDI_NOTE_VELS[i], MIDI_CHAN);
    } else {       [COLOR="#000080"] 
      if (MIDI_CC_TOGGLE[i] && midi_cc_state[i]){
        usbMIDI.sendControlChange (MIDI_CC_NUMS[i], 0, MIDI_CHAN);
        midi_cc_state[i] = false;
      } else {
        usbMIDI.sendControlChange (MIDI_CC_NUMS[i], MIDI_CC_VALS[i], MIDI_CHAN);
        midi_cc_state[i] = true;
      }[/COLOR]
     }
  }

RisingEdge - switch is open (not pressed) and pullup returns pin to HIGH state
On the rising edge it's very simple - if the toggle is on you ignore it and if not you set to off. Since it doesn't change when in toggle mode we don't need to update the state variable (although we could safe enough) since it's only checked when toggle is TRUE.

Code:
  else if (buttons[i + 1].risingEdge()){
    if (midiMode == MIDI_MODE_NOTES){
      usbMIDI.sendNoteOff (MIDI_NOTE_NUMS[i], 0, MIDI_CHAN);
    } else {
[COLOR="#000080"]      if (!MIDI_CC_TOGGLE[i]){
        usbMIDI.sendControlChange (MIDI_CC_NUMS[i], 0, MIDI_CHAN);
      }[/COLOR] 
    } 
  }
Note the exclamation point is the negation operator which make this the same as (MIDI_CC_TOGGLE = false) so the rising edge will get ignored unless the switch is not in toggle mode.

I was only able to do limited testing (and on a T2.0) and the pre-existing toggle (that sets Note vs. CC mode) was acting funny... my toggle stuff seemed to be working but, like I say, it's not fully tested.
 

Attachments

  • toggle_CC.ino
    5.5 KB · Views: 228
Do you understand the code you've posted?
Not every line perhaps but have you read through it and tried to work out what's going on?
The code is heavily commented and should offer you a good start.
But if you really plan to work with Teensy you should work your way through the tutorials and get the basics before posting problems changing someone else code. :)




Nope. Don't understand, really,... any of it. Some basic terms and understanding of MIDI values and CC, sure,.. but the coding makes zero sense to me.
I read through it several times and through some help sections that explained various values/concepts, but the language is just too thick for me.
Its like trying to learn French, and your teacher is speaking German. Knowing whether something should be False or True or DEBOUNCED means knowing the definition of those terms first and foremost.
Sorry. I thought I could wrap my head around it, but I just couldn't, and so was hoping someone would be kind enough on here to simply help a person out and share a simple bit of code to make a fellow DIY-er happy...which you have done ( the code works well as far as I can tell, thank you ). My apologies for not being able to read this language. I tried. For hours...
My brain works in a different way I'm afraid. Thank you for attaching it. It means I can stop staring at a computer screen going crazy and half blind. It is appreciated.
 
Well you jumped in at an intermediate level without doing the pre-requisites.

A couple things (even though you may not understand 'why' yet):

If you want to change the default to start with CC (currently defaults to Notes) change this line:
int midiMode = MIDI_MODE_NOTES;
to this:
int midiMode = MIDI_MODE_CCS;

If you can't make button eight work (I think there is a bug here but cannot test with my Teensy inside an enclosure) I think there is a problem with this line:

EDIT - I am mistaken... the code works because the count is compensated in the 'if' conditions in the MIDI message section.


for (int i = 0; i < NUM_OF_BUTTONS; i++)

and it should be:
for (int i = 1; i <= NUM_OF_BUTTONS; i++)

So that it skips pin-0 (which is the switch that's meant to pick the midi-mode) when figuring out what MIDI message to send by starting at pin-1 instead of pin-0 and so that it goes up to eight (currently it appears to only read to pin 7).

Edit - and I increased the debounce time way up from 5 to 25... you should be able to drop that back much lower; I only did this because the footswitch I have attached to my Teensy controller is super noisy.

const int DEBOUNCE_TIME = 10;


Could you point to where you located this code?
 
Last edited:
Well you jumped in at an intermediate level without doing the pre-requisites.

A couple things (even though you may not understand 'why' yet):

If you want to change the default to start with CC (currently defaults to Notes) change this line:
int midiMode = MIDI_MODE_NOTES;
to this:
int midiMode = MIDI_MODE_CCS;

If you can't make button eight work (I think there is a bug here but cannot test with my Teensy inside an enclosure) I think there is a problem with this line:
for (int i = 0; i < NUM_OF_BUTTONS; i++)

and it should be:
for (int i = 1; i <= NUM_OF_BUTTONS; i++)

So that it skips pin-0 (which is the switch that's meant to pick the midi-mode) when figuring out what MIDI message to send by starting at pin-1 instead of pin-0 and so that it goes up to eight (currently it appears to only read to pin 7).

Edit - and I increased the debounce time way up from 5 to 25... you should be able to drop that back much lower; I only did this because the footswitch I have attached to my Teensy controller is super noisy.

const int DEBOUNCE_TIME = 10;


Could you point to where you located this code?


Thanks for this. I haven't gotten to button 8 yet, as I was still testing just a handful on a breadboard and ensuring code before finalizing it. Multiple tests have come back positive though on your sketch. I'll be sure to save this and add it in when I get to this issue.

As far as pointing to my original "inspiration"... If you do a search for "diy usb midi controller using teensy" it should lead you to an "ask.audio" project on the first hit.

While I have you on the line, would you suggest any manuals or guides that can break all this stuff down ( in regards specifically to MIDI and Teensy code ) for a beginner ?
I would love to be able to expand and create more interesting interactive devices as time goes on, but the dialogue is just a huge wall for me. I've written some minor web code so the concept is not entirely alien, but the wordage and building blocks are nonsensical for me,.. currently. I've seen some of the online basics on this site, and a few other places, but I think I need something from the ground up.
Thanks again for the sketch, and your time.
 
Scratch my comment about the 'for' loop.

I didn't notice in the falling/rising edge part of the code he's using i+1 to compensate and still be able to use the standard i=0, i< n; i++ setup for a 'for' loop with n objects indexed from zero.

If you also take out the +1 in both locations you could go with my loop but it should work as is and it's not required.
 
Last edited:
Scratch my comment about the 'for' loop.

I didn't notice in the falling/rising edge part of the code he's using i+1 to compensate and still be able to use the standard i=0, i< n; i++ setup for a 'for' loop with n objects indexed from zero.

If you also take out the +1 in both locations you could go with my loop but it should work as is and it's not required.

Not sure if it is normal for things like this to happen in the Teensy world. But I went to use the same set up, same original sketch, and now for whatever reason, it is taking me two presses of a button in order to have a task done.
Using a MIDI monitor, it is showing that I am sending 0 on the first press and 127 on the second. Repeating. (as in, Up and Down = 0, -- then Up and Down = 127)
Thus any effect I am wanting on or off takes one hit the first time and two hits each additional time.

I haven't the slightest idea why the behavior should change from how it was working yesterday.
Any thoughts ? - or Places I can add/change to fix ?

Thanks oddson.
 
It is not normal for Teensy to behave unpredictably (though I have often had to prove that to myself with coding)

If you wish, I could spend a half-hour with you getting over the hump. The forum is good for most things, but not all. Sometimes a shared screen helps a lot. I have a WebEx account that would allow us to screen share and I could look over your shoulder. Let me know. I have some time slots each day this week. I'm in central US time zone.
david.elvig@gmail.com.
 
sorry... the code I posted above?

Yeah. Same code, Same Teensy 3.2, Literaly nothing changed, but curiously operation now needing 2 clicks on the button to activate or deactivate an effect. Very strange.
I even tried deleting everything and reinstalling from scratch.
 
It looks like my missing the +1 caused me to mess up the array stuff...
 
Last edited:
Code:
#include <Bounce.h>
//============CONFIGURE CONSTANTS; CREATE GLOBAL VARIABLES & BOUNCE OBJECTS==================

const int NUM_OF_BUTTONS = 8;   //The number of push buttons
const int MIDI_CHAN = 1;        //the MIDI channel number to send messages
const int DEBOUNCE_TIME = 10;   //button debounce time
const int PIN_ASSIGNMENT[1 + NUM_OF_BUTTONS] = {0,1,2,3,4,5,6,7,8};                       //PIN assingment - first entry is TOGGLE 
const int MIDI_NOTE_NUMS[NUM_OF_BUTTONS] = {40, 41, 42, 43, 36, 37, 38, 39};              //MIDI Note valuues (D1) 
const int MIDI_NOTE_VELS[NUM_OF_BUTTONS] = {110, 110, 110, 110, 110, 110, 110, 110};      //Note ON velocity values (D2)
const int MIDI_CC_NUMS[NUM_OF_BUTTONS] = {24, 25, 26, 27, 20, 21, 22, 23};                //MIDI CC ID array (D1) array
const int MIDI_CC_VALS[NUM_OF_BUTTONS] = {127, 127, 127, 127, 127, 127, 127, 127};        //MIDI CC ON value (D2) array
const int MIDI_CC_TOGGLE[NUM_OF_BUTTONS] = {true,true,true,true,true,true,true,true};     //Switch type = TOGGLE/LATCH when TRUE initialized to Toggle mode      
const boolean MIDI_MODE_TOGGLE_CC = true ;//negate current setting to revese whether ON means CC or Note

Bounce buttons[NUM_OF_BUTTONS] =
{  //create bounce objects - don't need one for toggle                       
  Bounce (PIN_ASSIGNMENT[1], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[2], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[3], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[4], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[5], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[6], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[7], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[8], DEBOUNCE_TIME)
};

//variable for midi mode default setting using constants defined above
boolean midiCCmode;                         //used to read toggle for mode setting
// ***added*** //array of button state variables initialized to OFF
int midi_cc_state[NUM_OF_BUTTONS]={false,false,false,false,false,false,false,false};    


//========CONFIGURE PINS==========
void setup(){
  for (int i = 0; i <= NUM_OF_BUTTONS; i++){  //plus 1 button pin0 is for toggle
    pinMode (i, INPUT_PULLUP);  //PULLUP set means you don't need resisters to make active low work
  }
}

//========LOOP======================
void loop(){
  // ========INNER LOOP======= 
  for (int i = 0; i < NUM_OF_BUTTONS; i++){
    buttons[i].update();
    if (buttons[i].fallingEdge()){
      //If in note mode send a MIDI note-on message.
      //Else send a CC message.
      if (!midiCCmode){
        usbMIDI.sendNoteOn (MIDI_NOTE_NUMS[i], MIDI_NOTE_VELS[i], MIDI_CHAN);
      } else {  // if in toggle mode and currently on then turn off otherwise turn on
        if (MIDI_CC_TOGGLE[i] && midi_cc_state[i]){
          usbMIDI.sendControlChange (MIDI_CC_NUMS[i], 0, MIDI_CHAN);
          midi_cc_state[i] = false;
        } else {
          usbMIDI.sendControlChange (MIDI_CC_NUMS[i], MIDI_CC_VALS[i], MIDI_CHAN);
          midi_cc_state[i] = true;
        }
      }
    }else if (buttons[i].risingEdge()){
      //If in note mode send a MIDI note-off message.
      //Else send a CC message with a value of 0.
      if (!midiCCmode){
        usbMIDI.sendNoteOff (MIDI_NOTE_NUMS[i], 0, MIDI_CHAN);
      } else {
        if (!MIDI_CC_TOGGLE[i]){
          usbMIDI.sendControlChange (MIDI_CC_NUMS[i], 0, MIDI_CHAN);
        } 
      } 
    }
  } 

    
  //====CHECK THE TOGGLE -- NO NEED TO DEBOUNCE============================================== 
  // Check the status of the toggle switch, and set the MIDI mode based on this.

  if (digitalRead(PIN_ASSIGNMENT[0])){
    midiCCmode = MIDI_MODE_TOGGLE_CC;
  } else {
    midiCCmode = !MIDI_MODE_TOGGLE_CC;
  }
  
  //================================================== 
  while (usbMIDI.read()){
    // ignoring incoming ---  http://forum.pjrc.com/threads/24179-...ses-midi-crash
  }
}
This 'seems' to work (i.e. minimal testing only again... so still no guarantees)

I did a rewrite just to make sure I was understanding each bit...
I thought it a bit strange that the pin assignment was hard coded but the CC on values got a constant array so I added one.

I nixed the bounce on the toggle switch. It might bounce a bit but I doesn't matter as it will have settled before it matters in normal cases and I don't think the denounce would prevent notes left on if you're flicking the toggle while hitting buttons.
 
Code:
#include <Bounce.h>
//============CONFIGURE CONSTANTS; CREATE GLOBAL VARIABLES & BOUNCE OBJECTS==================

const int NUM_OF_BUTTONS = 8;   //The number of push buttons
const int MIDI_CHAN = 1;        //the MIDI channel number to send messages
const int DEBOUNCE_TIME = 10;   //button debounce time
const int PIN_ASSIGNMENT[1 + NUM_OF_BUTTONS] = {0,1,2,3,4,5,6,7,8};                       //PIN assingment - first entry is TOGGLE 
const int MIDI_NOTE_NUMS[NUM_OF_BUTTONS] = {40, 41, 42, 43, 36, 37, 38, 39};              //MIDI Note valuues (D1) 
const int MIDI_NOTE_VELS[NUM_OF_BUTTONS] = {110, 110, 110, 110, 110, 110, 110, 110};      //Note ON velocity values (D2)
const int MIDI_CC_NUMS[NUM_OF_BUTTONS] = {24, 25, 26, 27, 20, 21, 22, 23};                //MIDI CC ID array (D1) array
const int MIDI_CC_VALS[NUM_OF_BUTTONS] = {127, 127, 127, 127, 127, 127, 127, 127};        //MIDI CC ON value (D2) array
const int MIDI_CC_TOGGLE[NUM_OF_BUTTONS] = {true,true,true,true,true,true,true,true};     //Switch type = TOGGLE/LATCH when TRUE initialized to Toggle mode      
const boolean MIDI_MODE_TOGGLE_CC = true ;//negate current setting to revese whether ON means CC or Note

Bounce buttons[NUM_OF_BUTTONS] =
{  //create bounce objects - don't need one for toggle                       
  Bounce (PIN_ASSIGNMENT[1], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[2], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[3], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[4], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[5], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[6], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[7], DEBOUNCE_TIME),
  Bounce (PIN_ASSIGNMENT[8], DEBOUNCE_TIME)
};

//variable for midi mode default setting using constants defined above
boolean midiCCmode;                         //used to read toggle for mode setting
// ***added*** //array of button state variables initialized to OFF
int midi_cc_state[NUM_OF_BUTTONS]={false,false,false,false,false,false,false,false};    


//========CONFIGURE PINS==========
void setup(){
  for (int i = 0; i <= NUM_OF_BUTTONS; i++){  //plus 1 button pin0 is for toggle
    pinMode (i, INPUT_PULLUP);  //PULLUP set means you don't need resisters to make active low work
  }
}

//========LOOP======================
void loop(){
  // ========INNER LOOP======= 
  for (int i = 0; i < NUM_OF_BUTTONS; i++){
    buttons[i].update();
    if (buttons[i].fallingEdge()){
      //If in note mode send a MIDI note-on message.
      //Else send a CC message.
      if (!midiCCmode){
        usbMIDI.sendNoteOn (MIDI_NOTE_NUMS[i], MIDI_NOTE_VELS[i], MIDI_CHAN);
      } else {  // if in toggle mode and currently on then turn off otherwise turn on
        if (MIDI_CC_TOGGLE[i] && midi_cc_state[i]){
          usbMIDI.sendControlChange (MIDI_CC_NUMS[i], 0, MIDI_CHAN);
          midi_cc_state[i] = false;
        } else {
          usbMIDI.sendControlChange (MIDI_CC_NUMS[i], MIDI_CC_VALS[i], MIDI_CHAN);
          midi_cc_state[i] = true;
        }
      }
    }else if (buttons[i].risingEdge()){
      //If in note mode send a MIDI note-off message.
      //Else send a CC message with a value of 0.
      if (!midiCCmode){
        usbMIDI.sendNoteOff (MIDI_NOTE_NUMS[i], 0, MIDI_CHAN);
      } else {
        if (!MIDI_CC_TOGGLE[i]){
          usbMIDI.sendControlChange (MIDI_CC_NUMS[i], 0, MIDI_CHAN);
        } 
      } 
    }
  } 

    
  //====CHECK THE TOGGLE -- NO NEED TO DEBOUNCE============================================== 
  // Check the status of the toggle switch, and set the MIDI mode based on this.

  if (digitalRead(PIN_ASSIGNMENT[0])){
    midiCCmode = MIDI_MODE_TOGGLE_CC;
  } else {
    midiCCmode = !MIDI_MODE_TOGGLE_CC;
  }
  
  //================================================== 
  while (usbMIDI.read()){
    // ignoring incoming ---  http://forum.pjrc.com/threads/24179-...ses-midi-crash
  }
}
This 'seems' to work (i.e. minimal testing only again... so still no guarantees)

I did a rewrite just to make sure I was understanding each bit...
I thought it a bit strange that the pin assignment was hard coded but the CC on values got a constant array so I added one.

I nixed the bounce on the toggle switch. It might bounce a bit but I doesn't matter as it will have settled before it matters in normal cases and I don't think the denounce would prevent notes left on if you're flicking the toggle while hitting buttons.

Well...
Oddson, I want to thank you for trying and for all your help thus far. It is greatly appreciated. Sadly, there seem to still be issues, and from all of my testing it still seems to be code based issues.
The newest code that you have put up (quoted here) does ultimately work, but it takes one press of the button (and nothing happening) first, before it then begins to work...
Aside from that it works fine for almost all "effects" and turning them on or off, but it still takes two hits every single time to get the Looper to "record" "stop" "play" "overdub"
Strangely, the very first code I posted about has no issues whatsoever working with the Looper, but has the issue of having to hold down the button to keep any other effects on or off.
I've read of other people having issues with Ableton and Teensy, rather...Ableton being finicky. It seems like a simple 8-10 button on/off scenario would be no problem.
At any rate...
I am thankful for your efforts, but I don't want to be any more trouble than I've already been. Thanks for trying. If it bugs you and you really want to sort it out, awesome...I'll gladly accept it. But I feel a bit burdensome at this point in time and just want to say thank you and the end.

Thanks again.
 
Strange... I may have a look in a couple weeks once my new cheap T3.0s arrive and if I can find enough switches.

Can you verify you have a physical toggle switch on pin-0 as in the tutorial you pointed to?
 
By-the-way... the 'finicky' aspects of this are strictly in my botched efforts to understand and alter the code you posted. It's nothing to do with Teensy itself or Teensyduino and everything to do with the complexities of coding and in particular of reading and altering other peoples code, who may also just be learning; as indeed am I. :)

edit - the code above seems to work as intended...
 
Last edited:
Strange... I may have a look in a couple weeks once my new cheap T3.0s arrive and if I can find enough switches.

Can you verify you have a physical toggle switch on pin-0 as in the tutorial you pointed to?

No. Currently I have a a ground running on the top left ( when usb is on the top ) and a single button on the 5th hole down, though I have put the button in a few places to the same results.
I'm not actually using any toggle switches from a mechanical standpoint... I was planning on 10 buttons, when I solidified the code.

and re: Teensy and Teensyduino reflections... Absolutely, I have no doubt that this is purely due to user error and nothing more. I see Teensy and Teensyduino to purely be a reflection of whatever one chooses it to be, which is what is so wonderful and awesome and attractive about it. But sadly I am not one for playtesting over and over and over again as in the end I have duties to perform that need to be fulfilled with or without certain ideologies and/or hobbies.

Thanks again Oddson. It has been a pleasure, and I only wish I could have added more to the forum. We'll get there...
 
Ok.. so you don't need the two modes; note and CC?

You just want CC messages?

Do you need to be able to set different switches to either latching or momentary action or do you a only want latching (press for on press again for off)?

I can write you a super-basic sketch for that in very short order...
 
Ok.. so you don't need the two modes; note and CC?

You just want CC messages?

Do you need to be able to set different switches to either latching or momentary action or do you a only want latching (press for on press again for off)?

I can write you a super-basic sketch for that in very short order...

Oh...
I was basically wanting 10 buttons.
Each one would send a single signal that can be midi mapped in Ableton.
So I hit button 1 and it is mapped to start my looper, I hit button one again and it hits the same mapped looper ( turning it from Record to Play). I don't want the buttons to actually do anything beyond sending a signal that can be mapped in Ableton ( not sure if that is a Note or what) Each 10 buttons being unique but otherwise performing exactly the same. The same way one could map any pad midi controller in Ableton. Beyond that explanation I'm at a loss. Thanks for your strong will. Very awesome.
 
Have you looked at the example, in File > Examples > Teensy > USB_MIDI > Buttons?

Hi Paul,

Thanks for chiming in. I've been through so many variants of code since I first tried this and decided to go back again and look at it.
It actually does work, basically exactly as needed. It seems the reason I kept looking beyond it and dismissed it was it was the first thing I tried, and it is looking like the issue I was having with it is actually related to my actual buttons. They are SUPER finicky. It seems they work best when very lightly tapped or extremely smoothly fully depressed. But any random hitting of them makes the commands jump and skitter a lot. Not sure if that is something that can be addressed from a code standpoint to handle... or if I just need to get better buttons. I have the uxcell Momentary buttons, and the reviews seemed pretty positive about them. But they are super jumpy when not fully smoothly depressed or very lightly slightly tapped.

Thanks again for the help and for getting me to go back and start at the drawing board again. Digging too deep and forgetting to apply learned knowledge of the process back to the beginning again...

Awesome. Beginning to look like a working machine !

Update ! I've adjusted the debounce time up to 10 and it seeeeems to be a bit smoother ( only had a few skittery jumps ). Does this make sense ? Would adjusting the debounce be the right move here ?
 
Last edited:
I think if we start over we can put together a bit of code that does what you want but is simple enough you can learn how each part works. Then you can add bells and whistles as you like later.

But I'm not 100% sure even now what midi event you want to send.

I'm guessing you want CC message with configurable D1 and 127 for D2 on one push and D2=0 on the subsequent push.

D1 and D2 are the data bytes that are the parameters of a sendMIDI.sendControlChange message; D1 is your choice or you can set to the default the software is already using if you know it. Here's a list of conventional usage for CC values but you don't have to use the 'correct' one http://nickfever.com/music/midi-cc-list. D2 is the data byte (minus one bit for reasons we'll skip for now)... for OFF zero is conventional and the maximum, 127, is for ON.

That is what my code in toggle CC mode is supposed to do but with the complexities of switching between mode I might have messed up somewhere. But code to do only that for ten switches could be very simple.

BTW - you can increase the constant DEBOUNCE_TIME as much as is needed. The limit is when it adds too much delay before it takes effect... but if it's not triggering a sound that has to hit on tempo or something similar, you're not likely to notice even fairly lengthy debounce times. I had it up at 25 because one of my switches is super bouncy and I didn't notice any delay.

This code has no delay() or timing limit on when it can go again... so it might need a longer debounce than code that includes some kind of message limiting.
 
Status
Not open for further replies.
Back
Top