teensy 3.6 midi sysex and clock prob

Status
Not open for further replies.

rotabox

Well-known member
hello
im bulding code for teensy 3.6 with midi clock and sysex massages handle HUI mackie midi protocol
the sysex massges code part is working ok and the clock is also working ok but separately.
but when i add the clock function the clock not respond to my protocol and the massage going crazy

its seems that the code work ok in studio one hui protocol when i checked the midi monitor but when i use it in protools hui protocol this code acts different and working correctly when the sysex and the ping handle working together.

*if i remove the sysex handle and run the code the ping seems to be ok and giving feedback to the system. then i bring back the sysex handle and flash the teensy when protools is steal runing. then i got the code works ok somehow but after i reset the teensy its not getting ping again and the sysex masseges i get is going crazy again. maybe im missing some delay somewhere?
any idea?
tnx
rota

here is my code:



Code:
#include <MIDIUSB.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include "Wire.h"
#endif

extern "C" { 
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
#define TCAADDR 0x70 // TCA9548A Encoder address
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); 



// Logic Control system exclusive messages
// changed serialnumber of Logic control from 48 to 49
const byte sysExHeader[6]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,};
//onst byte sysExDeviceQuery[8]                  = {0xF0,0x00,0x00,0x66,0x05,0x00,0xF7};
//onst byte sysExHostConnectionQuery[18]         = {0xF0,0x00,0x00,0x66,0x05,0x01,0x49,0x41,0x31,0x33,0x35,0x36,0x38,0x64,0x7A,0x61,0x41,0xF7};
//onst byte sysExHostConnectionConfirmation[14]  = {0xF0,0x00,0x00,0x66,0x05,0x03,0x49,0x41,0x31,0x33,0x35,0x36,0x38,0xF7};
//const byte sysExVersionReply[12]                = {0xF0,0x00,0x00,0x66,0x05,0x14,0x56,0x31,0x2E,0x30,0x32,0xF7};

//SCREANS RECOGNITION
const byte scrn0[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x00};
const byte scrn1[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x01};
const byte scrn2[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x02};
const byte scrn3[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x03};
const byte scrn4[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x04};
const byte scrn5[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x05};
const byte scrn6[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x06};
const byte scrn7[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x07};

int           sysExIndex=0;     // index for keeping track of incoming sysEx bytes
int ppqn = 0;

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

// handle incoming sysex messages
void handleSysEx(const byte* sysExData, uint16_t sysExSize, bool complete)
{
  // check if this is the start of the sysEx message
  if (sysExData[0]==240){
    sysExIndex=0;
  }
  Serial.print("The sysex length is ");
  Serial.print(sysExSize);
  Serial.print(" bytes\t");
  Serial.print("complete is\t");
  Serial.print(complete);
  Serial.println(); 
  for (int i=0;i<sysExSize;i++){
    sysExIndex++;
    Serial.print(sysExData[i],HEX);
    Serial.print(" ");
  }
  Serial.println(); 
  // message end
  if (complete && sysExData[sysExSize-1]==247){
   Serial.print("The total sysex message length is ");
   Serial.print(sysExIndex);
  Serial.print(" bytes");

  boolean isMackieControlMessage = true;
     // compare the first five bytes of the message to the sysExHeader to check if it is a Mackie control message
      for (int i=0;i<5;i++) {
        if (sysExData[i]!=sysExHeader[i]) {
          isMackieControlMessage = false;
        }
      }
      // handle mackie control message
      if (isMackieControlMessage) {
        Serial.println(" this is mackie massage");
      }
  }
 
    //sysex array
    const byte *pSysExArray = usbMIDI.getSysExArray(); //capture data
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x00){
           tcaselect(0);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i]);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x01){
           tcaselect(1);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x02){
           tcaselect(2);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x03){
           tcaselect(3);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x04){
           tcaselect(4);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x05){
           tcaselect(5);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x06){
           tcaselect(6);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x07){
           tcaselect(7);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
}           
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission(); 
}
void setup() {
  // register sysEx event handler function
  usbMIDI.setHandleSysEx(handleSysEx);
  //usbMIDI.setHandleNoteOff(myNoteOff);

  Serial.begin(9600);
  u8g2.begin();
  ppqn = 0;
}

void loop() {
  // read usbMIDI, let the handlers do their job
 usbMIDI.read();
  while (usbMIDI.read()) {
  }
}

