[SOLVED] Hold button state LOW - help needed.

Hello good people of Arduino Land! :slight_smile:

This is a continuation of the development of my water drop controller code, which so far is going well.
I'm now tidying up some bits and pieces, and so here is my question:

When I select a value to vary (via one of six push buttons and a single rotary encoder) I need to 'hold' the relevant button state LOW as well as holding the other five button states HIGH, so that the called function executes.

Here is the buttonPress1 function call:
(There are five more like this - one for each button/value)

  if (millis() - buttonDebounceLast[0] > 5) {
    if (buttonState[0] == LOW) {
      buttonPress1();
    }
    buttonDebounceLast[0] = millis();
  }

....and the function buttonPress1:
(Again, there are five more similar functions - one for each button/value)

void buttonPress1() {

  ////// VALUE 1 //////

  lcd.setCursor(1, 0);
  lcd.print(value[0]);

  digitalWrite(button1, LOW);    //TODO:
  digitalWrite(button2, HIGH);   //
  digitalWrite(button3, HIGH);   //There has to be a better
  digitalWrite(button4, HIGH);   //...way of holding button LOW.
  digitalWrite(button5, HIGH);   //
  digitalWrite(button6, HIGH);   //

  lcd.setCursor(0, 0);
  lcd.print(">");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    value[0] = 0;
    lcd.setCursor(1, 0);
    lcd.print(value[0]);
    lcd.setCursor(1, 0);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[0]++;
  }
  if (countDnFlag) {
    value[0]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[0] != valueLast[0]) {
    lcd.setCursor(1, 0);
    lcd.print(value[0]);
    lcd.setCursor(1, 0);
    lcd.print("   ");
    valueLast[0] = value[0];
  }
  value[0] = min(300, max(0, value[0]));
}

It's this bit that I would like to tidy up:

  digitalWrite(button1, LOW);    //TODO:
  digitalWrite(button2, HIGH);   //
  digitalWrite(button3, HIGH);   //There has to be a better
  digitalWrite(button4, HIGH);   //...way of holding button LOW.
  digitalWrite(button5, HIGH);   //
  digitalWrite(button6, HIGH);   //

It works well enough as it is, so maybe I shouldn't touch it....but there has to be another way to achieve this, other than the clunky way that I have now.

I've tried state change stuff, while loops and flags etc., but I haven't managed to get anything to work...I know it's a lack of knowledge on my part, so hopefully one of you kind and knowledgeable experts wouldn't mind nudging me in the right direction.

The answer is undoubtedly very simple, but I'm pulling out what little hair I have left!!

Many thanks folks!

P.S. The full sketch will be posted over the next two posts.

Here is the first half of the entire working sketch:

#include <digitalIOPerformance.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte encPinA = 2;
const byte encPinB = 12;
const byte encSw = 4;
const byte ledPin = 5;
const byte startButton = 3; // 100nF cap to GND for crude debounce

bool startButtonState = HIGH;
bool startButtonStateLast = HIGH;

const byte button1 = 6;
const byte button2 = 7;
const byte button3 = 8;
const byte button4 = 9;
const byte button5 = 10;
const byte button6 = 11;

