Hold Button down to increase number

Hey guys.

I am using a Nextion Diyplay with a ESP32.

What i am trying: Aslong i push a button on the Display, a counter should increase. I already managed it, that every time i push the button, the counter increase. I somehow try to modifiy it.

//Librarys
#include <Nextion.h>

//Display
HardwareSerial Serial2(2);
#define UP "b1"
NexPage page2 = NexPage(2, 0, "Manuell");
NexDSButton b1    = NexDSButton(2, 27, "b1");
int init_value = 2
bool state = false;


NexTouch *nex_listen_list[] =
{
  &b1,
  NULL
};

void bt0PushCallback(void *ptr){
state = true;
while (state = true){
init_value++;
}}

//----------------- S E T U P ----------------------------

void setup(void)
{
  //Serial COM
  Serial.begin(115200);
  
    //Display
  nexInit();      // default 115200
  b1.attachPush(bt0PushCallback, &b1);
}

//------------------- L O O P ----------------------------------------

void loop(void){
  nexLoop(nex_listen_list);
  
}

I know that there is something wrong with my code. Cuz the counter starts wildley to increace as soon i push the button and wont stop. I think it has something to do, that the “state” is always true as soon i push the button once.

How can i mange it, that the bool state is true, ONLY when i push the button.

Kinda lost ATM

Thank you

Manuel_o:
Cuz the counter starts wildley to increace as soon i push the button and wont stop.
I think it has something to do, that the “state” is always true as soon i push the button once.

The posted code should not behave like described, it should just hang after a button press,
invisibly incrementing the counter.

while (state = true){
init_value++;
}

The logic is flawed, making it an infinite loop (nothing in loop changes the condition)
The syntax is flawed making it an infinite loop (= assignment, == comparison)

Hallo

Thank you for the answer. Yes a skiped the part, where the counter is written into a Txt-area at my Nextion

//Librarys
#include <Nextion.h>

//Display
HardwareSerial Serial2(2);
#define UP "b1"
NexPage page2 = NexPage(2, 0, "Manuell");
NexDSButton b1    = NexDSButton(2, 27, "b1");
int init_value = 2;
bool state = false;


NexTouch *nex_listen_list[] =
{
  &b1,
  NULL
};

void bt0PushCallback(void *ptr){
state = true;
while (state == true){
init_value++;
}

}

//----------------- S E T U P ----------------------------

void setup(void)
{
  //Serial COM
  Serial.begin(115200);
 
    //Display
  nexInit();      // default 115200
  b1.attachPush(bt0PushCallback, &b1);
}

//------------------- L O O P ----------------------------------------

void loop(void){
  nexLoop(nex_listen_list);
 
}

Sorry, but i have no idea right now, how i can leave the infinit loop. I dont know how i can manage it to leave the loop as soon my finger leaves the button.

any hints?

thank you

Sorry, but i have no idea right now, how i can leave the infinit loop.

Two ways.

  1. Make sure that whatever the condition involves can change somewhere in the body of the while loop (or because of an interrupt). For instance, if you have:
   int pinState = digitalRead(somePin);
   while(pinState == LOW)
   {
      count++;
   }

you would need to add

      pinState = digitalRead(somePin);

in the body of the while loop.

  1. Use a break statement. An unconditional break in the while body would indicate that you don't understand the meaning of while, so do not put an unconditional break statement in the body of the while loop.

By the way, you probably want to make sure that some (small amount of) time has passed before you increment the counter in the while loop. Otherwise, you'll have no control over how much the value increases while the switch is held down.

Hey, thank you

Yes but the problem is, that my button is a digitalBUtton on a Display (Nextion) and has no "PIN" value.
So i cant use digitalRead(pin).

Thats how i understood it. Thats why i try to mange it to get around the digitalRead with my bool state Variable in my callback

Your whole approach is wrong.

You try to loop in an button press event.

For autoincrement you should also process the button release event.

  • set a flag to auto increment in the press event
  • in loop you check that flag and do the timed increment
  • reset the flag in the button release event

Hey

i tried to rethink it all

Second try:

//Librarys
#include <Nextion.h>

//Display
HardwareSerial Serial2(2);
#define UP "b1"
NexPage page2 = NexPage(2, 0, "Manuell");
NexDSButton b1    = NexDSButton(2, 27, "b1");
int init_value = 2
bool flag = 0;


NexTouch *nex_listen_list[] =
{
  &b1,
  NULL
};

void b1PushCallback(void *ptr){
flag = 1;
}

void b1PopCallback(void *ptr){
flag = 0;
}

//----------------- S E T U P ----------------------------

void setup(void)
{
  //Serial COM
  Serial.begin(115200);
  
    //Display
  nexInit();      // default 115200
  b1.attachPush(b1PushCallback, &b1);
  b1.attachPush(b1PopCallback, &b1);
  
}

//------------------- L O O P ----------------------------------------

void loop(void){
  nexLoop(nex_listen_list);
  increase()
}


void increase() {
while (flag ==1)
    init_value++;
}

Unfortunly i cant test it right now. But as far as i see it, it should work. When the button is pushed, the flag=1, when it is released it will be 0.
In my function increase() i only increase init_value when flag ==1 (button is pushed)

Any thoughts?

Thank you very much

Manuel_o:
Any thoughts?

Forget using while until you understand what it does and how it works.

Where is the timed increment, let's say each 200 ms?

And please don't use while/do/for/goto/delay.

But as far as i see it, it should word.

It won’t even compile.

while (flag ==1)
    init_value++;

