MajicDesigns / MD_Parola

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

Is possible to change text when animating? #81

Closed erdemefe90 closed 3 years ago

erdemefe90 commented 3 years ago

Is there any way to change text buffer while animation in prosess? For example, can i change text when animation in pause step?

MajicDesigns commented 3 years ago

You can change the text any time, just copy it into the buffer that you share with the library, and you should do a displayReset() to abandon the last message and start again with the new text. If you don't do a reset the results are undefined, as it depends what the library was doing. Most likely you will see a combination of the old message already displayed followed by the new message starting somewhere in the middle of the old text.

erdemefe90 commented 3 years ago

Actually, i want to show time message as HH:MM during 10 seconds with animation, additionally two dot should blink at 500 ms. To do this, i write pseudo code below. But it doesn't work as i expect. it is showing only time_msg[0] or time_msg[1] till exit effect come.

void show_time()
{
  char time_msg[2][6];
  static unsigned long time_prev_dot = millis();
  static bool dot_flag;
  static bool set_flag = true;
  sprintf(time_msg[0], "02:45");    // Example time
  sprintf(time_msg[1], "02 45");    // Example time

  if (millis() - time_prev_dot > 500)
  {
    dot_flag ^= 1;
    time_prev_dot = millis();
    strcpy(curMessage, dot_flag ? time_msg[0] : time_msg[1]);
  }

  if (set_flag)
  {
    scrollSpeed = 25;
    scrollPause = 10000;
    scrollAlign = PA_CENTER;
    scrollEffectIn = effect[rand() % ARRAY_SIZE(effect)];
    scrollEffectOut = effect[rand() % ARRAY_SIZE(effect)];
    set_flag = false;
  }

  if (P.displayAnimate())
  {
    P.displayText(curMessage, scrollAlign, scrollSpeed, scrollPause, scrollEffectIn, scrollEffectOut);
    P.displayReset();
    set_flag = true;
  }
}
MajicDesigns commented 3 years ago
  1. Not all effects will work properly when you change text (eg, scroll and slice will not). Generally only those effects that are based on print will work because they print the whole text every time, so will pick up the changed text on the next iteration of the effect. I would stick to one effect rather than a 'random'. This gives you better control while testing and you can then later decide what subset of effects will work for you. (You don't show the effect array, but I assume you copied one from the examples).
  2. dot_flag ^= 1 is a strange construct as you have defined the variable as bool. A more 'standard' way would be dot_flag = !dot_flag. However, if you think it works ...
  3. If changing the text does not work then your only other choice is to combine text and graphics. Here is an example by someone else https://www.youtube.com/watch?v=mO98BBGWHkg&list=PLjYv58N8CmSOQ1i_sv7cjPBh5XAXTa3NZ&index=58, but this will even more limit the number of effects.
MajicDesigns commented 3 years ago

Closed as no OP response for 3 weeks.

Kamal-Sonani commented 2 years ago

any possibilities for change text @ runtime (scroll left or right)?

MajicDesigns commented 2 years ago

Yes, just put new text in the buffer. If you want to abort you should also do a reset of the animation.

rafacorradi commented 4 months ago

It's possible to cut off the PA_SCROLL_LEFT animation, changing the text and the animation the display will show? I'm using a word as placeholder in my display with this effect, and it should change to another message when i trigger a sensor on my code. But it doesn't happen, it always finish the animation and after that, the text and animation change. I tried the reset and clear functions, but nothing stops that effect to finish. There are anyway to do that?

MajicDesigns commented 4 months ago

In future please create a new issue rather than resurrect this close issue.

The animation is stopped using the displayReset() method and the display cleared with displayClear(). Then change the string to the new message before the next time you can displayAnimate().

You should not wait for the displayAnimate() function to return tur (ie animation finished) before interrupting, which is what is shown in most of the example code.

rafacorradi commented 4 months ago

Thanks by your answer and sorry for ressurrect this topic. I already did what you are telling me, but it doesn't works. The animation always get to the end before show the other message.

This is my code now, I took the function you said from the code because it didn't work.

void showMessage() {
  if (display.displayAnimate()) {
    if(reading == true) {
      display.displayText("Assopre!", PA_CENTER, 0, 500, PA_PRINT, PA_PRINT);
      delay(500);
    }
    else if (resultReady == true) {
      display.displayText("FODEU!", PA_CENTER, 0, 3000, PA_PRINT, PA_PRINT);
      display.displayAnimate();
      delay(3000);
      display.displayText(sensorValue, PA_CENTER, 100, 5000, PA_FADE, PA_FADE);
      display.displayAnimate();
      resultReady = false;
      maxReading = 0;
    }
    else {
      display.displayText("Barfometro       ", PA_CENTER, 50, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    }
    display.displayAnimate();
  }
}
MajicDesigns commented 4 months ago

You are misunderstanding what displayAnimate() does. It does not do the full animation. It will do the NEXT step in the animation IF IT IS TIME to do the step.Your calls to displayAniate() with delay() following will do nothing.

Your "if (display.displayAnimate()) {" will also ensure you do nothing until the animation is finished - I said this in the last sentence of previous post.

See the structure of the loop() function in the Zone_TimeMesg example to see how to handle different messages. You will need to ignore the fact the example uses multiple zones, not relevant to you.

rafacorradi commented 4 months ago

Thanks for trying, but I'm not really understandig what you telling me. If I remove the delays from the code, all the messages are executed so fast, that we can't even read it, even if I change the speed and pause values, like it doesn't care about the arguments I'm putting in there. I'll try to see this part of doc you said, but I'm not confident I'll have lucky with this lib. Thanks.

MajicDesigns commented 4 months ago

OK, try this. Not ideal but it may work.

void showMessage() {
    display.displayAnimate();
    if (reading) {
      display.print("Assopre!");
    }
    else if (resultReady) {
      display.print("FODEU!");
      delay(3000);
      display.print(sensorValue);
      delay(3000);
      resultReady = false;
      maxReading = 0;
    }
    else {
      display.displayText("Barfometro       ", PA_CENTER, 50, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    }
}
rafacorradi commented 4 months ago

Ok, i think I get it about the displayAnimate. It doesn't make the animation, only ensure the current animation finish before the next one. Is that right? Abou the print(), i saw that, but with it i can't control differente animations, right? This is why i choose the display text. I'm sorry the trouble, but I'm new in arduino projects and I'm having a few problems in understand somethings. Anyway, I'll try this modifications.

rafacorradi commented 4 months ago

I tested and it doesn't work. The else and this one display.print(sensorValue); isn't printed.