Pages: [1]   Go Down
Author Topic: MIDI.getSysexArray - How to flusch the returned message?  (Read 730 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

Using <midi.h> library V3.2, I just try basically to have a diode blinking when a specific Sysex comes in.

Indeed, my MIDI device sends at each beat the same SysexMessage, where byte[5]==0x10. So I 'd like to have the tempo blinking.

So I wrote the following program :

Code:
#include <LiquidCrystal.h>
#include <MIDI.h>

const byte *  MyArray;
int ledPin = 13;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  pinMode(ledPin, OUTPUT);     
  lcd.begin(16,2);
  MIDI.begin();
  MIDI.turnThruOff();
}

void loop()
{
  MIDI.read();
  MyArray = MIDI.getSysExArray();
  lcd.setCursor(0,0);
  lcd.print(MyArray[5]);
  if ((MyArray[5])==0x10 )
    {
    digitalWrite(ledPin, HIGH);
    }
     
  else if ((MyArray[5])!=0x10 )
    {
    digitalWrite(ledPin, LOW);   
    }
}


As a result, the diode remains HIGH. It never comes down to the LOW state. When monitoring on the lcd MyArray[5] byte, it remains 0x10 all the time.

So I was wondering what's returned by "MIDI.GetSysExArray" request between 2 SysEx message received?
Does the function keeps in memory the last Sysex message?
If yes, is there a way to flush it?

Lionel
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49335
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  lcd.print(MyArray[5]);
How do YOU know how big the message is? There is nothing that is checking that 5 is a valid index.

Quote
Does the function keeps in memory the last Sysex message?
Yes, it does.

Quote
If yes, is there a way to flush it?
No, but you shouldn't need to.

You could quit ignoring the message type that was received, and pay attention to whether or not the last message was a sysex message.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Developer of the MIDI library
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

What you can do is the following:

Code:
void handleSysEx(byte* inData, byte inSize)
{
    if (inSize > 5)
    {
        if (inData[5] == 0x10)
            digitalWrite(ledPin, HIGH);
        else
            digitalWrite(ledPin, LOW);
    }
}

void setup()
{
    MIDI.begin();
    MIDI.setHandleSystemExclusive(handleSysEx);
}

void loop()
{
    MIDI.read();
}



Regarding your problem, are you sure there is another SysEx message with the fifth byte != 0x10 that is received, to turn off the LED?
If you want to detect beat, you can check for other supported messages, like Clock or SMPTE. They also have callbacks, although I think I fixed a few bugs in these since version 3.2.
The latest version is always available on GitHub:
https://github.com/FortySevenEffects/arduino_midi_library

Cheers!

Franky.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi!
Thanks a lot for your answers smiley!

First, the MIDI device (Axe-Fx 2) I use sends at each beat the following SysEx message (HEX):
{F0 00 01 74 03 10 F7}
So if tempo is 60, this message is sent once per second. I verified this by monitoring the MIDI out of the AF2 on my Digital Audio Worstation (Cubase). Nothing else comes.
And, except on request (unsing a specific SysEx code for example), the AF2 sends nothing else between 2 SysEx tempo message.

On the other hand, if I use another MIDI device that sends nothing on "idle", and if I request a "getSysExArray" to this other device, then the byte [5] returned is == 0.

Then Paul, to answer your point
Quote
How do YOU know how big the message is? There is nothing that is checking that 5 is a valid index.
I know it's a 7 byte array. But, even if there is no array, I get the value "0" in byte [5] (of course this is in case I did not receive previously a SysEx message) . 

Regarding
Quote
You could quit ignoring the message type that was received, and pay attention to whether or not the last message was a sysex message.
The last message is always the same SysEx.

Francky, I tested the code you suggested. And Finally I got the led High all time. It only gets on the LOW state when I send another SysEx message where byte[5] != 0x10. So it does not blink with tempo.

Quote
Regarding your problem, are you sure there is another SysEx message with the fifth byte != 0x10 that is received, to turn off the LED?
Indeed there is no other SysEx message received between.  smiley-cry

Quote
If you want to detect beat, you can check for other supported messages, like Clock or SMPTE.
Yeah I'd like to, but actully I receive nothing else but this tempo SysEx array.

Finally, I do use you latest version of the Library, but I have not yet tried to understand what are CallBacks.

Do you know if I can find or build a function (newbe level...) that could differenciate 2 identical SysEx array thanks only to lets say... their time of arrival  smiley-lol?

Cheers !!

Lionel

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Developer of the MIDI library
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If you can only set the LED high when you receive the beat message, then you could use a counter variable to turn off the LED after a few calls of the loop() method when no message has been received.

The SysEx buffer will contain valid data only when a SysEx message is received, and should not be used when other messages are received (or no message at all).

Callbacks are functions that you ask the library to call when a kind of message is received. It makes the handling of MIDI input much easier (and faster) than a big block of if/else in the loop..
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Francky,
If I turn of the led after a few loop, it turns off, indeed. But as soon as I will send a GetSysExArray, it will return message from the SysEx buffer right? So it will be the previous message and will turn on the led not because a new message has arrived, but because there is still the message in the buffer.
Is there a way to know if it is read from a new message arrived, and not from the buffer?

Lionel
« Last Edit: December 19, 2012, 02:43:39 pm by reblochon » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 51
Developer of the MIDI library
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The point of the callback is that it's called only when a new message is received. You should not need to access the SysEx buffer anyway, since it is passed as an argument of your callback function.

The following code should do what you need:

Code:
#include <MIDI.h>

static const unsigned gLedPin = 13;

// Number of loops until turning off the led.
static const unsigned gLedCounterThreshold = 100;
unsigned gLedCounter = 0;

// -----------------------------------------------------------------------------

void handleSysEx(byte* inData, byte inSize)
{
    if (inSize > 5 && inData[5] == 0x10)
    {
        digitalWrite(gLedPin, HIGH);
        gLedCounter = gLedCounterThreshold;
    }
}

// -----------------------------------------------------------------------------

void setup()
{
    pinMode(gLedPin, OUTPUT);
    MIDI.begin();
    MIDI.turnThruOff();
    MIDI.setHandleSystemExclusive(handleSysEx);
    gLedCounter = 0;
}

void loop()
{
    MIDI.read();
    if (digitalRead(gLedPin) && gLedCounter-- == 0)
    {
        digitalWrite(gLedPin, LOW);
    }
}

Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley-lol Hello Francky ! Your program is now working perfectly!!!
Thank you soooooo much smiley!
I'll now get a closer look to understand it!!!
Thanks again,
Lionel
Logged

Pages: [1]   Go Up
Jump to: