Is it possible to Pause a Void Loop without an external button?

I'm looking to see if there is a way to Pause the Void Loop on an Arduino UNO when I submit a new delay value without using an external button as an interrupt?

For example: If I set the delay for the LED on Pin 8 to blink at 3 minutes on and 3 minutes off, I'll have to wait for the Loop to complete before it would apply any new values sent during the 6 minute or so loop.

Here is the code (combined with a lot of code from contributors here as well) for the project:

#include <EEPROM.h>
#include <avr/eeprom.h>

const byte numChars = 30;
char receivedChars[numChars];
boolean newData = false;
long int redDelayValue = 0;

void setup()
{
  pinMode(8, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  recvWithStartEndMarkers();
  if (newData == true)
  {

    parseData();
    showParsedData();

    long address = 0;

    EEPROMWritelong(address, redDelayValue);
    address += 4;

  }
  else
  {
    digitalWrite(8, HIGH);
    delay(EEPROMReadlong(0));
    digitalWrite(8, LOW);
    delay(EEPROMReadlong(0));
  }
  newData = false;
}


void recvWithStartEndMarkers()
{
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false)
  {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}


void parseData()
{

  char * strtokIndx;
  strtokIndx = strtok(receivedChars, ",");
  redDelayValue = atof(strtokIndx);

}


void EEPROMWritelong(int address, long value)
{

  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);

  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);

}


long EEPROMReadlong(long address)
{

  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);

  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16)
         & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);

}


void showParsedData()
{

  Serial.println(" ");
  Serial.print("Red Delay Time (ms):  ");
  Serial.println(redDelayValue);

}

Thanks

Have a look at the blog without delay example in the IDE.
Really, really understand how it works.

Yes, use Blink without Delay style coding. (blog?)
Note the time you start the digitalWrite. Keep checking the current time at the top of loop, when enough time has passed proceed to the next phase.
Using a 'flag' to indicate which phase (or state) you are in will help.
Then you can be doing other things while time passes for the digitalWrite.

Does this make any sense to you?
BWD (blink without delay) example:

//BWD example
unsigned long FlashTime;
unsigned long WaitTime = 3*60*1000UL;
unsigned long currentmillis; 
byte x;

void setup()
{
  pinMode(13, OUTPUT); //connect to LED

  FlashTime = millis(); //Capture the current time now

} //  >>>>>>>>>>>>>> E N D   O F   s e t u p ( ) <<<<<<<<<<<<<<<<<


void loop()
{
  //leave this line of code at the top
  currentmillis  = millis();

  //***************************
  //just some code to see if the sketch is blocking
  if (CheckTime(FlashTime, WaitTime))
  {
    digitalWrite(13,!digitalRead(13)); //toggle LED
  }

  //***************************

  //Put your non-blocking regular stuff here



} //   >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<


//======================================================================
//                       F U N C T I O N S
//======================================================================

//***************************
//Delay time expired function
boolean CheckTime(unsigned long &lastMillis, unsigned long wait) 
{
  //is the time up for this task?
  if (currentmillis - lastMillis >= wait) 
  {
    lastMillis += wait;  //get ready for the next iteration

    return true;
  }

  return false;
} //END of CheckTime()

//***************************

//======================================================================
//                       E N D   O F   C O D E
//======================================================================

Use millis() instead of delay()

See my
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Or Robin2's several things at once
http://forum.arduino.cc/index.php?topic=223286.0

jon5221:
Here is the code (combined with a lot of code from contributors here as well) for the project:

You seem to be using code from my serial input basics - thank you.

If you look at several things at a time (which includes blinking LEDs) you will see how to use millis() rather than delay() to manage your timing. That will allow you to achieve what you want,

...R

LarryD:
Does this make any sense to you?
BWD (blink without delay) example:

//BWD example

unsigned long FlashTime;
unsigned long WaitTime = 3601000UL;
unsigned long currentmillis;
byte x;

void setup()
{
 pinMode(13, OUTPUT); //connect to LED

FlashTime = millis(); //Capture the current time now

} //  >>>>>>>>>>>>>> E N D   O F   s e t u p ( ) <<<<<<<<<<<<<<<<<

void loop()
{
 //leave this line of code at the top
 currentmillis  = millis();

//***************************
 //just some code to see if the sketch is blocking
 if (CheckTime(FlashTime, WaitTime))
 {
   digitalWrite(13,!digitalRead(13)); //toggle LED
 }

//***************************

//Put your non-blocking regular stuff here

} //   >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<

