Protocol Reparse mode: Buffer lost data in high speed

Hi everyone,

I’m trying to get my MCU to transfer data to the buffer at 3360 bytes per second.
baud rate is 115200.
I use a simple command to display the value of usize every second.
The numbers I actually see are around 3246~3324, which is always less a lot than I would like to see.
If I add more complex programs, the speed will get worse.
Where can I improve to reach the speed?
Also, I notice that the update time is very unstable when the timer performs multiple jobs in a short period of time. Is this the reason?
I am new to nextion and data transfer technology. Also, I am not an English speaker. Hope my description is not too bad.

Many thanks for your help.

0

Event of b0:

recmod=1
tm0.en=1
tm1.en=1

Event of b1:

recmod=0
tm0.en=0
tm1.en=0

Event of tm0: (tim=3000)

if(usize==0)
{
  // Disable Protocol Reparse Mode (this clears buffer)
  recmod=0
  // Status update
  result.txt="Command time-out"
  // Disable timers
  tm0.en=0
  tm1.en=0
  n0.val=usize
}

Event of tm1: (tim=1000)

if(usize>0)
{
  n0.val=usize
  code_c
  result.txt="Reply received"
}

There are a few things which should be understood:

  1. The Nextion’s serial buffer has a size of 1024 bytes. The wrong numbers you see are most probably overflow effects.
  2. To prevent such problems, the Nextion sends an error code back over serial when the buffer is full: 0x24 0xFF 0xFF 0xFF. When sending large amounts of data at relatively high speed, your MCU should listen to this and pause until the Nextion has processed the buffer.
  3. The 1024 bytes buffer is a ring buffer. That means that receiving further bytes when full and error sent will successively overwrite previously received data.

So, in your use case, you should probably set the tm1 interval to 250ms because at your data rate, you can’t make the buffer full in that time. In the timer event read the buffer size at this very moment into a variable => sys0=usize, free the “counted” amount of bytes up => udelete sys0, and add this partial count up => n0.val+=sys0. After 4 runs, you should see the true number of bytes received per second.

Thank you for reply! Fjodor.

I’m sorry I didn’t describe that my display is intelligent series. (4096 Byte)
So it might be worked, i think?

And I wonder that what’s the difference between code_c and udelete? Are they the same in this case?

Code_c deletes all pending instructions in the serial buffer when not in reparse mode. Udelete takes a parameter and allows to delete a specified number of bytes in reparse mode. And you are right, the instruction buffer seems to be larger for the intelligent series after looking closer at the data sheet. But I wonder if, at the same time, the firmware was adapted, too, to handle more than 1024 elements in the u[] array. But you can simply check this out by sending bytes (without udeleting them) to a previously cleared buffer and check for the buffer error code in real time.

1 Like

Thanks again for your reply, Fjodor!

I replaced code_c using your suggestion. I’m glad that you’re helping me improve it, but from the results it looks like I need to do more.

Yes, the firmware does allow me to handle 4096 elements in the u[] array.
I’ve tested sending out 420 bytes per second (unfortunately, it only received a little over 400 bytes) without removing the buffer.
The displayed value increased from about 400, 800… to 4000, and finally 4095 with an error code. This should be enough to confirm its functionality.

But your reminder makes me notice a strange thing:
When I stop Protocol Reparse Mode, the error code appears.
This happened every time before I press the start button and after I press the stop button. The error code is continuously generated once per second. (sendind data 3360 bytes per second)
It means that when I stop the Protocol Reparse Mode, the buffer continues to read data? I have no idea.

I can’t believe that after I repeatedly tested the connection between the computer and the screen, the values suddenly became correct.

The only reason I can think of is that I might have made a little mistake connecting the lines. But in fact, I didn’t do anything different…especially now that there are only four lines here.

I’ll report back here right away if I find any reason. And again, thank you Fjodor for taking the time to answer my questions. I learned a lot from it.

And also, I still want to know the answer to the question I mentioned in my last reply. I will be grateful for any help.

Now I do find the reason for the data loss!

In previous tests, I used code_c or udelete usize to empty the buffer. This is why the data is lost because the usize is constantly increasing while the program is processing.
Instead, use v0 or any variable to access the usize value and execute ‘udelete v0.val’. This can make a completely different result.

Let me explain with this test result:

wow

v0.val=usize //usize=3312 in this moment
if(usize>0)
{
   n0.val=v0.val //n0.val=3312
   v2.val=usize //usize=3318 in this moment
   n1.val=v2.val //n1.val=3318
   udelete v2.val //wrong instruction
   result.txt="Reply received"
}

The value of usize becomes completely different at the time of execution of several runs.
So if I want to receive complete data, I should use udelete v0.val

In conclusion, usize should be used carefully to ensure the result is what you want.

Hope this will help someone else.

Yes, usize is (logically) constantly evolving. That’s why already in my first reply, I “froze” it temporarily in a variable… “ In the timer event read the buffer size at this very moment into a variable => sys0=usize, free the “counted” amount of bytes up => udelete sys0”

Rethinking your reply is exactly why I realized my mistake, thank you so much!