Nextion - read and write at the same time


I'm trying to make control panel for ebike with Nextion and ESP32 (display the speed, energy and so on). Data is reading from ebike controller in loop every 200ms. This data is parsing and writting to Nextion in different text boxes.
At the same time I have some buttons with callbacks.
The problem is when I press any button with callback, this callback sometime not called.
If I comment all writing to text boxes - the buttons will work correctly.
I'm using the hardware serial (Serial2) for commuticate with Nextion.


struct Label 
 NexText speed = NexText(1, 3, "speed");
 NexText voltage = NexText(1, 5, "volts");
 NexText current = NexText(1, 6, "current");
 NexText ah = NexText(1, 13, "ah");
 NexText ahRegen = NexText(1, 15, "ahRegen");
 NexText tempCont = NexText(1, 20, "controllerTemp");
 NexText tempEngine = NexText(1, 18, "engineTemp");
 NexText distance = NexText(1, 21, "distance");
 NexText odometer = NexText(1, 22, "odometer");
 NexText power = NexText(1, 4, "watts");
 NexProgressBar ahBar = NexProgressBar(1, 1, "ahBar");
 NexText date = NexText(1, 11, "date");
 NexText time = NexText(1, 12, "time");
 NexPage splash = NexPage(0, 0, "splash");
 NexPage main = NexPage(1, 0, "main");

 NexText status = NexText(0, 2, "status");
 NexText version = NexText(0, 3, "version");
typedef Label Label;

boolean initialized = false;
boolean firstRun = true;
boolean regen = false;
boolean controllerLocked = true;

HardwareSerial BTserial(1);
AsyncWebServer server(80);

CurrentData currentData;
Label labels;

NexDSButton chargeModeButton = NexDSButton(3, 2, "chargeMode");
NexButton saveSettingsButton = NexButton(3, 5, "saveSettings");
NexTouch *nex_listen_list[] = 

void chargeModeCallback(void *ptr) {
  uint32_t state;
  if(state) {
    Serial.println("Charge mode - ON");
  else {
    Serial.println("Charge mode - OFF");

void saveSettingsCallback(void *ptr) {
  Serial.println("Save setting");

void setup(void)
    BTserial.begin(BtBaudRate, SERIAL_8N1, RX_BT, TX_BT);
    cfg.begin("vortex", false);

    chargeModeButton.attachPop(chargeModeCallback, &chargeModeButton);
    chargeModeButton.attachPush(chargeModeCallback, &chargeModeButton);
    saveSettingsButton.attachPop(saveSettingsCallback, &saveSettingsButton);

void coreTask( void * pvParameters ){  
  for(;;) {

void loop(void) {    
    // sending TrmRequest (request controller for data)
    BTserial.write(-1);     // 0xff
    BTserial.write(-1);     // 0xff
    BTserial.write(1);      // data length
    BTserial.write(113);    // command
    BTserial.write(-115);   // packet crc
    while(BTserial.available()) {
      data =;
      if(data == 0xFF && prevData == 0xFF) {
        byte packetLength =;
        byte packetType =;
        // data packet (5)
        if(packetType == 5) {
                    <<< there is some data parsing and view in Nextion >>>
      prevData = data;
    if(noData > 10 && initialized) {
     labels.status.setText("Waiting for data from controller...");
     initialized = false;
    if(initialized) {

Full sources is here: VectorMonitor/VortexMonitor.ino at master · MrNeuronix/VectorMonitor · GitHub

Hello Neuronix,
Welcome to the forum.

I've not looked at the code on the external site, better to post it here so people don't have to go hunting for it.

I am guessing you are using the Nextion libraries, is this correct? I am guessing you are relying on the code in the ESP asking the Nextion if a particular button is pressed, is this correct?

Assuming that's the case, have a look at my tutorial, which is not based on the Libraries and works by having code behind each object to send events to the controller (Arduino or otherwise) when they happen. I have used this method effectively for several projects and don't experience any of the problems you are having.

Have you managed to find a solution to this? I am currently struggling the same problem


I was experiencing exactly the same issue and i am using Nextion library as well. Spoofing the serial proved data transmitted has no errors. Callbacks are just not called from time to time, mostly when some labels are being refreshed in the background.

Solution: don't use the library, or do a nasty modifications:
In NexHardware.cpp remove:
while (nexSerial.available())

and in NexText replace return statements with "return true;"

As I said, nasty, but works. Some improvement is achieved as well with calling "nexLoop(nex_listen_list);" more often, especially before each and all of label updates.

My goal is to abandon library like PerryBebbington did. It is poorly designed.