Nextion touch button only works once

Hi everyone,

Please help.

I am using the Nextion library to utilize touch events. I am having trouble getting my Start button to work more than once without resetting the serial monitor. My STOP button can work multiple times as long as its the first and only button I press when the arduino resets.. It must have to do with the calculation in the if loop that I activate using the Start button..?

Here is a video I recorded of the problem:

And here you can find the Arduino Code and the Nextion File if you'd like to view/run the code:

https://github.com/giovanniguerrero3/Nextion-Touch-Event-Problem

I've also attached a picture of a summary of what's going on in the main parts of the code:

Help would be greatly appreciated this is my first big project and my first question here!

Best Regards,

Aero2019/Giovanni

Nextion_Flowmeter_UNO1.1.ino (8.62 KB)

Drop any output to Serial that is not directed to the Nextion.
You are spamming the Nextion with your debug messages.

There is an absolutely crazy delay(50) at the top of loop hindering communication.

Thanks for the advice.

I've heard a few times that a delay is normally necessary as the Nextion can't always keep up with a 115200 baud rate so that's why I used it. I've cleared all the unnecessary Serial.print functions but unfortunately that doesn't seem to be the main reason my situation exists..

Aero2019:
I've cleared all the unnecessary Serial.print functions but unfortunately that doesn't seem to be the main reason my situation exists..

As you don't want to share the new code, you seem not to be interested in an external solution.

Ah of course I'll attach it here.

Nextion_Flowmeter_UNO1.1.ino (8.78 KB)

Clean up your sketch, remove unused includes, commented code and comments that are no longer true or comment the obvious.

There is still spam sent to the Nextion.

      //flowmeter calculations using interrupt:
      
      NbTopsFan = 0;   //Set NbTops to 0 ready for calculations

      sei();      //Enables interrupts
      delay (1);   //Wait 1 second
      cli();      //Disable interrupts

      Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour

This is wrong in so many ways, it hurts me.

Interrupts have to be enabled as much as possible, not for a microsecond from time to time.

NbTopsFan is volatile and int, so it has to be accessed atomicaly (with disabled interrupts).

Forget about your whole while () approach.

Let loop run.

Just cleaned things up.

To clarify regarding the while loop; I need it so that a solenoid could be turned off once the while loop ends. There are many more sequences to come but this just needs to work so that any future programming updates can work.

In regards to the interrupt needing to be on for as long as possible, it seems that practically, I will lose lots of accuracy with delay(1000) as shown in this clip:

With delay(1000), my accuracy is +-200 mL... but with a delay(1), my accuracy is +-2 mL. I must be misunderstanding the nature of all this. I have very little experience so your advice is much appreciated.

Attached is the new code.

Nextion_Flowmeter_UNO1.2.ino (4.88 KB)

I think there are still more includes there than needed,
the rest is still as gruesome as before.

To give other people (on smartphones or tablets) a chance to look at your code,
I post is like you should have done.

#include <NexButton.h>
#include <NexNumber.h>
#include <NexPage.h>
#include <NexPicture.h>
#include <NexProgressBar.h>
#include <NexText.h>
#include <Nextion.h>
#include <NexTouch.h>
#include <NexVariable.h>

int CurrentPage = 0;

volatile int NbTopsFan; //measuring the rising edges of the signal
float Calc;
int hallsensor = 2;    
float totaldispensed;
int whole_intVal;
float diffValue;
int dec_intVal;
int ml_reading;
int barval_arduino = 0;

bool a = false;
bool b = false;
int loopbreak = 0;

NexButton b0 = NexButton(1, 1, "b0");
NexButton b1 = NexButton(1, 11, "b1");
NexNumber n0 = NexNumber(1, 9, "n0");
NexNumber liveread_whole = NexNumber(1, 6, "liveread_whole");
NexNumber liveread_dec = NexNumber(1, 13, "liveread_dec");

NexPage page0 = NexPage(0, 0, "page0");  // Page added as a touch event
NexPage page1 = NexPage(1, 0, "page1"); 
NexPage page2 = NexPage(2, 0, "page2");
NexPage page3 = NexPage(3, 0, "page3");
NexPage page4 = NexPage(4, 0, "page4");

