Possible Serial Overload

bool manualHltButtonUpPressed = false;

void ButtonBrewHltUpRelease (void *ptr) {
  manualHltButtonUpPressed = false;
  //  char tHltTemp[6];
  //  targetHltTemp += 1;
  //  dtostrf(targetHltTemp, 3, 1, tHltTemp);
  //  manualBrewHltTarget.setText(tHltTemp);
}
void ButtonBrewHltUpPress (void *ptr) {
  manualHltButtonUpPressed = true;
  do{ 
    char tHltTemp[6];
    targetHltTemp += 1;
    dtostrf(targetHltTemp, 3, 1, tHltTemp);
    manualBrewHltTarget.setText(tHltTemp);
  } while(manualHltButtonUpPressed);
}

I have a display that has these 2 methods attached to press and release function (Nextion). I am trying to press and hold the button and increasing a number until the button is released.

What happens right now, if i press the button, the do/while loop runs, but when i release, and the other function hits, but it doesnt stop the loop. Is this a reference/pointer thing?

i stand corrected, went into an infinite loop... the Release method doesnt get called. is there a right way of doing this?

How it will ever exit loop if buttonpress variable is always true?

my initial thought was to have another function to set it to false, causing that loop to stop. but that was a bad idea. unless there is some sort of interrupt thing i can do.

If you really insist on using a do-while loop to handle this then the button needs to be reread INSIDE that loop. Really, you should probably do this without the do-while. Use a state machine style of coding and you can let the loop function do the looping and just repeatedly check to see if the button is still pressed and do what needs to be done. But if you must use a do while then you have to read the button inside the while loop.

Thank you, I took that and applied it.

in my loop() function i have this:

  if (manualHltButtonUpPressed) {
    char tHltTemp[6];
    targetHltTemp += 1;
    dtostrf(targetHltTemp, 3, 1, tHltTemp);
    manualBrewHltTarget.setText(tHltTemp);
  }

and in the code tfor the buttons, I just flip manualHltButtonUpPressed.

What type is targetHltTemp? Why are you adding 1 to it on every pass through the do/while body?

If the type is float, you should make that clear by adding 1.0 to it. If the type is not float, then using dtostrf() to print the value to one decimal place does not make sense.

I created a test sketch to simplify things.

#include "Nextion.h" //https://github.com/itead/ITEADLIB_Arduino_Nextion/
bool manualBoilButtonUpPressed = false;
bool manualBoilButtonDownPressed = false;

int targetBoilTemp = 0;
NexButton manualBrewButton = NexButton(1, 2, "bManualBrew");
NexPage manualBrewPage(3, 0, "BrewManual");
NexButton manualBrewBoilUpButton = NexButton(3, 28, "btBoilUp");
NexButton manualBrewBoilDownButton = NexButton(3, 30, "btBoilDown");
NexText manualBrewBoilTarget = NexText(3, 25, "tBoil");

NexTouch *nex_listen_list[] = {
  &manualBrewButton,
  &manualBrewBoilUpButton,
  &manualBrewBoilDownButton,
  NULL
};

//Run when "+" button is released
void ButtonBrewBoilUpRelease(void *ptr)
{
  manualBoilButtonUpPressed = false;
}

//Run when "+" button is pressed
void ButtonBrewBoilUpPress(void *ptr)
{
  manualBoilButtonUpPressed = true;
}

//Run when "-" button is released
void ButtonBrewBoilDownRelease(void *ptr)
{
  manualBoilButtonDownPressed = false;
}

