chris@home
New member
Hello all.
My first post here because almost any issue I ever have can usually be answered with a good search of this forum. This time I can't find exactly what I want, likely due to the search terms I'm using and my lack of knowledge in describing exactly what I want in a technical manner for the search engine.
I'm working on a MIDI controller that I would like to use with an organ I'm building using a Teensy 4.0. The ultimate goal is to have 12 latching buttons, 9 faders (organ drawbars) and 9 or so analog rotary knobs. I'm familiarizing myself with each chunk as I go just so I don't overwhelm myself with too much at once. So I'm learning to build each part in phases and learn from my mistakes as I go. I've figured out that baby steps helps me understand what I'm doing. I know I'll likely need to incorporate a MUX at some point, but so far I feel like I've learned a bunch on this journey.
In one of my searches, I did see a thread with code posted that was pretty close to what I needed... but didn't have the latching functionality. Here's a link to the original post MIDI footswitch for Guitar
I changed a few things around to get the latching functionality, but now I see that I've overlooked something in my inexperience. While it latches based on the last value of 0 or 127... the lookback is agnostic. If I have two buttons and the last value of one is 127 and the last value of the other is 0, when I press again the next value entered will be 0 regardless of the value of that specific button. So it's applying that last read value for any press even if it's not what I'm wanting.
Example:
In this example you can see that the message outController Sustenuto Pedal (on/off) sent a value of 0 twice, but the expectation would have been a value of 127. However it looks like it was polling that last value of 127 set by the Controller Soft Pedal (on/off) and therefore sent a value of 0.
Honestly, I don't feel too bad about this because I'm amazed I made it this far.
I'm also seeing a similar issue with the LED's. My initial goal was to have a latching LED option assigned to each button so I would have a visual indicator of the state of each associated button. But it's merely turning on the LED associated with the button, then turning off when I press the next button. This one isn't an absolute, but I figured since I was being all fancy I might as well see if I could get that to do something neat as well.
Maybe I've just boy-coded too close to the sun and I need to lower my expectation and just use toggle switches instead of a momentary button?
Maybe I need to use something like control surface? I've only lightly dabbled with it so I'm not super comfortable with it. Also I feel like what I'm learning here can be ported to non-MIDI workflows as I get better so that's a consideration I've had too.
I would love some guidance and input on where I'm going wrong and if there's a better way to do this... let me know. I can take it.
Also, if I'm missing some detail please let me know and I'll add it.
Thanks!
Here's my code.
My first post here because almost any issue I ever have can usually be answered with a good search of this forum. This time I can't find exactly what I want, likely due to the search terms I'm using and my lack of knowledge in describing exactly what I want in a technical manner for the search engine.
I'm working on a MIDI controller that I would like to use with an organ I'm building using a Teensy 4.0. The ultimate goal is to have 12 latching buttons, 9 faders (organ drawbars) and 9 or so analog rotary knobs. I'm familiarizing myself with each chunk as I go just so I don't overwhelm myself with too much at once. So I'm learning to build each part in phases and learn from my mistakes as I go. I've figured out that baby steps helps me understand what I'm doing. I know I'll likely need to incorporate a MUX at some point, but so far I feel like I've learned a bunch on this journey.
In one of my searches, I did see a thread with code posted that was pretty close to what I needed... but didn't have the latching functionality. Here's a link to the original post MIDI footswitch for Guitar
I changed a few things around to get the latching functionality, but now I see that I've overlooked something in my inexperience. While it latches based on the last value of 0 or 127... the lookback is agnostic. If I have two buttons and the last value of one is 127 and the last value of the other is 0, when I press again the next value entered will be 0 regardless of the value of that specific button. So it's applying that last read value for any press even if it's not what I'm wanting.
Example:
Direction | Message | MIDI Ch | Value | Expected Value | Hex |
---|---|---|---|---|---|
out | Controller Sustenuto Pedal (on/off): 0 | 1 | 0 | 0 | B0 42 00 |
out | Controller Soft Pedal (on/off): 127 | 1 | 127 | 127 | B0 43 7F |
out | Controller Sustenuto Pedal (on/off): 0 | 1 | 0 | 127 | B0 42 00 |
In this example you can see that the message outController Sustenuto Pedal (on/off) sent a value of 0 twice, but the expectation would have been a value of 127. However it looks like it was polling that last value of 127 set by the Controller Soft Pedal (on/off) and therefore sent a value of 0.
Honestly, I don't feel too bad about this because I'm amazed I made it this far.
I'm also seeing a similar issue with the LED's. My initial goal was to have a latching LED option assigned to each button so I would have a visual indicator of the state of each associated button. But it's merely turning on the LED associated with the button, then turning off when I press the next button. This one isn't an absolute, but I figured since I was being all fancy I might as well see if I could get that to do something neat as well.
Maybe I've just boy-coded too close to the sun and I need to lower my expectation and just use toggle switches instead of a momentary button?
Maybe I need to use something like control surface? I've only lightly dabbled with it so I'm not super comfortable with it. Also I feel like what I'm learning here can be ported to non-MIDI workflows as I get better so that's a consideration I've had too.
I would love some guidance and input on where I'm going wrong and if there's a better way to do this... let me know. I can take it.
Also, if I'm missing some detail please let me know and I'll add it.
Thanks!
Here's my code.
Code:
// select MIDI from the "Tools > USB Type" menu
// Create an option to use momentary switch with latching functionality.
// Optimally, this will allow multiple MIDI Control Change messages to be read as 0 or 127
// with button presses.
#include <Bounce.h>
// Set up the pins for buttons and LED's
const int channel = 1;
const int buttonPins[] = { 2, 3, 4, 5, 20, 21, 22, 23 };
const int ledPins[] = { 6, 7, 8, 9, 16, 17, 18, 19 };
// Configured buttons with 15 ms debounce time because my test buttons are so jittery. Final version
//should be around 5-10ms
Bounce buttons[8] = {
Bounce(buttonPins[0], 15),
Bounce(buttonPins[1], 15),
Bounce(buttonPins[2], 15),
Bounce(buttonPins[3], 15),
Bounce(buttonPins[4], 15),
Bounce(buttonPins[5], 15),
Bounce(buttonPins[6], 15),
Bounce(buttonPins[7], 15)
};
int lastButtonPressed = -1; // Variable to track the last button pressed
void setup() {
// Set button pins as input with internal pullup
for (int i = 0; i < 8; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW); // Turn off all LEDs initially
}
}
// /Stores the value of Control Change state sent as high or low in the loop
uint8_t cc_value = 0;
// Stores the value of the last LED state as off or on in the loop
uint8_t led_value = LOW;
void loop() {
// Update the state of the buttons
for (int i = 0; i < 8; i++) {
buttons[i].update();
}
// Check if any button was pressed and updates based on the last state
for (int i = 0; i < 8; i++) {
if (buttons[i].fallingEdge()) {
if( cc_value == 127) cc_value = 0;
else cc_value = 127;
usbMIDI.sendControlChange(60 + i, cc_value, channel); // Send Control Change message (60 + i is the MIDI CC)
lastButtonPressed = i; // Update the last button pressed
}
}
// Turn on only the LED of the last button pressed and turn off the others
for (int i = 0; i < 8; i++) {
if (i == lastButtonPressed) {
if( led_value == LOW) led_value = HIGH; // This should be looking to the current state and
else led_value = LOW; // responding appropriately like a latching switch, but doesn't.
digitalWrite(ledPins[i], led_value);
}
}
// Read and discard incoming MIDI messages
while (usbMIDI.read()) {
// read and discard incoming messages
}
}