NexTouch *nex_listen_list[] = //list of touch events
{
  &b0,
  &b1,
  &page0,  // Page added as a touch event
  &page1,
  &page2,
  &page3,
  &page4,
  NULL
};

// Page change event:
void page0PushCallback(void *ptr)  // If page 0 is loaded on the display, the following is going to execute:
{
  CurrentPage = 0;  // Set variable as 0 so from now on arduino knows page 0 is loaded on the display
}  // End of press event

void page1PushCallback(void *ptr)
{
  CurrentPage = 1;
} 

//When START button is pushed then released:
void b0PopCallback(void *ptr)
{
  //TURN ON COMMAND
  a = true;
}

//When STOP button is pushed:
void b1PushCallback(void *ptr)
{
  //TURN OFF COMMAND
  b = true;
}

// Function for Flowmeter interupt:
void rpm ()     //This is the function that the interupt calls
{
  NbTopsFan++;  //This function measures the rising and falling edge of the hall effect sensors signal
}

void setup() //
{
  b0.attachPop(b0PopCallback);
  b1.attachPush(b1PushCallback);
  page0.attachPush(page0PushCallback);  
  page1.attachPush(page1PushCallback);  

  //Flowmeter Setup Code:
  pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
  pinMode(13, OUTPUT);
  attachInterrupt(0, rpm, RISING); //and the interrupt is attached

  Serial.begin(115200);
  Serial.println("Starting");
  Serial.println("...");

  delay(500);    
  Serial.print("baud=115200");   
  Serial.write(0xff);  
  Serial.write(0xff);
  Serial.write(0xff);

  Serial.end(); 

  Serial.begin(115200);
}

void loop ()
{
  nexLoop(nex_listen_list); //check for any touch event 

  if (a == true)
  {
    whole_intVal = 0;
    dec_intVal = 0;

    Serial.print("liveread_whole.val=");
    Serial.print(whole_intVal);
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);

    Serial.print("liveread_dec.val=");
    Serial.print(dec_intVal);
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);

    uint32_t target_volume = 0;
    n0.getValue(&target_volume); //This stores the chosen target volume entered in the display (n0) to the target_volume variable
    digitalWrite(13, HIGH); //"TURN ON SOLENOID" (allows fluid flow through flowmeter)
    ml_reading = 0;

    while (ml_reading <= target_volume)
    {
      //The integer of Liters units
      Serial.print("liveread_whole.val=");
      Serial.print(whole_intVal);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);

      //The decimal value of Liters units
      Serial.print("liveread_dec.val=");
      Serial.print(dec_intVal);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);

      //live progress bar in mL
      ml_reading = 1000 * whole_intVal + dec_intVal;
      barval_arduino = map(ml_reading, 0, target_volume, 0, 100);
      Serial.print("j0.val=");
      Serial.print(barval_arduino);
      Serial.write(0xff);
      Serial.write(0xff);
      Serial.write(0xff);

      //flowmeter calculations using interrupt:
      
      NbTopsFan = 0;   

      sei();      //Enables interrupts
      delay (1000);   //Wait 1 second
      cli();      //Disable interrupts

      Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour

      totaldispensed += (((float)Calc * 1.275) / 3600); //the 1.275 calibrates our current flowmeter(Model: 50-732-C)

      whole_intVal = (int)totaldispensed; // convert float PHValue to tricky int combination
      diffValue = totaldispensed - (float)whole_intVal;
      dec_intVal = (int)(diffValue * 1000.0);

    }
    digitalWrite(13, LOW); //Turn off "solenoid" that allows fluid flow
    a = false; //reset a to false

    // reset progress bar
    int reset = 0;
    Serial.print("j0.val=");
    Serial.print(reset); //make value 0 again
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);

  }
}

Don't use any delay.

NbTopsFan is volatile and int, so it has to be accessed atomicaly (with disabled interrupts).

Your method to measure the interrupts does not work while relying on serial communication.

And you will have to change the blocking while to a cooperative if.