Nextion not processing first Write using EasyNextion library

Hi,

I'm building a kind of home managing panel using a Wemos D1 mini esp8266 and a Nextion display using EasyNextion lib.
All works fine, even receiving events from the Nextion (what I could not get to work with the ITEAD lib).

There is however one thing that is rather strange. Upon sending a cluister of write commands to the nextion in some cases the first write is not processed. Adding a duplicate line resolves this but is rahter strange.

One example:

void loop() {

  delay(100);  // To avid timer issues on Nextion

  // Check if we should update open weather information
  if ((millis() - lastDownloadUpdateOpenWeather > 1000 * UPDATE_INTERVAL_SECS) || firstCycle) {
    updateOpenWeatherData();
    if (myNex.currentPageId == 0) {
      myNex.writeStr("tWeatherDescr.txt", currentWeather.description);
      myNex.writeStr("tWeatherDescr.txt", currentWeather.description);
      myNex.writeNum("pWeatherIcon.pic", getPictIdFromIconText(currentWeather.icon.c_str()));
      // Serial.println(String(currentWeather.temp, 1));
    }
//    drawCurrentWeatherDetail();
    lastDownloadUpdateOpenWeather = millis();
  }

  // Check if we should update my weather information
  if ((millis() - lastDownloadUpdateMyWeather > 1000 * MY_WEATHER_INTERVAL_SECS) || firstCycle) {
    updateMyWeatherData();
    if (myNex.currentPageId == 0) {
      myNex.writeStr("tTemp.txt", String(currentMyWeatherStation.temp, 1) + "°C");
      myNex.writeStr("tTemp.txt", String(currentMyWeatherStation.temp, 1) + "°C");
      // Serial.println(String(currentMyWeatherStation.temp, 1));
    }
    lastDownloadUpdateMyWeather = millis();
  }
  
  // Check if we should update wifi quality
  if ((millis() - lastWifiUpdate > 1000 * WIFI_INTERVAL_SECS) || firstCycle) {
    if (myNex.currentPageId == 0) {
      myNex.writeNum("nWifiStrength.val", getWifiQuality());  // Update wifi quality as presented on page0
    }
    if (myNex.currentPageId == 1) {
      myNex.writeNum("nWifiStrength.val", getWifiQuality());  // Update wifi quality as presented on page1
    }
    lastWifiUpdate = millis();
  }

  if (SLEEP_INTERVAL_SECS && millis() - timerPress >= SLEEP_INTERVAL_SECS * 1000) { // after 2 minutes go to sleep
    // go to deepsleep for xx minutes or 0 = permanently
    ESP.deepSleep(0,  WAKE_RF_DEFAULT);                       // 0 delay = permanently to sleep
  }

  if ((millis() - lastTimeUpdate > TIME_INTERVAL_MSECS) || firstCycle) {
    if (myNex.currentPageId == 0) {
      updateTime();
    }
    lastTimeUpdate = millis();
 }

  firstCycle = false; //first cycle initial update data is finished
  
  myNex.NextionListen(); // This function must be called repeatedly to response touch events from Nextion touch panel.
 }

As you see I added a duplicate writeStr command to get the weather description displayed.
Putting the WriteNum in front of the writeStr would result in not having that processed by the Nextion.

A step further I also have to write the current temperature twice.
This one has another issue: the degree symbol "°" is translated to "°". The degree symbol is part of the font I loaded in Nextion Editor.

On the other hand, having multiple writeStr or writeNum in the Trigger0 function works with no issue.

What would cause this missing first command issue?
I have the baud rate at 9600.

This one has another issue: the degree symbol "°" is translated to "°". The degree symbol is part of the font I loaded in Nextion Editor.

See this thread about utf-8 characters and the default iso=8859 font settings on the Nextion.

https://forum.arduino.cc/t/utf-8-code-to-nextion-display/1293647/2

Regarding the double entry, I have not seen this problem with my use of the EasyNextion Library. It feels to me more like an issue with the esp 8266.

What Nextion model are you using?
What Serial port on the esp8266 are you using?
Do you have any other Arduino or perhaps an esp32 to try with?

Hi cattledog,

I use the standard Serial, the ESP8266 unfortunately has only one.

The utf-8 on fonts in Nextion did not do it for me.
However, I just found the solution in char(176) working for me.

const char degreeSign = char(176);

myNex.writeStr("tTemp.txt", String(currentMyWeatherStation.temp, 1) + degreeSign + "C");

Just the missing first write command to go.

I certainly can not confirm your issue with a simple test sketch writing from a Wemos D1 mini to a text field on a Nextion. A single myNex.writeStr( ) is all it takes.

There's something about your environment independent of a WemosD1 mini and a The EasyNextion library which is causing your issue.

I can not replicate your issue, even if I use a more complex code similar to your sketch. What happens if you take out the sleep functions and try to simplify the code in other fashions.

This code works fine without double writes using either your String concatenation or a c style character string built with sprint().

#include "EasyNextionLibrary.h" // Include EasyNextionLibrary v1.0.6 latest
EasyNex myNex(Serial);//Pin0 wemos tx to nextion rx  Pin1 wemos rx to Nextion tx

const char* descriptions[] = {"Rainy", "Sunny"};
float temperatures[] = {23.5, 34.5};
const char degreeSign = char(176);

void setup() {
  myNex.begin(9600); //Begin the object with a baud rate of 9600 on Serial1
  delay(1000); // Wait for Nextion to start
  myNex.writeStr("page 0");
  delay(5000);
}

