ButtonDualState Nextion and Blynk Switch

Hello guys,
I have an ATS / AMF project, I want to connect the Nextion ButtonDualState and the switches in Blynk to be used as a Manual and automatic operation. ButtonDualState which is in the nextion is functioning properly how to synchronize with the switches in Blynk …?

I already got a sketch example but it’s very different from my sketch structure .

I use the library itead arduino nextion

#include <PZEM004Tv30.h>
#include <Nextion.h>
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include "RTClib.h" 
#include "NexDualStateButton.h"
#include "NexButton.h"
#include "NexText.h"
#define RX2 16
#define TX2 17 


SoftwareSerial HMISerial(18, 19);      //Pin Nextion


const int PLNStatus = 27;     // Status 220 AC
const int GENStatus = 14;    //GenStatus
const int Stop = 26;             //Stop Gen
const int Start = 25;            //Start Gen
const int GEN = 33;         //Relay Gen To Load
const int PLN = 32;              //Relay 220 AC To Load
int Starting=0;


const int StartMan = 25;     //Manual Operation
const int StopMan = 26;
const int Rst = 27;
uint32_t Selektor=0;
uint32_t Start1=0;
uint32_t Stop1=0;


 int GenState;   // voltage detection
 int PlnState; 
 

  bool On=LOW;
  bool Off=HIGH;

  int AutoMode=0;    //Switch case Auto
  int ManualMode=0;    //Switch case Manual
  

char HARI[7][12] = {"Ahad", "Senin", "Selasa", "Rabu", "Kamis", "Jum'at", "Sabtu"};  // Rtc

char buffer[100];
int energi;


PZEM004Tv30 pzem(&Serial2);   //Pin PZEM

 float voltage_blynk=0;   //Monitoring Energy In Blynk
  float current_blynk=0;
  float power_blynk=0;
  float energy_blynk=0;
  float freq_blynk=0;
  float Pf_blynk=0;


RTC_DS3231 rtc;
  

NexText V = NexText(1,3,"V");    //Nextion Energy
NexText A = NexText(1,5,"A");
NexText W = NexText(1,7,"W");
NexText Wh = NexText(1,9,"Wh");
NexText freq = NexText(1,11,"freq");
NexText Pf = NexText(1,21,"Pf");

NexText j = NexText(1,13,"j");      //Nextion Timer/RTC
NexText s = NexText(1,22,"s");
NexText tgl = NexText(1,16,"tgl");
NexText hari = NexText(1,19,"hari");
NexText bulan = NexText(1,23,"bulan");

NexText t5 = NexText(2,9,"t5");
NexText t2 = NexText(2,6,"t2");
NexText t8 = NexText(2,15,"t8");

NexDSButton Mode = NexDSButton(2,10,"Mode");      //selector in Nextion manual or Auto
NexDSButton Mstart = NexDSButton(2,11,"Mstart");   // Starting Gen in Nextion
NexDSButton Mstop = NexDSButton(2,12,"Mstop");   // StopGen in Nextion
NexButton Reset = NexButton(2, 17, "Reset");     // Reset Esp32 in Nextion
NexButton normal = NexButton(0, 14, "normal");

char auth[] = "xxxxxxxxxxxxxxxxxx";
char ssid[] = "xxxxxx";
char pass[] = "Ixxxxxxx";

//Reset
NexTouch *nex_listen_list[] = {
  &Reset,
  &normal,
  NULL
};

void ResetPopCallback(void *ptr) {
  digitalWrite(Rst, LOW);
  delay(500);
   digitalWrite(Rst, HIGH);
}

void normalPopCallback(void *ptr) {
   delay(100);
  digitalWrite(Rst, HIGH);  
}
 
void setup() {
 Serial.begin(9600);
  nexInit();
Serial2.begin(9600);
 Blynk.begin(auth, ssid, pass); 
rtc.begin();

Reset.attachPop(ResetPopCallback, &Reset);
normal.attachPop(normalPopCallback, &normal);

 

 pinMode(StartMan, OUTPUT);   //Manual Output
 pinMode(StopMan, OUTPUT);
 
pinMode(Stop, OUTPUT);  //Auto Output Relay
pinMode(Start, OUTPUT); 
pinMode(GEN, OUTPUT); 
pinMode(PLN, OUTPUT); 

pinMode(Rst, OUTPUT); //Reset

digitalWrite(Stop, Off); 
digitalWrite(Start, Off); 
digitalWrite(GEN, Off); 
digitalWrite(Stop, Off);
digitalWrite(Rst, Off);


pinMode(PLNStatus, INPUT_PULLUP);  //Input Voltage Ac 220
pinMode(GENStatus, INPUT_PULLUP);  //Input Voltage Gen
}

