Note: Should users need to create their own event loops, refer to the **user event loops** [documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/esp_event.html#using-esp-event-apis) and [example](https://github.com/espressif/esp-idf/tree/master/examples/system/esp_event/user_event_loops).
The [**default event loop**](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/esp_event.html#default-event-loop) is an [event loop](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/esp_event.html#) the system uses to post and handle events (e.g. Wi-Fi events). This example demonstrates the usage of the following default event loop features:
This example shows the typical setup of having the event base and event IDs declared in a header file, and having the definitions in a source file. Declaration of the event base makes use of the macro `ESP_EVENT_DECLARE_BASE()`, whilst the event IDs are declared as an `enum` (see `event_source.h`). The source file `main.c` holds the definition of the event base using the `ESP_EVENT_DEFINE_BASE()` macro.
Simply put, posting an event to a loop is the act of queueing its handlers for execution. For the default loop, this is done using the API `esp_event_post()`. The ability to pass event-specific data to the handler is also demonstrated.
This example demonstrates handler registration to the default event loop using `esp_event_handler_register` for (1) specific events, (2) **any** event under a certain base, and (3) **any** event. This also shows the possibility of registering multiple handlers to the same event as well as registering one handler to the same event multiple times.
Unregistering a handler is done using `esp_event_handler_unregister()`. Unregistering a handler means that it no longer executes even when the event it was previously registered to gets posted to the loop.
## How to use example
### Hardware Required
This example should be able to run on any commonly available ESP32 development board.
### Configure the project
```
idf.py menuconfig
```
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
(Replace PORT with the name of the serial port to use.)
The number of periodic timer expiries and loop iterations are limited. When the limit for the number of timer expiries is reached, the timer is stopped. When the limit for the number of iterations is reached, the task is deleted. In the case of the loop iteration, there is another limit: the number of iterations for when its handler will be unregistered.
The handlers are executed for the events that were posted in **(2)**. Note how `timer_started_handler()` is called twice on the same event post. This shows the ability to register a single event handler to a single event multiple times. Note also how `timer_started_handler_2()` is called on the same event post. This shows that multiple handlers can be registered to a single event.
In addition to the event-specific handlers `timer_started_handler()` (registered twice), `timer_started_handler_2()` and `task_iteration_handler()`, the `timer_any_handler()` and `all_event_handler()` are also executed.
The `timer_any_handler()` executes for **any** timer event. It can be seen executing for the timer expiry and timer stopped events in the subsequent parts of the log.
On the other hand, `all_event_handler()` executes for **any** event, hence why it executes for both ``TIMER_EVENTS:TIMER_EVENT_STARTED`` and ``TASK_EVENTS:TASK_ITERATION_EVENT``.
For both the timer and task events, notice that the handlers are executed in the same order they are registered in the code. This is a guarantee that the `esp_event` library provides.
At this point in the execution the handler `task_iteration_handler()` is unregistered, therefore it no longer executes when the event ``TASK_EVENTS:TASK_ITERATION_EVENT`` is posted.
When the periodic timer expiry limit is reached, the event ``TIMER_EVENTS:TIMER_EVENT_STOPPED`` is posted to the loop. The periodic timer is consequently deleted in the handler `timer_stopped_handler()`.