Nextion HMI & Arduino ( 2 way synchronise toggle button)[Solve]

I am trying to build 2 way toggle button which should synchronise between arduino and Nextion HMI display.

setup:
Push button and led connect with Arduino.
Nextion connect with arduino through software serial.

Achieved:
successfully toggle the led from HMI to Arduino.(On-Off...etc)
successfully toggle the led from Arduino to HMI.(On-Off...and update display accordingly)

Problem:

  1. If make ON from physical push button(arduino) it will Off from HMI in 2nd click and than toggle on each click but HMI display show always ON position.

  2. If Make ON from HMI display it will Off in 1st click of physical button on Arduino but HMI display did not update to Off condition.

I feel something wrong in Nextion code and did not find how to read incoming data in Nextion display. I need some help if someone can correct me.

My nextion and arduino program attached.

#include <SoftwareSerial.h>
#include <Nextion.h>

SoftwareSerial nextion(2, 3);// Nextion TX to pin 2 and RX to pin 3 of Arduino
Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps

const uint32_t debounceTime = 50;  // 5 mSec, enough for most switches
const uint8_t switchPin0     = 4;  //
#define ledPin0      9
const bool switchOn  = true;     // using INPUT_PULLUP
const bool switchOff = false;

bool lastState0   = switchOff;
bool newState0    = switchOff;
bool LED_state0 = false;

void setup() {
  Serial.begin(9600);
  myNextion.init();
  pinMode ( switchPin0, INPUT_PULLUP );
  pinMode(ledPin0, OUTPUT);
  digitalWrite(ledPin0, LOW);
}

void loop() {
  String message = myNextion.listen(); //check for message
  if (message != "") { // if a message is received...
    Serial.println(message); //...print it out
  }

  newState0 = digitalRead( switchPin0 );

  if ( lastState0 != newState0 ) // state changed
  {
    delay( debounceTime );
    lastState0 = newState0;

    // push on, push off
    if ( newState0 == switchOn && LED_state0 == false )
    {
      LED_state0 = true;
      Serial.println("1 true");
      myNextion.sendCommand("bt0.picc=1"); //set "b0" image to 2
      myNextion.sendCommand("ref bt0"); //refresh
    }
    else if ( newState0 == switchOn && LED_state0 == true )
    {
      LED_state0 = false;
      Serial.println("1 false");
      myNextion.sendCommand("bt0.picc=0"); //set "b0" image to 2
      myNextion.sendCommand("ref bt0"); //refresh
    }
    digitalWrite(ledPin0, LED_state0);
  }

  /////////////////////-----------------/////////////

  if (message.indexOf("bt0=0") > -1) {
    LED_state0 = false;

    Serial.print("HMI to arduino :");
    Serial.println("bt0= LOW");

  } else if (message.indexOf("bt0=1") > -1) {
    LED_state0 = true;
    Serial.print("HMI to arduino :");
    Serial.println("bt0= HIGH");
  }
  digitalWrite(ledPin0, LED_state0);

 // int i=myNextion.getComponentValue("page0.bt0"); 
//Serial.print(" FB from HMI :       ");
  // Serial.println(i);
}

Arduino_Physical_Btn.ino (2.08 KB)

I update the sketch and now Led is toggle completely Synchronized from both side (arduino and Nextion). But Nextion display is not Synchronized when toggle across the devices.

I try to use following code to read the button state on HMI but it work only when toggle state from HMI.If button state update through arduino it never read

 int i=myNextion.getComponentValue("page0.bt0");
      Serial.print("\t");
      Serial.print("Feedback from Naxtion from HMI :   ");
      Serial.println(i);

Serial output

Arduino Btn > HIGH    Feedback from Naxtion from HMI :   0    //arduino toggle and HMI display work 
Arduino Btn > LOW     Feedback from Naxtion from HMI :   0     // cannot read button status from HMI
Arduino Btn > HIGH    Feedback from Naxtion from HMI :   0
Arduino Btn > LOW     Feedback from Naxtion from HMI :   0

Naxtion Btn > HIGH    Feedback from Naxtion from HMI :   1    //Working when toggle from HMI
Naxtion Btn > LOW     Feedback from Naxtion from HMI :   0
Naxtion Btn > HIGH    Feedback from Naxtion from HMI :   1
Naxtion Btn > LOW     Feedback from Naxtion from HMI :   0

