A timer provides a way to perform a delayed action or a periodic action with user specified time. The timer waits until a certain time interval has elapsed and then fires executing user defnied function called handler. The use of timers are handled by functions in sm_timers.h
library.
To get started with timers you will need :
Take Smablo development board from your Smablo Development kit and place CPU on the described connector like in the pictures and video below:
{.force-inline}
{.force-inline}
When you’ve done connecting Shield you can connect Smablo Development board to your computer with USB cable.
Minimal code will briefly show you how to use timers. This example uses timer to update counter
variable every 1 second.
//1
#include "nrf_log.h"
#include "sm_timer.h"
#include "app_error.h"
//2
//timer definition
SM_TIMER_DEF(my_timer);
//helper variable
static uint16_t counter = 0;
//5
//user defibned handler
static void timer_handler(void * p_context)
{
counter++;
//show counter value on screen
NRF_LOG_RAW_INFO("Counter value = %d \n\r", counter);
}
void timer_demo(void)
{
//3
//create my_timer timer to repeatedly call timer_handler handler function
ret_code_t err_code = sm_timer_create(&my_timer, SM_TIMER_MODE_REPEATED, timer_handler );
APP_ERROR_CHECK(err_code);
//4
//Start timer with 1000ms interval
err_code = sm_timer_start(my_timer, SM_TIMER_TICKS(1000), NULL);
APP_ERROR_CHECK(err_code);
}
In point 1 we including all the libraries we will use in this project:
#include "nrf_log.h"
contains macros that we will use to print values on screen for more info see log marcos#include "sm_timer.h"
contains all the functions needed to use the timers #include "app_error.h"
is libary that will help us to check for errorsIn point 2 to use timer we need to create its definition first. We can do that with SM_TIMER_DEF
macro, in our case SM_TIMER_DEF(my_timer);
results in new my_timer
definition.
In point 3 we create the the my_timer
from its definition createrd in previous point. To create the timer we use sm_timer_create
function that takes 3 parameters:
sm_timer_mode_t
enum :
///timer mode
typedef enum
{
SM_TIMER_MODE_SINGLE_SHOT, ///< The timer will expire only once
SM_TIMER_MODE_REPEATED ///< The timer will restart each time it expires
} sm_timer_mode_t;
We can choose between SM_TIMER_MODE_SINGLE_SHOT
that will fire the timer handler only once and SM_TIMER_MODE_REPEATED
that will fire timer handler repeatedly with time defined in sm_timer_start
function.
timer_handler
In point 4 we are starting our timer with sm_timer_start
function, from this moment our timer will start counting. To start the timer function needs 3 parameters:
my_timer
SM_TIMER_TICKS
marco. This macro sets the time in ms so to have the call every 1 second we need to set the macro to SM_TIMER_TICKS(1000)
.NULL
In point 5 we have our timer handler function which will execute every 1 s, update the counter
variable and print its value on screen using log marcos
sm_timers
library referencesm_timer_init
Prototype:
ret_code_t sm_timer_init(void);
Function is used to initialize the timers. You don't need to use this function because it is already called upon system initialization. Function returns ret_code_t
value which indicates success or failure of an API procedure. In case of failure, a comprehensive error code indicating cause or reason for failure is provided.
sm_timer_create
Prototype:
ret_code_t sm_timer_create(sm_timer_id_t const * p_timer_id, sm_timer_mode_t mode, sm_timer_timeout_handler_t timeout_handler);
Function is used for creating the timer from definition. Function returns ret_code_t
value which indicates success or failure of an API procedure. In case of failure, a comprehensive error code indicating cause or reason for failure is provided. For this function the return error codes are following:
NRF_SUCCESS
if the timer was successfully created.NRF_ERROR_INVALID_PARAM
if a parameter was invalid.NRF_ERROR_INVALID_STATE
if the application timer module has not been initialized or the timer is running.Function takes 3 paramters:
p_timer_id
type sm_timer_id_t
which is pointer to the ID of the timer which we want to create. The timer definition should be created with use of SM_TIMER_DEF
macro.mode
type sm_timer_mode_t
///timer mode
typedef enum
{
SM_TIMER_MODE_SINGLE_SHOT, ///< The timer will expire only once
SM_TIMER_MODE_REPEATED ///< The timer will restart each time it expires
} sm_timer_mode_t;
which timer operation mode. We can choose between SM_TIMER_MODE_SINGLE_SHOT
that will fire the timer handler only once and SM_TIMER_MODE_REPEATED
that will fire timer handler repeatedly with time defined in sm_timer_start
function.
timeout_handler
type sm_timer_timeout_handler_t
pointer to handler function that is user defined function that will be called after timer timeout.
The use of this function was shown in Minimal code chaptersm_timer_start
Prototype:
ret_code_t sm_timer_start(sm_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
Function is used for starting the timer. After executing this function the timer start counting to execite timer handler defined in sm_timer_create
function. Function returns ret_code_t
value which indicates success or failure of an API procedure. In case of failure, a comprehensive error code indicating cause or reason for failure is provided. For this function the return error codes are following:
NRF_SUCCESS
if the timer was successfully started.NRF_ERROR_INVALID_PARAM
if a parameter was invalid.NRF_ERROR_INVALID_STATE
if the application timer module has not been initialized or the timer has not been created.NRF_ERROR_NO_MEM
if the timer operations queue was full.
Function takes 3 parameters:
timer_id
type sm_timer_id_t
the ID of the timer we want to start. The timer definition should be created with use of SM_TIMER_DEF
macro.timeout_ticks
type uint32_t
which is timer timeout ticks and specifies how many ticks from now it shall time out and execute the timer handler. For your convenience SM_TIMER_TICKS
macro was created that will convert the time in ms you want to the timer ticks. For example if we wanted 1 second time we will type SM_TIMER_TICKS(1000);
* p_context
type void
is the general purpose pointer that is passed to the timeout handler. Can be NULL
if we don't want to use it.The use of this function was shown in Minimal code chapter.
sm_timer_stop
Prototype:
ret_code_t sm_timer_stop(sm_timer_id_t timer_id);
Function is used for stopping the specified timer.Function returns ret_code_t
value which indicates success or failure of an API procedure. In case of failure, a comprehensive error code indicating cause or reason for failure is provided. For this function the return error codes are following:
NRF_SUCCESS
if the timer was successfully stopped.NRF_ERROR_INVALID_PARAM
if a parameter was invalid.NRF_ERROR_INVALID_STATE
if the application timer module has not been initialized or the timer has not been created.NRF_ERROR_NO_MEM
if the timer operations queue was full.Function takes one parameter timer_id
type sm_timer_id_t
which is the timer ID we want to stop.
The example below shows how to use sm_timer_stop
function. Example will execute timer_handler
five times with my_timer
and after the sm_timer_stop
will be called and the timer will be stopped.
#include "nrf_log.h"
#include "sm_timer.h"
#include "app_error.h"
//timer definition
SM_TIMER_DEF(my_timer);
//helper value
static uint16_t counter = 0;
//user defned handler
static void timer_handler(void * p_context)
{
if (counter >= 5 )
{
ret_code_t err_code = sm_timer_stop(my_timer );
APP_ERROR_CHECK(err_code);
return;
}
counter++;
NRF_LOG_RAW_INFO("Counter value = %d \n\r", counter);
}
void timer_demo(void)
{
//create my_timer timer to repeatedly call timer_handler handler function
ret_code_t err_code = sm_timer_create(&my_timer, SM_TIMER_MODE_REPEATED, timer_handler );
APP_ERROR_CHECK(err_code);
//Start timer with 1000ms interval
err_code = sm_timer_start(my_timer, SM_TIMER_TICKS(1000), NULL);
APP_ERROR_CHECK(err_code);
}
sm_timer_stop_all
Prototype:
ret_code_t sm_timer_stop_all(void);
Function is used for stopping all the timers. Function returns ret_code_t
value which indicates success or failure of an API procedure. In case of failure, a comprehensive error code indicating cause or reason for failure is provided. For this function the return error codes are following:
Function use is similar to sm_timer_stop
function. The difference is that sm_timer_stop_all
will stop all timers.