DAW Mackie SysEx Track names and OLED 128x64 SSD1306

Status
Not open for further replies.

Lenogi

Active member
Hi
Sorry for my poor English.
I can get the names of the 8 tracks normally.
I used part of the Zeus Commander DPC Project code made by Gerrit.

The display shows the information in one line that breaks automatically at the end of the display:

Track1 Track2 Track3
Track4 Track5 Track6
Track7 Track8

What I'm trying to do without success is to show each name in a different line:

Track1
Track2
Track3
Track4
Track5
Track6
Track7
Track8

I can't create anything to slice the SysEx message into eight parts to be sent to the display.

Any ideas?

Basic code information:

Code:
#include <SPI.h>
#include <Adafruit_SSD1306.h>

char  messageText[112];

void handleSysEx(const byte* sysExData, uint16_t sysExSize, bool complete) { 

        switch (sysExData[5]) {
          case 18:
          display.clearDisplay();
          display.setCursor(0, 0); // Pixel / Line
          for (int i=7; i<sysExSize-1; i++) {
          messageText[sysExData[6]+i-7] = sysExData[i];
          display.print(char(messageText[i-7]));
          }
     }
          display.display(); //
}
 
I think something like this may do the trick, I can’t test it right now to be certain though.
Code:
uint8_t textPos = 0;
display.clear();
for (uint8_t i = 0; i < 112; i++) {              //Do 56 instead of 112 if you only want the first line
  display.setCursor((i+1) % 8, textPos);
  display.print(char(messageText[i]));
  if((i+1) % 8 == 0) {
    textPos++;
  }
}
 
On some displays, you can use println to move the cursor to the next line. On other displays you have to use the setCursor or equivalent function to set the cursor to the first column of the next line.

If your library supports println, it probably might not scroll the lines when you reach the last line of the display. If you wanted scrolling on displays that don't provide the functionality, you would have to do the scroll manually. Also some libraries have problems if you are filling the screen and you do a println after the last character.

Also in your last example, you don't have a display.display (), so it won't update the screen.

Here is an alternative method of writing the last example if your library doesn't support println:

Code:
uint8_t line_number = 0;
display.clear();
display.setCursor (0, 0);
for (uint8_t i = 0; i < 112; i++) {              //Do 56 instead of 112 if you only want the first line
  display.print(char(messageText[i]));
  if((i+1) % 8 == 0) {
    line_number++;
    display.setCursor (0, line_number);
  }
}
display.display ();

Here is an alternative method of writing the last example if your library does support println:

