Start a new topic

Programming question

 I am having a bit of a problem guys.

I am trying to use a Nextion touch screen to control my off road lights. I am using a Arduino Mega 2560 board. A 8 module relay board. and the Nextion screen. The sketch I have written everything works except after I fire the relay I am unable to turn it off. In the sketch I am also posting in the first button toggle I am having the state of the pin read then based on the state turn it off or on. Well it now does nothing. It neither fires the relay or turns it off.

In the rest of the button toggles I just have it fire the relay when the button toggles.

The message that is called for in the button toggles does not change based on button state. Otherwise I would use that to turn the relay off.

Guys I am at a loss. Any guidance would be greatly appreciated.

/* This is my Sketch for the Touch Screen interface for the relay box that will be installed in my Jeep
  Robert L. Wardecker
  This code is in public domain

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

const int relayaPin = 52;
const int relaybPin = 53;
const int relaycPin = 50;
const int relaydPin = 51;

SoftwareSerial nextion(10, 11);// Nextion TX to pin 10 and RX to pin 11 of Arduino

Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps

boolean button1State;
boolean button2State;
boolean button3state;
boolean button4state;
boolean button5state;

void setup() {
  // put your setup code here, to run once:
  myNextion.init(); // send the initialization commands for Page 0

  pinMode(relayaPin, OUTPUT);
  pinMode(relaybPin, OUTPUT);
  pinMode(relaycPin, OUTPUT);
  pinMode(relaydPin, OUTPUT);


void loop() {
  // put your main code here, to run repeatedly:

  String message = myNextion.listen(); //check for message
  if (message == "65 0 1 1 ffff ffff ffff") {
  myNextion.buttonToggle(button1State, "b0", 0, 2);

  if (relayaPin == HIGH) {
  // turn Relay on:
  digitalWrite(relayaPin, HIGH);
  } else {
  // turn LED off:
  digitalWrite(relayaPin, LOW);

  if (message == "65 0 2 1 ffff ffff ffff") {
  myNextion.buttonToggle(button2State, "b1", 0, 2);
  digitalWrite(relaybPin, HIGH);
  if (message == "65 0 3 1 ffff ffff ffff") {
  myNextion.buttonToggle(button3state, "b2", 0, 2);
  digitalWrite(relaycPin, HIGH);
  if (message == "65 0 4 1 ffff ffff ffff") {
  myNextion.buttonToggle(button3state, "b3", 0, 2);
  digitalWrite(relaydPin, HIGH);
  if (message == "65 0 5 1 ffff ffff ffff") {
  myNextion.buttonToggle(button3state, "b4", 0, 2);
  digitalWrite(relayaPin, HIGH);
  digitalWrite(relaybPin, HIGH);
  digitalWrite(relaycPin, HIGH);
  digitalWrite(relaydPin, HIGH);


My approach would be to use a dual-state button with the send component ID checked

Listening for "0x65 0x00 0x01 0x00 0xff 0xff 0xff" where 0x01 is my dual-state button's ID

Then when I receive that trigger, I would issue a get command.

get bt0.val  // where bt0 is the objname of my dual-state button

This will generate a four-byte value being returned with the possibility of 1 for on and 0 for off

0x71 0x01 0x00 0x00 0x00 0xff 0xff 0xff 0xff  // signifies on

0x71 0x00 0x00 0x00 0x00 0xff 0xff 0xff 0xff  // signifies off

Using this approach allows me to query the display at anytime, just in case the display and Mega were not in sync, I can check the display value and sync the light via the Mega as necessary.

I'll leave you to code the Mega

(1.99 KB)

While I am not using the Arduino platform (Intel Edison with kylix pascal), I didn't see the actual function for toggling the button listed in your code above. I am unable to check the code I don't have. One issue for me

your function myNextion.buttonToggle, if toggling from the Mega has to send the text b3.val=1 or b3.val=0 to set the dual-state button on the nextion display.  If it was toggled from the nextion display than that value was already toggled on the nextion and it is your Boolean button3state that merely needs updating.

I have certainly run into scenarios where when responding to a button toggle and issuing another toggle will cancel themselves out in Boolean leaving the original state, like kind of what you are describing.

If button toggled from the nextion display by the user, you should be responding capture the state, and controlling your lights.  Perhaps using your response after capturing the event

button3state := not button3state

if button3state = true then

digitalWrite(relaycPin, HIGH)


digitalWrite(relaycPin, LOW)

I see where you in relayaPin you have high and lows

but I don't see any lows for the other 3 pins ?

Allow me to make a stab at this.

1 person likes this

I am going to back out on this one not knowing what the Arduino platform library are doing.

quick googling into Arduino and I notice that people have buffers defined, or are adding the received character to a message string that will be cleared later.  The nextion definitely has response codes that vary in length, and I have no idea what the library is/has taken care of todate.  I updated the backlight.hmi file to include your four buttons for each of your four pins and defined the fifth button as a master turning all on or all off.  Included the init and toggles inside the updated hmi.

however, in looking deeper at your code, you have a a mix of numer and hex values, and they don't combine.  The data terminator is three bytes of hex 0xFF, so ffff ffff ffff is going to be incorrect.

I apologize again, Arduino isn't my platform.  I hope that I might have been a bit of help to your goal

(1.99 KB)

1 person likes this
I solved my problem. I was trying to get the state of the button and switch the relay based on the state of the button. I am still doing that but remembered the sketch already knows the state of the button thus I don't have to get it a second time. In the Boolean declaration the state is stored. so I just use that to construct my if else code. Now it works as I envisioned it. Thank you so much for the help


 //52" Lightbar
  if (message == "65 0 1 1 ffff ffff ffff") {
    myNextion.buttonToggle(button1State, "b0", 0, 2);

    if (button1State == HIGH) {
      // turn Relay on:
      digitalWrite(relayaPin, HIGH);
    } else {
      // turn Relay off:
      digitalWrite(relayaPin, LOW);




Can you confirm for me the message as 65 0 1 1 ffff ffff ffff ? 
The format of the end of data being three bytes of 0xff, I picture the data coming in might be ff ff ff?

If the double f  (ff) is tried over the quad f (ffff) does it still function?

The other thing that I have a question on is "is message always in hex?", as it looks as if it is a mix.




Yes the message that the Nextion touch screen sends is 65 0 1 1 ffff ffff ffff. 65 being a touch event, 0 is the page(I can set up several pages on the touch screen), 1 is the component ID, 1 being the image of the button, the f series are just extraneous information that I have no idea what they mean. Yes the nextion always communicates in hex. 


How did you create a Nextion object named myNextion using the nextion serial port @ 9600bps? 


Such code with Nextion myNextion comes from unsupported lib where authors do not answer your questions.  It can also be identified by message=(xx x x x ffff ffff ffff) which is not correct to the Nextion Instruction Set which clearly states data is terminated by three bytes of 0xFF.  Perhaps look at IteadLib Arduino Nextion Library as a source for coding example.

You are of course free to choose as and struggle as you see fit.

Question...?  If i want the relay on for a specified time, i know i need to add a delay. But, instead of "else", do i write a "then" statement for delay to off? I think i just answered myself (i need to read more).

other question: i want 2 relays on 1 button. 

other question: what is <doxygen.h>  and what is <SoftwareSerial.h> and why are they used?

other question: if you are using an 8 channel relay, wouldnt that need to be included? #include<base>

Hi Daron,
I'm still searching how to control the relays... but i can help you on some questions :

2 Relays on 1 button is possible :

if(buttonx == HIGH){

  digitalWrite(R1, HIGH);

  digitalWrite(R2, HIGH);


<doxygen> i'm not sure it comes from official library...

<SoftwareSerial> is library to add more serial on your arduino by digital pins (attention, not all the pins are supported, you should check for the different boards) this library is useful to communicate with your Nextion.

#include<> are for library, you don't need library for relays, just to declare it :

int R1 = 2;

int R2 = 3;

int R3 = 4;


Just pay attention if you use more than 2 relays board, to have an external power, and to link the grounds !

Good luck for your project ;-)


For the specified time, i advice you not tu use the function delay(), but the function millis()

You can check some examples on Google.

When you use delay(200); it means you µc is freezing for 200 milliseconds

With the function millis(), i know it's a bit more... not complicated... but more commands to write, but your µc continue to work with other functions.

So..if i try to use a neopixel ring as well,  delay() will also delay() the neopixel?

Yes, delay() will halt the MCU, regardless of what library or code.

Here's a link to explain the millis() timer functions, and why delay() is not so good.....

Follow the blue next page links for the series, bottom right of the pages

Login or Signup to post a comment