void myNoteOff(byte channel, byte note, byte velocity) {
    ++ppqn;
    //Serial.println(channel);
       if(ppqn == 1){
          noteOn(0,0,127);
          MidiUSB.flush();
          ppqn = 0;
       }  
  }
 
Last edited by a moderator:
You should remove this from your loop:
Code:
while (usbMIDI.read()) {
}


Please put the code in CODE tags, it makes it so much more readable.
 
hello
im bulding code for teensy 3.6 with midi clock and sysex massages handle HUI mackie midi protocol
the sysex massges code part is working ok and the clock is also working ok but separately.
but when i add the clock function the clock not respond to my protocol and the massage going crazy

its seems that the code work ok in studio one hui protocol when i checked the midi monitor but when i use it in protools hui protocol this code acts different and working correctly when the sysex and the ping handle working together.

*if i remove the sysex handle and run the code the ping seems to be ok and giving feedback to the system. then i bring back the sysex handle and flash the teensy when protools is steal runing. then i got the code works ok somehow but after i reset the teensy its not getting ping again and the sysex masseges i get is going crazy again. maybe im missing some delay somewhere?
any idea?
tnx
rota

here is my code:



Code:
#include <MIDIUSB.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <U8x8lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include "Wire.h"
#endif

extern "C" { 
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}
#define TCAADDR 0x70 // TCA9548A Encoder address
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); 



// Logic Control system exclusive messages
// changed serialnumber of Logic control from 48 to 49
const byte sysExHeader[6]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,};
//onst byte sysExDeviceQuery[8]                  = {0xF0,0x00,0x00,0x66,0x05,0x00,0xF7};
//onst byte sysExHostConnectionQuery[18]         = {0xF0,0x00,0x00,0x66,0x05,0x01,0x49,0x41,0x31,0x33,0x35,0x36,0x38,0x64,0x7A,0x61,0x41,0xF7};
//onst byte sysExHostConnectionConfirmation[14]  = {0xF0,0x00,0x00,0x66,0x05,0x03,0x49,0x41,0x31,0x33,0x35,0x36,0x38,0xF7};
//const byte sysExVersionReply[12]                = {0xF0,0x00,0x00,0x66,0x05,0x14,0x56,0x31,0x2E,0x30,0x32,0xF7};

//SCREANS RECOGNITION
const byte scrn0[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x00};
const byte scrn1[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x01};
const byte scrn2[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x02};
const byte scrn3[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x03};
const byte scrn4[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x04};
const byte scrn5[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x05};
const byte scrn6[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x06};
const byte scrn7[8]                       = {0xF0,0x00,0x00,0x66,0x05,0x00,0x10,0x07};

int           sysExIndex=0;     // index for keeping track of incoming sysEx bytes
int ppqn = 0;

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

// handle incoming sysex messages
void handleSysEx(const byte* sysExData, uint16_t sysExSize, bool complete)
{
  // check if this is the start of the sysEx message
  if (sysExData[0]==240){
    sysExIndex=0;
  }
  Serial.print("The sysex length is ");
  Serial.print(sysExSize);
  Serial.print(" bytes\t");
  Serial.print("complete is\t");
  Serial.print(complete);
  Serial.println(); 
  for (int i=0;i<sysExSize;i++){
    sysExIndex++;
    Serial.print(sysExData[i],HEX);
    Serial.print(" ");
  }
  Serial.println(); 
  // message end
  if (complete && sysExData[sysExSize-1]==247){
   Serial.print("The total sysex message length is ");
   Serial.print(sysExIndex);
  Serial.print(" bytes");

  boolean isMackieControlMessage = true;
     // compare the first five bytes of the message to the sysExHeader to check if it is a Mackie control message
      for (int i=0;i<5;i++) {
        if (sysExData[i]!=sysExHeader[i]) {
          isMackieControlMessage = false;
        }
      }
      // handle mackie control message
      if (isMackieControlMessage) {
        Serial.println(" this is mackie massage");
      }
  }
 
    //sysex array
    const byte *pSysExArray = usbMIDI.getSysExArray(); //capture data
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x00){
           tcaselect(0);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i]);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x01){
           tcaselect(1);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x02){
           tcaselect(2);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x03){
           tcaselect(3);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x04){
           tcaselect(4);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x05){
           tcaselect(5);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x06){
           tcaselect(6);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
    //sysex array
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == 0x07){
           tcaselect(7);
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.firstPage();
  do {
  u8g2.setCursor(5, 10);
  for (int i=8;i<12;i++)
  u8g2.print(sysExData[i],HEX);  // write something to the internal memory
 
  for (int i=8;i<12;i++)
  Serial.print(sysExData[i],HEX);
  } while ( u8g2.nextPage() );
     }
    }
}           
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission(); 
}
void setup() {
  // register sysEx event handler function
  usbMIDI.setHandleSysEx(handleSysEx);
  //usbMIDI.setHandleNoteOff(myNoteOff);

  Serial.begin(9600);
  u8g2.begin();
  ppqn = 0;
}

void loop() {
  // read usbMIDI, let the handlers do their job
 usbMIDI.read();
  while (usbMIDI.read()) {
  }
}

void myNoteOff(byte channel, byte note, byte velocity) {
    ++ppqn;
    //Serial.println(channel);
       if(ppqn == 1){
          noteOn(0,0,127);
          MidiUSB.flush();
          ppqn = 0;
       }  
  }

I feel like this has something to do with you using two usb midi libraries, you shouldn’t have to use MIDIUSB.h with a Teensy controller. They already have a usb midi library that is active when you put it in usb midi mode, the way you currently have it setup you are using the built in library just to read the messages and then you are using the MIDIUSB library to send midi messages out. Doing it in this manner may be causing some kind of usb conflict that is causing undesired behavior, I would suggest to try switching to not using the MIDIUSB library and just strictly the using the built in usbMIDI library. I think this may fix the problem you are having, I’ve done HUI on several devices and tested it in multiple programs and it worked in all of them as far as I could tell and I’ve never experienced that issue personally.
 
Are you using a Midi In and Out cable in the same device?

I feel like this has something to do with you using two usb midi libraries, you shouldn’t have to use MIDIUSB.h with a Teensy controller. They already have a usb midi library that is active when you put it in usb midi mode, the way you currently have it setup you are using the built in library just to read the messages and then you are using the MIDIUSB library to send midi messages out. Doing it in this manner may be causing some kind of usb conflict that is causing undesired behavior, I would suggest to try switching to not using the MIDIUSB library and just strictly the using the built in usbMIDI library. I think this may fix the problem you are having, I’ve done HUI on several devices and tested it in multiple programs and it worked in all of them as far as I could tell and I’ve never experienced that issue personally.

I'll give it a try that sound like the issue but like I mentioned before only in protools I'm not able to see clock in the teenay monitor when I switch to studio one I get the clock read in the monitor. The HUI protocol is the Same in studio and in prootols I guess.
 
I'll give it a try that sound like the issue but like I mentioned before only in protools I'm not able to see clock in the teenay monitor when I switch to studio one I get the clock read in the monitor. The HUI protocol is the Same in studio and in prootols I guess.

I just looked at the code for MIDIUSB.h and that isn’t causing the problem, it actually uses usbMIDI.h to send it already. I would suggest using a MIDI monitor to look at the output of Pro Tools and see if it’s sending the right information.
 
I just looked at the code for MIDIUSB.h and that isn’t causing the problem, it actually uses usbMIDI.h to send it already. I would suggest using a MIDI monitor to look at the output of Pro Tools and see if it’s sending the right information.

I'm using midi monitor
In 126 velocity I get clock
127 it's stops
Prootols can ignore the ping and the midi steel function normal so I can live with it I guess its more related with serial RX tx transmit port
 
That is a really strange bug, the strangest part is that it only occurs in Pro Tools. Like you said, the HUI protocol doesn’t change between DAWs so the fact that it works fine in a different DAW is weird.
 
I just looked at the code for MIDIUSB.h and that isn’t causing the problem, it actually uses usbMIDI.h to send it already. I would suggest using a MIDI monitor to look at the output of Pro Tools and see if it’s sending the right information.

That is a really strange bug, the strangest part is that it only occurs in Pro Tools. Like you said, the HUI protocol doesn’t change between DAWs so the fact that it works fine in a different DAW is weird.

On theory is true but in the practical aspect I know thee is a small difference's between every DAW that use HUI protocol.
 
Status
Not open for further replies.
Back
Top