How repeater a command

Hi all,

I am trying to create a ‘loading’ style progress bar. This is purely visual and contained within one page.

I have it working using a progress bar and timer. The timer increases the bars position by 2 every 200ms.
to do this though I have used this in the event timer
j0.val=2
delay=200
j0.val=4
delay=200
j0.val=6

all the way up to 100. My question is can this be done with a simpler code rather than having 100 lines.

Something like j0.val= i++ /200ms I know that makes no sense as I have just made it up but it illustrates the sort of thing I mean.

Thanks in advance.

// Variant without timer, using delay (which is ugly)
// use whatever loop variable which is declared in program.s
// here, using sys0 which is declared by default
for(sys0=0;sys0<=100;sys0+=2)
{
j0.val=sys0
doevents // thank you @Max - silly me!
delay=200
}

Variant using a timer with 200ms interval:
// Put the following code in the timer tm0 event
// No delay needed
// Will disable itself when the progress bar is full
if(j0.val<=98)
{
j0.val+=2
}else
{
tm0.en=0
}
To initialise everything, put the following code into the page PostInitialize event:
j0.val=0
tm0.en=1

That was exactly what I was looking for.

Thank you.

One small addition: I think you‘d need to call doevents within the for loop otherwise you won‘t see anything (and no serial commands are processed) before the entire loop is done, a.k.a. the animation is done.

Regards,
Max

Hi Max,

to be honest you have completely lost me. I not sure what you mean (only because I’ve no idea when it comes to code) but using

if(j0.val<=98)
{
j0.val+=2
}else
{
tm0.en=0
}

works perfectly and is easy to edit to get the exact timing I wanted.

Hi @D4VEW557,

My reply was towards @Fjodor and his “Variant without timer”. It is not relevant to the version you picked, the one with timers. The only thing you may want to take away from this is that loops (for(...) { ... } and while(...) { ... }) are something you should avoid if possible.
The somewhat more detailed explanation:
Loops are blocking, meaning as long as Nextion is executing the loop, it’s doing nothing else. Doesn’t react to touches on the screen, doesn’t update the screen content (if you were drawing something within the loop f.ex. like here) nor does it react to serial commands. It executes the entire loop, and only then does it go back to normal operation. By adding the doevents command to the loop, you explicitly ask Nextion to update the screen and process the serial commands, though still no touch response (which makes sense; if not, don’t think about it for too long; the reason isn’t really important anyways).
In @Fjodor’s code example he’s changing the progress bar within a loop. But, as I just said, Nextion won’t show you any of these changes until the loop has finished. I encourage you to test it out (because that’s how you gather experience). You’ll see the progress bar frozen at zero; the screen remains unresponsive for the 10 seconds of the “animation” and then the progress bar jumps to 100% and everything works again.
Final note: by using a Timer component, you avoid all these issues because you’re not stuck within a loop nor are you using delays (which block the processor, too).

Kind regards,
Max

Thanks Max,

I absolutely agree 'having a go and experimentation is a great way to learn. At a basic level I see what you mean. Years ago I played around with Arduino IDE and seem to remember encountering issue with a loop blocking other commands on what ever project I was doing.

Thanks again for your input.

1 Like