MajicDesigns / MD_Parola

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

Combination of text scroll with bitmap sprite animation #129

Closed EdiFirst closed 4 months ago

EdiFirst commented 4 months ago

IMPORTANT

Before submitting this issue [x] Have you tried using the latest version of the library? [x] Have you checked this has not already been submitted and/or resolved? [x] If you are requesting help a better choice may be the Arduino forum

Subject of the issue

I'm tring to combine text scroll with bitmap sprite animation in a single zone, I have a FC16_HW display ( 4 * 8x8 display), I would like to apply an animation text in 3 of those and in the last an bitmap sprite animation. By doc , it should be possible ( althought I didn't find this exact example): `

void MD_Parola::setSpriteData | ( | uint8_t | z, -- | -- | -- | --   |   | const uint8_t * | inData,   |   | uint8_t | inWidth,   |   | uint8_t | inFrames,   |   | const uint8_t * | outData,   |   | uint8_t | outWidth,   |   | uint8_t

`

Your Environment

Library Version: MD_Parola@^3.7.3 Arduino IDE version: I'm using VS CODE Host OS and Version: Windows 11 CPU Hardware model/type: ESP8266

Steps to Reproduce

This is my code: `#include

include

include

define HARDWARE_TYPE MD_MAX72XX::FC16_HW

define CS_PIN D8 // (GPIO15)

define MAX_DEVICES 4

// Hardware SPI connection MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

const char *message = "Right answer!"; // Scrolling text message

// Sprite Definitions const uint8_t F_HEART = 5; const uint8_t W_HEART = 9; const uint8_t PROGMEM heart[F_HEART * W_HEART] = // beating heart { 0x0e, 0x11, 0x21, 0x42, 0x84, 0x42, 0x21, 0x11, 0x0e, 0x0e, 0x1f, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x1f, 0x0e, 0x0e, 0x1f, 0x3f, 0x7e, 0xfc, 0x7e, 0x3f, 0x1f, 0x0e, 0x0e, 0x1f, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x1f, 0x0e, 0x0e, 0x11, 0x21, 0x42, 0x84, 0x42, 0x21, 0x11, 0x0e, };

void setup(void) { P.begin(); P.setZone(0, 1, 3); // Set up first 3 displays as Zone 0 P.setZone(1, 0 , 0); // Set up last display as Zone 1 P.displayZoneText(0, message, PA_CENTER, P.getSpeed()*5, P.getPause(), PA_SCROLL_LEFT, PA_SCROLL_LEFT); P.setSpriteData(1, heart, W_HEART, F_HEART, heart, W_HEART, F_HEART); // Set sprite data for Zone 1 P.displayAnimate(); }

void loop(void) { if (P.displayAnimate()) // animates and returns true when an animation is completed { P.displayReset(0); // Reset the text animation in Zone 0 P.displayReset(1); // Reset the bitmap animation in Zone 1 } } `

Expected Behaviour

It should print the text in the first 3 display: " Right answer!" and a heart sprite bitmap on the last display

Actual Behaviour

The text " Right answer!" are being 'printed' but the sprite nop

Code Demonstrating the Issue

Insert your compilable code code here (no code snippets).
Configuring upload protocol...
AVAILABLE: espota, esptool
CURRENT: upload_protocol = esptool
Looking for upload port...
Auto-detected: COM3
Uploading .pio\build\esp12e\firmware.bin
esptool.py v3.0
Serial port COM3
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: xyz..
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 283680 bytes to 207683...
Writing at 0x00000000... (7 %)
Writing at 0x00004000... (15 %)
Writing at 0x00008000... (23 %)
Writing at 0x0000c000... (30 %)
Writing at 0x00010000... (38 %)
Writing at 0x00014000... (46 %)
Writing at 0x00018000... (53 %)
Writing at 0x0001c000... (61 %)
Writing at 0x00020000... (69 %)
Writing at 0x00024000... (76 %)
Writing at 0x00028000... (84 %)
Writing at 0x0002c000... (92 %)
Writing at 0x00030000... (100 %)
Wrote 283680 bytes (207683 compressed) at 0x00000000 in 19.0 seconds (effective 119.6 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
================================================================= [SUCCESS] Took 27.65 seconds 
MajicDesigns commented 4 months ago

The sprit animation includes text, not just a sprite, so you will need to animate a " " (space).

You need to set up 2 zones, one for the graphics and one for the text. You can run each zone as per normal Parola animations. The Parola_Sprites_Library example shows how to run a sprite animation. Read https://arduinoplusplus.wordpress.com/2018/04/19/parola-a-to-z-sprite-text-effects/for more info.

If you truly want to mix text and graphics then it will be more complicated. See the example Parola_TG_Combo and the blog post https://arduinoplusplus.wordpress.com/2018/03/29/parola-a-to-z-mixing-text-and-graphics/,

EdiFirst commented 4 months ago

Thank you @MajicDesigns , If I'm not doing wrong I already setup 2 zones:

P.setZone(0, 1, 3); // Set up first 3 displays as Zone 0 P.setZone(1, 0 , 0); // Set up last display as Zone 1 P.displayZoneText(0, message, PA_CENTER, P.getSpeed()*5, P.getPause(), PA_SCROLL_LEFT, PA_SCROLL_LEFT); P.setSpriteData(1, heart, W_HEART, F_HEART, heart, W_HEART, F_HEART); // Set sprite data for Zone 1

About mixing text and graphics I kind not doing it, once the text is animated in one zone don't affect other zone (of bitmap). Im not sure what happening..

MajicDesigns commented 4 months ago

setSpriteData() only sets the data for the sprite in the zone. You also need to displayZoneText() using the sprite, as per the blog post article and the examples provided.

EdiFirst commented 4 months ago

Thank you @MajicDesigns yep I realize it later, but ever trying pass the message it are not happening: P.displayZoneText(1, "", PA_CENTER, P.getSpeed(), P.getPause(), PA_SPRITE, PA_SPRITE); P.setSpriteData(1, heart, W_HEART, F_HEART, heart, W_HEART, F_HEART);

But I kind find another way, I'm using both libraries: MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); Create a bitmap for instance: const uint8_t heartBitmap[8] = {0x1c, 0x3e, 0x7e, 0xfc, 0xfc, 0x7e, 0x3e, 0x1c}; A message: message = "Right Answer!"; and setup both: mx.begin(); set zones, etc then display message: P.displayZoneText(0, message, PA_CENTER, P.getSpeed()*2, P.getPause(), PA_SCROLL_LEFT, PA_SCROLL_LEFT); and Image: for (uint8_t col = 0; col < 8; col++) { mx.setColumn(DISPLAY_TO_USE, col, imageToDisplay[col]); }

That was the best solution, but I believe you could do better for sure.

MajicDesigns commented 4 months ago

Good to know it works for you.

FYI, you need define the sprite data before you do the animation:

P.setSpriteData(1, heart, W_HEART, F_HEART, heart, W_HEART, F_HEART);
P.displayZoneText(1, "", PA_CENTER, P.getSpeed(), P.getPause(), PA_SPRITE, PA_SPRITE);

I think the libraries will ignore animation when the string is empty ("") as there is nothing to display. You should try a space (" ").

Also, not go practice to declare a new mx object like you did. First blog post referenced above shows how to do it properly.