I am looking for code examples of a Finite State Machine (roughly a single-core multithread).
I'm building a motor controller with an Arduino that needs to output serial data. The loop execution timing needs to be fixed. The loop has a routine that measures each loop's execution time and adds a few microseconds delay, so that each loop finishes in the same amount of time.
A serial transmit is required about once every 20 loops. The loop that contains the serial transmit takes much longer than the normal loop time (about twice as long). I wrote a software serial buffer to distribute the workload of sending a serial transmission across multiple loops, so no single loop would be encumbered by the serial TX. The problem still remained: one of the loops was still taking a very long time.
Unfortunately, I found that String concatenation is very slow on the Arduino, so the code in the loop that assembles the serial string is a huge asymmetry.
The solution is to start a new pseudo-thread that concatenates the output string in a low-priority "background task" while the foreground loop is executing. That way, the foreground loop can have fixed loop timing, and the background task can assemble and transmit the serial string when the foreground task is idle. I can add a few more delays into the foreground loop, which would give the background loop more time to execute.
The background task may need to halt and resume code mid-instruction. For example, each string concatenation instruction takes approximately 200 microseconds (I wrote a little benchmark to time individual instructions). Since some individual instructions take so long, they may need to be interrupted mid-instruction by the foreground task and resumed later, :
outputstring = String(somevariable); // this instruction takes 200us // may be interrupted mid-instruction by foreground task // and resumed later
As the code may have a lot of time-intensive content (i.e. floating-point calculations, etc.), forking a low-priority "background task" for lower-priority housekeeping or data reporting tasks would be very useful.