Arduino uno midi system exclusive

I'm going to put the code soon, but now I have to go, and I want to do something right in the code before I put it, I have something wrong and do not have time right now.
thanks anyway
very kind of you
you are very helpful :wink:

The format of the messages should be explained in the manual of your keyboard, that's not something I can tell you.

You compare arrays in your code using std::equal or memcmp, or individual bytes using the == operator. You can find which of the bytes is set using something like
std::find or std::find_if, or a manual for loop if you don't have access to the standard library.

After some days working and searching Google, i wrote this code which is working good on pc by sending the message through the serial monitor, but still not working on my keyboard...:frowning:

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
#define MIDI_SYSEX_ARRAY_SIZE 255
static const unsigned SysExMaxSize = 256;
MIDI_CREATE_INSTANCE(HardwareSerial,Serial, MIDI);
const unsigned int MAX_MESSAGE_LENGTH = 69;
uint8_t Con[23]   ={0x42,0x7F,0x60,0x01,0x01,0x10,0x7D,0x00,0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
String C1= "F0 42 7F 60 01 01 10 7D 00 4E 00 00 00 00 00 00 00 00 00 00 00 00 F7";
String off="F0 42 7F 60 01 01 00 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7";
int led = 13;
int ledState = LOW;


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(led, OUTPUT);
 Serial.begin(9600);

}

void loop() {

 //Check to see if anything is available in the serial receive buffer
 while (Serial.available() > 0)
 {
   //Create a place to hold the incoming message
   static char message[MAX_MESSAGE_LENGTH];
   static unsigned int message_pos = 0;
  
   //Read the next available byte in the serial receive buffer
   char inByte = Serial.read();
int S = MIDI.getSysExArray();
char X = MIDI.getSysExArray();
byte Z = MIDI.getSysExArray();


   //Message coming in (check not terminating character) and guard for over message size
   if ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1) )
   {
     //Add the incoming byte to our message
     message[message_pos] = inByte;
     message_pos++;
     
   }
   //Full message received...
   
   else
   {
     //Add null character to string
     message[message_pos] = '\0';
  String Y = message;
  
     //Print the message (or do other things)
   
     if (Y == off && ledState == HIGH)
 {
 ledState = LOW;}
 if (Y == C1 && ledState == LOW)
 {
 ledState = HIGH;}
     
     //Reset for the next message
     message_pos = 0;
    
   Serial.println(S);
    Serial.println(X);
     Serial.println(Z); 
     Serial.println(Y);
     Serial.println(message); 
   }
  }
  digitalWrite(led, ledState);
 }

Hi, I have checked if I change Serial baud from 9600 to 31250 , the code will not work even on my PC!
Someone help please
Im new on writing Arduino codes...

I'm sorry, but the code you posted doesn't make any sense.

These aren't used anywhere.

Neither is this MIDI interface you're creating here.

These are not MIDI messages, they are readable text representations for humans, they will never compare equal to the actual binary MIDI messages you might receive from your keyboard.

You never call MIDI.read() so this will never return anything meaningful. On top of that, MIDI.getSysExArray() returns a pointer to an array of bytes, you cannot store that in any of the types you have in your code. The compiler should be complaining about that, please open the IDE preferences and turn up the warnings.

As mentioned earlier, this can never be true for actual MIDI messages.

Does your PC support 31250 baud? Did you select that baud rate in the serial monitor?

I would recommend taking a step back, before you start combining snippets of code, start with simple, small examples, and try to understand each line, each word, each character before combining it with other examples.
You'll also need to understand what “baud” rate means, how serial ports work, and how MIDI data is encoded.

you're right, but this code is mixed I know, for me to try and see the result, it's not done, still working hard to build a real project, add and delete new lines to finde out how things works, the Strings C1 and off are just to compare to have a function to light the led goes on when SysEx message received and it works when i send from PC through the serial terminal, I know I'm a little confused, but I do not want to give up, i will continue study on it.
thanks so much for the tip, i will check further and write the result here then.

