Unofficial Nextion/TJC User Forum

Upload FW via serial - never reaches 100%


I have a project, where I want to upload a Nextion Firmware from an ESP32, where the TFT file is stored on the ESP in SPIFFS file system. Yes I have found the ESPNexUpload library, but it looks way-way overkill. It is also full of string operations, what is considered as a big no-no in microcontrollers’ world. I checked the documentation of Nextion Upload Protocol V1.1, and it looks pretty easy and straightforward, so I implemented it… Aaaand it does not work. :frowning:

The issue is, it sends the whole file, but the display says only about 90% of the packets has arrived. When I put a delay(100) (or 200 or 300 or 500) between each packet, then it goes up to 99% of all bytes, but it still waits for more. (It changes, but 6-8Kbytes are missing, so not only the last partial package.) When I put delay(1000) between each 4096 byte packages, then it works perfectly. (but takes ages to finish) What am I doing wrong? I think I perfectly followed the protocol documentation.
Ohh, and another strange thing: the 0x88 arrives at the end of the while loop from the display, but it still shows the white screen with the small red text, saying “SIZE: 1957708 writing DATA… 90% 1777664” (When I add delay(100), it stops at 99% and 1949696 bytes)

  HardwareSerial SerialNextion(1);
  SerialNextion.begin(115200, SERIAL_8N1, 25, 26);
  File file ="/Nextion35.tft");
    size_t filesize = file.size();
    SerialNextion.printf("whmi-wri %d,115200,0\xFF\xFF\xFF", filesize);

    WaitForNextionResponse(0x05, 10000);

    char buf[4096];
    size_t avail;
    size_t readcount;
    while(filesize > 0){
      avail = file.available();
        readcount = file.readBytes(buf, avail > 4096 ? 4096 : avail);
        SerialNextion.write(buf, readcount);
        filesize -= readcount;
        // delay(1000); would solve the problem here
        WaitForNextionResponse(0x05, 10000);

    WaitForNextionResponse(0x88, 10000);

void WaitForNextionResponse(byte ResposeToWait, uint32_t TimeoutMillis){
  byte b = 0;
  uint32_t waittime = millis();
  while(b != ResposeToWait && (waittime + TimeoutMillis) < millis()){
      b =;
      waittime = millis();

Got it! The issue is (as always): The controller did the thing I told it to do, and not what I wanted to do. :man_facepalming:

In WaitForNextionResponse
while(b != ResposeToWait && (waittime + TimeoutMillis) < millis()){
The while should run when waittime plus TimeoutMillis is LARGER than millis(). Not smaller. :face_with_symbols_over_mouth:

So it always returned isntantly, without waiting the response from Nextion.


Man if I had a nickel for every time I made that exact same error I would… well I would be making nickels in a very weird manner but you get the idea.

Glad you got it sorted and thanks for the follow up!

This forum is in no way affiliated with NEXTION®, ITEAD STUDIO®, TJC®, or anyone else really. All product names, logos, and brands are property of their respective owners. All company, product, and service names used in this website are for identification purposes only. Use of these names, logos, and brands does not imply endorsement from the respective rights holder(s).