Arduino Btn > HIGH    Feedback from Naxtion from HMI :   0
Naxtion Btn > LOW     Feedback from Naxtion from HMI :   1
Arduino Btn > HIGH    Feedback from Naxtion from HMI :   1
Naxtion Btn > LOW     Feedback from Naxtion from HMI :   0

Naxtion Btn > HIGH    Feedback from Naxtion from HMI :   1
Arduino Btn > LOW     Feedback from Naxtion from HMI :   -1
Naxtion Btn > HIGH    Feedback from Naxtion from HMI :   0
Arduino Btn > LOW     Feedback from Naxtion from HMI :   0

Updated sketch (also I used image and crop image methode in HMI but same result)

#include <SoftwareSerial.h>
#include <Nextion.h>

SoftwareSerial nextion(2, 3);// Nextion TX to pin 2 and RX to pin 3 of Arduino
Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps

const int buttonPin = 6;    // the number of the pushbutton pin
const int ledPin = 9;      // the number of the LED pin

int ledState = LOW;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers


void setup() {
  Serial.begin(9600);
  myNextion.init();
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {

  String message = myNextion.listen(); //check for message
  if (message != "") { // if a message is received...
   // Serial.println(message); //...print it out
  }

  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState)   {
    lastDebounceTime  = millis();
  }
  /////////////////-------------------------///////////////////////////

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == LOW) {
        ledState = !ledState;

        if (ledState) {
          myNextion.sendCommand("bt0.pic=1"); //set "b0" image to 2
          myNextion.sendCommand("ref bt0"); //refresh
          Serial.print("Arduino Btn > HIGH");
        }

        if (!ledState) {
          myNextion.sendCommand("bt0.pic=0"); //set "b0" image to 2
          myNextion.sendCommand("ref bt0"); //refresh
          Serial.print("Arduino Btn > LOW");
        }

      int i=myNextion.getComponentValue("page0.bt0");
      Serial.print("\t");
      Serial.print("Feedback from Naxtion from HMI :   ");
      Serial.println(i);
      }
    }
  }

  ////////////////////////------------------//////////////////

  if (message.indexOf("bt0=0") > -1 || message.indexOf("bt0=1") > -1) {
    ledState = !ledState;

    if (ledState) {
      myNextion.sendCommand("bt0.pic=1"); //set "b0" image to 2
      myNextion.sendCommand("ref bt0"); //refresh
      Serial.print("Naxtion Btn > HIGH");
    }

    if (!ledState) {
      myNextion.sendCommand("bt0.pic=0"); //set "b0" image to 2
      myNextion.sendCommand("ref bt0"); //refresh
      Serial.print("Naxtion Btn > LOW");
    }

      int i= myNextion.getComponentValue("page0.bt0");
      Serial.print("\t");
      Serial.print("Feedback from Naxtion from HMI :   ");
      Serial.println(i);
  }

  //////////////////////---------------------////////////////////////

  digitalWrite(ledPin, ledState);
  lastButtonState = reading;
}

Hello Ghulamfarid,
I saw this when you first posted it and hoped someone else might reply, but so far they have not. Unfortunately for you there isn't much support on here for the official Nextion libraries. I can't help with them and if you really want to use them then I think you might struggle here (if someone wants to help please do!).

What you are trying to do is simple enough using the methods I set out in https://forum.arduino.cc/index.php?topic=604185.0 , but you will have to learn a completely different approach, including getting rid of all and any delays.

Try the tutorial, see how you get on and ask if you get stuck.

Thanks "PerryBebbington" for your comment.

I will start to read your post in my next project.

In above my post I realize that dual state button is not helpful. I use simple push button and its work as I want to "2 way synchronise toggle button". Only looking the indicator on HMI which show the relay state as a virtual LED. I hope I will get that with basic colour change command to nextion

I use normal buttons to get 2 states: on - off, I just change the colour of the text and background to indicate the state and keep a record of what the state is in the code.

Finally resolve the issue after reading some comment by "PerryBebbington" with below command.

myNextion.sendCommand("click bt0,1");  // instead of changing the image I use touch event over serial command.