Stop The loop() Insanity!

The simplest Arduino program looks like this:

This does nothing beyond build and run.

The setup() function is used for one time, well, setup. This is where you initialize a sensor or connect to Wifi or set the speed of your serial port.

The loop() function is where you do the work. This is intended for repetitive tasks, like reading from a sensor or uploading some information or blinking lights.

The Arduino SDK (including when it’s used on a non-Arduino chips like the ESP8266 and ESP32) is designed expecting loop() to do a little work and then return. The loop() function itself is called from an infinite loop.

loop() Loopiness

Sometimes Arduino coders write things like:

This will completely fail on some processors. Notably the ESP8266 and the ESP32 both have “watchdog timers” which are used to help with stability. Watchdog timers are intended to catch when the software has gone into an infinite loop or otherwise failed. If they’re not reset periodically, they’ll restart the processor and your program will run over again from the beginning.

The watchdog timer is automatically reset when loop() returns. When loop() returns the underlying software also gets to perform certain housekeeping tasks, like handle serial I/O, perform any interrupt service it couldn’t do in the interrupt handler, and handle network protocol interactions if it has a networking stack and interface. You can also give up control from inside loop() temporarily by calling yield() or delay(), and some other calls may also give the underlying software a chance to run.

So it’s vital that you don’t loop indefinitely inside loop(). Instead, structure your code to be aware of the fact that loop will be called over and over again for you.

So instead of:

write:

Delay Delaying

People also often write:

This is fine as long as you’re not doing much inside loop(). If you have a very simple application that only does one thing inside loop() then calling delay() this way is harmless.

Let’s suppose we’re doing something more. Imagine that we’re running on a wifi-enabled platform and we have a small web server. We’ll avoid details of how the web server works – there are plenty of tutorials out there and the details would be a distraction.

Now our loop() looks something like this:

So we take a sensor reading, print it to the serial port, check if there’s a web request available and process it if there is, and then delay for ten seconds because we don’t want to output sensor readings too often.

See the problem?

This delays handling web requests for ten seconds as well.

That means you may wait ten seconds before the page can load. And if the page tries to load any other resources from your server (Javascript, CSS, data) they may each be delayed by 10 seconds as well.

Instead we can write loop() like this:

Now we’re checking on web requests every run through loop()but only handling sensor readings every second.

We can generalize this to let us handle several things with different timing needs all in the same loop just by keeping track of the time for each of them separately.

Using this structure instead of calling delay() inside loop() will let the handlers inside loop() remain responsive while still reading the sensor only as often as it’s supposed to be read.

Please License Your Code

Dear Lupo:

I ran across your public repository of Arduino code on Github today. It’s nicely written and does almost exactly what I need. I would like to have used it in a project. I would have forked it, added a little functionality and contributed that back in case you’d like to integrate the changes. I might also have called it “George”. This would have saved me some time and let me add a bit of functionality to it that others might find useful.

Unfortunately it had no license – none at all. And you don’t have any links to social media or list any contact info in your profile so I can’t easily reach you to ask about it.

No license is equivalent to “All Rights Reserved”. It turns out that about half of public repositories on Github have no license.

Without a license I don’t know if it’s okay for me to use the library in my open (or closed) source project. I don’t know if it’s okay for me to modify it and distribute my modifications. Without a license I have to assume that you intended that no one else use it for anything, despite the fact that you left it out in the open for everyone to see.

I totally get it if you’d rather that I didn’t try to contribute changes. I write a lot of code which I just want to use for a while and not be responsible for forever. If your code had a license permitting me to do so, I’d be happy to evolve it and share my changes with other people myself. Unfortunately it doesn’t have a license at all.

I like the MIT license, and I publish almost all of my code under it. It’s short and sweet:

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

This license says:

  1. You can do what you want with the code except remove the copyright notice
  2. I’m not liable for anything related to this code

And that’s about it.

If that doesn’t suit you, there are many other licenses to choose from. Choose A License can help you find the license that works best for you.

And if you don’t want to license your code – or just choose a license – that’s certainly your right. It’s your code, your say. But if you’re thinking that just popping it up on Github without a license makes it open source and usable but the rest of the world, sadly, the defaults don’t work that way.

So please – choose a license – even if it’s “All Rights Reserved” – so that we can know whether it’s okay for us to use or improve your code.

Thanks Lupo!