void Data(){
  PlnState = digitalRead(PLNStatus); 
  GenState = digitalRead(GENStatus); 
   Mode.getValue(&Selektor);
   Mstart.getValue(&Start1);
   Mstop.getValue(&Stop1);
 
   if (PlnState== On && GenState== Off)digitalRead(AutoMode=1);
   if (PlnState== Off)digitalRead(AutoMode=2);  
   if (GenState== On &&  PlnState== Off)digitalRead(AutoMode=3);
   if (GenState== On && PlnState== On)digitalRead(AutoMode=4);
   if (Starting >=3)(AutoMode=5);
   if(Start1==0 && Stop1==0)(ManualMode=1);
   if(Start1==1 && Stop1==0)(ManualMode=2);
   if(Start1==0 && Stop1==1)(ManualMode=3);
   if(Start1==1 && Stop1==1)(ManualMode=3);
    
}
void Change_Over(){
 if (Selektor==0){
    t5.setText(": Auto");
   switch (AutoMode) {
    case 1: 
    delay(3000);
      digitalWrite(PLN, On);  
      t2.setText(": PLN");
      digitalWrite(GEN, Off); 
      t8.setText(": Off");
      digitalWrite(Start, Off);
      digitalWrite(Stop, Off);
      digitalWrite(StartMan,Off);
      digitalWrite(StopMan,Off);
      break;
      
    case 2:  
  
     digitalWrite(Stop, On); 
     t8.setText(": Off"); 
    delay(3000);  
     Starting++; 
    digitalWrite(Start, On);
     t8.setText(": Starting"); 
     digitalWrite(GEN, Off); 
    delay(4000); 
    digitalWrite(Start, Off);
   t8.setText(": Ready");
    delay(1000);
      break;
      
    case 3:
    digitalWrite(Start, Off);
    digitalWrite(Stop, On); 
    delay(10000);
    digitalWrite(PLN, Off);
    digitalWrite(GEN, On);
      t2.setText(": Genset");
      t8.setText(": On");
    break;

     case 4:
    t2.setText(": PLN");
    digitalWrite(PLN, On);
    digitalWrite(Start, Off);
    digitalWrite(GEN, Off);
    delay (5000);
    t8.setText(": Off");
    digitalWrite(Stop, Off);
    break;

   case 5:
    t8.setText(": Gagal Starting");
     digitalWrite(PLN, On);  
      t2.setText(": PLN");
      digitalWrite(GEN, Off); 
      digitalWrite(Start, Off);
      digitalWrite(Stop, Off);
      digitalWrite(StartMan,Off);
      digitalWrite(StopMan,Off);
      break;
    default:
    break;
  }
  Blynk.virtualWrite(V7, Off);
  Blynk.virtualWrite(V8, Off);
   
}
else if(Selektor==1){
   t5.setText(": Manual");
switch(ManualMode){
  
  case 1:
  digitalWrite(StartMan, HIGH);
  digitalWrite(StopMan, LOW);
  delay(1);
  break;

  case 2:
  digitalWrite(StartMan, LOW);
  digitalWrite(StopMan, LOW);
  delay(1);
  break;

  case 3:
  digitalWrite(StartMan, HIGH);
  digitalWrite(StopMan, HIGH);
  delay(1);
  break;
  default:
  break;
  
}
}
}

void Energy() {

float voltage = pzem.voltage();
if (voltage >= 0.0){
  itoa(voltage, buffer, 10);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  V.setText (buffer);}
  else{
     Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
      V.setText ("0");
  }
  
  float current = pzem.current();
  if (current >= 0.0){
  itoa(current, buffer, 10);
  A.setText (buffer);}
  else{
    A.setText ("0");
  }

 float power = pzem.power();
 if (power >= 0.0){
  itoa(power, buffer, 10);
  W.setText (buffer);}
else{
  W.setText ("0");
}

   float energy = pzem.energy();
   energi=energy*1000;
   if (energi >= 0.0){
  itoa(energi, buffer, 10);
  Wh.setText (buffer);}
  else{
   Wh.setText ("0"); 
  }

  float frequency = pzem.frequency();
if (frequency >= 0.0){
  itoa(frequency, buffer, 10);
  freq.setText (buffer);}
  else{
     freq.setText ("0");
  }

float pf = pzem.pf();
if (pf >= 0.0){
  itoa(pf, buffer, 10);
  Pf.setText (buffer);}
  else{
     Pf.setText ("0");
  }
}

