SigFox downlink is now available since the Telecom Design SDK 5. This allow to send a message to your SigFox device from the network. You have a 4 message a day limitation.
This post will explain how to configure and use SigFox downlink
How it works
The Downstream messages are, in fact, frame acknowledgment. It means that to receive a message on the device, you have to send one indicating the Sigfox network you are expecting a ack.
This ack is a 8bytes message the network can send directly with predefined value like current time or any used defined fixed value. It can also be a dynamic message sent by your own backend.
The device is sending a message with ack flag activated and then turn into receive mode during 25 seconds, looking for the network acknowledgment. This one received it will go back sleeping. Between the end of the send and the begin or the receive you have about 15 seconds sleep.
Step 1 – configure your device group for downlink
The first step is to have a sigfox account configured to accept downlink, for this you have to contact your sigfox support. Once done, you can configure a device group to support downlink.
You have two type of Downlink
- Direct is automatically sent by sigfox network if you fill the downlink data field
With a such configuration each time a frame is send with a requested ack, the 8 bytes message containing 32b time + 2 bytes RSSI + 0000 will be sent back to the device.
This could be, as an example, an easy way to get current time on startup and manage a RTC
- The second mode is a callback based acknowledgment ; in this mode your backend server will return the value to send back to the device. To configure it, just change the Downlink mode from DIRECT to CALLBACK
Then you have to setup your callback, for this you can choose BIDIR mode, then you will have two new parameters you can add to the URL : ack indicating if an ack is requiered and longPolling (not documented). Basically we are expecting to get ack to know what to do on backend side
The last step is to link this callback with the Acknowledge source, this is done by clicking on the expected callback source.
In the next steps, I will describe what to do to manage a callback acknowledgment
Step 2 – code your device
The Telecom Design SDK provides a complete example to manage bidirectional messages ; take a look to sigfox_downlink in the RF_Example list.
First you need to configure a callback for the downlink messages
// Register down-link callback function TD_SIGFOX_DOWNLINK_SetUserCallback(downlink_callback);
This callback look like this :
static int downlink_callback(uint8_t *rx_frame, uint8_t length) { if (rx_frame == 0) { // rx_frame == 0 when the receiving process is ending // it goes here even if you have receive a frame previously // or if the reception windows is finished return 1; } else { if (length == 0) { // You are in this step when the reception starts // it will be only once return 1; } else { // You are in this step when a ack is received // the message is in the rx_frame table return 1; } } }
To send a message indicating you expect an ack from the network you have to use the following function :
TD_SIGFOX_SendV1(MODE_FRAME, false, message, 12, 2, true, false);
Only the TD_SIGFOX_SendV1 allow you to indicate the ack status, here in red.
Then you need to call the DownLink Process in the user loop to make it works
void TD_USER_Loop(void) { // Process down-link events TD_SIGFOX_DOWNLINK_Process(); }
You can easily identify, in the sigfox backend, what are the messages requesting a ack.
The message, once sent to the SigFox network will be displayed with bi directional arrows indicating the status of the downlink message like in the picture below :
I do not know if it is a bug or not but the callback arrow is always green, even if you reject to answer to the ack. I assume it could be gray in that case to get a better visibility on what are the callback answered or not. If you move your mouse on the arrow you will get a different message “acked” when acked and “no answer” when not acked.
The arrow is RED if you respond with a malformed message ; arrow is yellow when the message has been received from your backend server and is pending to be transfered back to the device.
Step 3 – setup your web server backend
The backend server will receive a new parameter : ack ; the value will be “false” or “true” ; when true an acknowledgment is expected.
Then you have two choices :
- You can refuse to respond to the ack, for this you have two ways
The first one is to respond with a HTTP 204 (no Content) ; this can be done in php simply executing
header("HTTP/1.0 204 No Content");
The second way is to use the standard json way indicating you do not want to ack. For this you can use something like this :
<?php $_id = $_GET["id"]; $_time = $_GET["time"]; $_ack = $_GET["ack"]; $_data = $_GET["data"]; if ( $_ack == "true" ) { echo "{"; echo "\"". $_id ."\" : { \"noData\" : true }"; echo "}"; } ?>
- You can answer to the acknowledgment by a 8 byte message like this
<?php $_id = $_GET["id"]; $_time = $_GET["time"]; $_ack = $_GET["ack"]; $_data = $_GET["data"]; if ( $_ack == "true" ) { echo "{"; echo "\"". $_id ."\" : { \"downlinkData\" : \"0102030405060708\" }"; echo "}"; } header("HTTP/1.0 200 OK"); header("Content-Type : application/json"); ?>
What about battery consumption
During the RX period, the device is consuming 15mA until the message is received, this has to be added to the device consumption and it reduce the battery life if you are expecting potential acknowledgment on every message. If no ack is sent the system will listen for 25 seconds. If an ack is sent, the device will transmit again and consume an extra 45mA during less than a second.
Downlink message
The number of message in downlink depends on your contract, it can be up to 4 on platinum contract. It seems (but it have to be verified) that you can send more than that but it will be transferred on best effort – meaning you have no insurance it will be transmitted or not and no and no feedback on transmission or not.
Good explanation.
The downlink message received by module is automatically ACKed with a service status message, in this case without voltage and temperature.
I was worried about asymmetrical link budget, and it is true. Uplink budget is little bigger than downlink budget with today’s modems (TD, Telit). You need a high gain antenna and a LNA+SAW Filter to have better sensibility. Axsem modems have better sensibility and consumption.
Hi thanks for all the updates on TD12xx chips and Sigfox. I’m trying to experiment but not yet able to get access to the Sigfox backend. Got my Base64 encoded token, now trying to get the PAC serial numbers with https://sensor.insgroup.fr/iot/developers/pacs.csv. Any pointers for further reading?
Not sure to understand your question. To transfer a device from TD to Sigfox, I know there is a way but I do no know the process.
If you are looking for some other sigfox reading, use the tag cloud or search box on the disk91 website, you will find some.
Hi thanks. Just trying to get a password for the sigfox backend in order to get for example the panels that you have copied in in the post above. For this you need to “download” the PAC serial numbers. I’m able to log on to Telecom Design Developer portal no problem but I don’t see any activity from my registered modules and I’m not able to get the PAC numbers downloaded that I need to email to Sigfox in order to get access to their backend. Clearer? I also emailed Sigfox.
The right way is to contact sigfox to create an account take a look to the website, you should find the right contact email.
That’s fine.
Does we know exactly how Sigfox has secured the exchanges between devices, operator and backoffice?
Semtech has begun to make it clear but that still claims some effort right now.
What’s about SigFox?
db
I think you have to sign a NDA with sigfox to get a such information. By the way, it is secured better than LoRa for the following reasons : emission is made on 3 different frequencies changing every frame and following a predictive algorithm to ensure sender identity and reduce the capability of creating noise around. Sequence number and encryption to avoid message repetition ; stuff like that. LoRa is encrypting also but device always use 1 network attributed frequency.
Hi,
Excellent tuto 🙂
I was wondering if downlink frames have a built-in CRC or if this has to be managed in an applicative way ?
Thank you.
As much as I know, CRC kind of stuff is managed by sigfox protocol so you shoud assume your received message is valid.
Hello,
Are you sure the downlink message is an acknowledgement? I am a little bit confused because when I look at the downlink timing diagram I found on th web for Sigfox, there is in fact a downlink message sent by the base station and after some milliseconds an acknowledgement sent from the module (called an OOB frame)?
Is there actually a double acknowledgement from both sides?
Thank you in advance for clarifying this
If you get a downlink message it means your message has been send and basically we can call it an ack. It is a functional point of view as in LPWAN there is basically no ack as you can have some in TCP protocol. It is one of the use of a downlink. Have in mind in LPWAN everything is slow… time between two transmissions is minutes. at this scale 30 second for an ack is an acceptable roundtrip.
Thank you for replying Paul.
In deed from the functional point of view that is an ACK, but from the application point of view, I was wondering if the downlink frame contains some network data queried be the sigfox device.
The downlink work that way :
1 – your device send a message with a downlink expected flag.
2 – your device start to be in reception mode for 30 seconds
3 – your backend receive the message and compute the downlink value to send back (here is an advantage of the delay you have to answer : your backend can react on received message). Your backend respond with this value
4 – sigfox send the value to your device
5 – your device get the value and send back a ack message to sigfox network (this message is not pushed to your backend in the normal way : you receive it in the service callback). This part is included in the sigfox library so you do not have to manage this.
6 – end of the communication
With this protocol you can be sure that a message has been received by the device.
Alright then, I got it 🙂
Thank’s a lot for your time and explanations.
Cheers !
If My device sent the downlink message, but I don’t send anything from backend to my device, this count 1 of the 4 downlink message of the contract? Or just if i send something from bakcend(server) to the device it count 1 downlink message ??
The downlink is count only when you request the backend to send data to your device. If you have nothing to receive this is not counting.
Hey Paul,
First of all, thanks for the tutorials. They’re surely a great way to start tinkering and learn the principles of how Sigfox work.
I’ve followed this tutorial but I can’t get the downlink to work. Mainly because my server acts up on the header(“Content-Type : application/json”); giving me a 500 Internal Server Error. If I remove that line everything is cool with the callback but the downlink message is not received.
I’ve tried my Uni’s IT support (it’s their server) but all they told me was to remove that line. And since they took a while to reply I’m hoping to get a quicker one here xD
Is there anyway to do this differently (still using PHP)?
Hi Rui, I had a similar error, I solve delete html labels in my script file (downlink.php), my file only contents php code; also I send HTTP/1.0 header, Content-Type: application/json and data in json format in this order
Bonjour,
JE me permet cette question en Français, mon anglais n’étant pas top.
J’ai du mal à comprendre la différence entre DIRECT et CALLBACK
DIRECT permet il de stocker le downlink sur le backend Sigfox ? et si non, y a t’il une possibilité de le faire pour les objets pour lesquels ont souhaite pas d’uplink sur l’application ?
DIRECT means the downlink value is specified in the sigfox backend and always the same value. CALLBACK means the downlink value is given by the backend as a result of the callback. This way you can dynamically set your downlink value.
It is not possible to have a downlink w/o uplink. I recommend to check my video on downlink on youtube (in french) – https://www.youtube.com/watch?v=N0tEAvCV6J8
Thank you, it’s clear now