How long will it take until init_value overflows? Suppose that init_value is 12 when you press the switch. How long would you have to hold the switch until init_value got to 35? Can you possibly release the switch, and have the Nextion react and send data to the Arduino, and have it process the data and invoke the callback, in that period of time?

Thank you for your help an support.

I tried it now with millis()

//Librarys
#include <Nextion.h>

//Display
HardwareSerial Serial2(2);
#define UP "b1"
NexPage page2 = NexPage(2, 0, "Manuell");
NexDSButton b1    = NexDSButton(2, 27, "b1");
int init_value = 2
bool flag = 0;
int holdTime = 200;
long onTime = 0;
long lastSwitchTime = 0;

NexTouch *nex_listen_list[] =
{
  &b1,
  NULL
};

void b1PushCallback(void *ptr){
flag = 1;
}

void b1PopCallback(void *ptr){
flag = 0;
}

//----------------- S E T U P ----------------------------

void setup(void)
{
  //Serial COM
  Serial.begin(115200);
  
    //Display
  nexInit();      // default 115200
  b1.attachPush(b1PushCallback, &b1);
  b1.attachPush(b1PopCallback, &b1);
  
}

//------------------- L O O P ----------------------------------------

void loop(void){
  nexLoop(nex_listen_list);
  increase()
}

void increase() 
{
//held
 if (flag ==1){
   if ((millis() - onTime) >= holdTime){
     init_value++;  
     onTime = millis();
    }
  }
}

onTime should be unsigned long, but basically you solved your problem IMHO.

millis() returns an unsigned long. You should NOT store that value in a signed long.

EVERY statement needs a ; at the end.

thanks a lot

I will try it at night and let you know!

just wanna inform you that it worked=) thank you very much

Now i try a little thing to add. I can manipulate my variable init_value (increase and decrease).
Now i try to add 2 functions. One function should set init_value to 100 as long as i push the button. When i release the button the previouse value should appear again
The other function should to the same, just set the value to zero.

I am lost again. How can store the previouse value so i can use it again as soon i release the button.
The problem is, that my main function uses just one argument (init_value ). so i just can use one variable.

Do i miss something?

Hope you guys understand what i mean

......

void loop(void)
{
  nexLoop(nex_listen_list);

  else if(flag_case==3)
  {
    hundred_percent(init_value);
  }
    else if(flag_case==4)
  {
    start_stop(init_value);
  }
  double value = map(init_value, 0, 100, 0, 255); // scale it to use it with analogWrite
  ledcWrite(ledChannel, value);
  delay(7);
  Serial.println(init_value);
}


/********set pump performance temporary to 100%*******/
void hundred_percent(double& a)
{
  double init_value_buff = init_value;
  if (flag_100 == 1 )
  {
    
    a = 100;
    Serial2.print("t0.txt=\""+String(a)+"\"");
    Serial2.write(0xff);  
    Serial2.write(0xff);
    Serial2.write(0xff);
    delay(50);
  }
  else if  (flag_100 ==0) 
  {
    a = init_value_buff;
    Serial2.print("t0.txt=\""+String(a)+"\"");
    Serial2.write(0xff);  
    Serial2.write(0xff);
    Serial2.write(0xff);
    delay(50);     
  }    
}

/********set pump performance on or off*******/

void start_stop(double& a)
{
 
//held}
  if (flag_O_F)
  {
    a = 0.0;
        Serial2.print("t0.txt=\""+String(int(a))+"\"");
        Serial2.write(0xff);  
        Serial2.write(0xff);
        Serial2.write(0xff);
        delay(50);}
        else{
 a = temp;
 Serial.println (init_value);
          Serial2.print("t0.txt=\""+String(int(a))+"\"");
        Serial2.write(0xff);  
        Serial2.write(0xff);
        Serial2.write(0xff);
        delay(50);}
        }

ok…i managed to store the value, but now, the main function, which controls the LED is not working anymore

void hundred_percent(double& a)
{
  double init_value_buff = init_value;
  if (flag_100 == 1 )
  {
    
    a = 100;
    Serial2.print("t0.txt=\""+String(a)+"\"");
    Serial2.write(0xff);  
    Serial2.write(0xff);
    Serial2.write(0xff);
    delay(50);
   a = init_value_buff;
    
    
  }
  else if  (flag_100 ==0) 
  {
    a = init_value_buff;
    Serial2.print("t0.txt=\""+String(a)+"\"");
    Serial2.write(0xff);  
    Serial2.write(0xff);
    Serial2.write(0xff);
    delay(50);     
  }    
}

i dont get it. When i include the line (a = init_value_buff;). My nextion shows me the right thing. It gives me the value 100 aslong as i push the button and the previous value when i release it. But the LED is not responding.

When i remove the line: a = init_value_buff;, my nextion does not show the previouse value, but the LED is working.

I am depressed=)

Thank you guys

Do i miss something?

Obviously, as the code you posted won't even compile.

    Serial2.print("t0.txt=\""+String(a)+"\"");

Using a String so you can use one Serial.print() statement, instead of 3, is wasteful. Your convenience counts for very little.I don't try to help people that piss away resources uselessly, like this.

I don't try to help people that can't be bothered to fix all the compilation issues before posting code that they claim actually does something on the microcontroller.

Hello,

First of all. I managed it by myself. It is working now

About your critic. I am totaly aware that this specific code was not compiling. I reduced the code on
purpose to a mimum. My target was not to get a specific code, but to get an general discusion and idea about my (wrong) thoughts, of how to solve such a prolem. I realy try to give my best

I oppose this assumption that i post here wihtout my best conscience to manage the code and problems..

best regards