Code:
display.clear();
display.setCursor (0, 0);
for (uint8_t i = 0; i < 112; i++) {              //Do 56 instead of 112 if you only want the first line
  if (((i+1) % 8 == 7) && (i != 111) {        // Use println after every 8th character, but don't use it on the last character.
    display.println(char(messageText[i]));
  } else {
    display.print(char(messageText[i]));
  }
}
display.display ();
 
Maybe I miss something? What I don't understand here is what is the format of the data? That is from the code:
Code:
char  messageText[112];

void handleSysEx(const byte* sysExData, uint16_t sysExSize, bool complete) { 

        switch (sysExData[5]) {
          case 18:
          display.clearDisplay();
          display.setCursor(0, 0); // Pixel / Line
          for (int i=7; i<sysExSize-1; i++) {
            messageText[sysExData[6]+i-7] = sysExData[i];
            display.print(char(messageText[i-7]));
          }
     }
          display.display(); //
}
I know that if the 6th byte is an 18, than the next byte is the index to where you start storing data into messageText, and you display whatever is at the start of the array?
That is if sysExData[6] is not zero, the byte you display in the for loop is not the byte you just stored in messageText array the line before.

You say that you wish to output the lines like:
Track1
Track2
Track3
Track4
Track5
Track6
Track7
Track8

So how do you know where the name of one track ends and the name of the next one begins? Are they fixed size? Is there some termination character?
The code to split it up will depend on this. If they are fixed size like 8 bytes, you can do it like has been suggested and look at the index and either do println or set cursor.

If they are actually variable length and some form of termination or break character. You would instead simply look at the output stream for that character (or characters) and break to the next line...
 
Thank you Vjmuzik and MichaelMeissner for the help.
I'm trying to adapt based on what you were suggesting, but so far, only freezes have happened in the DAW.
In the example of both of you is not missing something that shows where the information for "messageText " comes from?
 
Maybe I miss something? What I don't understand here is what is the format of the data? That is from the code:
Code:
char  messageText[112];

void handleSysEx(const byte* sysExData, uint16_t sysExSize, bool complete) { 

        switch (sysExData[5]) {
          case 18:
          display.clearDisplay();
          display.setCursor(0, 0); // Pixel / Line
          for (int i=7; i<sysExSize-1; i++) {
            messageText[sysExData[6]+i-7] = sysExData[i];
            display.print(char(messageText[i-7]));
          }
     }
          display.display(); //
}
I know that if the 6th byte is an 18, than the next byte is the index to where you start storing data into messageText, and you display whatever is at the start of the array?
That is if sysExData[6] is not zero, the byte you display in the for loop is not the byte you just stored in messageText array the line before.

You say that you wish to output the lines like:
Track1
Track2
Track3
Track4
Track5
Track6
Track7
Track8

So how do you know where the name of one track ends and the name of the next one begins? Are they fixed size? Is there some termination character?
The code to split it up will depend on this. If they are fixed size like 8 bytes, you can do it like has been suggested and look at the index and either do println or set cursor.

If they are actually variable length and some form of termination or break character. You would instead simply look at the output stream for that character (or characters) and break to the next line...

I'm following these information:
https://github.com/Silhm/bcf-scribble-strips/wiki/Understanding-Mackie-Control-Protocol
 
Some victory, even if it's ugly :)

Code:
char  messageText[112];

        switch (sysExData[5]) {

          case 18:
          uint8_t textPos = 0; 
          display.clearDisplay();
          display.setCursor(0, textPos); // Pixel / Line
          
            for (int i = 7; i<63-1; i++) {
              
              messageText[sysExData[6]+i-7] = sysExData[i];
              display.print(char(messageText[i-7]));
  if((i+1) % 7 == 0) {
    textPos++;
    textPos++;
    textPos++;
    textPos++;
    textPos++;
    textPos++;
    textPos++;
    textPos++;
    
    display.setCursor (0, textPos);
  }

It's working that way, but some things don't make sense.

char messageText[112]; - Any value less than 112 freezes the DAW

i < 63-1-any number less than 63 does not show the name of the last track.

I'm going to keep making changes to make the code cleaner and more functional.
Really, thank you so much for your help.
 
Thank you Vjmuzik and MichaelMeissner for the help.
I'm trying to adapt based on what you were suggesting, but so far, only freezes have happened in the DAW.
In the example of both of you is not missing something that shows where the information for "messageText " comes from?

You can use your original code to get “messageText” just delete any calls to display, then you can put the code we’ve suggested in another function to be called at anytime such as this.

Code:
void textUpdate() {
  uint8_t textPos = 0;
  display.clear();
  for (uint8_t i = 0; i < 112; i++) {              //Do 56 instead of 112 if you only want the first line
    display.setCursor(i % 7, textPos);
    display.print(char(messageText[i]));
    if((i+1) % 7 == 0) {
      textPos++;
    }
  }
  display.display();
}

Slightly altered from before so that it actually works how I intended it to when I first wrote it because I forgot how many characters each track name had and I was half asleep.
 
Note could replace the 8 ++ lines with
textPos += 8;

As this uses adafruit library, you You should be able to replace setCursor and the increments with:
display.println()
 
Any value less than 112 will freeze your program because 112 is the amount of characters that the Mackie display has, so if your array is anything less than that you’ll get undefined behavior since it’s trying to write to an address of the array that wouldn’t exist. Your current code is going to run into a problem when only part of the track names are written to instead of the whole thing, the code you posted at the start of the thread does not have this same problem.
 
Note could replace the 8 ++ lines with
textPos += 8;

As this uses adafruit library, you You should be able to replace setCursor and the increments with:
display.println()

I'm not a programmer and I miss simple things like that.

Thank you.
 
Any value less than 112 will freeze your program because 112 is the amount of characters that the Mackie display has, so if your array is anything less than that you’ll get undefined behavior since it’s trying to write to an address of the array that wouldn’t exist. Your current code is going to run into a problem when only part of the track names are written to instead of the whole thing, the code you posted at the start of the thread does not have this same problem.

I'm doing my project by trial and error. :)
What you wrote makes perfect sense.
 
Status
Not open for further replies.
Back
Top