iotexpresslink2  2.1.0.0
Main Page

IoT ExpressLink 2 click

IoT ExpressLink 2 Click is a compact add-on board that allows users to connect to IoT ExpressLink services easily and securely interact with cloud applications and other services. This board features the SARA-R510AWS, an LTE-M AWS IoT EsxpressLink module from u-blox. It supports a comprehensive set of 3GPP Rel. 14 features that are relevant for IoT applications, like improvements to power consumption, coverage, data rate, mobility, and positioning. They are 5G-ready, meaning customers will be able to (software) upgrade their deployed devices once 5G LTE has been fully rolled out by mobile operators, greatly improving end-product scalability and lifetime.

click Product page


Click library

  • Author : Stefan Filipovic
  • Date : Sep 2023.
  • Type : UART type

Software Support

We provide a library for the IoT ExpressLink 2 Click as well as a demo application (example), developed using MikroElektronika compilers. The demo can run on all the main MikroElektronika development boards.

Package can be downloaded/installed directly from NECTO Studio Package Manager(recommended way), downloaded from our LibStock™ or found on Mikroe github account.

Library Description

This library contains API for IoT ExpressLink 2 Click driver.

Standard key functions :

Example key functions :

Example Description

This example demonstrates the use of IoT ExpressLink 2 click board by connecting

to the selected AWS account's data endpoint and showcasing the messaging topic model through sending and receiving messages to/from AWS IoT console.

The demo application is composed of two sections :

Application Init

Initializes the driver and logger, powers up the device, reads and displays

the vendor model, thing name, and the PEM certificate of the device. It then sets the SIM APN and device endpoint, and attempts to connect to AWS network. Finally, it configures the topic name and number and subscribes to it.

void application_init ( void )
{
log_cfg_t log_cfg;
iotexpresslink2_cfg_t iotexpresslink2_cfg;
LOG_MAP_USB_UART( log_cfg );
log_init( &logger, &log_cfg );
log_info( &logger, " Application Init " );
// Click initialization.
iotexpresslink2_cfg_setup( &iotexpresslink2_cfg );
IOTEXPRESSLINK2_MAP_MIKROBUS( iotexpresslink2_cfg, MIKROBUS_1 );
if ( UART_ERROR == iotexpresslink2_init( &iotexpresslink2, &iotexpresslink2_cfg ) )
{
log_error( &logger, " Communication init." );
for ( ; ; );
}
log_printf( &logger, "Power up device\r\n\n" );
iotexpresslink2_power_on ( &iotexpresslink2 );
log_printf( &logger, "Get vendor model\r\n" );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_CONF_CHECK );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
strcat ( app_buf, IOTEXPRESSLINK2_CONF_KEY_ABOUT );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_printf( &logger, "Get thing name\r\n" );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_CONF_CHECK );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_printf( &logger, "Get certificate pem\r\n" );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_CONF_CHECK );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_printf( &logger, "Set SIM APN to: %s\r\n", ( char * ) SIM_APN );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_CONF );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
strcat ( app_buf, IOTEXPRESSLINK2_CONF_KEY_APN );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SIGN_EQUAL );
strcat ( app_buf, SIM_APN );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_printf( &logger, "Set device endpoint to: %s\r\n", ( char * ) DEVICE_ENDPOINT );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_CONF );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
strcat ( app_buf, IOTEXPRESSLINK2_CONF_KEY_ENDPOINT );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SIGN_EQUAL );
strcat ( app_buf, DEVICE_ENDPOINT );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_printf( &logger, "Trying to connect...\r\n" );
log_printf( &logger, "This may take up to 15min for the initial connect.\r\n" );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_CONNECT_TIMEOUT ) )
{
log_printf( &logger, "\r\nUNABLE TO CONNECT\r\n" );
log_printf( &logger, "Make sure that the SIM card is inserted in the board, \r\n" );
log_printf( &logger, "an antenna is connected, and the module is within range \r\n" );
log_printf( &logger, "of a cellular network that provides LTE-M coverage.\r\n" );
log_printf( &logger, "Double check that the device registration procedure have been \r\n" );
log_printf( &logger, "correctly followed. If CONNECT worked in the past for this \r\n" );
log_printf( &logger, "device, it may be that the cellular network has decided \r\n" );
log_printf( &logger, "to refuse service for a \"guard time\" (e.g. 1 hour) because \r\n" );
log_printf( &logger, "the device has connected and disconnected more than a handful \r\n" );
log_printf( &logger, "of times in quick succession. The only way to avoid this is \r\n" );
log_printf( &logger, "avoiding many connections/disconnections. \r\n" );
for ( ; ; );
}
log_printf( &logger, "Set topic %s to: %s\r\n", ( char * ) TOPIC_NUM, ( char * ) TOPIC_NAME );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_CONF );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
strcat ( app_buf, IOTEXPRESSLINK2_CONF_KEY_TOPIC );
strcat ( app_buf, TOPIC_NUM );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SIGN_EQUAL );
strcat ( app_buf, TOPIC_NAME );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_printf( &logger, "Subscribe to topic %s\r\n", ( char * ) TOPIC_NUM );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_SUBSCRIBE );
strcat ( app_buf, TOPIC_NUM );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
log_info( &logger, " Application Task " );
}

Application Task

Sends a desired message on the configured topic and retrieves the next two pending

messages from the same topic approximately every 10 seconds. The sent message is also added to the receive queue because the same topic is used for both sending and receiving.

void application_task ( void )
{
// Send message on topic
log_printf( &logger, "Send message on topic: %s\r\n", ( char * ) TOPIC_NAME );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_SEND );
strcat ( app_buf, TOPIC_NUM );
strcat ( app_buf, IOTEXPRESSLINK2_CMD_SEPARATOR );
strcat ( app_buf, TEXT_MESSAGE );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
Delay_ms ( 1000 );
// Retrieve the next message received on topic in the order of arrival.
log_printf( &logger, "Request next message pending on topic: %s\r\n", ( char * ) TOPIC_NAME );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_GET );
strcat ( app_buf, TOPIC_NUM );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
Delay_ms ( 1000 );
// Retrieve the next message received on topic in the order of arrival.
log_printf( &logger, "Request next message pending on topic: %s\r\n", ( char * ) TOPIC_NAME );
strcpy ( app_buf, IOTEXPRESSLINK2_CMD_GET );
strcat ( app_buf, TOPIC_NUM );
iotexpresslink2_send_cmd ( &iotexpresslink2, app_buf );
iotexpresslink2_read_response ( &iotexpresslink2, IOTEXPRESSLINK2_NORMAL_TIMEOUT );
Delay_ms ( 8000 );
}

Note

Steps for the very first connection attempt:

  1. During the initial connection attempt, the device responds with: "ERR14 UNABLE TO CONNECT Certificate generation completed. Proceed to register device with AWS cloud and then try to connect again".
  2. At this point, you should restart the system and proceed with registering the device with the AWS Cloud using device's thing name and PEM certificate displayed in the logger. Detailed steps for registering device are described in the module's application development guide.
  3. After registering the device with your AWS account, restart the system, and it should now successfully connect to the cloud.

The full application code, and ready to use projects can be installed directly from NECTO Studio Package Manager(recommended way), downloaded from our LibStock™ or found on Mikroe github account.

Other Mikroe Libraries used in the example:

  • MikroSDK.Board
  • MikroSDK.Log
  • Click.IoTExpressLink2

Additional notes and informations

Depending on the development board you are using, you may need USB UART click, USB UART 2 Click or RS232 Click to connect to your PC, for development systems with no UART to USB interface available on the board. UART terminal is available in all MikroElektronika compilers.


IOTEXPRESSLINK2_CONF_KEY_TOPIC
#define IOTEXPRESSLINK2_CONF_KEY_TOPIC
Definition: iotexpresslink2.h:97
IOTEXPRESSLINK2_CONNECT_TIMEOUT
#define IOTEXPRESSLINK2_CONNECT_TIMEOUT
Definition: iotexpresslink2.h:111
iotexpresslink2_send_cmd
void iotexpresslink2_send_cmd(iotexpresslink2_t *ctx, uint8_t *cmd)
IoT ExpressLink 2 send cmd function.
iotexpresslink2_cfg_setup
void iotexpresslink2_cfg_setup(iotexpresslink2_cfg_t *cfg)
IoT ExpressLink 2 configuration object setup function.
TOPIC_NUM
#define TOPIC_NUM
Definition: main.c:55
IOTEXPRESSLINK2_CMD_SEND
#define IOTEXPRESSLINK2_CMD_SEND
Definition: iotexpresslink2.h:67
IOTEXPRESSLINK2_MAP_MIKROBUS
#define IOTEXPRESSLINK2_MAP_MIKROBUS(cfg, mikrobus)
MikroBUS pin mapping.
Definition: iotexpresslink2.h:146
IOTEXPRESSLINK2_CONF_KEY_ABOUT
#define IOTEXPRESSLINK2_CONF_KEY_ABOUT
IoT ExpressLink 2 config key parameters list.
Definition: iotexpresslink2.h:83
iotexpresslink2_init
err_t iotexpresslink2_init(iotexpresslink2_t *ctx, iotexpresslink2_cfg_t *cfg)
IoT ExpressLink 2 initialization function.
iotexpresslink2_generic_read
err_t iotexpresslink2_generic_read(iotexpresslink2_t *ctx, uint8_t *data_out, uint16_t len)
IoT ExpressLink 2 data reading function.
IOTEXPRESSLINK2_CMD_SIGN_EQUAL
#define IOTEXPRESSLINK2_CMD_SIGN_EQUAL
Definition: iotexpresslink2.h:77
IOTEXPRESSLINK2_OK
@ IOTEXPRESSLINK2_OK
Definition: iotexpresslink2.h:211
application_task
void application_task(void)
Definition: main.c:210
iotexpresslink2_power_on
void iotexpresslink2_power_on(iotexpresslink2_t *ctx)
IoT ExpressLink 2 power on function.
SIM_APN
#define SIM_APN
Definition: main.c:48
IOTEXPRESSLINK2_CMD_CONNECT
#define IOTEXPRESSLINK2_CMD_CONNECT
Definition: iotexpresslink2.h:60
IOTEXPRESSLINK2_CONF_KEY_APN
#define IOTEXPRESSLINK2_CONF_KEY_APN
Definition: iotexpresslink2.h:95
iotexpresslink2_cfg_t
IoT ExpressLink 2 Click configuration object.
Definition: iotexpresslink2.h:185
IOTEXPRESSLINK2_CONF_KEY_CERTIFICATE_PEM
#define IOTEXPRESSLINK2_CONF_KEY_CERTIFICATE_PEM
Definition: iotexpresslink2.h:88
TOPIC_NAME
#define TOPIC_NAME
Definition: main.c:56
IOTEXPRESSLINK2_NORMAL_TIMEOUT
#define IOTEXPRESSLINK2_NORMAL_TIMEOUT
Definition: iotexpresslink2.h:112
TEXT_MESSAGE
#define TEXT_MESSAGE
Definition: main.c:57
DEVICE_ENDPOINT
#define DEVICE_ENDPOINT
Definition: main.c:52
IOTEXPRESSLINK2_CMD_GET
#define IOTEXPRESSLINK2_CMD_GET
Definition: iotexpresslink2.h:68
IOTEXPRESSLINK2_CONF_KEY_ENDPOINT
#define IOTEXPRESSLINK2_CONF_KEY_ENDPOINT
Definition: iotexpresslink2.h:90
iotexpresslink2_t
IoT ExpressLink 2 Click context object.
Definition: iotexpresslink2.h:162
IOTEXPRESSLINK2_CMD_CONF
#define IOTEXPRESSLINK2_CMD_CONF
Definition: iotexpresslink2.h:71
IOTEXPRESSLINK2_CMD_CONF_CHECK
#define IOTEXPRESSLINK2_CMD_CONF_CHECK
Definition: iotexpresslink2.h:72
application_init
void application_init(void)
Definition: main.c:103
IOTEXPRESSLINK2_CMD_SEPARATOR
#define IOTEXPRESSLINK2_CMD_SEPARATOR
Definition: iotexpresslink2.h:76
IOTEXPRESSLINK2_CONF_KEY_THING_NAME
#define IOTEXPRESSLINK2_CONF_KEY_THING_NAME
Definition: iotexpresslink2.h:86
IOTEXPRESSLINK2_CMD_SUBSCRIBE
#define IOTEXPRESSLINK2_CMD_SUBSCRIBE
Definition: iotexpresslink2.h:69