//Run when "-" button is pressed
void ButtonBrewBoilDownPress(void *ptr)
{
  manualBoilButtonDownPressed = true;
}
void setup() {
  // put your setup code here, to run once:
  //Serial.begin(115200);

  nexInit();

  manualBrewBoilUpButton.attachPop(ButtonBrewBoilUpRelease, &manualBrewBoilUpButton);
  manualBrewBoilUpButton.attachPush(ButtonBrewBoilUpPress, &manualBrewBoilUpButton);

  manualBrewBoilDownButton.attachPush(ButtonBrewBoilDownPress, &manualBrewBoilDownButton);
  manualBrewBoilDownButton.attachPop(ButtonBrewBoilDownRelease, &manualBrewBoilDownButton);
}
void loop() {
  nexLoop(nex_listen_list);
  if (manualBoilButtonUpPressed) {
    char tBoilTemp[6];
    targetBoilTemp += 1;
    dtostrf(targetBoilTemp, 3, 1, tBoilTemp);
    manualBrewBoilTarget.setText(tBoilTemp);
  }
  if (manualBoilButtonDownPressed) {
    char tBoilTemp[6];
    targetBoilTemp -= 1;
    dtostrf(targetBoilTemp, 3, 1, tBoilTemp);
    manualBrewBoilTarget.setText(tBoilTemp);
  }

}

Paul,

to answer your question, it is an int. the display is "XXX.X" and I need to keep the format for the 1 place to the right of decimal point.

I also have another function in the main program for actual temp that is a double, and I use the same method to display it, hense the dtostrf.

In this code if I hit the "+" button (manualBrewBoilUpButton), then the display runs on and will not stop. The goal is for the targetTemp to increment by as long as the button is pressed and held. once it is released, it should stop.

to answer your question, it is an int. the display is "XXX.X" and I need to keep the format for the 1 place to the right of decimal point.

If it is an int then you need to study up a little on what types of values an int can hold and think for a bit no whether it really makes sense to try to print one with a decimal place.

You could just:

Serial.print(someIntVar);
Serial.println(".0");

And get the same output.

understood, thank you. I will change it later, and take it a step further, after more thinking, i dont need the .0 really. so ill change the bit around, but i dont want to get too far off topic as my issue is unable to break a loop when the if statement should change.

if I have a main loop() with an if statement based on a boolean variable, every time the loop happens, the variable should, when set back to false, bypass the if statement.

so only a few things could be:

  1. the variable doesnt get set.
  2. the loop isnt looping anymore, and it's stuck
  3. something else altogether

I just did a test between the display and the ESP8266. I added a Serial.println(manualBoilButtonUpPressed); in the loop just to read the value. when i restarted the esp, the Serial printed a lot of "0"s. then i hit the + button and the "0"s stopped and the nexLoop took over it seems:

1\x0D\x0AtBoil.txt="1.0"ÿÿÿ
1\x0D\x0AtBoil.txt="2.0"ÿÿÿ
1\x0D\x0AtBoil.txt="3.0"ÿÿÿ
1\x0D\x0AtBoil.txt="4.0"ÿÿÿ
1\x0D\x0AtBoil.txt="5.0"ÿÿÿ
1\x0D\x0AtBoil.txt="6.0"ÿÿÿ
1\x0D\x0AtBoil.txt="7.0"ÿÿÿ

actually, another test, the 1 is the variable, so even if the button is released, the value isnt changed back to 0. would that be a case for "volate"?

would that be a case for "volate"?

Are you using that variable in an interrupt handler? If not then there's no need for volatile.

That output looks like something somewhere is going out of bounds on an array and corrupting memory. Or maybe a string is missing it's terminating null.

Delta_G:
Are you using that variable in an interrupt handler? If not then there’s no need for volatile.

That output looks like something somewhere is going out of bounds on an array and corrupting memory. Or maybe a string is missing it’s terminating null.

no, i dont think it’s an interrupt. I had to look at the NexLoop function.

void nexLoop(NexTouch *nex_listen_list[])
{
    static uint8_t __buffer[10];
    
    uint16_t i;
    uint8_t c;  
    
    while (nexSerial.available() > 0)
    {   
        delay(10);
        c = nexSerial.read();
        
        if (NEX_RET_EVENT_TOUCH_HEAD == c)
        {
            if (nexSerial.available() >= 6)
            {
                __buffer[0] = c;  
                for (i = 1; i < 7; i++)
                {
                    __buffer[i] = nexSerial.read();
                }
                __buffer[i] = 0x00;
                
                if (0xFF == __buffer[4] && 0xFF == __buffer[5] && 0xFF == __buffer[6])
                {
                    NexTouch::iterate(nex_listen_list, __buffer[1], __buffer[2], (int32_t)__buffer[3]);
                }
                
            }
        }
    }
}

