You will have to make clear what the requirement is. Setting a flag or using a capacitor will still delay the reaction till your algorithm is completed. Question is if that is acceptable or not.
Regarding reading Serial, you will not loose data if properly configured; there is a 64 byte buffer so if you don't send more than that while the algorithm is being executed, you will not risk the loss of data.
As I said earlier, break your algorithm in pieces. Take this extremely simple example of an algorithm; it takes about 1.2 seconds to complete (due to the added NOP) on a Nano.
bool algorithm()
{
static uint64_t result = 0;
for (uint32_t xCnt = 0; xCnt < numIterations; xCnt++)
{
result += xCnt;
__asm__("nop\n\t");
}
sprintf(buffer, "result: 0x%lx%08lx", (uint32_t)(result >> 32), (uint32_t)(result & 0xFFFFFFFF));
Serial.println(buffer);
result = 0;
return true;
}
You can break it into the individual steps as shown below
bool algorithm2()
{
static uint64_t result = 0;
static uint32_t xCnt = 0;
result += xCnt;
__asm__("nop\n\t");
xCnt++;
if (xCnt == numIterations)
{
sprintf(buffer, "result: 0x%lx%08lx", (uint32_t)(result >> 32), (uint32_t)(result & 0xFFFFFFFF));
Serial.println(buffer);
xCnt = 0;
result = 0;
return true;
}
else
{
return false;
}
}
Below is an additional function to similate something that needs to be running in parallel with the algorithm; it simply toggles a LED every 250ms.
void heartBeat()
{
static uint32_t nextUpdateTime = 0;
static int ledState = LOW;
if(millis() > nextUpdateTime)
{
nextUpdateTime += 250;
ledState = !ledState;
digitalWrite(ledPin, ledState);
//Serial.print(millis()); Serial.print(" > "); Serial.println(ledState);
}
}
Using the algorithm and the heart beat in loop()
uint32_t numIterations = 0x2FFFF;
char buffer[64];
const byte ledPin = LED_BUILTIN;
void setup()
{
Serial.begin(57600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
}
void loop()
{
static bool isRunning = false;
static uint32_t startTime;
heartBeat();
if (isRunning == false)
{
startTime = micros();
isRunning = true;
}
else
{
if (algorithm() == true)
{
uint32_t endTime = micros();
Serial.print("duration: "); Serial.println(endTime - startTime);
isRunning = false;
}
}
}
Using algorithm() in loop(), you will not see the LED flash; using agorithm2() in loop(), it will flash as expected.