bool buttonState[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
bool buttonStateLast[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};

bool ledReady = false;

volatile bool countUpFlag = false;
volatile bool countDnFlag = false;

unsigned long value[6] = {0, 0, 0, 0, 0, 0};
unsigned long valueLast[6] = {0, 0, 0, 0, 0, 0};

unsigned long buttonDebounceLast[6];
unsigned long previousMillis = 0;

bool buttonFlag[6] = {false, false, false, false, false, false};

void setup() {

  Serial.begin(9600);

  lcd.init();
  lcd.backlight();
  lcd.begin(16, 2);
  lcd.clear();

  pinMode(encPinA, INPUT_PULLUP);
  pinMode(encPinB, INPUT_PULLUP);
  pinMode(encSw, INPUT_PULLUP);

  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);
  pinMode(button4, INPUT_PULLUP);
  pinMode(button5, INPUT_PULLUP);
  pinMode(button6, INPUT_PULLUP);
  pinMode(startButton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  attachInterrupt(digitalPinToInterrupt(encPinA), encISR, LOW);

  ///////////////////////////////////
  ////   PRINT VALUES TO LCD     ////
  ///////////////////////////////////

  lcd.setCursor(0, 0);
  lcd.print("Drop Controller");
  lcd.setCursor(0, 1);
  lcd.print("***  START  ***");
  delay(1000);
  lcd.clear();

  lcd.setCursor(1, 0);
  lcd.print(value[0]);
  lcd.setCursor(5, 0);
  lcd.print(value[1]);
  lcd.setCursor(9, 0);
  lcd.print(value[2]);
  lcd.setCursor(1, 1);
  lcd.print(value[3]);
  lcd.setCursor(5, 1);
  lcd.print(value[4]);
  lcd.setCursor(9, 1);
  lcd.print(value[5]);

}

void encISR () {

  ///////////////////////////////////
  ////      ENCODER INTERRUPT    ////
  ///////////////////////////////////

  static unsigned long debounceLast = 0;
  unsigned long debounce = millis();

  if (debounce - debounceLast > 5) {
    if (digitalRead(encPinB) == LOW) {
      countUpFlag = true;
    } else {
      countDnFlag = true;
    }
  }
  debounceLast = debounce;
}

void loop() {

  ///////////////////////////////////
  ////   READ BUTTON STATES      ////
  ///////////////////////////////////

  buttonState[0] = digitalRead(button1);
  buttonState[1] = digitalRead(button2);
  buttonState[2] = digitalRead(button3);
  buttonState[3] = digitalRead(button4);
  buttonState[4] = digitalRead(button5);
  buttonState[5] = digitalRead(button6);

  ///////////////////////////////////
  ////    START LED SEQUENCE     ////
  ///////////////////////////////////

  startButtonState = digitalRead(startButton);
  if (startButtonState != startButtonStateLast) {
    if (startButtonState == LOW) {
      ledReady = true;
      previousMillis = millis();
    }
    startButtonStateLast = startButtonState;
  }

  if (ledReady) {
    static int ndx = 0;
    if (ndx < 6) {
      if (millis() - previousMillis >= value[ndx]) {
        previousMillis = millis();
        digitalWrite(ledPin, ! digitalRead(ledPin));
        ndx ++;
      }
    }
    else {
      ndx = 0;
      ledReady = false;
    }
  }

  //////////////////////////////////////
  //// BUTTON SELECT FUNCTION CALLS ////
  //////////////////////////////////////

  //////// BUTTON 1 /////////

  if (millis() - buttonDebounceLast[0] > 5) {
    if (buttonState[0] == LOW) {
      buttonPress1();
    }
    buttonDebounceLast[0] = millis();
  }

  //////// BUTTON 2 /////////

  if (millis() - buttonDebounceLast[1] > 5) {
    if (buttonState[1] == LOW) {
      buttonPress2();
    }
    buttonDebounceLast[1] = millis();
  }

  //////// BUTTON 3 /////////

  if (millis() - buttonDebounceLast[2] > 5) {
    if (buttonState[2] == LOW) {
      buttonPress3();
    }
    buttonDebounceLast[2] = millis();
  }

  //////// BUTTON 4 /////////

  if (millis() - buttonDebounceLast[3] > 5) {
    if (buttonState[3] == LOW) {
      buttonPress4();
    }
    buttonDebounceLast[3] = millis();
  }

  //////// BUTTON 5 /////////

  if (millis() - buttonDebounceLast[4] > 5) {
    if (buttonState[4] == LOW) {
      buttonPress5();
    }
    buttonDebounceLast[4] = millis();
  }

  //////// BUTTON 6 /////////

  if (millis() - buttonDebounceLast[5] > 5) {
    if (buttonState[5] == LOW) {
      buttonPress6();
    }
    buttonDebounceLast[5] = millis();
  }
}

///////////////////////////////////
////  BUTTON SELECT FUNCTIONS  ////
///////////////////////////////////

void buttonPress1() {

  ////// VALUE 1 //////

  lcd.setCursor(1, 0);
  lcd.print(value[0]);

  digitalWrite(button1, LOW);    //TODO:
  digitalWrite(button2, HIGH);   //
  digitalWrite(button3, HIGH);   //There has to be a better
  digitalWrite(button4, HIGH);   //...way of holding button LOW.
  digitalWrite(button5, HIGH);   //
  digitalWrite(button6, HIGH);   //

  lcd.setCursor(0, 0);
  lcd.print(">");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    value[0] = 0;
    lcd.setCursor(1, 0);
    lcd.print(value[0]);
    lcd.setCursor(1, 0);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[0]++;
  }
  if (countDnFlag) {
    value[0]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[0] != valueLast[0]) {
    lcd.setCursor(1, 0);
    lcd.print(value[0]);
    lcd.setCursor(1, 0);
    lcd.print("   ");
    valueLast[0] = value[0];
  }
  value[0] = min(300, max(0, value[0]));
}






void buttonPress2() {

  ////// VALUE 2 //////

  lcd.setCursor(5, 0);
  lcd.print(value[1]);

  digitalWrite(button1, HIGH);
  digitalWrite(button2, LOW);
  digitalWrite(button3, HIGH);
  digitalWrite(button4, HIGH);
  digitalWrite(button5, HIGH);
  digitalWrite(button6, HIGH);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(">");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    value[1] = 0;
    lcd.setCursor(5, 0);
    lcd.print(value[1]);
    lcd.setCursor(5, 0);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[1]++;
  }
  if (countDnFlag) {
    value[1]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[1] != valueLast[1]) {
    lcd.setCursor(5, 0);
    lcd.print(value[1]);
    lcd.setCursor(5, 0);
    lcd.print("   ");
    valueLast[1] = value[1];
  }
  value[1] = min(300, max(0, value[1]));
}

...second half in next post...

FYI. Digital write to a digital input does NOT change the state of the input. It actually enables/disable the internal pullup resistor. The following is from the digitalWrite reference page:

"If the pin is configured as an INPUT, digitalWrite() will enable (HIGH) or disable (LOW) the internal pullup on the input pin. It is recommended to set the pinMode() to INPUT_PULLUP to enable the internal pull-up resistor. See the Digital Pins tutorial for more information."

You will need to save the state of button pushes.

....second half:

void buttonPress3() {

  ////// VALUE 3 //////

  lcd.setCursor(9, 0);
  lcd.print(value[2]);

  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
  digitalWrite(button3, LOW);
  digitalWrite(button4, HIGH);
  digitalWrite(button5, HIGH);
  digitalWrite(button6, HIGH);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(">");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    value[2] = 0;
    lcd.setCursor(9, 0);
    lcd.print(value[2]);
    lcd.setCursor(9, 0);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[2]++;
  }
  if (countDnFlag) {
    value[2]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[2] != valueLast[2]) {
    lcd.setCursor(9, 0);
    lcd.print(value[2]);
    lcd.setCursor(9, 0);
    lcd.print("   ");
    valueLast[2] = value[2];
  }
  value[2] = min(300, max(0, value[2]));
}

void buttonPress4() {

  ////// VALUE 4 //////

  lcd.setCursor(1, 1);
  lcd.print(value[3]);

  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
  digitalWrite(button3, HIGH);
  digitalWrite(button4, LOW);
  digitalWrite(button5, HIGH);
  digitalWrite(button6, HIGH);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(">");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    value[3] = 0;
    lcd.setCursor(1, 1);
    lcd.print(value[3]);
    lcd.setCursor(1, 1);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[3]++;
  }
  if (countDnFlag) {
    value[3]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[3] != valueLast[3]) {
    lcd.setCursor(1, 1);
    lcd.print(value[3]);
    lcd.setCursor(1, 1);
    lcd.print("   ");
    valueLast[3] = value[3];
  }
  value[3] = min(300, max(0, value[3]));
}

void buttonPress5() {

  ////// VALUE 5 //////

  lcd.setCursor(5, 1);
  lcd.print(value[4]);

  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
  digitalWrite(button3, HIGH);
  digitalWrite(button4, HIGH);
  digitalWrite(button5, LOW);
  digitalWrite(button6, HIGH);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(">");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    value[4] = 0;
    lcd.setCursor(5, 1);
    lcd.print(value[4]);
    lcd.setCursor(5, 1);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[4]++;
  }
  if (countDnFlag) {
    value[4]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[4] != valueLast[4]) {
    lcd.setCursor(5, 1);
    lcd.print(value[4]);
    lcd.setCursor(5, 1);
    lcd.print("   ");
    valueLast[4] = value[4];
  }
  value[4] = min(300, max(0, value[4]));
}

void buttonPress6() {

  ////// VALUE 6 //////

  lcd.setCursor(9, 1);
  lcd.print(value[5]);

  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
  digitalWrite(button3, HIGH);
  digitalWrite(button4, HIGH);
  digitalWrite(button5, HIGH);
  digitalWrite(button6, LOW);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(">");

  if (!digitalRead(encSw)) {
    value[5] = 0;
    lcd.setCursor(9, 1);
    lcd.print(value[5]);
    lcd.setCursor(9, 1);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    value[5]++;
  }
  if (countDnFlag) {
    value[5]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[5] != valueLast[5]) {
    lcd.setCursor(9, 1);
    lcd.print(value[5]);
    lcd.setCursor(9, 1);
    lcd.print("   ");
    valueLast[5] = value[5];
  }
  value[5] = min(300, max(0, value[5]));
}

Once again, thanks for any help or guidance...I know I'll kick myself when I figure it out!! :smiley:

ToddL1962:
FYI. Digital write to a digital input does NOT change the state of the input. It actually enables/disable the internal pullup resistor. The following is from the digitalWrite reference page:

"If the pin is configured as an INPUT, digitalWrite() will enable (HIGH) or disable (LOW) the internal pullup on the input pin. It is recommended to set the pinMode() to INPUT_PULLUP to enable the internal pull-up resistor. See the Digital Pins tutorial for more information."

You will need to save the state of button pushes.

Thanks for your reply Todd.

That makes sense, and I knew I would probably need to monitor state changes, but I am having trouble where in my code to put the relevant state changes.

I'm assuming (perhaps wrongly) that I should place it here, like so:

  if (millis() - buttonDebounceLast[0] > 5) {
    if (buttonState[0] == LOW) {
//////////PLACE STATE CHANGE CHECK HERE?///////////
      buttonPress1();
    }
    buttonDebounceLast[0] = millis();
  }

I have tried various ways here, and I even created an array buttonStateLast[6] to try to keep track of them.
I've got myself into a few knots though!

Should I place the state change check within the if() statement that calls the function, or within the actual function itself?

That’s not the way to do it.

If there’s some action you need to perform and not be interrupted by another button press, set a flag or state variable to indicate that the action is currentlyin progress.

If the flag/state is set, do not let the buttons start a new action (at a basic level you can just skip checking them). When the action is complete clear the flag/state variable, thus letting a new action be selected via the buttons.

Edit: State changes should happen in response to events. An event is some stimulus being provided (e.g. a button press), or certain amount of time elapsed (e.g. millis() condition being met), or a piece of processing completed.

Regardless, you are correct that is ONE of the places a state change should happen. Your state changes from “waiting for button to be pressed” to “performing adjustment of variable x” (where x is one of your 6, or whatever, available variables).

Thanks for your reply pcbbc.

pcbbc:
That’s not the way to do it.

I know, I'm having a thick-day! :smiley:

If there’s some action you need to perform and not be interrupted by another button press, set a flag or state variable to indicate that the action is currentlyin progress.

If the flag/state is set, do not let the buttons start a new action (at a basic level you can just skip checking them). When the action is complete clear the flag/state variable, thus letting a new action be selected via the buttons.

I think I've got a tenuous handle on the concept of flags...I'm just having trouble finding out where to put them.

