midi controller

Status
Not open for further replies.
OK I went back to the original many knobs sketch, the 3 pots work but the buttons cause some of the other lights to flicker. I'm going to get rid of the bread board and solder everything. but I think its more than a connection issue.
 
There are other problems, It crashed Ableton twice. I soldered all connections but even before, the buttons were making other lights come on. I know you tested it with midi ox but has it ever been tested with a DAW like Ableton?
 
There are other problems, It crashed Ableton twice. I soldered all connections but even before, the buttons were making other lights come on. I know you tested it with midi ox but has it ever been tested with a DAW like Ableton?

If you run Many_button_knobs with floating configured pins it will send enough garbage midi to crash your DAW.
 
I don't know what you mean by (floating configured pins) I have pots on A0 through A5 and buttons on pins 0-3, what am I doing wrong?
 
Floating means not electrically connected to the circuit via any low impedance path (wire, solder, copper trace).

Configured Pins are those you set up as inputs when your program first loads.
The ResponsiveAnalogRead() library configures the input pin and which pins it configures are set out at the top of the code (and appear to be the ones you are trying to use)

Code:
// 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};
This second line is where you set up which CC number you want to use with each pot.

With a good MIDI monitor you should be able to see which channels are firing in error.
 
OK I fixed my mistakes and it works now. I modified the code for 24 pins, it loads but can't test it till I build the unit. Please check the code and see if there's anything wrong. Thanks for your help!

Code:
[/* Use arrays to manage lists of knobs/pots and pushbuttons.

   By Leif Oddson
   https://forum.pjrc.com/threads/45376

   This more complex example demonstrates how to use arrays to
   manage a larger number of inputs, without duplicating your
   code for every signal.

   You must select MIDI from the "Tools > USB Type" menu

   This example code is in the public domain.
*/


//************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 = 24; // number of Analog PINS
const int D_PINS = 24; // number of Digital PINS
const int ON_VELOCITY = 99; // note-one velocity sent from buttons (should be 65 to  127)

// 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,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,A21,A22,A23};
const int CCID[A_PINS] = {21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44};

// 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,12,13,14,15,16,17,18,19,20,21,22,23};
const int note[D_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};
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},
  {ANALOG_PINS[8],true},
  {ANALOG_PINS[9],true},
  {ANALOG_PINS[10],true},
  {ANALOG_PINS[11],true},
  {ANALOG_PINS[12],true},
  {ANALOG_PINS[13],true},
  {ANALOG_PINS[14],true},
  {ANALOG_PINS[15],true},
  {ANALOG_PINS[16],true},
  {ANALOG_PINS[17],true},
  {ANALOG_PINS[18],true},
  {ANALOG_PINS[19],true},
  {ANALOG_PINS[20],true},
  {ANALOG_PINS[21],true},
  {ANALOG_PINS[22],true},
  {ANALOG_PINS[23],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),
  Bounce(DIGITAL_PINS[12], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[13], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[14], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[15], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[16], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[17], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[18], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[19], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[20], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[21], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[22], BOUNCE_TIME),
  Bounce(DIGITAL_PINS[23], 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();
  getDigitalData();
  while (usbMIDI.read()) {
     // controllers must call .read() to keep the queue clear even if they are not responding to MIDI
  }
}


//************ANALOG SECTION**************
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.sendNoteOn(note[i], ON_VELOCITY, channel);  
    }
    // Note Off messages when each button is released
    if (digital[i].risingEdge()) {
      usbMIDI.sendNoteOff(note[i], 0, channel);  
    }
  }
}
 

Attachments

  • Capture 1.jpg
    Capture 1.jpg
    126.4 KB · Views: 93
Last edited by a moderator:
A quick look shows nothing but I'm terrible at seeing error. A [ /code] would help for readability

The compiler will almost certainly have objection to the syntax (unless you have been very careful and a little lucky).

You can compile without loading... that will give you error messages or not.

You can also test from a breadboard if you have pins on your Teensy. The configured pins can be set to HIGH or LOW voltages or to a voltage divider output. Ground is usually all you need to do as the loops will work for all or none for the most part.

You can still have bugs but if you can get your code to compile, and you understand what the configuration part is doing, then you should be able to sort out remaining error if any. If not I'll try to help to a reasonable degree but I'm not a free debugging service. This is DIY so a bit of Y is required. :)
 
