Unable to bit-bang SoftwareSerial MIDI DIN pins

Status
Not open for further replies.

Sandwich

Member
Hey there!

I'm having trouble making software serial MIDI connections. I have everything wired up and it works flawlessly on true Serial1-SerialX pins, but when I try to implement the software ones I'm not getting anything. Using my setup (with USB set to MIDI in the arduino sketch upload) I'm able to monitor MIDI commands over the USB jack as well as with equipment on the outbound DIN ports. And both USB and DIN ports work fine and communicate all directions when all connections are hardware serial, but no data seems to be getting transferred over software serial at all. I've stripped down the sketch to be pretty basic at this point trying to troubleshoot the issue:

Code:
#include <Arduino.h>
#include <MIDI.h>
#include <USBHost_t36.h> // access to USB MIDI devices (plugged into 2nd USB port)
#include <SoftwareSerial.h>


//pins for software bit-banged MIDI DIM ports
SoftwareSerial softSerial1(4, 5); //rx, tx



// Create the Serial MIDI ports
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
MIDI_CREATE_INSTANCE(SoftwareSerial, softSerial1, MIDI2);



void setup() {
  
  //Serial.begin(115200);  //for serial connection over usb to PC
  
  //initialize DIN connectors
  MIDI1.begin(MIDI_CHANNEL_OMNI);
  MIDI2.begin(MIDI_CHANNEL_OMNI);
}

void loop() {
  
  if (MIDI1.read()) {
    sendMIDI(MIDI1.getType(), MIDI1.getChannel(), MIDI1.getData1(), MIDI1.getData2(), MIDI1.getSysExArray());
  }

  if (MIDI2.read()) {
    sendMIDI(MIDI2.getType(), MIDI2.getChannel(), MIDI2.getData1(), MIDI2.getData2(), MIDI2.getSysExArray());
  }

  if (usbMIDI.read()) {
    sendMIDI(usbMIDI.getType(), usbMIDI.getChannel(), usbMIDI.getData1(), usbMIDI.getData2(), usbMIDI.getSysExArray()); //usbMIDI.getCable());
  }
  
}


// When messages are received, this function sends the message to all the devices
void sendMIDI(byte type, byte channel, byte data1, byte data2, const uint8_t *sysexarray) {
  
  if (type != midi::SystemExclusive) {
    midi::MidiType mtype = (midi::MidiType)type;
    
    // Normal messages, simply give the data to the usbMIDI.send()
    MIDI1.send(mtype, data1, data2, channel);
    MIDI2.send(mtype, data1, data2, channel);
    usbMIDI.send(type, data1, data2, channel, 0);
    
  } else {
    
    // SysEx messages are special.  The message length is given in data1 & data2
    unsigned int SysExLength = data1 + data2 * 256;
    MIDI1.sendSysEx(SysExLength, sysexarray, true);
    MIDI2.sendSysEx(SysExLength, sysexarray, true);
    usbMIDI.sendSysEx(SysExLength, sysexarray, true, 0);
    
  }
  usbMIDI.send_now();  
}

Thanks for any help!
 
SoftwareSerial on Teensy 3.6 only supports transmitting, unless you choose 2 pins which are a real serial port. But for the MIDI library, you should not use SoftwareSerial (on any board, not just Teensy) because SoftwareSerial disables interrupts for too long. That long interrupt disable time can cause data loss on the other real serial port.

Use the real serial ports on Teensy 3.6 for MIDI.
 
I'm actually using a 4.0, I forgot to include that. But, I wanted to be able to be able to include more ports eventually than there are hardware pins. I think the teensy night actually run fast enough to do that if I could figure out what library to use for software serial. But, I could probably get away with just having more output ports than there are hardware pins, and just using hardware for inputs.
 
Last edited:
As an aside, even when using a hardware input to successfully collect the MIDI in, the software serial library I'm using isn't outputting the MIDI over software serial with the code I included in the original post.
 
I am trying to achieve something similar on a Teensy 3.5. I also have my reasons for not using any of the hardware serial ports. I need them for other things. People on this thread have been saying you can't use SoftwareSerial MIDI on Teensy boards, but not given any reason for that. I will use much needed functionality if I cannot pull this off.
 
People on this thread have been saying you can't use SoftwareSerial MIDI on Teensy boards, but not given any reason for that.

Maybe you didn't see msg #3, where I wrote "SoftwareSerial on Teensy 3.6 only supports transmitting, unless you choose 2 pins which are a real serial port"? Or maybe you missed the words "because SoftwareSerial disables interrupts for too long. That long interrupt disable time can cause data loss on the other real serial port".

Hopefully those reasons are clear? You can't use SoftwareSerial to receive because it doesn't support receiving at all, and you can't use it to transmit without messing up the other 6 ports which you apparently need for some purpose you aren't willing to say.

However, you might be able to use AltSoftSerial. It does support both transmitting and receiving on Teensy 3.5. It only supports pins 20 & 21, because it uses the timer hardware connected to those pins. It does generate a lot of interrupts (up to 1 per bit), so AltSoftSerial isn't nearly as efficient as regular hardware serial. But at least AltSoftSerial doesn't hog the CPU and it can tolerate some interrupt latency from other uses, so you've got a pretty good chance of an error-free 7th serial stream while those other 6 serial ports are actively transmitting and/or receiving.

If any of your other 6 serial streams can use a slower baud rate, you might do better to use AltSoftSerial for the slower speed and use a real hardware serial port for MIDI.

If any of your other serial ports need high baud rates, use Serial1 or Serial2, because those are the only 2 ports (on Teensy 3.5) with FIFOs.
 
Thanks Paul,
no that wasn't clear. I'll definitely take it from you as an authoritative answer.
I know this is off-topic as far as this thread is concerned, but could you please tell me if A25, A26 can be made to work as analog input while also using the USB?
alternatively if A23, A24 can be used - given some skilful soldering? If I need to move MIDI back to RX4,TX4 then I need to find alternatives for those analog inputs.
 
I know this is off-topic as far as this thread is concerned, but could you please tell me if A25, A26 can be made to work as analog input while also using the USB?
Assuming T3.5 - Then the pins that on T3.6 would be USB Host pins), then yes you should be able to use those two pins as Analog pins.

BUT note: like other Analog only pins, these pins ARE NOT 5v tolerant.
 
Status
Not open for further replies.
Back
Top