MajicDesigns / MD_Parola

Library for modular scrolling LED matrix text displays
GNU Lesser General Public License v2.1
427 stars 135 forks source link

Issue with diagonal scrolling on a 4x Module #87

Closed Ntrino closed 3 years ago

Ntrino commented 3 years ago

Hi Marco.. what a great comprehensive library you have written! Thank you... Unfortunately i am experiencing a strange issue, and would really appreciate some help

Subject of the issue

Issues with diagonal scrolling effects

Your Environment

Library Version:Latest version to date Arduino IDE version: Latest version to date Host OS and Version: Windows 10, up to date CPU Hardware model/type: i7 *Matrix hardware model/type: FC-16*

Steps to Reproduce

By simply using the Parola_Animation_Catalog example, and setting the correct hardware

define HARDWARE_TYPE MD_MAX72XX::FC16_HW

define MAX_DEVICES 4

Expected Behavior

After viewing your example video on Youtube, i can see your diagonal effects work as expected without any issue like im experiencing

Actual Behavior

When using the Parola_Animation_Catalog example, all 4 of the diagonal scrolling effects (PA_SCROLL_UP_LEFT etc) have issues with the first zone. The first character of the text suddenly appears, and then is overwritten as the text scrolls into view.

Matrix

Code Demonstrating the Issue

// Program to show full catalog of the MD_Parola animations
//
// MD_MAX72XX library can be found at https://github.com/MajicDesigns/MD_MAX72XX
//

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW  //MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 4

// Wemos D1 (ESP8266)
#define CLK_PIN   D5    //SCK
#define DATA_PIN  D7    //MOSI
#define CS_PIN    D8    //SS

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Global data
struct sCatalog
{
  textEffect_t  effect;   // text effect to display
  const char *  psz;      // text string nul terminated
  uint16_t      speed;    // speed multiplier of library default
  uint16_t      pause;    // pause multiplier for library default
};

sCatalog catalog[] =
{
  /*  { PA_PRINT, "PRINT", 1, 1 },
    { PA_SCROLL_UP, "SC_U", 5, 1 },
    { PA_SCROLL_DOWN, "SCR_D", 5, 1 },
    { PA_SCROLL_LEFT, "SCR_L", 5, 1 },
    { PA_SCROLL_RIGHT, "SCR_R", 5, 1 },
    #if ENA_SPRITE
    { PA_SPRITE, "SPRIT", 5, 1 },
    #endif
    #if ENA_MISC
    { PA_SLICE, "SLICE", 1, 1 },
    { PA_MESH, "MESH", 20, 1 },
    { PA_FADE, "FADE", 20, 1 },
    { PA_DISSOLVE, "DSLVE", 7, 1 },
    { PA_BLINDS, "BLIND", 7, 1 },
    { PA_RANDOM, "RAND", 3, 1 },
    #endif
    #if ENA_WIPE
    { PA_WIPE, "WIPE", 5, 1 },
    { PA_WIPE_CURSOR, "WPE_C", 4, 1 },
    #endif
    #if ENA_SCAN
    { PA_SCAN_HORIZ, "SCNH", 4, 1 },
    { PA_SCAN_HORIZX, "SCNHX", 4, 1 },
    { PA_SCAN_VERT, "SCNV", 3, 1 },
    { PA_SCAN_VERTX, "SCNVX", 3, 1 },
    #endif
    #if ENA_OPNCLS
    { PA_OPENING, "OPEN", 3, 1 },
    { PA_OPENING_CURSOR, "OPN_C", 4, 1 },
    { PA_CLOSING, "CLOSE", 3, 1 },
    { PA_CLOSING_CURSOR, "CLS_C", 4, 1 },
    #endif*/

#if ENA_SCR_DIA
  { PA_SCROLL_UP_LEFT, "SCR_UL", 7, 2 },
  { PA_SCROLL_UP_RIGHT, "SCR_UR", 7, 1 },
  { PA_SCROLL_DOWN_LEFT, "Adam", 7, 1 },
  { PA_SCROLL_DOWN_RIGHT, "SCR_DR", 7, 1 },
#endif
  /*#if ENA_GROW
    { PA_GROW_UP, "GRW_U", 7, 1 },
    { PA_GROW_DOWN, "GRW_D", 7, 1 },
    #endif*/
};

// Sprite Definitions
const uint8_t F_PMAN1 = 6;
const uint8_t W_PMAN1 = 8;
static const uint8_t PROGMEM pacman1[F_PMAN1 * W_PMAN1] =  // gobbling pacman animation
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
};

const uint8_t F_PMAN2 = 6;
const uint8_t W_PMAN2 = 18;
static const uint8_t PROGMEM pacman2[F_PMAN2 * W_PMAN2] =  // ghost pursued by a pacman
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x73, 0xfb, 0x7f, 0xf3, 0x7b, 0xfe,
};

void setup(void)
{
  P.begin();
#if ENA_SPRITE
  P.setSpriteData(pacman1, W_PMAN1, F_PMAN1, pacman2, W_PMAN2, F_PMAN2);
#endif

  for (uint8_t i = 0; i < ARRAY_SIZE(catalog); i++)
  {
    catalog[i].speed *= P.getSpeed();
    catalog[i].pause *= 500;
  }
}

void loop(void)
{
  static textPosition_t just = PA_CENTER; //PA_LEFT;
  static uint8_t i = 0;   // text effect index
  static uint8_t j = 0;   // text justification index

  if (P.displayAnimate()) // animates and returns true when an animation is completed
  {
    // progress the justification if needed
    if (i == ARRAY_SIZE(catalog))
    {
      j++;
      if (j == 3) j = 0;

      switch (j)
        {
        case 0: just = PA_LEFT;    break;
        case 1: just = PA_CENTER;  break;
        case 2: just = PA_RIGHT;   break;
        }

      i = 0;  // reset loop index
    }

    // set up new animation
    P.displayText(catalog[i].psz, just, catalog[i].speed, catalog[i].pause, catalog[i].effect, catalog[i].effect);

    i++;   // then set up for next text effect
  }
}
MajicDesigns commented 3 years ago

What Arduino processor are you using?

Ntrino commented 3 years ago

What Arduino processor are you using?

Hi, that was a quick reply, cheers.. Its a Wemos D1, ESP8266

MajicDesigns commented 3 years ago

If you are powering the LED matrix modules with the 3V supply this can cause errors., You should use a separate 5V supply.

Ntrino commented 3 years ago

Yes i have tried that, they are being fed with 5v All the other effects in the example work flawlessly, its just these 4 diagonal ones.. Seems rather strange

MajicDesigns commented 3 years ago

Yep, I will need to set up a test system. Don't have time this week.

Ntrino commented 3 years ago

No worries, no rush, Still have plenty to write for my project :) Lets hope we can sort it.. Thanks for getting back to me so fast

Ntrino commented 3 years ago

I have also tried a pullup on CS and setting STATIC_ZONES to 1, and increasing the number of zones by 1 or 2, which i seen you had mentioned in another posters issue, sadly nothing helped Ive looking into your code, buts its certainly over my hobby grade knowledge to decipher what could be wrong with the effectDiag(...) function.. if anything

MajicDesigns commented 3 years ago

Fixed for release 3.5.7

Ntrino commented 3 years ago

Great thank you for that :)

Another issue i found, if an animation is currently active and i update the pText pointer value, then it crashes after a couple animation iterations, eg. if i either setTextBuffer(), or displayText() with a new text value (when using it as a clock) and updating the time seconds value every second, if the value changes during an animation such as the PA_SPRITE one, it causes the ESP8266 to crash with a WDT issue. For now to get around the crashing, i have to wait for the .displayAnimate() to return true before i update the text value. Is this normal behavior?

Thanks!

MajicDesigns commented 3 years ago

Changing the text while an animation is active will have undefined behaviours as the library is working its way through a string. For example, if the text is shorter than the current and the nul has disappeared from the end of the 'old' string, it will screw up for sure.

If you change the text you should also do a reset() and may also need to clear().