SkillAgentSearch skills...

BlockNot

BlockNot is a library that creates non-blocking timers with simplicity.

Install / Use

/learn @EasyG0ing1/BlockNot
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

BlockNot Arduino Library

This library enables you to create non-blocking timers using simple, common sense terms which simplifies the reading and writing of your code. It offers, among several things, convenient timer functionality, but most of all ... it gets you away from blocking methods - like delay() - as a means of managing events in your code.

Non-Blocking is the proper way to implement timing events in Arduino code and BlockNot makes it easy!

*** If you are updating to this new version (2.4.0), READ THIS so that your code doesn't stop working.

*** If you are noticing unwanted rapid succession triggering on high speed microcontrollers, READ THIS

Table of Contents

<!-- TOC --> <!-- TOC -->

Quick Start

Here is an example of BlockNot's easiest and most common usage:

First, you crate the timer:

#include <BlockNot.h>   
BlockNot helloTimer(1300); //In Milliseconds    

OR optionally

#include <BlockNot.h>   
BlockNot helloTimer(15, SECONDS); //Whole Seconds timer    
BlockNot helloTimer(120000, MICROSECONDS); //Microseconds timer    

Then, you just test it to see if it triggered.

   if (helloTimer.TRIGGERED) {  
      Serial.println("Hello World!"); 
   } 

Every time the TRIGGERED call returns true, the timer is reset and it wont trigger again until the duration time has elapsed (all behaviors can be changed based on your needs).

That is all you need to start using BlockNot. Keep reading to learn about other features of the library.

Theory behind BlockNot

This is a traditional non-blockling timer:

long someDuration = 1300;  
long startTime = millis();  
if (millis() - startTime >= someDuration) {  
        //Code to run after someDuration has passed.
 }  

This does the same thing, only with much simpler code!

if (myTimer.TRIGGERED) {  
        //Code to run after timer has triggered.
 }  

The idea behind BlockNot is very simple. You create the timer, setting its duration when you declare it, then check on the timer in your looping code to see if it TRIGGERED. Or, you can check for other information such as how long until it will trigger, or how much time has passed since it last triggered or you can ask it what the current duration is, which might be useful in scenarios where you change the duration based on dynamic criteria.

For example, if you wanted to see if the timers duration has come to pass, but you don't want to reset the timer, you can use this method:

if (myTimer.triggered(NO_RESET)) {}  

OR, you can do it like this:

if (myTimer.HAS_TRIGGERED) {}  

They both do the same thing, but in terms of readability, the second example is the obvious choice. BlockNot has several easy to understand commands that make it very 'user-friendly' and make your code much more readable.

Here is a simple graph showing you how BlockNot timers work. What's important here is to realize that your code never stops executing while the timer is passing time.

How To Use BlockNot

The Trigger

BlockNot is all about the trigger event. When runners line up to start a race, it is a traditional practice for someone to stand next to the line and hold a gun in the air and pull the trigger when the race starts. That is the idea behind the TRIGGERED event in BlockNot. If your timer is set, for example, to 1300 milliseconds, it will return true when you call the TRIGGERED event on or after 1300 milliseconds have passed ... there are exceptions, however, as you will see which can be useful.

if (voltageReadTimer.TRIGGERED) {  
    readVoltage();
}  

One Time Trigger

I have personally found it quite handy in some scenarios, to be able to get a boolean true response after the timer has triggered, but only once, so that the code which executes after getting a true response only executes once and when the test comes up again in the loop, a response of false will be given until the timer has been manually reset. The false response can be changed to true if you desire, by running this method:

myTimer.setFirstTriggerResponse(true);

This kind of trigger is called FIRST_TRIGGER and you use it like this:

if (myTimer.FIRST_TRIGGER) { my code }  

That method will return true ONLY ONE TIME after the timer's duration has passed, but subsequent calls to that method will return false until you manually reset the timer like this:

myTimer.RESET;  

Why would you need to do that? There are countless scenarios where that would be immediately useful. I have used it with stepper motor projects where I want an idle stepper motor to be completely cut off from any voltage when it has been idle for a certain length of time ... lets say 25 seconds.

So first, we define the timer

BlockNot stepperSleepTimer (25, SECONDS);  

Then, we reset the timer every time we use the motor:

stepperSleepTimer.RESET;  

Then, in your loop, you would put something like this:

if (stepperSleepTimer.FIRST_TRIGGER) {  
     sleepStepper();
 }  

So that if the stepper hasn't moved in the last 25 seconds, it will be put to sleep and that sleep routine won't execute over and over again each time the loop encounters the check. Yet when the stepper is engaged again, the sleep timer is reset and when it becomes idle again for 25 seconds, it is put to sleep. This helps efficiency in your program, and it conserves valuable CPU time.

Trigger Next

This allows you to signal the timer to trigger the next time it is checked regardless of whether or not the duration time has passed.

I have found situations where I am using more than one timer to accomplish some purpose where I need a dependent timer to trigger the next time it is checked depending on the situation. For example: When using a WiFi module in a project, I often use a timer to periodically check to make sure WiFi is connected. If not, then I reset the module so that it makes a clean effort to re-connect to the access point. But lets say that I have another method that will do something like sync a local Real Time Clock with an Internet Network Time Protocol (NTP) server but I only want to run this method once the WiFi has connected. Lets also say that I prefer to re-run the time sync method every few days to mitigate time drift in the local RealTimeClock. So I have a timer called resyncTimeTimer but its duration is set to execute every three days.

In that case, I want resyncTimeTimer to trigger the next time it is checked once the WiFi module has connected to the local access point, so my code would look something like this:

#include <BlockNot.h>

enum UpDown {
    UP,
    DOWN
}

UpDown wifiState = DOWN;

void getWifiState() {
    wifiState = WiFi.status() == WL_CONNECTED ? UP : DOWN;
}

void connectWifi() {
    BlockNot delay(25, SECONDS);
    Serial.println("Attempting to connect to Wifi...");
    WiFi.disconnect();
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    getWifiState();
    // This while loop will wait for the WiFi to connect for 25 seconds
    // If the Wifi connects OR 25 seconds pass, the loop exits.
    while (wifiState == DOWN and !delay.TRIGGERED) {
        getWifiState();   
    }
}

void loop() {
    static BlockNot checkWifiTimer(60, SECONDS);
    static BlockNot resyncTimeTimer(4320, MINUTES); // 72 hours (60 * 72)

    if (checkWifiTimer.TRIGGERED) {
        getWifiState();
        if (wifiState == DOWN) {
            connectWifi();
            resyncTimeTimer.TRIGGER_NEXT;
        }
    }
    
    if (resyncTimeTimer.TRIGGERED and wifiState == UP) {
        syncRTCTime();
    }
}

Using the TRIGGER_NEXT macro on the re-sync timer lets me use the code that the time holds in the situation where I need that code to run immediately instead of waiting for the timer to trigger. After it runs, the timer will not trigger again until its duration has passed (three days in this example).

Code like this works especially well on a micro controller like the Pi Pico, where it can be run in a loop in a separate thread in the second core of

Related Skills

View on GitHub
GitHub Stars46
CategoryDevelopment
Updated1mo ago
Forks5

Languages

C++

Security Score

90/100

Audited on Feb 13, 2026

No findings