I've tried them in the if() statements that call the functions, and in the functions themselves, but I just can't figure it out.

In my short eg above, I've tried something like this:

  //////// BUTTON 1 /////////

  if (millis() - buttonDebounceLast[0] > 5) {
    if (buttonState[0] == LOW) {
      buttonFlag[0] = true;
      buttonPress1();
    }
    buttonDebounceLast[0] = millis();
  }

...and then set the flag to false at the end of the function which is called by the above.

This didn't work, so I'm at a bit of a loss at the moment!

Sorry for being thick!!

Where you detect the button presses...

if (state == WAITING_FOR_BUTTON) (
  state = ADJUSTING_VARIABLE;
  variable = x;
}

Where x is the button/variable index.

And then presumably somewhere there is something that signals ending of adjusting a variable (maybe another button press)....

if (state == ADJUSTING_VARIABLE) (
  state = WAITING_FOR_BUTTON;
}

You just need to decide what states you need, and then define them as an enum or #define. Up to you.

And you want to keep on doing buttonPress1() function, even once the button is released? Am I correct?

Then you need to remove that call from the button check, and write some code...

if (state == ADJUSTING_VARIABLE) {
  switch(variable)
  {
  case 1:
    buttonPress1();
    break;
  case 2:
    buttonPress2();
    break;
   .....
  }
}

See how pressing the button causes the state to change, and it’s the new state that causes the correct function to be called to do the work, and the work keeps getting called (regardless of if the button is still pressed or not, or if a different button is pressed) until something changes state back to WAITING_FOR_BUTTON.

bongobreak:
Thanks for your reply Todd.

That makes sense, and I knew I would probably need to monitor state changes, but I am having trouble where in my code to put the relevant state changes.

I have tried various ways here, and I even created an array buttonStateLast[6] to try to keep track of them.
I've got myself into a few knots though!

Should I place the state change check within the if() statement that calls the function, or within the actual function itself?

Here is a code refactor that reduces the size of your code using a button data structure. It compiles but I haven't tested it and also I have not made any changes to it to address your original issue. When I have time I will look at it some more.

#include <digitalIOPerformance.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte encPinA = 2;
const byte encPinB = 12;
const byte encSw = 4;
const byte ledPin = 5;
const byte startButton = 3; // 100nF cap to GND for crude debounce

bool startButtonState = HIGH;
bool startButtonStateLast = HIGH;

bool ledReady = false;

volatile bool countUpFlag = false;
volatile bool countDnFlag = false;
unsigned long previousMillis = 0;

struct ButtonData_s
{
  const byte buttonPin;
  bool buttonState;
  bool buttonStateLast;
  unsigned long value;
  unsigned long valueLast;
  unsigned long buttonDebounceLast;
  bool buttonFlag;
  int cursorCol;
  int cursorRow;
};

ButtonData_s buttonData[6] = {  {6, HIGH, HIGH, 0, 0, 0, false, 1, 0},
                                {7, HIGH, HIGH, 0, 0, 0, false, 5, 0},
                                {8, HIGH, HIGH, 0, 0, 0, false, 9, 0}, 
                                {9, HIGH, HIGH, 0, 0, 0, false, 1, 1},
                                {10, HIGH, HIGH, 0, 0, 0, false, 5, 1},
                                {11, HIGH, HIGH, 0, 0, 0, false, 9, 1} };
