Humans are slow, how not to block

Just like the title says, my problem is that humans are slow and interacting with them blocks the rest of my program. This problem doesn't really have to do with any one particular project, but is something that seems to come up for me all the time.

Let's say I'm have a program like this. I have a function that runs a really tight loop and does some really important stuff called importantFunction(). We can't allow that function to be blocked for more than a few milliseconds.

Now I want a function that allows the user to set the time. It has to ask sequentially for the month, day, year, hour, and minute and it can't block the importantFunction. So I'll make this function quick and make a pointer to this function and call it over and over again. One obvious solution is to have all of those answers as global variables and set them to -1 or something so I know where I am in the chain and each time through see where I am and check real quick if the user has entered anything yet. For just setting the time that sounds cool, but once my program has a lot of different things it can do, keeping up with all those globals becomes an issue.

But I don't see another option. If I wrote a blocking function I'd have month, day, year, hour, and minute as local to the function. They'd be in RAM on the stack but only while the function is alive. Then they're gone leaving space for the next thing that has to ask three or four questions in a row. But if I don't want to block I have to leave a whole bunch of globals around or use static variables and that's going to have the same memory issue. I also have to have a way to get this information back to the part of the program that was asking. I know how to use a callback, but again I have to leave all this information in a global place so it can be used by another function.

How is this supposed to work?

If I wrote a blocking function I'd have month, day, year, hour, and minute as local to the function.

What makes you think that? It will only be local to your function if you declare it to be, it is just as easy to have it global.

One obvious solution is to have all of those answers as global variables and set them to -1 or something so I know where I am in the chain and each time through see where I am and check real quick if the user has entered anything yet.

Yes that technique is called a state machine or sometimes finite state machine, you can look it up.

I am not sure what your difficulty is. If it is running out of SRAM memory with too many variables them maybe you could encode the information into fewer bytes in a more efficient way. So your month, day, year, hour, and minute can take up less space, for example put the year and month into one byte, The top four bits for the month and the bottom four bit for a year offset from the year 2014. That gives the code 16 years of life.

I wonder if part of the problem is the general structure that you have in mind for your program.

It is natural to think of it having separate "sections" that have to be dealt with one at a time. But it is easy to organize a program so that all of the separate sections (functions) are interleaved with each other so that they appear to be running in parallel.

The demo code in the first post of this Thread illustrates the point with some simple code to blink LEDs.

I don't think there is any need to worry about confusing variables if they are all given meaningful names. And in any case the Arduino has limited space for data.

...R