ITEADLIB_Nextion published on Particle Build

Tried using a serial over usb cable to upload a 1.7 MB file to the display. Took 133 seconds at 115200 bps. I am wondering if it is worth the effort to try the SD card method at this point. My tft file is over 16MB and that would take about 20 minutes to OTA.

Hello @ScruffR and @rickkas7. I used a micro sd card and modified the nextion upload library to work with sdfat library. Added some delays to get the replies working. I copied a 5.6mb tft file on the sd card and ran the upload cmd. It works!! Takes about 400 seconds to update and is very reliable in the 10-15 times that i have tested it. I will next add a download from ftp to sd card and then update.

It would be great to have it stream the update without storing but an sd card will have to do for now.

UPDATE:
made a typo in setting the baudrate to 1115200 and it worked at blazing speeds. Did some more experimentation and connected at 921600 and it seems to run fine.

3 Likes

Hello @Ali, this is very interesting. I am getting tired of the display I designed, but too lazy to go through the process of making a new one by swapping the SD card, etc.
Are you willing to share the library and a picture of the setup?

I used an adafruit micro sd break out for testing. I will setup a repo for the library and share it here once i add the ftp download part.

3 Likes

@rickkas7 and @ScruffR I tried using http-download library to download the tft file to the sd card. I made changes to make it work with sdfat library and made it a little more c++ .It does not seem to be writing data to the card. On further debugging in the function receiveResponse is where the problem lies. numAvail is always 0 so the callback is never executed. I do not know enough about http but maybe one of you guys can help out

        int HttpToSd::receiveResponse(HttpDownloadResponse& response,
                              callback cb,
                              void* callbackParam) {
  // If a proper response code isn't received it will be set to -1.
  response.status = -1;

  //
  // Receive HTTP Response
  //
  // The first value of client.available() might not represent the
  // whole response, so after the first chunk of data is received instead
  // of terminating the connection there is a delay and another attempt
  // to read data.
  // The loop exits when the connection is closed, or if there is a
  // timeout or an error.

  unsigned long lastTime = millis();

  // Wait until the server either disconnects, gives us a response, or the timeout is exceeded
  logger.trace("Waiting a for response.");
  while (client.connected() && !client.available()
      && millis() - lastTime < TIMEOUT_INITIAL_RESPONSE) {
    // While we are waiting, which could be a while, allow cloud stuff to happen as needed
    Particle.process();
  }

  if (client.connected() && client.available()) {
    // We stopped waiting because we actually got something
    int charCount = 0;
    int lastReadTime = millis();

    // Keep going until the server either disconnects, or stops feeding us data in a timely manner
    logger.trace("Reading response.");
    bool headersEnded = false;
    // char headerBuffer[1024];
    // headerBuffer[0] = 0;
    while (client.connected() && millis() - lastReadTime < TIMEOUT_RESPONSE_READ) {
      // We got something!
      int numAvail = client.available();
      int packetSize = numAvail;
      if (numAvail > 0) {
        logger.trace("Bytes available: %d", numAvail);
        byte* availBuff = new byte[numAvail];
        client.read(availBuff, numAvail);

        if (response.status == -1) {
          char httpStatus[4];
          httpStatus[0] = availBuff[9];
          httpStatus[1] = availBuff[10];
          httpStatus[2] = availBuff[11];
          httpStatus[3] = 0;
          response.status = atoi(httpStatus);

          if (response.status == 416) {
            //All done.
            return response.status;
          }
        }

        // Make note of when this happened
        lastReadTime = millis();

        byte* callbackData = availBuff;
        //Eat the headers
        if (!headersEnded) {
          logger.trace("Processing headers");

          char* headerEnd = strstr((const char*) availBuff, "\r\n\r\n");

          // strncat(headerBuffer, (char*)availBuff, (byte*)headerEnd - availBuff);
          if (headerEnd != NULL) {
            headerEnd += 4;      // \r\n\r\n from above

            callbackData = (byte*) headerEnd;
            numAvail -= (byte*) headerEnd - availBuff;

            headersEnded = true;

          } else {
            //Still haven't found headers.  Don't send anything to the callback.
            numAvail = 0;
          }

        }

        charCount += packetSize;

        //Send the data to our callback
        if (numAvail != 0) {
          logger.trace("write");
          if (cb != NULL) {
            cb(callbackData, numAvail, callbackParam);
          }
        }
        delete availBuff;
      }

      // While we are waiting, which could be a while, allow cloud stuff to happen as needed
      Particle.process();
    }```

How are you calling the sending of the .tft file using http-download?

At this point i am just trying to get the example to copy the jpg on the sd card. It creates the file and shows me the following

0000010874 [httpSD] TRACE: Connecting to: upload.wikimedia.org
0000010875 [httpSD] TRACE: Start of HTTP Request. GET /wikipedia/commons/9/95/Burning_Yellow_Sunset.jpg HHTP/1.1
0000010875 [httpSD] TRACE: Connection:close
0000010876 [httpSD] TRACE: Range:bytes=0-899
0000010876 [httpSD] TRACE: HOST:upload.wikimedia.org
0000010876 [httpSD] TRACE: End of HTTP Request.
0000010877 [httpSD] TRACE: Waiting a for response.
0000010890 [comm.sparkprotocol] INFO: Sending S describe message
0000010956 [httpSD] TRACE: Reading response.
0000010956 [httpSD] TRACE: Bytes available: 128
0000010956 [httpSD] TRACE: Processing headers
0000010957 [httpSD] TRACE: Bytes available: 128
0000010957 [httpSD] TRACE: Processing headers
0000010958 [httpSD] TRACE: Bytes available: 128
0000010958 [httpSD] TRACE: Processing headers
0000010959 [httpSD] TRACE: Bytes available: 27
0000010959 [httpSD] TRACE: Processing headers
0000010961 [httpSD] TRACE: Bytes read: 411
0000010961 [httpSD] TRACE: Connection closed

But the file created is 0 bytes

My question was how are you initiating the upload (I thought you were trying to update file on the SD card for the Nextion display). Sorry if I am a bit confused about what the process is.

That is correct!
I already have the sd to nextion update working. I copied the tft file to the sd using a card reader.
Next step was to download the tft file to the sd using wifi. So i used the http-download lib and updated it to work with sdfat. The example file downloads a jpg and that is all i am trying to get working right now.

1 Like

Bumping this one!! Any one have any other suggestions for a library for http downloads?

Hi @ScruffR,

thank you for porting this library.
I could not avoid laughing at the license, seems very very very permissive! :wink:

2 Likes

Yup, that was ITEAD’s own license - I’d have refrained from using such language, but since it’s their IP I felt bound to copy it :innocent:

1 Like