When I use SysEx-Send-Receive for sending a SysEx message with a button, I get an unexpected behaviour; the sketch get uploaded and runs perfectly, through MIDI Monitor I can see the SysEx message being sent normally.
However if I monitor the activity between Midi Device and Midi Host, I don't see any SysEx message from the host.
I can see any other kind of messages (PB, CC, Notes) from the Host, except SysEx.
If I plug the host directly to the computer I can see the SysEx messages.
What's the intention of these lines? sysex is a C-style array, it doesn't have a .data() method. Even if it did, data() would be a pointer, so you couldn't compare it to an integer.
Finally, the check is unnecessary, because you just set the first element to 0xF0.
The code I've highlighted does not deal with received messages at all, so it's not quite clear what it tries to achieve. The "detection" of incoming SysEx messages is already handled by the library, you only get a callback when a SysEx message is received, and it will always start with 0xF0.
Hi again,
yes it works BUT there is still something that doesn't look right:
actually I don't need the sketch to send the same SysEx message every time it receives a SysEx. Shall I get rid of midi.update to send my SysEx just once?
unfortunately the Teensy passthrough sketch doesn't let SysEx messages to pass through (sorry for the word play) from the host to the device. It runs but IDE gives me the following warning, which seems SysEx related: cast between incompatible function types from 'void ()(const uint8_t, uint16_t, bool)' {aka 'void ()(const unsigned char, short unsigned int, bool)'} to 'void ()(const uint8_t, uint16_t, uint8_t)' {aka 'void ()(const unsigned char, short unsigned int, unsigned char)'} [-Wcast-function-type]
347 | usb_midi_handleSysExPartial = (void (*)(const uint8_t *, uint16_t, uint8_t))fptr;
No, that wouldn't work. Besides, you need to regularly update the MIDI interface to clear the USB buffer, otherwise you'll stall the MIDI software on the computer. Simply create a global counter or flag, increment or set it whenever you send a SysEx message, and then make the sending conditional using e.g. if (num_messages_sent < 10) to limit the number of responses you send.
Yes, I though about the global counter. But can I move the whole MyMIDI_Callbacks inside the Loop section if I want to make it conditional?
Something like this:
#include <Control_Surface.h>
USBMIDI_Interface midi;
int passFlag = 0;
void setup() {
Serial.begin(115200);
Control_Surface.begin();
midi.begin();
midi.setCallbacks(callback);
}
void loop() {
Control_Surface.loop();
if(passFlag == 0) {
uint8_t sysexout[]{ 0xF0, 0x11, 0x22, 0x33, 0xF7 };
// Custom MIDI callback that prints incoming SysEx messages.
struct MyMIDI_Callbacks : MIDI_Callbacks {
// This callback function is called when a SysEx message is received.
void onSysExMessage(MIDI_Interface &, SysExMessage sysex) override {
// Send the message
midi.sendSysEx(sysexout);
}
} callback{};
passFlag++; // Increment passFlag
}
// SysEx message has been received.
midi.update();
}
Re-Midipass-through, I could create a different topic for this issue for avoiding confusion.
At least in the code you posted, passFlag is only accessed in the onSysExMessage() function of the myMIDI_Callbacks struct. So, there's no need for it to be global. Why not make it a data member of the struct?