//======================================================================
//                       F U N C T I O N S
//======================================================================

//***************************
//Delay time expired function
boolean CheckTime(unsigned long &lastMillis, unsigned long wait)
{
 //is the time up for this task?
 if (currentmillis - lastMillis >= wait)
 {
   lastMillis += wait;  //get ready for the next iteration

return true;
 }

return false;
} //END of CheckTime()

//***************************

//======================================================================
//                       E N D   O F   C O D E
//======================================================================

It does, and I truly appreciate the example.

Robin2:
You seem to be using code from my serial input basics - thank you.

If you look at several things at a time (which includes blinking LEDs) you will see how to use millis() rather than delay() to manage your timing. That will allow you to achieve what you want,

...R

No, thank you! Your codes does exactly what I need and it scales beautifully for additional code.

Grumpy_Mike:
See my
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Or Robin2's several things at once
Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Excellent examples, and they truly helped to finally clear up what was going on and why.

Thanks again everyone!

I did the changes (at least I think I did them correctly), but I'm still kind of back to my original issue of waiting for part of the loop to complete before the new value is written.

I've set it for 3 minutes on and off again from the serial monitor for a total of six minutes, but I have wait 3 minutes (or half the loop) for the new value from the serial monitor to be written. I'm sure I don't have something written properly, but I'm not sure where?

#include <EEPROM.h>
#include <avr/eeprom.h>

const byte numChars = 100;
char receivedChars[numChars];
boolean newData = false;
boolean LEDstate = LOW;  //// NEW CODE
long int goTime;  //// NEW CODE
long int redDelayValue = 0;  /// Modified Variable 

void setup()
{
  pinMode(8, OUTPUT);
  Serial.begin(9600);

  goTime = millis();  //// NEW CODE
}

void loop() {

  recvWithStartEndMarkers();
  if (newData == true)
  {

    parseData();
    showParsedData();

    long address = 0;

    EEPROMWritelong(address, redDelayValue);
    address += 4;

  }
  else
  {
  if (millis() >= goTime) functionGo();   ///// NEW CODE
  }
  newData = false;
}


//############### NEW CODE ###################

void functionGo()
{
  if (LEDstate == HIGH) {
    digitalWrite(8, LOW);
    LEDstate = LOW;
  }
  else
  {
    digitalWrite(8, HIGH);
    LEDstate = HIGH;
  }

  goTime = millis() + EEPROMReadlong(0);  /// Modified Var

}

//############### NEW CODE ###################


void recvWithStartEndMarkers()
{
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false)
  {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}


void parseData()
{

  char * strtokIndx;
  strtokIndx = strtok(receivedChars, ",");
  redDelayValue = atof(strtokIndx);

}


void EEPROMWritelong(int address, long value)
{

  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);

  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);

}


long EEPROMReadlong(long address)
{

  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);

  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16)
         & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);

}


void showParsedData()
{

  Serial.println(" ");
  Serial.print("Red Delay Time (ms):  ");
  Serial.println(redDelayValue);

}

You need to act on the new data as soon as it is available. If timing is critical you could change the on/off before the data is written to and read from the eeprom, but it is easy to just call functionGo().

void loop() {

  recvWithStartEndMarkers();
  if (newData == true)
  {

    parseData();
    showParsedData();

    long address = 0;

    EEPROMWritelong(address, redDelayValue);
    address += 4;
    functionGo();  //act as soon as new data is in eeprom

  }
  else
  {
  if (millis() >= goTime) functionGo();   ///// NEW CODE
  }
  newData = false;
}

I'll give it a try, Thanks.

Edit...
Thank You! That was it.

jon5221:
I did the changes (at least I think I did them correctly),

Sorry, no.

If you look at several things at a time you will see that the time is always calculated using subtraction as that means it works when millis() goes back to 0

Rather than

if (millis() >= goTime)

you should have something like

if (millis() - prevMillis >= EEPROMReadlong(0) ) {
    prevMillis += EEPROMReadlong(0);
    functionGo();
}

Why are you only checking the time for functionGo() if newData is false. I think you should check it all the time.
Also, I think your code is setting newData to false when it shouldn't. That should be within the IF.

 else
  {
  if (millis() >= goTime) functionGo();   ///// NEW CODE
  }
  newData = false;

It is not clear how you plan to match the timing to the arrival of data. For example, what happens if the time expires but newData is false? Or what should happen if more data arrives before the time has expired?

I think you need to get a pencil and paper and do a bit of planning and thinking.

...R