void loop() {
  myNex.NextionListen();
  //char buf1[] = "          ";//10 space place holder
  
  myNex.writeStr("tWeatherDescr.txt", descriptions[0]);
 // sprintf(buf1, "%.1f%c", temperatures[0], degreeSign);
 // myNex.writeStr("tTemp.txt", buf1);
  myNex.writeStr("tTemp.txt", String(temperatures[0],1) + degreeSign + "C");

  delay(5000);
  
  myNex.writeStr("tWeatherDescr.txt", descriptions[1]);  
  //sprintf(buf1, "%.1f%c", temperatures[1], degreeSign);
  //myNex.writeStr("tTemp.txt", buf1);
  myNex.writeStr("tTemp.txt", String(temperatures[1],1) + degreeSign + "C");
 
  delay(5000);

}

Thanks for helping me.

Did you use the actual Nextion?
In the serial monitor indeed all is visible on my side but the Nextion does not process the first one.

In a Trigger function I have also constructions with multiple commands and these work fine.

void trigger0(){
  // bSend button page1, id: 4, event printh 23 02 54 00
  //Serial.println("bSend button");
  String txt;
  txt = myNex.readStr("bSend.txt");
  if(txt == "Send") 
  {
    myNex.writeStr("tState.txt", "State: Send");
    myNex.writeStr("bSend.txt", "Release");
  }
  else
  {
    myNex.writeStr("tState.txt", "State: Release");
    myNex.writeStr("bSend.txt", "Send");
  }
}

So it beats me why this is not working in the Loop procedure.

btw: I removed the sleep function.

Yes, I used a Nextion Discovery 2.8". NX3224F028_011

What model do you have. There have been some strange issues with Intelligent Series.

but the Nextion does not process the first one.

Did you try the sprintf() construction of the message to send?

EDIT:

In the serial monitor indeed all is visible on my side but the Nextion does not process the first one.

Have you tried running with the serial monitor unopened when powered through usb or with the usb connection removed and the esp8266 powered from a regulated 5v?

I have a Nextion Basic 3.6, NX4832T035_011.

Not yet since the String solution works and is documented like that.
The weather items are part of a struct.
But to exclude this I tried having the same issue. I need to write twice.

Yes, running with the Serial Monitor unopened. Power however was always through USB of the Wemos. I'm in a development fase now.

My guess is the functions before, "updateOpenWeatherData()" and "updateMyWeatherData()", using a network connection have something to do with this.
That's the only difference with your sketch.

I agree there's something in the access and parsing of data from the Open Weather site which is causing the issue.

Can you provide a complete sketch with your setup, libraries, the weather data structs, and documentation on the Open Weather calls?

Do you know how long of a time it takes for the OpenWeather functions to fill the structs?
If you don't use the Nextion but just run a sketch with serial output of the struct data, do you need two serial print statements to get the data to the monitor?

The OpenWeather and MyWeather (blueprint of OpenWeather used) functions just open a temporary WifiClient object (the first uses WifiClient and the secont WifiClientSecure) to optain a JSON file from the respective web portal API.
The JSON file is is transformed by JsonStreamingParser object to a data struct for each of them.
During the whole time the standard hardware Serial is used. Probably the Serial output of the Open Weather part is causing an issue with the myNex objectusing the same one.
Although using Serial.println during the use of myNex write/read functions did not harm the Nextion response.

The OpenWeater solution used is a 1 on 1 copy as used in the "ESP 8266 Weather Station" library.

I have built that ThingPulse weather station (other screen used there) a few years ago and works until today just fine. It gets the data within a few seconds. Only one Serial is used. It sets up a Wifi data connection just to get the JSON data to parse to a struct and closes the connection directly afterwards.
The "ESP 8266 Weather Station" library is in the Arduino IDE environment to install.

I think it will be to much to investigate what exactly is happening and since I'm not an expert in this code reading (I grab bits from other things and combine for my projects), I think it will be difficult to address.
Performing the Nextion commands twice the first time after the weather data refresh is not a big deal as long as it works. I could sent a dummy write just to make it clear in my code.

Maybe you find it a challenge to figure out what is going on. In that case I'm of course interested but I don't want you to spend a lot of time on my behalf.

You helped already a lot. I got it somehow to work :slight_smile:

Yes, there is something in the Open Weather serial data which is making it so the Nextion does not see a clean library writeStr().

void EasyNex::writeStr(String command, String txt){ 
	_component = command;
	_strVal = txt;
  
  if(_strVal == "cmd"){
    _serial->print(_component);
    _serial->print("\xFF\xFF\xFF");
    
  }else if(_strVal != "cmd"){
    _serial->print(_component);
    _serial->print("=\"");
    _serial->print(_strVal);
    _serial->print("\"");
    _serial->print("\xFF\xFF\xFF");
  }
}

If you have stable work arounds you're good.

If the project could be ported from an ESP8266 to an ESP32 you would not have this "Hey that's my Serial" issue as there are multiple hardware Serial ports.

EDIT: This library for Open Weather certainly supports the ESP32
https://github.com/Bodmer/OpenWeather/tree/main

For now I would say I have a stable work around in just starting a 'dummy' write to myNex after a network data update.
I like the esp8266 as it works now but might change in case I run into other issues during this project.
I'll cross that bridge when I come to it...

Many Thanks so far!