Help with MIDI Controller: Trying to send pitch bend over 8 separate channels

Status
Not open for further replies.

toutant

Well-known member
I'm running into an issue in a MIDI controller project I'm working on. I'm trying to make an MPE controller that will send pitch bend data over 8 channels of MIDI. But for some reason, I can only send 2 channels at a time. Every time I introduce a third channel, the program completely crashes.

Is there something I'm missing about the MIDI library that I need to address to be able to do this?

Here's a condensed version of the code. I'm using a serial output on the Teensy 4.1.

Any help would be greatly appreciated.

Code:
#include <MIDI.h>

// DIN MIDI
MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, MIDI);

void setup() {
  MIDI.begin();
  delay(100);
}

void loop() {
  updateSlider(1, analogRead(A0));
  updateSlider(2, analogRead(A1));
  updateSlider(3, analogRead(A2));
  updateSlider(4, analogRead(A3));
  updateSlider(5, analogRead(A4));
  updateSlider(6, analogRead(A5));
  updateSlider(7, analogRead(A6));
  updateSlider(8, analogRead(A7));
}

void updateSlider(byte sliderNumber, int value) {
  int osc1Bend,
      osc2Bend,
      osc3Bend,
      osc4Bend,
      osc5Bend,
      osc6Bend,
      osc7Bend,
      osc8Bend;

  // Pitch bend goes from -8192 to +8192.
  // The MPE standard is 48 semitones for a full pitch up/down.
  int pitchBendMultiplier = 8192 / 48;

  switch (sliderNumber) {
    case 1:
      osc1Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc1Bend, sliderNumber);
      break;
    case 2:
      osc2Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc2Bend, sliderNumber);
      break;
    case 3:
      osc3Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc3Bend, sliderNumber);
      break;
    case 4:
      osc4Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc4Bend, sliderNumber);
      break;
    case 5:
      osc5Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc5Bend, sliderNumber);
      break;
    case 6:
      osc6Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc6Bend, sliderNumber);
      break;
    case 7:
      osc7Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc7Bend, sliderNumber);
      break;
    case 8:
      osc8Bend = map(value, 0, 1023, 0, 3 * pitchBendMultiplier);
      MIDI.sendPitchBend(osc8Bend, sliderNumber);
      break;
  }


}
 
Last edited:
What does your condensed version of the code do?
In the loop function it only ever does updateSlider on sliderNumber 1.
In the updateSliders function, case 2 in the switch statement sends a pitch bend via usbMIDI whereas all the other cases send it via MIDI.

Pete
 
Hi Pete,

That code was a bit messy. Sorry about that. I just cleaned up the typos.

The code reads the values of 8 different sliders and sends a MIDI pitch bend to 8 different channels based on the values of those sliders.
 
Here's the full code repo.


The problem lies in the updateSlider function. I can send MIDI pitch bends over 8 channels with USBMidi, no problem. But when I attempt to do that over the serial port, the Teensy crashes.

Again, thanks for any help.
 
I modified your new code to toggle the LED on every 100 times through the loop function so that I can see that it is still running. It does not crash. Which version of TeensyDuino and Arduino are you using?

Pete
 
I modified your new code to toggle the LED on every 100 times through the loop function so that I can see that it is still running. It does not crash. Which version of TeensyDuino and Arduino are you using?

Pete

This suggests to me you might be overflowing the MIDI buffer on your PC and the USB linkage is what is crashing.

EDIT - looks like you are sending messages on every loop. You need to send only if different from the previous to avoid MIDI overload.
 
Thanks to you both for the feedback.

I tried to extract the offending piece of code from a much larger program, but I'm realizing I left out a lot of context. (I never know exactly how much context to give or what the best way is to extract only the relevant details. I guess when you're bug hunting the bug really could be anywhere.) In the full program, I'm only sending MIDI signals when the value changes, so that's not the problem.

I don't think the USB linkage is crashing it because I can reboot the program without the USB cable plugged in, and it still doesn't work.

Alas, I'll keep digging. I'll also try to provide a more complete code snippet to reproduce the issue. It's so strange, because I can send MIDI data on any two channels, but as soon as I add a 3rd it crashes. (This only happens with the serial MIDI. I can send USB Midi with no problems.)

Thanks again.
 
Last edited:
Can you describe exactly what you mean by "it crashes". Is it possible that the Teensy is still running but the device it is talking to has stopped responding?
Would it be possible to add a piece of code to the loop function to toggle the LED to give an indication that the Teensy is "alive".

Pete
 
Sure. I have several LEDs in the circuit that flash when the program is running (LFO indicators). When I load the program, they all go out immediately. The serial monitor logs the first few things that I print to it, so I know the program is loading, but then the serial monitor stops logging and the LEDs all go out.

I'm working on extracting a reproducible version of it in code so I can give you more info to work with.
 
Aha!!! 48 hours of debugging has finally paid off.

It turns out I had a couple redundancies in the setup function that were causing a big pileup of MIDI data. Basically I was doing an initial read of all the knobs and sliders and sending MIDI data for all of them at the same time. No wonder it was crashing the Teensy.

Truly thanks to you both for helping spitball. It helped a lot.
 
Status
Not open for further replies.
Back
Top