Skip to main content

How To Write Non-Blocking Code Loops

Recommended Code Flow For Long Loops

To loop through a block in code, Squirrel provides common modern programming language constructs, including for... next, do... while, while and foreach. However, all of these structures block the imp’s processor. If the code needs to run through the loop only a handful of times, that’s not a problem. But if the loop count is large — or even infinite — impOS™, which shares the Squirrel execution thread, is prevented from managing the device’s WiFi connection and performing other housekeeping duties.

To prevent this undesirable outcome, there is an easy way to code long loops. Embed the loop code in a function and include within that code the imp API method imp.wakeup() to set a timer that will call the function again at a set time in the future. The imp.wakeup() takes two parameters: the timer duration in seconds (down to hundredths of a second) and the function to be called, either the name of an already defined function or an inline function.

The call to imp.wakeup() returns a reference to the specific timer the method has instantiated. If you may need to prevent the timer from firing, retain this reference. Pass the reference to imp.cancelwakeup() to dispose of the timer.

If you don’t know what duration to include, use the imp API method imp.onidle(). It takes one parameter: the function to call when the imp enters an idle state. This happens when there is no more code to run and impOS has had an opportunity to perform the tasks in its care.

Example Code

The following code snippets show the use of imp.wakeup() to manage a loop structure. In each case, imp.wakeup() is used to keep the loop flowing. In the first example, we just want the loop to trigger, so the the call to imp.wakeup() can go after the loop code has been run. In the second example, we want the loops duration to be fixed: the time spent looping will be what we specify in imp.wakeup() not that value plus the time it takes to execute the loop code.

In each case, we don’t preserve the timer reference returned by imp.wakeup() because we don’t need it. Had we done so, however, we could call imp.cancelwakeup() to dispose of it.

API Methods Used

Further Reading