Problem using MD_MAX72xx, need some advice

Hello guys!

First, I would like to thank you for your attention.

I'm building a display with four 8x8 matrices and using MD_MAX72xx to control it all. The library works well, but everything appears horizontally mirrored.

I've already tried all possible solutions, switching between parola, FC16, generic, etc.

I also used the command

mx.transform(MD_MAX72XX::TFLR);

And I managed to solve the problem in the PrintText example, but that doesn't solve it when there is a Scroll Text, like in the Daft Punk example, which is what I want to use.

Would anyone know how to solve this?

It's okay for animations to get mirrored. But I need the correct text characters, as I managed to do in PrintText.

Here is the part of the code that handles text messages and where I believe it needs a modification.

// ========== Text routines ===========
//
// Text Message Table
// To change messages simply reorder, add to, or delete from, this table
const char *msgTab[] =
{
  "DAFT PUNK",
  "GET LUCKY",
  "ONE MORE TIME",
  "HARDER  BETTER  FASTER  STRONGER",
  "HUMAN AND ROBOT",
  "TECHNOLOGIC",
  
};

bool scrollText(bool bInit, const char *pmsg)
// Callback function for data that is required for scrolling into the display
{
  static char   curMessage[BUF_SIZE];
  static char   *p = curMessage;
  static uint8_t  state = 0;
  static uint8_t  curLen, showLen;
  static uint8_t  cBuf[8];
  uint8_t         colData;
  // are we initializing?
  if (bInit)
  {
    PRINTS("\n--- Initializing ScrollText");
    resetMatrix();
    strcpy(curMessage, pmsg);
    state = 0;
    p = curMessage;
    bInit = false;
  }
  // Is it time to scroll the text?
  if (millis()-prevTimeAnim < SCROLL_DELAY)
    return(bInit);
  // scroll the display

  mx.transform(MD_MAX72XX::TSL);  // scroll along
  
  prevTimeAnim = millis();        // starting point for next time
  

  // now run the finite state machine to control what we do
  PRINT("\nScroll FSM S:", state);
  switch (state)
  {
    case 0: // Load the next character from the font table
      PRINTC("\nLoading ", *p);
      showLen = mx.getChar(*p++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
      curLen = 0;
      state = 1;

    // !! deliberately fall through to next state to start displaying

    case 1: // display the next part of the character
      colData = cBuf[curLen++];
      mx.setColumn(0, colData);
      if (curLen == showLen)
      {
        showLen = ((*p != '\0') ? CHAR_SPACING : mx.getColumnCount()-1);
        curLen = 0;
        state = 2;
       
      }
      break;

    case 2: // display inter-character spacing (blank column) or scroll off the display
      mx.setColumn(0, 0);
      if (++curLen == showLen)
      {
        state = 0;
        bInit = (*p == '\0');
      }
      break;

    default:
      state = 0;
  }

  return(bInit);

}

hi There

My 2 cents here

The library from Parola is very famous and I have a collection of examples here. MD_Parola: Parola_Ambulance Code for Arduino with Simulation

Did you try all of these? I think you can also check in the Discord channel of Wokwi where I have seen several MAX72xx projects discussed.

Hello sir, thanks for your response!

As I am building a Daft Punk helmet, I would really like to use the MD_MAX72xx library, as there is a very good code for this in the examples.

When I use the "PAROLA_HW", the continuity of writing is broken. This is corrected when using "FC16_HW", but the text is mirrored horizontally.

The best option so far has been to use the "DR1CR0RR1_HW", but I need to physically reverse my MAX7219 upside down, which makes mounting complications...

Well, what you have not explained is only the important details!

We presume that you are actually using FC-16 modules - these ones:

In which case the setting is "FC16_HW" and no other. :roll_eyes:

Now there then are switches in the library to reverse (mirror) either or both horizontally and vertically. You need to read the documentation carefully (which is to say, I do not remember offhand where they are! :worried: ).

Hello Paul!

Sorry about that. I will try to be more clear.

The module I'm using is one of those that have the 4 together on a single board, which would lead me to believe that it's an FC-16 (there are no inscriptions on the board)

However, using "FC16_HW" in the code, I have the mirrored text.

When I use "PAROLA_HW", the text comes out in the CORRECT orientation. However, the triggering order is mirrored.

If it should be 1 2 3 4 to work correctly, it does 4 3 2 1.

I'm a beginner and I'm doing my best to find the problem and complete the project, so sometimes I can overlook something "trivial" due to lack of experience. Thank you for your help

I found a solution to my problem, which maybe can help someone who in the future goes through the same situation.

I thought: Why not invert the font itself?

With the help of the website MD_MAX72XX Font Editor, I'm drawing all the characters backwards and replacing the codes in the file "MD_MA72xx_font.cpp" in the library folder.

a pain in the ass but it's working lol.

The cool thing is that now the font have my style :slight_smile:

In the code, I must write the words backwards and reverse the order as well. Then "DAFT PUNK" becomes "TFAD KNUP"

Perhaps you should cite the actual display you are using (Web site). There are in fact two versions of the module including the four-matrix module. One is (much) less common but has been discussed here and does use a different descriptor.

I thought: Why not invert the font itself?

Because, as you found, you will then need to invert the text and it makes no sense. Also all the animations will work in weird ways.

Have you made sure that the orientation of the DATA IN pins is ON THE RIGHT of the display when you are looking at it. Module 0 is the furthest on the right and the modules chain together towards the left. This is the correct orientation for the hardware in order for the MD_* libraries to work.

The test reverse and flip upside down functions mentioned by Paul are in the Parola library and not in MD_MAX72xx.

1 Like

Hello Marco and Paul. Thanks again for the answers and for the assistance. I think the problem lives around the board's orientation. It would work 100% with "PAROLA_HW" if I had wired it correctltly.

The fact is that it would be impractical to redo all the wiring at this point in the assembly, so the solution of inverting the font worked perfectly for me and I'm happy with the result, even If it's not the perfect scenario.

The animations remained perfect and I really liked the font I designed, so no problem! Of course it's boring to write the words backwards in the code, but there's a lote of sites that do that and it shows right on the display, so that's what matters to someone who's just having fun with a Daft Punk helmet build.

OK, The main thing is to have fun. On the next project remember to put it on the left.

1 Like

I'll definitely remember, haha. In time, could I ask you another question?

Is there any way to change the direction the text scrolls? I studied the code a lot and did several searches, but I didn't find the answer yet.

In the part of the code that deals with the texts, there is the following line:

mx.transform(MD_MAX72XX::TSL); // scroll along

I thought maybe changing "TSL" to "TSR" would do the trick, but that way, the display doesn't work.

Thank you again!

I know that in the MD_Parola library this can be done easily with the command

textEffect_t scrollEffect = PA_SCROLL_LEFT;

Replacing LEFT with RIGHT and vice versa.

But it seems that there is no clear command that does this in the MD_MAX72xx library, which is the one I need to use because of the Daft Punk example.

So, here I am again :slight_smile:

I found that small changes to the text section of the code not only resolve the scroll orientation, as well as my initial mirroring issue.

mx.transform(MD_MAX72XX::TSL);

Becomes:

mx.transform(MD_MAX72XX::TSR);

mx.setColumn(0, colData);

Becomes:

mx.setColumn(31, colData);

That way everything works perfectly fine, with the original font. That way I don't need to write anything backwards anymore.

I'm posting the results here in case anyone experiences the same problem.


  // scroll the display
  mx.transform(MD_MAX72XX::TSR);  // scroll along
  prevTimeAnim = millis();        // starting point for next time

  // now run the finite state machine to control what we do
  PRINT("\nScroll FSM S:", state);
  switch (state)
  {
    case 0: // Load the next character from the font table
      PRINTC("\nLoading ", *p);
      showLen = mx.getChar(*p++, sizeof(cBuf)/sizeof(cBuf[0]), cBuf);
      curLen = 0;
      state = 1;
      

    // !! deliberately fall through to next state to start displaying

    case 1: // display the next part of the character
      colData = cBuf[curLen++];
      mx.setColumn(31, colData);
      if (curLen == showLen)
      {
        showLen = ((*p != '\0') ? CHAR_SPACING : mx.getColumnCount()-1);
        curLen = 0;
        state = 2;
      }
      break;

Yeah! :grin:

1 Like