im currently trying to understand this to see if there is an issue.

as my issue is unable to break a loop when the if statement should change.

What if statement? A do/while statement does not necessarily contain an if statement.

post #5 i change from a do/while to an if statement inside the main loop. i should change the title.

Changing to this sketch helps (using Millis to delay updates)

#include "Nextion.h" //https://github.com/itead/ITEADLIB_Arduino_Nextion/
bool manualBoilButtonUpPressed = false;
bool manualBoilButtonDownPressed = false;
unsigned const long updateIncrementInterval = 250;
unsigned long lastIncrementUpdated;

double targetBoilTemp = 0.0;
NexButton manualBrewButton = NexButton(1, 2, "bManualBrew");
NexPage manualBrewPage(3, 0, "BrewManual");
NexButton manualBrewBoilUpButton = NexButton(3, 28, "btBoilUp");
NexButton manualBrewBoilDownButton = NexButton(3, 30, "btBoilDown");
NexText manualBrewBoilTarget = NexText(3, 25, "tBoil");

NexTouch *nex_listen_list[] = {
  &manualBrewButton,
  &manualBrewBoilUpButton,
  &manualBrewBoilDownButton,
  NULL
};

//Run when "+" button is released
void ButtonBrewBoilUpRelease(void *ptr)
{
  manualBoilButtonUpPressed = false;
}

//Run when "+" button is pressed
void ButtonBrewBoilUpPress(void *ptr)
{
  manualBoilButtonUpPressed = true;
}

//Run when "-" button is released
void ButtonBrewBoilDownRelease(void *ptr)
{
  manualBoilButtonDownPressed = false;
}

//Run when "-" button is pressed
void ButtonBrewBoilDownPress(void *ptr)
{
  manualBoilButtonDownPressed = true;
}
void setup() {
  // put your setup code here, to run once:
  //Serial.begin(115200);

  nexInit();

  manualBrewBoilUpButton.attachPop(ButtonBrewBoilUpRelease, &manualBrewBoilUpButton);
  manualBrewBoilUpButton.attachPush(ButtonBrewBoilUpPress, &manualBrewBoilUpButton);

  manualBrewBoilDownButton.attachPush(ButtonBrewBoilDownPress, &manualBrewBoilDownButton);
  manualBrewBoilDownButton.attachPop(ButtonBrewBoilDownRelease, &manualBrewBoilDownButton);
}
void loop() {
  unsigned long currentMillis = millis();
  nexLoop(nex_listen_list);
  if (currentMillis - lastIncrementUpdated >= updateIncrementInterval) {
    if (manualBoilButtonUpPressed) {
      char tBoilTemp[6];
      targetBoilTemp += 1.0;
      dtostrf(targetBoilTemp, 3, 1, tBoilTemp);
      manualBrewBoilTarget.setText(tBoilTemp);
    }
    if (manualBoilButtonDownPressed) {
      char tBoilTemp[6];
      targetBoilTemp -= 1.0;
      dtostrf(targetBoilTemp, 3, 1, tBoilTemp);
      manualBrewBoilTarget.setText(tBoilTemp);
    }
    lastIncrementUpdated = currentMillis;
  }
}

it works if i hold the + button and release at least a second later. but if i tap it, it goes forever again, just slower. and then if i hit the “-” to go down, it bounces between the current number that the next one down. If I get it to stop correctly, and then press the “-” button, it goes down normally as long as it is a slow press.

the issue now is that a quick tap will cause it to either continue going up, or down depending on the button pressed.

Updating the display periodically makes sense. Reading the button state periodically does not.

EVERY time through loop(), see if the buttons have been pressed or released.