Addressing multiple serial midi outputs through a variable or array?

Status
Not open for further replies.

massahwahl

Active member
The midi controller that I am building has 5 serial midi outputs on it and will not be using usbmidi. I am having a difficult time finding good examples that show how other people have handled multiple serial midi outputs with regards to assigning them to variables that I can cycle between.

Currently, my outputs are established as:
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, MIDI2);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, MIDI3);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial4, MIDI4);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial5, MIDI5);

This works fine for establishing my outputs and I can send commands to them individually but the problem I am trying to figure out is how to address them programmatically through a variable that i could change through an interface control such as a button.

Ideally assigning them to an array seems like the best option but for the life of me I can not decipher what the proper syntax is to do this with the MIDI.h library. Is there a better way to do it or is anyone familiar with how to handle this?
 
Maybe this is along the needed lines ?

I posted this on the T4_Beta thread - using the 7 Serial# ports it has - you can see the array I made and then cycle through - courtesy of a further refines sample from KurtE:
Code:
#define SPD 2000000
#define BUFFER_SIZE  320
char buffer_out[BUFFER_SIZE];
char buffer[80];

[B]HardwareSerial *psAll[7] = { &Serial1, &Serial2, &Serial3, &Serial4, &Serial5, &Serial6, &Serial7 };[/B]
void setup() {
  pinMode(13, OUTPUT);
  for ( int ii = 0; ii < 7; ii++ ) {
    psAll[ii]->begin(SPD);
  }
  digitalWrite( LED_BUILTIN, 1 );
  while (!Serial && millis() < 2200) digitalWrite( LED_BUILTIN, !digitalRead( LED_BUILTIN) );
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  digitalWrite( LED_BUILTIN, 1 );
  delay(100);
  Serial.print("Test all Serials - Serial @ms=");
  digitalWrite( LED_BUILTIN, !digitalRead( LED_BUILTIN));
  delay(100);
  Serial.println(millis());
  digitalWrite( LED_BUILTIN, !digitalRead( LED_BUILTIN));
  delay(10);
  Serial.printf("Baud rate: %d\n", SPD);
  digitalWrite( LED_BUILTIN, !digitalRead( LED_BUILTIN));
  Serial1.println( "Hello World! #1" );
}

[B]void serialXfer(HardwareSerial * psIn, HardwareSerial * psOut, bool bWrite, uint32_t ii)[/B]
{
  uint32_t cb = psIn->available();
  if (cb) {
    if (cb > sizeof(buffer)) cb = sizeof(buffer);
    [B]if (cb >  psOut->availableForWrite()) cb = psOut->availableForWrite();[/B]
    psIn->readBytes(buffer, cb);
    if ( bWrite ) {
      psOut->print((char)('A' + ii));
      psOut->write(buffer, cb);
    }
  }
}

uint32_t iiCnt = 0;
void loop() {
  for ( int ii = 0; ii < 7; ii++ ) {
    serialXfer( psAll[ii], psAll[ii], true, ii );
    Serial.print( buffer );
    delay(10);
  }
  Serial.println( "==============================" );
  delay(2000);
  iiCnt++;
  if ( !(iiCnt % 10) ) {
    for ( int jj = 0; jj < 4; jj++ ) {
      for ( int ii = 0; ii < 7; ii++ ) {
       [B] serialXfer( psAll[ii], psAll[ii], false, ii );[/B]
        delay(5);
      }
    }
    Serial1.print( "Hello World!" );
    Serial1.println( iiCnt );
    buffer[0] = 0;
  }
}
 
Thank you! This definitely looks promising and solves the problem of how to properly address each output in an array. I’ll have to check out the T4 page and see what that’s all about, it looks a lot more complicated than what I’m probably going to accomplish!
 
I know nothing of MIDI. But, using standard C++ techniques, you can define your array of MIDI object pointers like this:
Code:
#include "Arduino.h"
#include "Audio.h"
#include "MIDI.h"

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, MIDI2);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, MIDI3);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial4, MIDI4);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial5, MIDI5);

midi::MidiInterface<HardwareSerial> *interfaceArray[] = { &MIDI1, &MIDI1, &MIDI3, &MIDI4, &MIDI5 };

const uint8_t numMidi = sizeof(interfaceArray) / sizeof(interfaceArray[0]);

void setup() {
	for (uint8_t i = 0; i < numMidi; i++) {
		interfaceArray[i]->begin();
	}
}

void loop() {
}
 
… the mechanics work - the Array, passing and using the pointers .. - just a trivial and incomplete sample that runs each of 7 serial ports cross wired between two Teensys to send and receive the message across all the ports.
 
You can also instantiate an array of objects directly:
Code:
#include "Arduino.h"
#include "MIDI.h"

midi::MidiInterface<HardwareSerial> interfaceArray[] = {
		{ Serial1 }, { Serial2 }, { Serial3 }, { Serial4 }, { Serial5 }
};

const uint8_t numMidi = sizeof(interfaceArray) / sizeof(interfaceArray[0]);

void setup() {
	for (uint8_t i = 0; i < numMidi; i++) {
		interfaceArray[i].begin();
	}
}

void loop() {
}
 
I owe all you guys a beer! Thank you so much for the suggestions. gfvalvo I had about gave up on trying to figure out how to do exactly that! I've been close to this a couple times but never got it right, I think because I was not understanding what the "::" does.
 
Thank you for the explanation, i do coding with VB for my day job and C++ is way different but its coming together the further i get into these more complex topics like this. Much appreciated!
 
Status
Not open for further replies.
Back
Top