Skip to main content

Event-driven Programming

Most of the firmware uses this type of programming, it works by calling events each time some event occurs on some module or tag.

For example, you can set up an event that will be called each time that something happens on a Button Module and in this event handler, you can check specifically what happened and then do some action based on this.


This type of programming the firmware slightly differs from the one described in Task Scheduler chapter. Although the events are sometimes planned by the scheduler.

Example of Event-Driven Programming

You need to set the event handler, which is a specific function that will be called when some event occurs.

The functions must have a specific signature for every module and tag, you can see them in the examples on GitHub or in the [How To: chapters] in this section.


In the first example, there is a function called every time some event occurs on a Button Module.

The Button Module is specific because you don't have to set the update interval like with most modules. After all, the button can be pressed at any time.

Button Event Handler Code Example

#include <application.h>// This function dispatches button eventsvoid button_event_handler(twr_button_t *self, twr_button_event_t event, void *event_param){    if (event == TWR_BUTTON_EVENT_CLICK)    {        // Pulse LED for 100 milliseconds        twr_led_pulse(&led, 100);        // Increment press count        button_click_count++;        twr_log_info("APP: Publish button press count = %u", button_click_count);        // Publish button message on radio        twr_radio_pub_push_button(&button_click_count);    }    else if (event == TWR_BUTTON_EVENT_HOLD)    {        // Pulse LED for 250 milliseconds        twr_led_pulse(&led, 250);        // Increment hold count        button_hold_count++;        twr_log_info("APP: Publish button hold count = %u", button_hold_count);        // Publish message on radio        twr_radio_pub_event_count(TWR_RADIO_PUB_EVENT_HOLD_BUTTON, &button_hold_count);    }}// Button instancetwr_button_t button;void application_init(void){    // Initialize button    twr_button_init(&button, TWR_GPIO_BUTTON, TWR_GPIO_PULL_DOWN, false);    twr_button_set_event_handler(&button, button_event_handler, NULL);}


In the second example, there is a function called every time an update occurs on the Temperature Sensor integrated into Core Module. The update interval is set for 5 seconds (5 * 1000 milliseconds).

Contrary to the previous example you have to set the update interval as well as the event handler, this interval will make it so the event handler will be called periodically.

Temperature Sensor Event Handler Code Example

#include <application.h>#define TMP112_UPDATE_INTERVAL (5 * 1000)void tmp112_event_handler(twr_tmp112_t *self, twr_tmp112_event_t event, void *event_param){    float value;    if (event != TWR_TMP112_EVENT_ERROR)    {        return;    }    else if(event == TWR_TMP112_EVENT_UPDATE)    {        if (twr_tmp112_get_temperature_celsius(self, &value))        {            twr_radio_pub_temperature(TWR_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_ALTERNATE, &value);        }    }}void application_init(void){    // Initialize TMP112    twr_tmp112_init(&temperature, TWR_I2C_I2C0, 0x49);    twr_tmp112_set_event_handler(&temperature, tmp112_event_handler, &temperature_event_param);    twr_tmp112_set_update_interval(&temperature, TMP112_UPDATE_INTERVAL);}