Overview
In this article:
This section shows you how to schedule messages on your Myriota device, so they can be sent to your Destination.
More examples of how you might schedule messages for different types of applications can be found in the Module Code Examples.
In a production environment, the Myriota Module requires its location and the current time in order to operate correctly. The Module will obtain this information from GNSS satellites at start up.
Sending Messages Tutorial
Prerequisites
- Make sure you have already installed the SDK, set up your Developer Toolkit, can program the Myriota Module and read output from its serial port.
- Make sure you have a Device Manager account and that you have registered your device and configured a Destination.
Setting Operational Modes
The Myriota Module's mode of operation is specified when the application is compiled by setting the environment variable SATELLITES. If this environment variable is not set at build time the Module is configured in Production mode and sends messages to the Myriota Network and requires a valid GNSS fix.
Follow the steps below to learn how the Myriota Module schedules messages and build your application to transmit in the various modes.
From Blinky to Hello, Space!
To start programming your application, start in the SDK root directory and copy an existing example from the SDK. This command will create a folder in the SDK root directory called hello_space and copy the blinky example files.
cp -r examples/blinky hello_space; cd hello_space
Open the Makefile in the hello_space folder and replace the line
PROGRAM_NAME=blinky
with the line
PROGRAM_NAME=hello_space
and replace the line
ROOTDIR ?= $(abspath ../..)
with the line (this changes the root directory path for the hello_space application as we have not created it within the examples directory)
ROOTDIR ?= $(abspath ..)
Give the Myriota Module a job
When the Myriota Module first starts the AppInit() function is called. This function can be implemented to initialise the application. Open up the main.c file in the hello_space folder and replace the contents with:
#include "myriota_user_api.h"
void AppInit() {
printf("Hello, Space!\n");
}
Build Your Application
Build this application and program it into the Myriota Module.
cd hello_space; make clean; make updater.py -u hello_space.bin -s -l
This builds a hello_space.bin binary that will transmit to the Myriota Network. The output from the Module's serial port will be the string "Hello, Space!" printed once at startup.
Schedule Jobs
The Myriota Module is given jobs using the ScheduleJob() function. The arguments of ScheduleJob() are a function and the time at which the function should run. The function should take no arguments and return a time_t. We call such functions jobs in what follows. All jobs, including system and user jobs, are scheduled in the order of their time to run. Jobs won't be preempted. Let's create a simple hello world type job:
#include "myriota_user_api.h"
time_t HelloSpace() {
printf("Hello, Space!\n");
return SecondsFromNow(5);
}
void AppInit(){
ScheduleJob(HelloSpace, ASAP());
}This outputs the string "Hello, Space!" every 5 seconds. The time_t returned from a job is the timestamp at which it will next run.
Schedule Messages
The ScheduleMessage() function can be used to schedule messages for transmission. Let's modify the example code:
#include "myriota_user_api.h"
time_t HelloSpace(){
static uint16_t sequence_number;
const int message_len = 60;
char message[message_len] = {0};
sprintf(message, "%04d Hello, Space! This is a message from your Myriota device.", sequence_number++);
const int id = ScheduleMessage((uint8_t *)message,sizeof(message));
if (id >= 0) {
printf("Successfully scheduled message of %d bytes with ID=%d\n", message_len, id);
} else {
printf("Failed to schedule message of %d bytes\n", msg_len);
}
return HoursFromNow(8);
}
void AppInit() { ScheduleJob(HelloSpace, ASAP()); }The ScheduleMessage() function takes two arguments: a pointer to the message to be transmitted, and the number of bytes to transmit. The function returns a message ID (>=0) when the message was successfully scheduled, or <0 on failure. The maximum message size that can be transmitted is dynamically determined by MessageBytesFree().
MessageBytesFree() reflects the available space for messages. It is updated each time a new message is added with ScheduleMessage(), or when the transmission of a message is complete. As of SDK 2.1.0, this API supports transmission of messages larger than the previous 20-byte limit, now offering messages from 20 to 1,500 bytes of user payload.
Additionally, MessageSlotsFree() reflects the number of free slots available in the scheduling queue. This indicates how many more messages can be scheduled for transmission before one of the messages in the queue is overwritten.
In the example above, we have programmed the HelloSpace job to run every 8 hours to replicate a real world application scheduling 3 messages per day. The ScheduleMessage() function pushes each message to the Module queue.
When using the Myriota Network, the message will be transmitted when a satellite is overhead. The satellite passes can be checked from Access Times in Device Manager.
ScheduleMessage() returns an ID for the message if it’s successfully scheduled. Message IDs are sequential unsigned 16-bit integers and start at zero. IDs are guaranteed to be unique across messages that are in the queue at any given time. However, note that the message IDs wrap after 65535.
Message Destinations
Messages sent via the Myriota Network will be received at the device's assigned Destination(s). Depending upon the time and your location, you may need to wait to receive messages sent via satellite (see Message Latency for more information)
