Callbacks

Callbacks

Supported callbacks:

Callback Case

Description

Callback Case

Description

IBUTTON_ID

RFID driver identification

GO_TO_SLEEP

Script will be terminated and module will go to sleep after executing this callback

CAN1

Received message via CAN1 BUS

CAN2

Received message via CAN2 BUS

TIMER1

Custom period timer

SMS

Received data via SMS

SOCKET_CLOSED

Socket was closed

SOCKET_DATA_RECEIVED

Received data via socket

SOCKET_SENT

Data was successfully sent via socket (confirmation)

ACCELEROMETER

Received data via accelerometer

MQTT_PUBLISH_PENDING

Module is about to publish new data to the telemetry server

MESSAGES_RECEIVED

Received message from other script

REMOTE_COMMAND

Remote command received

BT_FILTER_MATCH

Bluetooth scan callback when added scan filter matches with found device

BT_FILTER_MISMATCH

Bluetooth scan callback when added scan filter mismatches with found device or no filter was enabled

BT_NOTIFICATION_RX

Bluetooth GATT client callback when notification or indication from subscribed characteristic is received

BT_EVENT_RECEIVED

Received Bluetooth event

BT_GATT_SERVER_RX

Received data into a GATT server characteristic

IBUTTON_ID:

  • To utilize the IBUTTON_ID callback, it must first be initialized (line 36 in the example bellow).

  • Upon receiving the IBUTTON_ID callback and processing the ID values, it is crucial to reset the sensor values to ensure the callback can be received correctly the next time (lines 30 and 31 in the example bellow)

