MMMC sysex Transport messages

AntiLoop

Well-known member
Hello,to all reaper afficionados,
i'm building a system with a 10" screen to control the DAW,using only the buttons created by the TFT,
i've found enough materials to create a sketch for transport control:
Code:
//---------------------SYSEX COMMANDS REAPER MACKIE CONTROL MMC------------------------
byte sysex_stop[]= {0xF0, 0x7F, 0x7F, 0x06, 0x01, 0xF7};//stop
byte sysex_play[] = {0xF0, 0x7F, 0x7F, 0x06, 0x02, 0xF7};//play
byte sysex_defPlay[] = {0xF0, 0x7F, 0x7F, 0x06, 0x03, 0xF7};//deferred play
byte sysex_fastForward[] = {0xF0, 0x7F, 0x7F, 0x06, 0x04, 0xF7};//fast forward
byte sysex_rewind[] = {0xF0, 0x7F, 0x7F, 0x06, 0x05, 0xF7};//rewind
byte sysex_punchIn[] = {0xF0, 0x7F, 0x7F, 0x06, 0x06, 0xF7};//punch in
byte sysex_punchOut[] = {0xF0, 0x7F, 0x7F, 0x06, 0x07, 0xF7};//punch out
byte sysex_pause[] = {0xF0, 0x7F, 0x7F, 0x06, 0x09, 0xF7};//pause

...and so on
void setup()

...and so on
void loop(){

if(blabla...){
usbMIDI.sendSysEx(sizeof(sysex_stop), sysex_stop, true);
}


}
But i've some problem with the PAUSE,it never stops,only quickly stop then play continuously,the others like
stop,play,rewind,fast forward work fine.
Does someone has the same trouble? :unsure:
 
I didn't notice that i was always repeating the play and sthe stop in a loop because you can't see it,until
you look at the monitor to debug,i should have noticed it with the forward and review never stopping.

Well i've not that problem when i use physical buttons and the pressed/released process,it gives only one reaction,
but with the TFT touch button,it's always in a loop and don't stop after one reaction.

physical buttons exerpt:
Code:
if (button2.pressed())
{
   usbMIDI.sendSysEx(sizeof(sysex_play), sysex_play, true);
 
   Serial.println("Button 2 PLAY pressed");
 
}

if (button2.released())
{
   Serial.println("Button 2 PLAY released");
 
 
}

The ideal is to simulate a physical button process,but how? :unsure:

EDIT:i use the goodix.h driver for the touch because i'm using a RA8876 TFT
and it's not easy to make it work like adafruit FT6206.
 
Last edited:
Ok, finally @DJETH helped me to handle goodix's touch in a better way,no more problem with the loop result and touch is fast,

Here's the MMC touch with goodix & RA8876 - 4 wires that works with my reaper DAW.

Code:
// adapted from DJETH - GT9271_Teensy_Touch.ino
/*
 * License: Refer to LICENSE file in main directory.
 * Modified: For use with Teensy 4.x and MicroMod
 *       By: Warren Watson 2024.
*/
#include "RA8876_Config_SPI.h"
#include <font_CourierNew.h>
#include <RA8876_t3.h>
#include <SPI.h>
#include <Wire.h>
#include "Goodix.h"


RA8876_t3 tft = RA8876_t3(RA8876_CS, RA8876_RESET); //Using standard SPI pins//CS=30 & RST = 28
#define INT_PIN 22
#define RST_PIN 255

Goodix touch = Goodix(INT_PIN, RST_PIN, GOODIX_I2C_ADDR_28);


//---------------------SYSEX COMMANDS REAPER MACKIE CONTROL MMC------------------------
byte sysex_stop[]= {0xF0, 0x7F, 0x7F, 0x06, 0x01, 0xF7};//stop
byte sysex_play[] = {0xF0, 0x7F, 0x7F, 0x06, 0x02, 0xF7};//play
byte sysex_defPlay[] = {0xF0, 0x7F, 0x7F, 0x06, 0x03, 0xF7};//deferred play
byte sysex_fastForward[] = {0xF0, 0x7F, 0x7F, 0x06, 0x04, 0xF7};//fast forward
byte sysex_rewind[] = {0xF0, 0x7F, 0x7F, 0x06, 0x05, 0xF7};//rewind
byte sysex_punchIn[] = {0xF0, 0x7F, 0x7F, 0x06, 0x06, 0xF7};//punch in
byte sysex_punchOut[] = {0xF0, 0x7F, 0x7F, 0x06, 0x07, 0xF7};//punch out
byte sysex_pause[] = {0xF0, 0x7F, 0x7F, 0x06, 0x09, 0xF7};//pause





int TFT_Backlight_Pin = 33;

int ScreenActive = 0;
int ButtonPressGoToScreen = 0;
int XAxis = 0;
int YAxis = 0;
int TimeADDEDForButtonDebounceMillis = 300;
long unsigned int TimeForButtonDebounceMillis = 0;


void setup() {


  digitalWrite(TFT_Backlight_Pin, HIGH);

  Serial.begin(115200);
  while (!Serial && millis() < 1000) {}  //wait for Serial Monitor

 
  tft.begin();       

 HomeScreenDraw();

  // Setup callback.
  touch.setHandler(handleTouch);
  // We are using Wire2 on T41. Set this to your wire usage.
  touch.setWireObject(&Wire1);  // Default set to Wire on reset or power up.  // was &Wire
  // Start touchscreen.
  if (touch.begin() != true) {
    Serial.println("! Module Initialize: Failed");
  } else {
    Serial.println("Module Initialize: Succeded");
  }
 
  Serial.printf("\nUp to 10 contact points can be used with this driver.\n");
  Serial.printf("The screen is ready to be touched...\n");
  Wire1.setClock(400000);
  HomeScreenDraw();
  attachInterrupt(INT_PIN, InterruptRoutine, FALLING);

  TimeForButtonDebounceMillis = millis();

}  // End Void Setup  //////////////////////////////////////////////////////////////////////

void loop() {
  //touch.armIRQ();
  //touch.onIRQ();
  //touch.loop();
  // delay(100);
}  // End Void Loop/ ////////////////////////////////////////////////////////////


// Callback from irq function.
void handleTouch(int8_t contacts, GTPoint *points) {
  detachInterrupt(digitalPinToInterrupt(INT_PIN));
  Serial.printf("Number Of Contact Points: %d\n", contacts);
  for (uint8_t i = 0; i < contacts; i++) {
    // X and Y coords are inverted side to side and up and down.
    // Subtract from screen width and height to get x/y origins at
    // 0,0 instead of 1023,599. Also generate 16bit coords from two
    // 8bit coords (big endian).
    XAxis = (uint16_t)LCD_WIDTH - ((points[i].x_msb << 8) | points[i].x_lsb);
    YAxis = (uint16_t)LCD_HEIGHT - ((points[i].y_msb << 8) | points[i].y_lsb);
    uint16_t area = (uint16_t)((points[i].area_msb << 8) | points[i].area_lsb);
    Serial.printf("Contact #%d: Track ID %d, X position %d, Y position %d, area %d\n", i, points[i].trackId, XAxis, YAxis, area);
    

  }  // End for loop
  if (TimeForButtonDebounceMillis < millis()) {
      ScreenButtonCheck();
    TimeForButtonDebounceMillis = millis() + TimeADDEDForButtonDebounceMillis;
    
  }  // End if(TimeForButtonDebounceMillis < millis())
 attachInterrupt(INT_PIN, InterruptRoutine, FALLING);
}  // End void handleTouch(int8_t contacts, GTPoint *points)

void InterruptRoutine() {
 // tft.setCursor(20, 20);
 // tft.print("Hello");
  touch.onIRQ();
}


void ScreenButtonCheck() {
  if (XAxis > 190 && XAxis < 290 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_rewind), sysex_rewind, true);
    Serial.println("REWIND");   
  }
  if (XAxis > 290 && XAxis < 390 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_stop), sysex_stop, true);
    Serial.println("STOP");   
  }
  if (XAxis > 390 && XAxis < 490 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_play), sysex_play, true);
    Serial.println("PLAY");   
  }
  if (XAxis > 490 && XAxis < 590 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_pause), sysex_pause, true);
    Serial.println("PAUSE");   
  }
  if (XAxis > 590 && XAxis < 690 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_punchIn), sysex_punchIn, true);
    Serial.println("RECORD PUNCH IN");   
  }
  if (XAxis > 690 && XAxis < 790 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_punchOut), sysex_punchOut, true);
    Serial.println("RECORD PUNCH OUT");   
  }
  if (XAxis > 790 && XAxis < 890 && YAxis > 350 && YAxis < 450) {
    usbMIDI.sendSysEx(sizeof(sysex_fastForward), sysex_fastForward, true);
    Serial.println("FAST FORWARD");   
  }                       

} 


void HomeScreenDraw(){
//---------------MIDI MMC SWITCHES-------------------

 for(int i = 0;i < 9;i++){
  tft.fillRect(100 + i*100,350,95,95,BLUE);//-> BUILD BUTTONS
}

//---------------REVIEW BEGINNING-----------------
      tft.setTextColor(WHITE);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(110, 380);tft.print("|<");
      //tft.setCursor(15, 555);tft.print("BACK");
//---------------REVIEW-----------------
      tft.setTextColor(WHITE);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(210, 380);tft.print("<<");
      //tft.setCursor(15, 555);tft.print("REVIEW");     
        
//---------------STOP BUTTON-----------------
      tft.setTextColor(RED);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(310, 380);tft.print("[]");
      //tft.setCursor(15, 555);tft.print("STOP");     
//---------------START BUTTON-----------------
      tft.setTextColor(GREEN);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(430, 380);tft.print(">");
      //tft.setCursor(15, 555);tft.print("START");
//---------------PAUSE BUTTON-----------------
      tft.setTextColor(GREEN);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(510, 380);tft.print("||");
      //tft.setCursor(15, 555);tft.print("PAUSE");
//---------------RECORD PUNCH IN BUTTON-----------------
      tft.setTextColor(GREEN);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(630, 380);tft.print("O");
      //tft.setCursor(15, 555);tft.print("RECORD");
//---------------RECORD PUNCH OUT BUTTON-----------------
      tft.setTextColor(RED);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(730, 380);tft.print("O");
      //tft.setCursor(15, 555);tft.print("RECORD");     
//---------------FORWARD BUTTON-----------------
      tft.setTextColor(WHITE);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(810, 380);tft.print(">>");
      //tft.setCursor(15, 555);tft.print("FORWARD");
//---------------FORWARD END BUTTON-----------------
      tft.setTextColor(WHITE);
      tft.setFontSize(1,true);
      tft.setFont(CourierNew_48);     
      tft.setCursor(910, 380);tft.print(">|");
      //tft.setCursor(15, 555);tft.print("END");             
                                  
      
}

Hope it works for you too :)
 
Back
Top