teensy LC MIDI usb to serial and serial to usb... freeze.

lokki

Well-known member
hi there,

i have two teensy LC boards connected TX to RX pin and GND. one teensy receives MIDI from usb and sends it out the serial port and the other receives from serial and sends back out to usb (MIDI).

i reconfigured the serial midi baud rate to be much higher then standard midi in order to speed up the "conversion" from usb to usb.

this generally works very well, but sometimes the receiving teensy freezes completely and only a reset helps. i have compiled the code with the "fastest" optimisation, could that lead to freezes? is there any benefit in my use case to use the "fastest" optimisation? i just want to send the usb MIDI as fast as possible to the other usb-port. how long can the wire from TX to RX be at 1.5Mb baud rate? would it be wise to use a small resistor?

find attached the code of the two boards:

usb to serial:
Code:
#include <MIDI.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
//MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, MIDI2);
elapsedMillis ledOnMillis;
void setup() {
  pinMode(13, OUTPUT); // LED pin
  digitalWrite(13, LOW);
  MIDI1.begin(MIDI_CHANNEL_OMNI);
//  MIDI2.begin(MIDI_CHANNEL_OMNI);
  Serial1.begin(1500000);
 // Serial2.begin(1500000); 
  // put your setup code here, to run once:

}

void loop() {
  bool activity = false;
    if (usbMIDI.read()) {
    
    // get the USB MIDI message, defined by these 5 numbers (except SysEX)
    byte type = usbMIDI.getType();
    byte channel = usbMIDI.getChannel();
    byte data1 = usbMIDI.getData1();
    byte data2 = usbMIDI.getData2();
  //  byte cable = usbMIDI.getCable();

    // forward this message to 1 of the 3 Serial MIDI OUT ports
    if (type != usbMIDI.SystemExclusive) {
      // Normal messages, first we must convert usbMIDI's type (an ordinary
      // byte) to the MIDI library's special MidiType.
      midi::MidiType mtype = (midi::MidiType)type;

      // Then simply give the data to the MIDI library send()
      
          MIDI1.send(mtype, data1, data2, channel);
     //     MIDI2.send(mtype, data1, data2, channel);
            activity = true;
      }
  
    }
 if (activity) {
    digitalWriteFast(13, HIGH); // LED on
    ledOnMillis = 0;
  }
  if (ledOnMillis > 15) {
    digitalWriteFast(13, LOW);  // LED off
  } 
  // put your main code here, to run repeatedly:

}

serial to usb:
Code:
#include <MIDI.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
void setup() {
  MIDI1.begin(MIDI_CHANNEL_OMNI);
  Serial1.begin(1500000);
  // put your setup code here, to run once:

}

void loop() {
    if (MIDI1.read()) {
    // get a MIDI IN1 (Serial) message
    byte type = MIDI1.getType();
    byte channel = MIDI1.getChannel();
    byte data1 = MIDI1.getData1();
    byte data2 = MIDI1.getData2();

    // forward the message to USB MIDI virtual cable #0
    if (type != midi::SystemExclusive) {
      // Normal messages, simply give the data to the usbMIDI.send()
      usbMIDI.send(type, data1, data2, channel, 0);
    }
    }
  
  // put your main code here, to run repeatedly:

}
 
I was hoping someone qualified would reply. I think you should not use digitalWriteFast as I believe it's meant for compatibility only in Teensyduino.

I think you need not worry too much about the serial exchange speed given normal MIDI latencies.


Is there a reason you're not running the same code on each Teensy for two way traffic?




.. does anyone know of an example of a full thru program that could run on each teensy that converts USB to serial and vice versa?

I recall it being raised here but at the time there was no generic .send for USB MIDI and the two libraries had drifted apart making it difficult. Now it should be fairly easy and mostly would involve the three-byte MIDI as above plus a sysex pass-thru.
 
I was hoping someone qualified would reply. I think you should not use digitalWriteFast as I believe it's meant for compatibility only in Teensyduino.

I think you need not worry too much about the serial exchange speed given normal MIDI latencies.


Is there a reason you're not running the same code on each Teensy for two way traffic?




.. does anyone know of an example of a full thru program that could run on each teensy that converts USB to serial and vice versa?

I recall it being raised here but at the time there was no generic .send for USB MIDI and the two libraries had drifted apart making it difficult. Now it should be fairly easy and mostly would involve the three-byte MIDI as above plus a sysex pass-thru.

thanks for your answer!

let me explain:

-i need to worry about serial speed, because USB-Midi is much faster than serial midi, that is the whole point of the project :)
i am connecting two usb-host ports with each other. one host port is on my midi controller and hosts all physical instruments (synths), and one of them is a computer, used as a virtual instrument (running soft synths)

-i don't need two way communication, that is why i left it out. i thought it would be faster that way.

-the code comes from an example in teensyduino called Interface_3x3 so it really is very straightforward. i left out sysex, because again i don't need it.

-the digitalWriteFast part actually comes from that example as well, so i hope it is not the problem.

so i guess my questions are more general to serial communication. do i need to worry about cable length at these speeds (i have about 2cm now), is a small value resistor advised?

i recompiled the above code with the "fast" optimisations and slowed serial down to "Serial1.begin(500000);" it has been stable so far.

there is a document which shows the available Serial speeds and errors on teensies, but there are forum posts that claim the lc can go above those speeds (and use different speeds as well) on Serial1, so that is all a bit unclear to me.
 
Back
Top