IBUTTON callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> new ibutton_low; new ibutton_high; forward public callback (event); public callback (event) { switch(event) { case IBUTTON_ID: { ibutton_parse(); } } return 0; } ibutton_parse() { ibutton_low = get_val(SENSOR_IBUTTON_ID, Bit64_low); // Read Ibutton_ID lowest 32bit from 64bit (0x00000000FFFFFFFF) ibutton_high = get_val(SENSOR_IBUTTON_ID, Bit64_high); // Read Ibutton_ID highest 32bit from 64bit (0xFFFFFFFF00000000) set_val(SENSOR_IBUTTON_ID, 0, Bit64_low); // Reset sensor value in order to get new ibutton value set_val(SENSOR_IBUTTON_ID, 0, Bit64_high); // Reset sensor value in order to get new ibutton value } main() { Init(IBUTTON_ID); while(1) { Delay(500); // 500ms delay } }

GO_TO_SLEEP:

  • This callback is called when the device is entering sleep mode.

  • When this callback is called, certain peripherals may already be in sleep mode. For instance, operations such as sending SMS or performing MQTT publishing (QoS) may not be possible.

  • This callback is intended to write some data to the sensors or peripherals before the device enters sleep mode.

  • Script will be terminated and module will go to sleep after executing this callback.

  • Upon wake up script will not continue from it’s last state, but start from beginning.

GO_TO_SLEEP callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> forward public callback (event); public callback (event) { switch(event) { case GO_TO_SLEEP: { device_sleep_cb(); } } return 0; } device_sleep_cb() { EEPROM(WRITE, 1, 0xAA); // Write 0xAA value to EEPROM, addres 1 } main() { while(1) { Delay(100); } }

CAN1/CAN2:

  • To utilize the CAN1 or CAN2 callback, respective CAN-BUS must first be initialized ((lines 29 and 32 in the example bellow). and #include <can> must be added (line 8 in the example bellow)..

  • Upon receiving CAN callback it must be read out using ReadCANmsg function. Otherwise the callback will be called indefinitely until the message is read.

CANX callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <can> forward public callback (event); public callback (event) { switch(event) { case CAN1: // CAN1 callback event { //Code in this location will be executed upon successful CAN filter match } case CAN2: // CAN1 callback event { //Code in this location will be executed upon successful CAN filter match } } return 0; } main() { Init(CAN1, NORMAL, 500000); CANconfig(CAN1 ,RESET_FILTER); // Reset all filters before setting new CANconfig(CAN1, ADD_MASK_EXT, 0x00FEE900, 0x00FFFF00); //Standard mask would look like so: CANconfig(CAN1, ADD_MASK_STD, 0xFEE, 0xFFF); Init(CAN2, NORMAL, 500000); CANconfig(CAN2, RESET_FILTER); // Reset all filters before setting new CANconfig(CAN2, ADD_MASK_EXT, 0x00FEE900, 0x00FFFF00); //Standard mask would look like so: CANconfig(CAN1, ADD_MASK_STD, 0xFEE, 0xFFF); while(1) { Delay(100); } }

TIMER1:

  • To utilize TIMER1 callback, it must first be initialized (line 24 in the example bellow).

  • Timer callback is called periodically. Timer period is defined by the user in the Init function.

  • Timer is called indefinitely until it’s de-initialized.

TIMER1 callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #define PERIOD_MS 50 forward public callback (event); public callback (event) { switch(event) { case TIMER1: { //Code in this location will be executed upon successful TIMER1 timeout } } } main() { Init(TIMER1, PERIOD_MS); while(1) { Delay(100); } }

SMS:

  • This callback does not require any initialization. Adding it to the switch case is enough to receive the callback.

  • Upon receiving SMS callback it must be read out using read_buf function. Otherwise the callback will be called indefinitely until the message is read.

SMS callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> forward public callback (event); public callback (event) { switch(event) { case SMS: { //Code in this location will be executed upon receiving SMS } } } main() { while(1) { Delay(100); } }

SOCKET CALLBACKS:

  • None of socket callbacks require any initialization. Adding it to the switch case is enough to receive the callback.

  • SOCKET_CLOSED callback is triggered when a socket that was previously created is closed either by remote device.

  • SOCKET_DATA_RECEIVED callback is triggered when new data is received through the socket.

  • SOCKET_SENT callback is triggered whenever user data sent confirmation is received.

SOCKET callbacks use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> forward public callback (event); public callback (event) { switch(event) { case SOCKET_CLOSED: { //Code in this location will be executed upon receiving closed socket event } case SOCKET_DATA_RECEIVED: { //Code in this location will be executed upon receiving data via socket } case SOCKET_SENT: { //Code in this location will be executed upon receiving data sent confirmation. } } } main() { while(1) { Delay(100); } }

ACCELEROMETER:

  • To utilize ACCELEROMETER callback, it must first be initialized (line 23 in the example bellow).

  • Callback is called every 10 ms (100 Hz).

  • Regardless of whether self-orientation is enabled or disabled, the callback will be called at the same interval as previously stated.

ACCELEROMETER callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> forward public callback (event); public callback (event) { switch(event) { case ACCELEROMETER: { //Code in this location will be executed every 100Hz } } } main() { Init(ACCELEROMETER, false); while(1) { Delay(100); } }

MQTT_PUBLISH_PENDING:

  • To utilize MQTT_PUBLISH_PENDING callback, it must first be initialized (line 23 in the example bellow).

  • The callback is triggered exclusively when the SENSOR_GNSS_COORDINATES (53248) is about to be published. Therefore, for this callback to be invoked, the user must either configure the publishing of SENSOR_GNSS_COORDINATES through the settings template or publish SENSOR_GNSS_COORDINATES via a script.

  • This callback is meant to be used for synchronizing sensors publishing with script.

MQTT_PUBLISH_PENDING callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> forward public callback (event); public callback (event) { switch(event) { case MQTT_PUBLISH_PENDING: { //Code in this location will be executed when SENSOR_GNSS_COORDINATES is about to be published } } } main() { Init(MQTT_PUBLISH_PENDING); while(1) { Delay(100); } }

MESSAGES_RECEIVED:

  • Message received callback does not require any initialization. Adding it to the switch case is enough to receive the callback.

  • The callback is triggered when message from other running script was sent to this script.

MESSAGES_RECEIVED callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> forward public callback (event); public callback (event) { switch(event) { case MESSAGES_RECEIVED: { //Code in this location will be executed when message from other script is received } } } main() { while(1) { Delay(100); } }

REMOTE_COMMAND:

  • To utilize REMOTE_COMMAND callback, it must first be initialized (line 23 in the example bellow).

  • The callback is triggered when command is sent via remote server. For more information about remote commands: MQTT communication protocol

REMOTE_COMMAND callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> forward public callback (event); public callback (event) { switch(event) { case REMOTE_COMMAND: { //Code in this location will be executed when command from remote server is received } } } main() { Init(REMOTE_COMMAND); while(1) { Delay(100); } }

BT_FILTER_MATCH/BT_FILTER_MISMATCH:

  • To utilize BT_FILTER_MATCH callback, scan module must be initialized, scan configured, callback enabled, filters added and scan started.

  • To utilize BT_FILTER_MISMATCH callback, scan module must be initialized, scan configured, callback enabled and scan started. For mismatch, scan filters are optional.

  • The callbacks triggered when the scan module finds desired device or finds any device that is not in the device filters.

  • Both callbacks can be enabled at the same time.

  • Both callbacks can be enabled and disabled on the fly.

BT_FILTER_MATCH callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> #include <bluetooth> forward public callback (event); new scan_parameters[.type, .options, .interval, .window, .timeout, .interval_coded, .window_coded]; new mac_addr_filter[] = [0xFF, 0x48, 0x80, 0x33, 0xE3, 0xA8]; public callback (event) { switch(event) { case BT_FILTER_MATCH: { // SCAN FILTER MATCH CALLBACK } case BT_FILTER_MISMATCH: { // SCAN FILTER MISMATCH CALLBACK } } return 0; } main() { scan_parameters[.type] = BT_SCAN_TYPE_ACTIVE; scan_parameters[.options] = BT_ADV_OPT_NONE; scan_parameters[.interval] = BT_SCAN_INTERVAL_FAST; scan_parameters[.window] = BT_SCAN_WINDOW_FAST; scan_parameters[.timeout] = 0; scan_parameters[.interval_coded] = 0; scan_parameters[.window_coded] = 0; bt_init(); bt_scan_init(scan_parameters); bt_scan_filter_add(BT_SCAN_FILTER_TYPE_ADDR_PUBLIC, mac_addr_filter, sizeof(mac_addr_filter)); bt_scan_filter_enable((BT_SCAN_FILTER_NAME | BT_SCAN_FILTER_ADDR), false); bt_scan_callback_enable(BT_FILTER_MATCH); bt_scan_start(); for(;;) { Delay(100); } }
BT_FILTER_MISMATCH callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> #include <bluetooth> forward public callback (event); new scan_parameters[.type, .options, .interval, .window, .timeout, .interval_coded, .window_coded]; public callback (event) { switch(event) { case BT_FILTER_MATCH: { // SCAN FILTER MATCH CALLBACK } case BT_FILTER_MISMATCH: { // SCAN FILTER MISMATCH CALLBACK } } return 0; } main() { scan_parameters[.type] = BT_SCAN_TYPE_ACTIVE; scan_parameters[.options] = BT_ADV_OPT_NONE; scan_parameters[.interval] = BT_SCAN_INTERVAL_FAST; scan_parameters[.window] = BT_SCAN_WINDOW_FAST; scan_parameters[.timeout] = 0; scan_parameters[.interval_coded] = 0; scan_parameters[.window_coded] = 0; bt_init(); bt_scan_init(scan_parameters); bt_scan_callback_enable(BT_FILTER_MISMATCH); bt_scan_start(); for(;;) { Delay(100); } }

BT_NOTIFICATION_RX:

  • To utilize BT_NOTIFICATION_RX callback, Bluetooth must be initialized, GATT client must be initialized, connected to GATT server and subscribed to characteristic.

  • The callback is triggered when notification or indication data is received from subscribed characteristic

BT_NOTIFICATION_RX callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> #include <bluetooth> #define FIRST_CONNECTION 0 #define SECOND_CONNECTION 1 new peer_mac_address[] = [0xFF, 0x48, 0x80, 0x33, 0xE3, 0xA8]; new chr_val_handle = 0x0F; new chr_val_ccc_handle = 0x10; new notification_size = 0; new notification_data[50]; forward public callback (event); public callback (event) { switch(event) { case BT_NOTIFICATION_RX: { notification_size = bt_notification_read(notification_data); } } return 0; } main() { bt_init(); bt_gatt_client_init(); while (bt_gatt_client_connect(FIRST_CONNECTION, BT_ADDR_RANDOM, peer_mac_address) != SCRIPT_OPERATION_SUCCESS) { Delay(100); } bt_gatt_client_subscribe(FIRST_CONNECTION, chr_val_handle, chr_val_ccc_handle, BT_GATT_CCC_NOTIFY); for(;;) { Delay(100); } }

BT_EVENT_RECEIVED:

BT_EVENT_RECEIVED callback use example
#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> #include <bluetooth> forward public callback(event); new bt_event = 0; public callback(event) { switch (event) { case BT_EVENT_RECEIVED: { bt_event_read(bt_event); } } return 0; } main() { bt_init(); /* Application specific BLE init code start */ /* Application specific BLE init code end */ for(;;) { if (bt_event == BT_EVENT_RESET) { /* BT reset code start */ /* BT reset code end */ } Delay(100); } }

BT_GATT_SERVER_RX:

  • To utilize BT_GATT_SERVER_RX callback, Bluetooth must be initialized, GATT server must be initialized, a service and characteristic with write property must be registered and server started.

  • The callback is triggered when data is received into the GATT characteristic.

  • bt_gatt_server_receivefunction is used to read the data. Click here for the function documentation and the data structure.

#include <io> #include <read> #include <float> #include <string> #include <core> #include <write> #include <define> #include <socket> #include <bluetooth> new service_uuid[UUID_LENGTH_128_BIT] = [0x08, 0x07, 0x06, 0x05, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB]; new chrc_uuid_1[UUID_LENGTH_128_BIT] = [0x05, 0x12, 0x96, 0x99, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB]; new chrc_uuid_2[UUID_LENGTH_128_BIT] = [0x05, 0x12, 0x96, 0x99, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB]; new chrc_handle_2 = 5; new gatt_rx_data[64]; forward public callback (event); public callback (event) { switch(event) { case BT_GATT_SERVER_RX: { new data_len = bt_gatt_server_receive(gatt_rx_data); if (gatt_rx_data[GATT_RX_HEADER_USER_REF_POS] == chrc_handle_2) { chrc_2_rx(data_len); } } } return 0; } chrc_2_rx(msg_len) { /* Handle characteristic write code start */ /* Handle characteristic write code end */ } main() { bt_init(); bt_gatt_server_init(); bt_gatt_service_create(service_uuid); bt_gatt_chrc_create(chrc_uuid_1, GATT_CHRC_PROP_WRITE, 0, 0); bt_gatt_chrc_create(chrc_uuid_2, GATT_CHRC_PROP_WRITE, 0, chrc_handle_2); for(;;) { Delay(100); } }