You can also test from a breadboard if you have pins on your Teensy. The configured pins can be set to HIGH or LOW voltages or to a voltage divider output. Ground is usually all you need to do as the loops will work for all or none for the most part.
Er... what I mean is; just tie any pins not set to a functioning wiper to ground.

Any tied to ground should stay quite for MIDI out.
 
I'm trying to get the chain selector to work with digital buttons. The picture in post#32 shows the bar with 0 to 127 places, if I map a pot to it it works but then I have to try to find what I want by turning the knob. I want to make an array of 24 buttons instead. So like a radio with preset buttons, instead of turning the knob to find the station. This is the main reason I wanted to make this because there is nothing available that will do that. I'm Using the buttons sketch which has 12 notes mapped to the pins. beginning with C3 TO B3. When I map it to the selector and hit the buttons it plays notes as well as move the selector sporacticly any suggestions? I assume I have to convert the notes to cc?
 
Update. I can make it select instruments 1 through 12 with the buttons now I just have to stop it from also playing notes. I hope I can make this work with the many knobs and buttons sketch. One last thing, is there a way to light a led in the switch that is being used so that only one lights at a time?
 
If you could write a concise description of the type of controls and the desired behavior, I'm sure I can point you in the right direction. It's too difficult to extract your goal from scattered hints....
 
1 change the digital pins to send cc messages and not notes
2 tell the pin when its pressed to turn on led and turn off previous led so that all leds are off except the one that is pressed.
For now an array of 24 digital buttons that I can add more to later if needed.
 
1 change the digital pins to send cc messages and not notes
2 tell the pin when its pressed to turn on led and turn off previous led so that all leds are off except the one that is pressed.
For now an array of 24 digital buttons that I can add more to later if needed. knobs and buttons.jpg
 
I didn't mean to post that twice. I'm trying to be as clear as I can, the pots can all be mapped to any parameter so we can disregard those for now. Its just a matter of changing the buttons to cc messages instead of notes and if its not to hard, turn a light on. I have momentary switches with leds in them. I don't know if any additional components would be needed for that
 
For latching code.

The main addition is an array to track the state of the button so you can send the oposite message on the next push.

Then you just listen for the falling edge only as you are only making one change per button press.
Code:
//************DIGITAL SECTION**************
void getDigitalData(){
  for (int i=0;i<D_PINS;i++){
  digital[i].update();
    if (digital[i].fallingEdge()) {
[COLOR="#B22222"]      if (state[i]) {
        state[i] = 0;
      }else{
        state[i] = 127;
      }[/COLOR]
      usbMIDI.sendControlChange(CCnumber[i], state[i], channel);  
    }
  }
}

The bit in red says that if the state of button i is anything other than zero it will set it to zero and if it is zero it will set to 127. The generates the toggle behaviour.

https://forum.pjrc.com/threads/5250...p-writing-code?p=180440&viewfull=1#post180440
 
Last edited:
I tried replacing note[D_PINS] with CCID[A_PINS] it didn't work so I don'k know how to do it.
they are normally open switches, it would be press on and stay on until another button is pressed only 1 button at a time can be on.
 
I'm on a tablet and no compiler available ATM.

I'll have a look next time I am but no promises as to when.
 
I tried the latching code, it works for parameters like record on off ect. but the way they have the chain selector set up to map is, you press the first button and hold it while you press the last button. that defines the distance it will travel. I have 6 switches set up on the bread board. This works great with the buttons sketch, it moves the selector accordingly to each of the 6 positions. The latching sketch does not register the last button when I try to set it up. I know this might be difficult to explain.
I just tried it with the many knobs and buttons sketch, it doesn't work there either, only with the buttons sketch.



Capture 1.jpg
 
Last edited:
The chain selector is like a radio dial, just a similar comparison. Anyway this sketch works with the chain selector, how do you change it to cc instead of note on? The first few seconds of this video show how the lights should work. after that it does other thing but I only want the button thats used to be on, Do I need a driver for leds?


https://www.youtube.com/watch?v=MW0JLxRgJ1Q

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
  }
}
 
Last edited:
Tried it, doesn't work. it doesn't do the second button, when I try to enter the second number it just changes the first. I guess I could put it on a separate channel but then I'd have to change all the instruments too. and there are a lot. I'm working on adding pins to the sketch then I was going to try to add your analog section and see if that works.
 
So I combined your analog section with the buttons sketch digital section. It compiles, I'll test it tomorrow. I'm still not clear on how to light the leds.
 
Status
Not open for further replies.
Back
Top