void RTC() {

   DateTime now = rtc.now();
    int Tahun = now.year();
    int Bulan = now.month();
    int Tanggal = now.day();   
    int Jam = now.hour();
    int Menit = now.minute();
    int Detik = now.second();
    int Suhu = rtc.getTemperature();
       
        sprintf(buffer, "%02d:%02d:%02d", Jam, Menit, Detik);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        j.setText (buffer);

         sprintf(buffer, "%s,", HARI[now.dayOfTheWeek()]);
         Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        hari.setText (buffer);

    sprintf(buffer, "%02d'C", Suhu);
       Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        s.setText (buffer);  

     sprintf(buffer, "%02d/%02d/%02d", Tanggal, Bulan, Tahun);
     Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        tgl.setText (buffer);     
         delay(100);
}

void Android(){
 Blynk.run();

 float v = pzem.voltage();
  if (v >= 0.0){voltage_blynk=v;}  

  float i = pzem.current();
   if(i >= 0.0){current_blynk=i;}

  float w = pzem.power();
   if(w >= 0.0){power_blynk=w;}

  float KWh = pzem.energy();
   if(KWh >= 0.0){energy_blynk=KWh*1000;}

    float Hz = pzem.frequency();
   if(Hz >= 0.0){freq_blynk=Hz;}

    float pF = pzem.pf();
   if(pF >= 0.0){Pf_blynk=pF;}
   
   Blynk.virtualWrite(V0, voltage_blynk, " V");
   Blynk.virtualWrite(V1, current_blynk, " A");
   Blynk.virtualWrite(V2, power_blynk, " W");
   Blynk.virtualWrite(V3, energy_blynk, " Wh");
   Blynk.virtualWrite(V4, freq_blynk, " Hz");
   Blynk.virtualWrite(V5, Pf_blynk);
}

 }
 else if (Selektor == 0) {
  Change_Over();
  Blynk.virtualWrite(V7, Off);
  Blynk.virtualWrite(V8, Off);
 }
}
BLYNK_WRITE(V7) {
 Start1 = param.asInt();
 Change_Over();
}

BLYNK_WRITE(V8){
 Stop1 = param.asInt();
  Change_Over();
}
   
void loop() {
  Data();
  Change_Over();
  Android();
  Energy();
 RTC();
  nexLoop(nex_listen_list);
  }

@Ichsan_Kautsar please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Pete.

well done

Your void loop needs to be much cleaner than it is, and those delays that are scattered around your code - mostly in Change_Over probably need to go. You can’t have Blynk.virtualWrites in your void loop, or in functions that are called from your void loop every time it executes. This document explains more…

Pete.

1 Like

I’m using Nextion too, but without library,

//timers
  timer.setInterval(100L, listen);//listen nextion
  timer.setInterval(1000L, RTC);//get time every sec
  timer.setInterval(60210L, Data);// can be change don't forget to stage
  timer.setInterval(60420L, Change_Over); // can be change, don't forget to stage, 210 ms interval each
  timer.setInterval(60630L, Android); // can be change, don't forget to stage
  timer.setInterval(60840L, Energy); // can be change, don't forget to stage

void loop() 
{
Blynk.run();
Timer.run();
}

void listen()
{
nexLoop(nex_listen_list);
}

I’ve made a simpler sketch, Start and stop switches in blynk can already be connected with ButtonDualState in nextion. but Mode switch in blynk is not yet connected to ButtonDualState nextion…

#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <TimeLib.h>
#include <Nextion.h>
#include "NexText.h"
#include "NexDualStateButton.h"

SoftwareSerial HMISerial(18, 19);

BlynkTimer timer;

const int StartMan = 26;
const int StopMan = 25;
int ManualMode=0;

uint32_t Selektor=0;
uint32_t Start1=0;
uint32_t Stop1=0;

int ModeB;
int StartM;
int StopM;

NexText t2 = NexText(2,6,"t2");
NexText t5 = NexText(2,9,"t5");
NexDSButton Mode = NexDSButton(2,10,"Mode");
NexDSButton Mstart = NexDSButton(2,11,"Mstart");
NexDSButton Mstop = NexDSButton(2,12,"Mstop");

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "Ixxxxxxxxx";


void setup() {
  Serial.begin(9600);
 nexInit();
  Blynk.begin(auth, ssid, pass);

pinMode(StartMan, OUTPUT);
pinMode(StopMan, OUTPUT);
timer.setInterval(1000L, Data);
timer.setInterval(1000L, Manual);
Blynk.syncAll();
}

