# How does it work?

Under the hood, **ptScheduler** uses the native `millis()` implementation of Arduino. The `millis()` function is a timer based **ISR** (Interrupt Service Routine) that increments a global counter variable (32-bit unsigned integer) every millisecond. Calling the `millis()` function will return the current value of the counter. Since Arduino implements the counter as a 32-bit unsigned integer, the counter will overflow every **49.71026962963 days**. But ptScheduler is written with a workaround to overcome such overflow event.

When you create a new ptScheduler object, you can specify the **time intervals** and **execution modes**. The time interval is stored in a variable or in an array, and is compared to the **time elapsed** since the last time the task was executed. For example if the time period is 1000 milliseconds, the value is stored in a list called `intervalList` and is compared to the elapsed time every time the associated `call()` function is invoked. If the elapsed time is less than 1000 ms, `call()` will return false. If the elapsed time is equal or greater than 1000 ms, `call()` will return true. This will cause the code under the conditional clause will be executed only once. The next time you invoke call() and if the elapsed time is less than 1000 ms,  the function will again return false. This kind of tasks where the code is executed only once every time interval is called a **Oneshot** task. This may not be how you want it. You might want to execute a task continuously for a specific time period and then sleep for the next cycle. It is possible with Spanning tasks. In addition to these basic types of tasks, ptScheduler allows you to alter many other behavior of tasks on the fly.

Let's look at detail how logic behind modes and timing work.

## **Task Properties**

There are three properties that determine the task mode.

1. Whether a task is executed once every interval or executed repeatedly (continuously) during the interval.
2. Whether a task has equal or unequal intervals.
3. Whether a task is periodic or iterated (stops after specific number of interval cycles).

### **1. Oneshot or Spanning**

There are two types of tasks – **oneshot** and **spanning**. A oneshot task is executed **once** every recurring interval. See the graph below.

![Equal interval, oneshot task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-Oneshot_1-1024x485.png)

For example, every time a oneshot task is executed, you can toggle the state of an LED. This will blink the LED at every interval.

A **spanning task** is a one that is executed repeatedly during an interval. Such a task could be sampling a sensor continuously over a period of time. See the graph below.

![Equal interval, spanning task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-Equal-Initerval_1-1024x499.png)

During the Active time, the `call()` function will return `true`, and will return `false` during the inactive time. Both the tasks shown above have a single interval value of **`Ti`**

### **2. Equal or Unequal Intervals**

Tasks are **periodic** or **recurring** and their intervals can be equal or unequal. For example, below is a spanning task with two unequal intervals.

![Unequal interval, spanning task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-Unequal-Interval_1-1024x483.png)

The active time and inactive time intervals are different. ptSchdeuler allows you to set any number of intervals of any length. For example, something like below is also possible with 6 interval values of different lengths. Every **interval set** is called an **iteration**. This iteration or pattern can repeat as many times you want.

![Unequal interval, spanning task with 6 different interval values](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-Unequal-Interval_2-1024x483.png)

### **3. Periodic/Recurring or Iterated**

A task can run for either an indefinite period of time or stop after a number of iterations. You can set the number of iteration for a task using `setIteration()` function. If no iteration was set (`itearations` = 0), it will be a periodic indefinite task.

## Modes

Depending on these properties, there can be 8 modes.

### **1. EPO – Equal, Periodic, Oneshot**

![EPO task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-EPO_1-1024x538.png)

This example has a single interval value of **`Ti`**.

Call `setTaskMode(PT_MODE_EPO)` to use this mode.

**2. EIO – Equal, Iterated, Oneshot**

![EIO task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-EIO_1-1024x551.png)

This example also has single interval value but it is iterated. After 5 iterations, the task will be either disabled or suspended.

Call `setTaskMode(PT_MODE_EIO)` to use this mode.

### **3. UPO – Unequal, Periodic, Oneshot**

![UPO task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-UPO_1-1024x538.png)

This example has two intervals **`T1`** and **`T2`**.

Call `setTaskMode(PT_MODE_UPO)` to use this mode.

### **4. UIO – Unequal, Iterated, Oneshot**

![UIO task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-UIO_1-1024x539.png)

This example has two intervals and the iteration is set to 2. After the two iterations, the task is suspended until you manually reactivate it.

Call `setTaskMode(PT_MODE_UIO)` to use this mode.

### **5. EPS – Equal, Periodic, Spanning**

![EPS task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-EPS_1-1024x534.png)

This is a spanning task with equal intervals. Iteration is not set and so it repeats indefinitely.

Call `setTaskMode(PT_MODE_EPS)` to use this mode.

### **6. EIS – Equal, Iterated, Spanning**

![EIS task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-EIS_1-1024x526.png)

This has iterations set to 4. Once four iterations are completed, the task will be suspended until you reactivate it again.

Call `setTaskMode(PT_MODE_EIS)` to use this mode.

### **7. UPS – Unequal, Periodic, Spanning**

![UPS task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-UPS_1-1024x532.png)

This spanning task has two unequal intervals **`T1`** and **`T2`**.

Call `setTaskMode(PT_MODE_UPS)` to use this mode.

### **8. UIS – Unequal, Iterated, Spanning**

![UIS task](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-UIS_1-1024x543.png)

This spanning task has two unequal intervals **`T1`** and **`T2`** and is also iterated.

Call `setTaskMode(PT_MODE_UIS)` to use this mode.

In addition to these, you can set a **skip time** or a **pre-task delay**. You can either express this delay in milliseconds, number of intervals or number of iterations. **`Ts`** is the skip time.

![Skipped interval](https://circuitstate.com/wp-content/uploads/2021/01/ptScheduler-Task-Types-Skipped_1-1024x540.png)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vishnumaiea.gitbook.io/ptscheduler/v2.0.0/how-does-it-work.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
