Reading pin state changes from inside loops?

What I'm trying to do is fairly simple, I have an ATmega328, and am using it to control multiple pumps and valves based on button presses, all tied to various LED's. In the interest of making things more understandable to the end user I'm trying to get blinks into these LED's, some timed and some continuous until there's a state change, which is where the problem is coming up.

For one of the continuous loops I've essentially done exactly what's spelled out in the blink without delay example, assuming that by bypassing the delay function I'd allow the board to still read state changes on pins outside of the loop, but apparently this isn't the case.

Here are the relevant portions of the code:

  int OverrideLED = 9;
  int OverrideBut = 10;
  int OverrideButState = 0;
  int OverrideOutState = LOW;
  int OverrideReading;
  int OverridePrevious = HIGH;
	
  int OverrideLEDState = 0;
  int OverrideLEDFlashInterval = 250;
  long OverrideLEDTimerCurrent = 0;
  long OverrideLEDTimerPrevious = 0;

  long OverrideTime = 0;
  long OverrideDebounce = 200;

void setup() {
  pinMode(OverrideBut, INPUT);
  pinMode(OverrideLED, OUTPUT);
}


void loop(){
  OverrideButState = digitalRead(OverrideBut);

  //Override control
    digitalWrite(OverrideLED, HIGH);
    OverrideReading = digitalRead(OverrideBut);
    if (OverrideReading == LOW && OverridePrevious == HIGH && millis() - OverrideTime > OverrideDebounce) {
      if (OverrideOutState == HIGH) {
        OverrideOutState = LOW;
        digitalWrite(OverrideLED, HIGH);}
       else {
         OverrideOutState = HIGH;}
     }
		
     OverridePrevious = OverrideReading;
				
    while (OverrideOutState == HIGH) {
      OverrideLEDTimerCurrent = millis();
      if(OverrideLEDTimerCurrent - OverrideLEDTimerPrevious > OverrideLEDFlashInterval){
        OverrideLEDTimerPrevious = OverrideLEDTimerCurrent;
        if(OverrideLEDState == LOW) {
          OverrideLEDState = HIGH;}
        else {
          OverrideLEDState = LOW;}
					
       digitalWrite(OverrideLED, OverrideLEDState);
       }
    }
}

Sorry for the long variables, I was trying to make it as readable to someone else as possible.

So, I have a while loop running while OverrideOutState == HIGH, however while the loop is running apparently no other portions of the code can be read. I have several functions (all would be triggered by a button press) that would need to be able to work while the blinking was going on, how can I make them still execute even if the loop is running? And (if it's even possible) I'd like to have more than one of these running at the same time.

I looked into interrupts, initially thinking that that's what I'd need, but everywhere I looked seemed to be talking about timers and hardware registers and many other things that are far beyond my few days of coding.

Is there a simpler way to do it?

Thanks in advance.

Your approach (i.e. eliminating "delay") is correct, but the execution is maybe flawed, and you're quite right, interrupts are probably not the way to go.
Have a search for "state machine" or "finite state machine" and see if that fits the bill.

Normally timer overflow interrupts are the way to handle this, but learning how to implement them might be too much of a pain.

The solution I would look into is handing off control while inside the loop. Have all the logic about blinking done in a separate routine, and then call that routine from inside the loop.

This code was written off the top of my head, so it hasn't been debugged.

#define NUM_LEDS 3
#define BLINK_DELAY 500
#define MODE_OFF 0
#define MODE_ON 1
#define MODE_BLINK 2

int ledPins[] = {3, 4, 5};
int ledStates[] = {LOW, LOW, LOW};
int ledModes[] = {0, 0, 0};
long ledChangeTimes[] = {0, 0, 0};

void setOn(int led) {
  ledModes[led] = MODE_ON;
  ledStates[led] = HIGH;
  digitalWrite(ledPins[led], HIGH);
}

void setOff(int led) {
  ledModes[led] = MODE_OFF;
  ledStates[led] = LOW;
  digitalWrite(ledPins[led], LOW);
}

void setBlink(int led) {
  ledModes[led] = MODE_BLINK;
  ledState[led] = HIGH;
  ledChangeTimes[led] = millis() + BLINK_DELAY;
  digitalWrite(ledPins[led], HIGH)
}

void doBlink() {
  long now=millis();
  for(int led=0; led < NUM_LEDS; led++) {
    if(ledStates[led] == MODE_BLINK && now >= ledChangeTimes[led]) {
      ledStates[led] = ledStates[led]==HIGH?LOW:HIGH;
      ledChangeTimes[led] = now + BLINK_DELAY;
    }
    digitalWrite(ledPins[led], ledStates[led]);
  }
}

Then make sure that doBlink() is called from inside your loop. It shouldn't add too much execution time to your loop.

-- Mitch