void Data(){
  Mode.getValue(&Selektor);
   Mstart.getValue(&Start1);
   Mstop.getValue(&Stop1);
  
  if(Start1==0 && Stop1==0)(ManualMode=1);
   if(Start1==1 && Stop1==0)(ManualMode=2);
   if(Start1==0 && Stop1==1)(ManualMode=3);
   if(Start1==1 && Stop1==1)(ManualMode=3);
   delay(200);
}

void  Manual(){
  if(Selektor==1){
Blynk.syncVirtual(V6);
  t5.setText(": Manual");
switch(ManualMode){
  
  case 1:
  digitalWrite(StartMan, HIGH);
  digitalWrite(StopMan, LOW);
  delay(1);
  break;

  case 2:
  digitalWrite(StartMan, LOW);
  digitalWrite(StopMan, LOW);
  delay(1);
  break;

  case 3:
  digitalWrite(StartMan, HIGH);
  digitalWrite(StopMan, HIGH);
  delay(1);
  break;
  default:
  break;
}
}
 else if(Selektor==0){
  Blynk.syncVirtual(V6);
   t5.setText(": Automatic");
   digitalWrite(StartMan, HIGH);
  digitalWrite(StopMan, HIGH);

  }
}

void loop() 
{
Blynk.run();
timer.run();
}

BLYNK_WRITE(V6) {
 ModeB = param.asInt(); 
 if (ModeB == 1) {
   Mode.setValue(1);
  digitalWrite(StopMan, LOW);
    Blynk.syncVirtual(V7);
    Blynk.syncVirtual(V8);
 }
 else if (ModeB == 0) {
  Mode.setValue(0);
 Mstart.setValue(0);
 Mstop.setValue(0);
  digitalWrite(StopMan, HIGH);
  digitalWrite(StartMan, HIGH); 
   Blynk.virtualWrite(V7, HIGH);
    Blynk.virtualWrite(V8, HIGH);
  Blynk.syncVirtual(V7);
  Blynk.syncVirtual(V8);
  
 }
}
BLYNK_WRITE(V7) {
 StartM = param.asInt();
  if(StartM == 1){
    Mstart.setValue(1);
    digitalWrite(StartMan, LOW); 
 } else if(StartM == 0) {
    Mstart.setValue(0);
    digitalWrite(StartMan, HIGH); 
  }
  Blynk.syncVirtual(V6);
}
BLYNK_WRITE(V8){
 StopM = param.asInt();
  if(StopM == 1){
    Mstop.setValue(1);
    digitalWrite(StopMan, HIGH);
  }
  else if(StopM == 0){
    Mstop.setValue(0);
    digitalWrite(StopMan, LOW);
  }
   Blynk.syncVirtual(V6);
}

which part is wrong??
start and stop switch in blynk will work when the Mode switch in the nextion is pressed

So, it is not same nextion than me, I think you are talking bout physical buttons :thinking:

this is mine

2020-07-05_112934

Why do you have all of these Blynk.syncVirtual(vPin) commands in your BLYNK_WRITE callbacks and in your Nextion functions?
It’s a very sloppy way of coding and will lead to issues down the line.

Pete.

for sure :stuck_out_tongue_winking_eye:

I don’t see any stored value for Selektor :thinking:
So Selektor remain always 0

uint32_t Selektor=0;

not this ??

void manual() don’t get the value of Selektor

Do I have to write it like this ??

Yes because it is to declare Selector as a variable

I think this is the get function

Mode.getValue(&Selektor)

what kind of Nextion do you have ?

NX4024T032

I’ve tried writing it like this but it’s still the same

Ok, so it’s same than mine.
I don’t use any nextion library , so I have to take a look at Nextion lib, to see how they use
Mode.getValue(&Selektor);
Maybe @PeteKnight know that :thinking:

No, I use a different Nextion library.

Pete.

They use that to get the value

    bt0.getValue(&dual_state);
    if(dual_state) 
    {
        t0.setText("HI! OPEN STATE");
    }
    else
    {
        t0.setText("HI! OFF STATE");
    }
}

So you have to replace by

 /* Get the state value of dual state button component . */
    mode.getValue(&dual_state);
    if(dual_state) 
    {
       Selecktor = 1;
    }
    else
    {
        Selecktor = 0;
    }
}

I assume that the `getValue’ command tales the current state of the Nextion objects and assigned them to the current variable (Start1, Stop1 and Selektor), but I have no idea what values are being returned from the selector switch to the Selektor variable. A serial print statement might be the simplest way of seeing those values, but as the serial port is being used for Nextion communications, it makes like difficult. That’s why I prefer to use Serial1 via an FTDI to get debug data when I’m using this type of setup.

Pete.