I have found this copy, then I would study midi SysEx more, and when I upload the code in my UNO, then on serial monitors only strange signs come ....
is there something wrong with UNO that does not fit this service or is there something wrong with my PC?!!!

#include <MIDI.h>

byte sysex14[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0xF7 };
byte sysex15[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0x4D, 0xF7 };
byte sysex16[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x32, 0x50, 0x4D, 0xF7 };
byte sysexBig[] = { 0xF0, 0x41,
                    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
                    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
                    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
                    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
                    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
                    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
                    0x7a,

                    0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
                    0xF7
                  };

MIDI_CREATE_DEFAULT_INSTANCE();

unsigned long t0 = millis();

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void setup()
{
  Serial.begin(115200);
  while (!Serial);

  // Listen for MIDI messages on channel 1
  MIDI.begin(1);

  MIDI.setHandleSystemExclusive(OnMidiSysEx);
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void loop()
{
  // Listen to incoming notes
  MIDI.read();

  // send a note every second
  // (dont cáll delay(1000) as it will stall the pipeline)
  if ((millis() - t0) > 1000)
  {
    t0 = millis();
    //   Serial.print(F(".");

    MIDI.sendSysEx(sizeof(sysex14), sysex14, true);
  }
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void OnMidiSysEx(byte* data, unsigned length) {
  Serial.print(F("SYSEX: ("));
  Serial.print(length);
  Serial.print(F(" bytes) "));
  for (uint16_t i = 0; i < length; i++)
  {
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

On serial monitor:----

The serial monitor only supports text (ASCII, UTF-8), it cannot print MIDI messages. You'll either have to use a MIDI interface connected to pins 0/1 or software like Hairless.

You cannot use Serial and MIDI at the same time on an Arduino UNO. There's only a single serial port that's used for uploading, the serial monitor and MIDI. You can only use it for one task at a time. Other boards have multiple serial ports.

Thanks for your replay:
can i use somthing like this?!
Köp USB IN-OUT MIDI-gränssnittskabelomvandlare PC till musik-tangentbord | Fyndiq

You could, but I wouldn't recommend it (you would need additional hardware to connect it to the Arduino, and you would still be unable to use the serial monitor for debugging).
If it's just for quick testing, use Hairless, if it's for a permanent project (and if you need your PC to see the Arduino as a MIDI device), get an Arduino board that supports MIDI over USB natively.

Does the MIDI keyboard you intend to use have 5-pin DIN connectors? In that case you don't need a MIDI USB interface. If your MIDI keyboard has a USB connector for MIDI, it's probably a device port, and a MIDI USB interface won't work either.

I want to make my project just working with my keyboard, as I mentioned, I have a little big project going on, breath controller + quarter switch control, then I would use a touch screen, all in one.
except for the LCD touch screen as I would take it last, everything else works and talk to my keyboard perfectly via USB, but SysEx comparison I can not succeed ...
Arduino sends SysEx message to the keyboard but as I said, I would that when I press my keybard and send back the same message that my arduino board should rule...
therefore I take each sketch separately and try it, then put everything in one
Thanks att all
Best regard

Are you connecting the Arduino to this keyboard directly? Does your keyboard have a host or a device USB port? Do you have a model number for this keyboard?

Korg Pa4x, it have USB port and host

You could try something like this:

#include <Control_Surface.h> // https://github.com/tttapa/Control-Surface

USBDebugMIDI_Interface midi;

constexpr uint8_t Coff[] {0xF0,0x42,0x7F,0x60,0x01,0x01,0x10,0x7D,0x00,0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF7};
constexpr uint8_t Con[]  {0xF0,0x42,0x7F,0x60,0x01,0x01,0x00,0x7D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF7};

constexpr uint8_t ledPin = 13;
bool ledState = false;

void updateLed(bool state) {
  ledState = state;
  digitalWrite(ledPin, ledState ? HIGH : LOW);
}

// Custom MIDI callback to handle incoming SysEx messages.
struct MyMIDI_Callbacks : MIDI_Callbacks {

  // This function is called when a SysEx message is received.
  void onSysExMessage(MIDI_Interface &, SysExMessage sysex) override {
    if (sysex.length == sizeof(Coff)
     && std::equal(std::begin(Coff), std::end(Coff), sysex.data)) {
      updateLed(false);
    } else if (sysex.length == sizeof(Con)
     && std::equal(std::begin(Con), std::end(Con), sysex.data)) {
      updateLed(true);
    }
    // Note that the std::equal calls could be optimized because the
    // Coff and Conn messages are largely the same, but this is just
    // a proof of concept
  }

} callback;

// Push button connected between pin 12 and ground. 
// Internal pull-up is enabled.
Button pushbutton {12};

void setup() {
  pushbutton.begin(); // enables internal pull-up
  pinMode(ledPin, OUTPUT);
  midi.begin();
  midi.setCallbacks(callback);
}

void loop() {
  if (pushbutton.update() == Button::Falling) {
    updateLed(!ledState);
    midi.sendSysEx(ledState ? Con : Coff);
  }

  // Read incoming MIDI data and call the callback if a new
  // SysEx message has been received.
  midi.update();
}

Upload, open the serial monitor (115200 baud) and press the button on pin 12 (connected to ground, using internal pull-up resistor).
You should see something like this:

System Exclusive [23]	F0 42 7F 60 01 01 00 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7
System Exclusive [23]	F0 42 7F 60 01 01 10 7D 00 4E 00 00 00 00 00 00 00 00 00 00 00 00 F7
System Exclusive [23]	F0 42 7F 60 01 01 00 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7
System Exclusive [23]	F0 42 7F 60 01 01 10 7D 00 4E 00 00 00 00 00 00 00 00 00 00 00 00 F7

Now enter F0 42 7F 60 01 01 00 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7 and press enter. The LED should turn on.
Enter F0 42 7F 60 01 01 10 7D 00 4E 00 00 00 00 00 00 00 00 00 00 00 00 F7 and the LED should turn off.

To test it with your keyboard, change USBDebugMIDI_Interface midi to HardwareSerialMIDI_Interface midi = Serial. Then use MIDI firmware such as USBMidiKlik.

1 Like

thanks for the help, it works great on my PC and the keyboard, then it's time to think further and find out how should I enter everything so that all my twelve buttons with LEDs will work ...
all real messages coming from my keyboard are like this:
F0 42 7F 60 01 01 10 7D 00 4E 00 00 00 00 00 00 00 00 00 00 00 00 F7
F0 42 7F 60 01 01 18 7D 00 4E 4E 00 00 00 00 00 00 00 00 00 00 00 F7
F0 42 7F 60 01 01 1C 7D 00 4E 4E 4E 00 00 00 00 00 00 00 00 00 00 F7
F0 42 7F 60 01 01 1E 7D 00 4E 4E 4E 4E 00 00 00 00 00 00 00 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 00 00 00 00 00 00 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 40 4E 00 00 00 00 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 60 4E 4E 00 00 00 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 70 4E 4E 4E 00 00 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 78 4E 4E 4E 4E 00 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 7C 4E 4E 4E 4E 4E 00 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 7E 4E 4E 4E 4E 4E 4E 00 F7
F0 42 7F 60 01 01 1F 7D 00 4E 4E 4E 4E 4E 7F 4E 4E 4E 4E 4E 4E 4E F7
And last to switch off all is:
F0 42 7F 60 01 01 00 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7

you are the best hero ever PieterP
maybe i ask more questions if it's ok !?

You can access the i-th byte of the message using sysex.data[i] (index is zero-based).

Sure, I don't have much free time at the moment, but you can always ask questions here.