void setup() {

  Serial.begin(9600);

  lcd.init();
  lcd.backlight();
  lcd.begin(16, 2);
  lcd.clear();

  pinMode(encPinA, INPUT_PULLUP);
  pinMode(encPinB, INPUT_PULLUP);
  pinMode(encSw, INPUT_PULLUP);

  for (int i=0; i<6; i++)
  {
    pinMode(buttonData[i].buttonPin, INPUT_PULLUP);
  }
  pinMode(startButton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  attachInterrupt(digitalPinToInterrupt(encPinA), encISR, LOW);

  ///////////////////////////////////
  ////   PRINT VALUES TO LCD     ////
  ///////////////////////////////////

  lcd.setCursor(0, 0);
  lcd.print("Drop Controller");
  lcd.setCursor(0, 1);
  lcd.print("***  START  ***");
  delay(1000);
  lcd.clear();

  for (int i=0; i<6; i++)
  {
    lcd.setCursor(buttonData[i].cursorCol, buttonData[i].cursorRow);
    lcd.print(buttonData[i].value);
    lcd.setCursor(buttonData[i].cursorCol, buttonData[i].cursorRow);
  }

}

void encISR () {

  ///////////////////////////////////
  ////      ENCODER INTERRUPT    ////
  ///////////////////////////////////

  static unsigned long debounceLast = 0;
  unsigned long debounce = millis();

  if (debounce - debounceLast > 5) {
    if (digitalRead(encPinB) == LOW) {
      countUpFlag = true;
    } else {
      countDnFlag = true;
    }
  }
  debounceLast = debounce;
}

void loop() {

  ///////////////////////////////////
  ////   READ BUTTON STATES      ////
  ///////////////////////////////////
  for (int i=0; i<6; i++)
    buttonData[i].buttonState = digitalRead(buttonData[i].buttonPin);

  ///////////////////////////////////
  ////    START LED SEQUENCE     ////
  ///////////////////////////////////

  startButtonState = digitalRead(startButton);
  if (startButtonState != startButtonStateLast) {
    if (startButtonState == LOW) {
      ledReady = true;
      previousMillis = millis();
    }
    startButtonStateLast = startButtonState;
  }

  if (ledReady) {
    static int ndx = 0;
    if (ndx < 6) {
      if (millis() - previousMillis >= buttonData[ndx].value) {
        previousMillis = millis();
        digitalWrite(ledPin, ! digitalRead(ledPin));
        ndx ++;
      }
    }
    else {
      ndx = 0;
      ledReady = false;
    }
  }

  //////////////////////////////////////
  //// BUTTON SELECT FUNCTION CALLS ////
  //////////////////////////////////////

  for (int i=0; i<6; i++)
  {
    if (millis() - buttonData[i].buttonDebounceLast > 5) {
      if (buttonData[i].buttonState == LOW) {
        buttonPress(i);
      }
      buttonData[i].buttonDebounceLast = millis();
    }
  }
}

///////////////////////////////////
////  BUTTON SELECT FUNCTIONS  ////
///////////////////////////////////

void buttonPress(int index) {

  lcd.setCursor(1, 0);
  lcd.print(buttonData[index].value);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  lcd.setCursor(buttonData[index].cursorCol-1, buttonData[index].cursorRow);
  lcd.print(" ");

  if (!digitalRead(encSw)) {
    buttonData[index].value = 0;
    lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
    lcd.print(buttonData[index].value);
    lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
    lcd.print("   ");
    while (!digitalRead(encSw))
      delay(1);
  }

  if (countUpFlag) {
    buttonData[index].value++;
  }
  if (countDnFlag) {
    buttonData[index].value--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (buttonData[index].value != buttonData[index].valueLast) {
    lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
    lcd.print(buttonData[index].value);
    lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
    lcd.print("   ");
    buttonData[index].valueLast = buttonData[index].value;
  }
  buttonData[index].value = min(300, max(0, buttonData[index].value));
}

pcbbc:
And you want to keep on doing buttonPress1() function, even once the button is released? Am I correct?

Then you need to remove that call from the button check, and write some code...

if (state == ADJUSTING_VARIABLE) {

switch(variable)
 {
 case 1:
   buttonPress1();
   break;
 case 2:
   buttonPress2();
   break;
  .....
 }
}




See how pressing the button causes the state to change, and it’s the new state that causes the correct function to be called to do the work, and the work keeps getting called (regardless of if the button is still pressed or not, or if a different button is pressed) until something changes state back to WAITING_FOR_BUTTON.

Thank you pcbbc, I really appreciate the time taken to address my rookie problem!

I am not very familiar with switch/case statements yet, so I will start reading and practising!

ToddL1962:
Here is a code refactor that reduces the size of your code using a button data structure. It compiles but I haven't tested it and also I have not made any changes to it to address your original issue. When I have time I will look at it some more.

#include <digitalIOPerformance.h>

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte encPinA = 2;
const byte encPinB = 12;
const byte encSw = 4;
const byte ledPin = 5;
const byte startButton = 3; // 100nF cap to GND for crude debounce

bool startButtonState = HIGH;
bool startButtonStateLast = HIGH;

bool ledReady = false;

volatile bool countUpFlag = false;
volatile bool countDnFlag = false;
unsigned long previousMillis = 0;

struct ButtonData_s
{
 const byte buttonPin;
 bool buttonState;
 bool buttonStateLast;
 unsigned long value;
 unsigned long valueLast;
 unsigned long buttonDebounceLast;
 bool buttonFlag;
 int cursorCol;
 int cursorRow;
};

ButtonData_s buttonData[6] = {  {6, HIGH, HIGH, 0, 0, 0, false, 1, 0},
                               {7, HIGH, HIGH, 0, 0, 0, false, 5, 0},
                               {8, HIGH, HIGH, 0, 0, 0, false, 9, 0},
                               {9, HIGH, HIGH, 0, 0, 0, false, 1, 1},
                               {10, HIGH, HIGH, 0, 0, 0, false, 5, 1},
                               {11, HIGH, HIGH, 0, 0, 0, false, 9, 1} };
void setup() {

Serial.begin(9600);

lcd.init();
 lcd.backlight();
 lcd.begin(16, 2);
 lcd.clear();

pinMode(encPinA, INPUT_PULLUP);
 pinMode(encPinB, INPUT_PULLUP);
 pinMode(encSw, INPUT_PULLUP);

for (int i=0; i<6; i++)
 {
   pinMode(buttonData[i].buttonPin, INPUT_PULLUP);
 }
 pinMode(startButton, INPUT_PULLUP);
 pinMode(ledPin, OUTPUT);
 digitalWrite(ledPin, LOW);

attachInterrupt(digitalPinToInterrupt(encPinA), encISR, LOW);

///////////////////////////////////
 ////   PRINT VALUES TO LCD     ////
 ///////////////////////////////////

lcd.setCursor(0, 0);
 lcd.print("Drop Controller");
 lcd.setCursor(0, 1);
 lcd.print("***  START  ***");
 delay(1000);
 lcd.clear();

for (int i=0; i<6; i++)
 {
   lcd.setCursor(buttonData[i].cursorCol, buttonData[i].cursorRow);
   lcd.print(buttonData[i].value);
   lcd.setCursor(buttonData[i].cursorCol, buttonData[i].cursorRow);
 }

}

void encISR () {

///////////////////////////////////
 ////      ENCODER INTERRUPT    ////
 ///////////////////////////////////

static unsigned long debounceLast = 0;
 unsigned long debounce = millis();

if (debounce - debounceLast > 5) {
   if (digitalRead(encPinB) == LOW) {
     countUpFlag = true;
   } else {
     countDnFlag = true;
   }
 }
 debounceLast = debounce;
}

void loop() {

///////////////////////////////////
 ////   READ BUTTON STATES      ////
 ///////////////////////////////////
 for (int i=0; i<6; i++)
   buttonData[i].buttonState = digitalRead(buttonData[i].buttonPin);

///////////////////////////////////
 ////    START LED SEQUENCE     ////
 ///////////////////////////////////

startButtonState = digitalRead(startButton);
 if (startButtonState != startButtonStateLast) {
   if (startButtonState == LOW) {
     ledReady = true;
     previousMillis = millis();
   }
   startButtonStateLast = startButtonState;
 }

if (ledReady) {
   static int ndx = 0;
   if (ndx < 6) {
     if (millis() - previousMillis >= buttonData[ndx].value) {
       previousMillis = millis();
       digitalWrite(ledPin, ! digitalRead(ledPin));
       ndx ++;
     }
   }
   else {
     ndx = 0;
     ledReady = false;
   }
 }

//////////////////////////////////////
 //// BUTTON SELECT FUNCTION CALLS ////
 //////////////////////////////////////

for (int i=0; i<6; i++)
 {
   if (millis() - buttonData[i].buttonDebounceLast > 5) {
     if (buttonData[i].buttonState == LOW) {
       buttonPress(i);
     }
     buttonData[i].buttonDebounceLast = millis();
   }
 }
}

///////////////////////////////////
////  BUTTON SELECT FUNCTIONS  ////
///////////////////////////////////

void buttonPress(int index) {

lcd.setCursor(1, 0);
 lcd.print(buttonData[index].value);

lcd.setCursor(0, 0);
 lcd.print(" ");
 lcd.setCursor(4, 0);
 lcd.print(" ");
 lcd.setCursor(8, 0);
 lcd.print(" ");
 lcd.setCursor(0, 1);
 lcd.print(" ");
 lcd.setCursor(4, 1);
 lcd.print(" ");
 lcd.setCursor(8, 1);
 lcd.print(" ");

lcd.setCursor(buttonData[index].cursorCol-1, buttonData[index].cursorRow);
 lcd.print(" ");

if (!digitalRead(encSw)) {
   buttonData[index].value = 0;
   lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
   lcd.print(buttonData[index].value);
   lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
   lcd.print("   ");
   while (!digitalRead(encSw))
     delay(1);
 }

if (countUpFlag) {
   buttonData[index].value++;
 }
 if (countDnFlag) {
   buttonData[index].value--;
 }

countUpFlag = false;
 countDnFlag = false;

if (buttonData[index].value != buttonData[index].valueLast) {
   lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
   lcd.print(buttonData[index].value);
   lcd.setCursor(buttonData[index].cursorCol, buttonData[index].cursorRow);
   lcd.print("   ");
   buttonData[index].valueLast = buttonData[index].value;
 }
 buttonData[index].value = min(300, max(0, buttonData[index].value));
}

Wow Todd!
I don't know what to say...thank you for going to such trouble, I really appreciate it.
I'm not sure how any of it works yet, but I'll try to follow it line-by-line and see if I can figure it out.

Thank you both pcbbc and Todd, you're both very kind and are indeed a credit to these forums!
I'm just sorry that I'm quite a slow learner!! :smiley:

pcbbc:
And you want to keep on doing buttonPress1() function, even once the button is released? Am I correct?

Oops, sorry pcbbc, I forgot to answer this bit!

Yes, that is what I would like to do - continue with buttonPress1, until another buttonPress# is called.

@ToddL1962
Your code does indeed compile, but it doesn't yield the expected results...I will study it and try to learn and understand what you've done - thanks once again!

pcbbc:
And you want to keep on doing buttonPress1() function, even once the button is released? Am I correct?

Then you need to remove that call from the button check, and write some code...

if (state == ADJUSTING_VARIABLE) {

switch(variable)
  {
  case 1:
    buttonPress1();
    break;
  case 2:
    buttonPress2();
    break;
  .....
  }
}




See how pressing the button causes the state to change, and it’s the new state that causes the correct function to be called to do the work, and the work keeps getting called (regardless of if the button is still pressed or not, or if a different button is pressed) until something changes state back to WAITING_FOR_BUTTON.

A huge thank you pcbbc, this worked perfectly!!!

I followed your advice - I dropped the function call, and implemented a switch-case, and it works very well indeed!!

I can't thank you enough pcbbc!!!!

bongobreak:
Oops, sorry pcbbc, I forgot to answer this bit!

Yes, that is what I would like to do - continue with buttonPress1, until another buttonPress# is called.

@ToddL1962
Your code does indeed compile, but it doesn't yield the expected results...I will study it and try to learn and understand what you've done - thanks once again!

bongobreak, get it working like you want with the changes pcbbc suggested first. Maybe you can use my code as a starting point to make your code more efficient.

ToddL1962:
bongobreak, get it working like you want with the changes pcbbc suggested first. Maybe you can use my code as a starting point to make your code more efficient.

Thanks again Todd, indeed I have the sketch working well now - thanks to pcbbc's advice.

I really appreciate the time you've spent in streamlining my code too...it'll take me a little while to get to grips with it, but I think I might be able to understand it soon - it looks like you've placed all the button# operations in a 2D array, and then you're using a series of for() loops to cycle the relevant actions....is that right?

It's very clever and certainly more efficient, I will keep studying it - I'm sure I'll learn a lot.

Thanks again @pcbbc and @ToddL1962.

For the sake of completion, I shall post the entire working sketch here, and mark this thread [SOLVED].

Another big thank you to @pcbbc and @ToddL1962 - Todd, I have begun to learn about how you've streamlined my code, and also tried to implement it myself.
Though I haven't used the full blown struct system, I have employed a number of arrays, and used for() loops to vary the relevant variables, and it has indeed made my code much smaller and more efficient.

I will keep reading and studying to improve it further, I don't think it will be too much farther til I have an array for all necessary variables, so a struct is the next logical step.

Here is the first half of the sketch:

//Thanks to pcbbc and ToddL1962

#include <digitalIOPerformance.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte encPinA = 2;
const byte encPinB = 12;
const byte encSw = 4;
const byte ledPin = 5;
const byte startButton = 3; // 100nF cap to GND for crude debounce

bool startButtonState = HIGH;
bool startButtonStateLast = HIGH;

const int buttonPin[6] = {6, 7, 8, 9, 10, 11};

bool buttonState[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};

bool encSwState[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
bool encSwStateLast[6] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};

bool ledReady = false;

volatile bool countUpFlag = false;
volatile bool countDnFlag = false;

unsigned long value[6] = {0, 0, 0, 0, 0, 0};
unsigned long valueLast[6] = {0, 0, 0, 0, 0, 0};

unsigned long buttonDebounceLast[6];
unsigned long previousMillis = 0;

int buttonValue;

byte cols[6] = {1, 5, 9, 1, 5, 9};
byte rows[6] = {0, 0, 0, 1, 1, 1};

void setup() {

  Serial.begin(9600);

  lcd.init();
  lcd.backlight();
  lcd.begin(16, 2);
  lcd.clear();

  pinMode(encPinA, INPUT_PULLUP);
  pinMode(encPinB, INPUT_PULLUP);
  pinMode(encSw, INPUT_PULLUP);

  for (int i = 0; i < 6; i++) {
    pinMode(buttonPin[i], INPUT_PULLUP);
  }

  pinMode(startButton, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  attachInterrupt(digitalPinToInterrupt(encPinA), encISR, LOW);

  ///////////////////////////////////
  ////   PRINT VALUES TO LCD     ////
  ///////////////////////////////////

  lcd.setCursor(0, 0);
  lcd.print("Drop Controller");
  lcd.setCursor(0, 1);
  lcd.print("***  START  ***");
  delay(1000);
  lcd.clear();

  for (int i = 0; i < 6; i++) {
    lcd.setCursor(cols[i], rows[i]);
    lcd.print(value[i]);
  }
}

void encISR () {

  ///////////////////////////////////
  ////      ENCODER INTERRUPT    ////
  ///////////////////////////////////

  static unsigned long debounceLast = 0;
  unsigned long debounce = millis();

  if (debounce - debounceLast > 5) {
    if (digitalRead(encPinB) == LOW) {
      countUpFlag = true;
    } else {
      countDnFlag = true;
    }
  }
  debounceLast = debounce;
}

void loop() {

  ///////////////////////////////////
  ////   READ BUTTON STATES      ////
  ///////////////////////////////////

  for (int i = 0; i < 6; i++) {
    buttonState[i] = digitalRead(buttonPin[i]);
  }

  ///////////////////////////////////
  ////    START LED SEQUENCE     ////
  ///////////////////////////////////

  startButtonState = digitalRead(startButton);
  if (startButtonState != startButtonStateLast) {
    if (startButtonState == LOW) {
      ledReady = true;
      previousMillis = millis();
    }
    startButtonStateLast = startButtonState;
  }
  if (ledReady) {
    static int ndx = 0;
    if (ndx < 6) {
      if (millis() - previousMillis >= value[ndx]) {
        previousMillis = millis();
        digitalWrite(ledPin, ! digitalRead(ledPin));
        ndx ++;
      }
    }
    else {
      ndx = 0;
      ledReady = false;
    }
  }

  //////////////////////////////////////
  //// BUTTON SELECT FUNCTION CALLS ////
  //////////////////////////////////////

  for (int i = 0; i < 6; i++) {

    if (millis() - buttonDebounceLast[i] > 5) {
      if (buttonState[i] == LOW) {
        buttonValue = i;
      }
      buttonDebounceLast[i] = millis();
    }
  }

  ////////////////////////////////////////
  ////  SWITCH-CASE SELECT FUNCTIONS  ////
  ////////////////////////////////////////

  switch (buttonValue) {
    case 0:
      buttonPress1();
      break;

    case 1:
      buttonPress2();
      break;

    case 2:
      buttonPress3();
      break;

    case 3:
      buttonPress4();
      break;

    case 4:
      buttonPress5();
      break;

    case 5:
      buttonPress6();
      break;
  }
}

...second half in next post...

...here is the second half of the sketch:

///////////////////////////////////
////  BUTTON SELECT FUNCTIONS  ////
///////////////////////////////////

void buttonPress1() {

  ////// VALUE 1 //////

  lcd.setCursor(1, 0);
  lcd.print(value[0]);

  lcd.setCursor(0, 0);
  lcd.print(">");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");

  encSwState[0] = digitalRead(encSw);
  if (encSwState[0] != encSwStateLast[0]) {
    if (encSwState[0] == LOW) {
      value[0] = 0;
    }
    encSwStateLast[0] = encSwState[0];
  }

  if (countUpFlag) {
    value[0]++;
  }
  if (countDnFlag) {
    value[0]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[0] != valueLast[0]) {
    lcd.setCursor(1, 0);
    lcd.print(value[0]);
    lcd.setCursor(1, 0);
    lcd.print("   ");
    valueLast[0] = value[0];
  }
  value[0] = min(300, max(0, value[0]));
}

void buttonPress2() {

  ////// VALUE 2 //////

  lcd.setCursor(5, 0);
  lcd.print(value[1]);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(">");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");


  encSwState[1] = digitalRead(encSw);
  if (encSwState[1] != encSwStateLast[1]) {
    if (encSwState[1] == LOW) {
      value[1] = 0;
    }
    encSwStateLast[1] = encSwState[1];
  }

  if (countUpFlag) {
    value[1]++;
  }
  if (countDnFlag) {
    value[1]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[1] != valueLast[1]) {
    lcd.setCursor(5, 0);
    lcd.print(value[1]);
    lcd.setCursor(5, 0);
    lcd.print("   ");
    valueLast[1] = value[1];
  }
  value[1] = min(300, max(0, value[1]));
}

void buttonPress3() {

  ////// VALUE 3 //////

  lcd.setCursor(9, 0);
  lcd.print(value[2]);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(">");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");


  encSwState[2] = digitalRead(encSw);
  if (encSwState[2] != encSwStateLast[2]) {
    if (encSwState[2] == LOW) {
      value[2] = 0;
    }
    encSwStateLast[2] = encSwState[2];
  }

  if (countUpFlag) {
    value[2]++;
  }
  if (countDnFlag) {
    value[2]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[2] != valueLast[2]) {
    lcd.setCursor(9, 0);
    lcd.print(value[2]);
    lcd.setCursor(9, 0);
    lcd.print("   ");
    valueLast[2] = value[2];
  }
  value[2] = min(300, max(0, value[2]));
}

void buttonPress4() {

  ////// VALUE 4 //////

  lcd.setCursor(1, 1);
  lcd.print(value[3]);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(">");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(" ");


  encSwState[3] = digitalRead(encSw);
  if (encSwState[3] != encSwStateLast[3]) {
    if (encSwState[3] == LOW) {
      value[3] = 0;
    }
    encSwStateLast[3] = encSwState[3];
  }

  if (countUpFlag) {
    value[3]++;
  }
  if (countDnFlag) {
    value[3]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[3] != valueLast[3]) {
    lcd.setCursor(1, 1);
    lcd.print(value[3]);
    lcd.setCursor(1, 1);
    lcd.print("   ");
    valueLast[3] = value[3];
  }
  value[3] = min(300, max(0, value[3]));
}

void buttonPress5() {

  ////// VALUE 5 //////

  lcd.setCursor(5, 1);
  lcd.print(value[4]);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(">");
  lcd.setCursor(8, 1);
  lcd.print(" ");


  encSwState[4] = digitalRead(encSw);
  if (encSwState[4] != encSwStateLast[4]) {
    if (encSwState[4] == LOW) {
      value[4] = 0;
    }
    encSwStateLast[4] = encSwState[4];
  }

  if (countUpFlag) {
    value[4]++;
  }
  if (countDnFlag) {
    value[4]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[4] != valueLast[4]) {
    lcd.setCursor(5, 1);
    lcd.print(value[4]);
    lcd.setCursor(5, 1);
    lcd.print("   ");
    valueLast[4] = value[4];
  }
  value[4] = min(300, max(0, value[4]));
}

void buttonPress6() {

  ////// VALUE 6 //////

  lcd.setCursor(9, 1);
  lcd.print(value[5]);

  lcd.setCursor(0, 0);
  lcd.print(" ");
  lcd.setCursor(4, 0);
  lcd.print(" ");
  lcd.setCursor(8, 0);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(" ");
  lcd.setCursor(4, 1);
  lcd.print(" ");
  lcd.setCursor(8, 1);
  lcd.print(">");


  encSwState[5] = digitalRead(encSw);
  if (encSwState[5] != encSwStateLast[5]) {
    if (encSwState[5] == LOW) {
      value[5] = 0;
    }
    encSwStateLast[5] = encSwState[5];
  }

  if (countUpFlag) {
    value[5]++;
  }
  if (countDnFlag) {
    value[5]--;
  }

  countUpFlag = false;
  countDnFlag = false;

  if (value[5] != valueLast[5]) {
    lcd.setCursor(9, 1);
    lcd.print(value[5]);
    lcd.setCursor(9, 1);
    lcd.print("   ");
    valueLast[5] = value[5];
  }
  value[5] = min(300, max(0, value[5]));
}

Again, huge thanks to @pcbbc and @ToddL1962

I do, however, have another issue, but it isn't related to this subject so I will start another thread if needed.

Cheers! :slight_smile: