void LEDdisplay(byte a, byte b, byte c)
{
if (IsMailMessage){
c = c | message;
}
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, a);
shiftOut(dataPin, clockPin, LSBFIRST, b);
shiftOut(dataPin, clockPin, LSBFIRST, c);
digitalWrite(latchPin, HIGH);
delay(500);
}
Whatever calls this function needs to set up a start time and interval and put code following the call into a block that checks time whenever loop() runs.
You can use more than one state variable if it will help, or ... if you have a common sub-task in loop() that many other tasks call (like to evaluate numbers) that when it is done needs to run a different state depending on which task called it then (and I've done this) you can save the when-finished-go-to-state in the task that calls the common sub-task and when the common sub-task is done it sets the state to the when-finished value, as below.
------- this is pseudocode to hopefully demonstrate a trick
switch ( state )
{
case step1 // no, I'm thinking up meaningful names for a general example so don't ask!
// something. this may break before the next lines and run next loop as well. it does the next lines when finished
retstate = step10
state = common-task
break
case step2
// something as above
retstate = step11
state = common-task
break
................ other cases between
case step10
// something that picks up from step1, maybe checks time, I dunno, whatever fits
break
case step11
// something that picks up from step2, maybe checks time, I dunno, whatever fits
break
................ other cases between
case common-task
// something, when it's done then run the next lines
state = retstate // the next thing done changes depending on what sent execution to this case
break
................ other cases
}
One definition of program is code + data. You can run generalized code with different data to achieve what many similar blocks of code will do. Imagine if each block costs $100, you'd be generalizing! One thing I found early on fixing a business code package was that about half the bugs I had to deal with were due to bad data. That was one of the drivers to get me to write my own user-I/O to replace the BASIC INPUT$ routines in the original package.
You can go miles datafying programs. Once the code is right, you can pass it data and have it work with all the flexibility you wrote in. It's very satisfying but beware, you may need to write a program to ensure that the data set is good.
Any program can be bigger than it needs to be. How small it can be and work right is unknown until it's done or the task is so trivial the answer is obvious. And even then, Morris Dovey might come along and surprise you!