Skip to main content
Associate II
January 9, 2025
Question

Issue with Receiving Downlink Data on STM32WL Device Using JSON Format in LoRaWAN

  • January 9, 2025
  • 3 replies
  • 1616 views

Hi everyone,

I am working on an STM32WL-based device and have successfully operated downlink in LoRaWAN communication when using the following JSON payload format:

 

 

{
"devEui": "0102030405060708",
"confirmed": true,
"fPort": 10,
"data": "ESIzRFU="
}

 

 

In this case, I sent a base64-encoded data string, and the downlink was successfully received by the device. Here's the relevant log output from the device:

 

 

 

[16:16:14:337] 1735817707s657:RX_C on freq 869525000 Hz at DR 0␍␊
[16:17:20:696] 1735817774s061:MAC rxDone␍␊
[16:17:40:846] +EVT:RX_C, PORT 10, DR 0, RSSI -32, SNR 5␍␊
[16:17:40:890] +EVT:12:1122334455␍␊

 

 

 

However, when I attempt to send the following JSON payload, where I pass individual parameters in the object field instead of a base64-encoded string, the payload is successfully sent from the server, but the STM32WL device only receives the fport value. The data and datasize  fields are both zero on the device.

 

 

{
"devEui": "0102030405060708",
"confirmed": true,
"fPort": 10,
"object": {
 "deviceId": 01020304AABBCCDD,
 "cmdType": 01,
 "cmdId": 01,
 "epochTime": 677FAA90
 }
}

 

 

Has anyone encountered a similar issue or can suggest how to resolve this?

Thanks in advance for your help!

Best regards,
Pratham

 

3 replies

Andrew Neil
Super User
January 9, 2025

@PrathamSalunkhe wrote:

I am working on an STM32WL-based device and have successfully operated downlink in LoRaWAN communication when using the following JSON payload format:


So where, exactly, are you specifying that JSON payload?

Are you sure that your JSON with an object field is valid for whatever system it is that you're using?

ie, what makes you think that the problem is with the STM32WL-based device - rather than elsewhere in the system?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate II
January 10, 2025

Hello @Andrew Neil 

Thank you for your response!

I’m using the LoRaWAN_AT_Slave example code, and after the device successfully joins the server, I change its class to CLASS C to receive downlinks.

When I send the JSON payload with base64-encoded data in the data field, it works fine.

Now I’d like to ask: Can I send a JSON payload with different parameters? For example, instead of sending a payload with the data field containing base64-encoded data (which the device successfully receives), I want to send a payload in JSON format like this:

 

{ 
 "devEui": "0102030405060708", 
 "confirmed": true, 
 "fPort": 10, 
 "object": { 
 "deviceId": "01020304AABBCCDD", 
 "cmdType": "01", 
 "cmdId": "01", 
 "epochTime": "677FAA90" 
 } 
} 

 

 
 

With the payload above, the device only receives the fport value, and both data and datasize are zero.

Is it possible to send JSON payloads with different parameters like this? Or do I need to modify the example code to handle such payloads?

I would appreciate further guidance on verifying whether the STM32WL-based device supports downlink payloads with nested JSON objects or if additional modifications are required in the firmware.

 

Best Regards,
Pratham

Andrew Neil
Super User
January 10, 2025

You didn't answer the question:

So where, exactly, are you specifying that JSON payload?

Are you sure that your JSON with an object field is valid for whatever system it is that you're using?

ie, what makes you think that the problem is with the STM32WL-based device - rather than elsewhere in the system?

 


@PrathamSalunkhe wrote:

Now I’d like to ask: Can I send a JSON payload with different parameters?


That would depend on whatever it is that you're using to send the data.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Andrew Neil
Super User
January 13, 2025

Duplicate here from @anupam1511 ?

are you working together?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate II
January 16, 2025

Thank you for your insights!

  • Application Server: I am using AWS IoT Core as the application server.
  • Network: I don’t receive detailed logs from the network, but I can verify on the gateway (RAK7289) that the downlink is received when sent from the server.

Regarding your point about the device only seeing the binary data:
Could you confirm if there is any JSON parsing function or downlink parsing functionality in the firmware library? After the downlink is received, the data seems to be stored in the following structure:

 

 

typedef struct LmHandlerAppData_s
{
 uint8_t Port;
 uint8_t BufferSize;
 uint8_t *Buffer;
} LmHandlerAppData_t;

 

 

 

Before the data gets stored in the buffer (in hexadecimal format), where is it being parsed? Specifically, how does the firmware handle and map JSON fields to binary data?

As for your query about duplicates: yes, @anupam1511  and I are colleagues, but we’re working on different projects. We’re both using LoRaWAN communication, which is why there’s some overlap in our discussions.

Looking forward to your guidance!

Andrew Neil
Super User
January 16, 2025

@PrathamSalunkhe wrote:
  • I can verify on the gateway (RAK7289) that the downlink is received when sent from the server.

And that's both in the case of using just 'data' and also in the case of using 'object' ?

But this still doesn't guarantee that the data is (correctly) passed-on by the Gateway.

 


@PrathamSalunkhe wrote:

Could you confirm if there is any JSON parsing function or downlink parsing functionality in the firmware library? 


I would think that unlikely in the extreme: JSON is grossly inefficient - which is completely at odds with a low-data protocol like LoRaWAN.

eg,

 

{
"devEui": "0102030405060708",
"confirmed": true,
"fPort": 10,
"data": "ESIzRFU="
}

 

takes 84 bytes for just 8 byes of payload!

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Visitor II
February 10, 2025

Hi @PrathamSalunkhe
I understand the issue you're facing. I'm also working on some projects related to Class C with the ChirpStack server. When I use the JSON data field for downlink, I have to convert the data from ASCII encoding to a byte array. ChirpStack provides a place to write code for the encode() function for downlink data, so I think you also need to find a similar place to configure the encode() function for JSON data to ensure the device receives the correct data when downlinking.
If you are using the AWS IoT Core application integrated with the TTN server, TTN provides a place where you can modify the decoder() or encoder() functions for the payload using JavaScript.

https://aws.amazon.com/blogs/iot/connect-your-devices-to-aws-iot-using-lorawan/

dkminh_0-1739155961555.png

 

 

// Encode encodes the given object into an array of bytes.
// - fPort contains the LoRaWAN fPort number
// - obj is an object, e.g. {"temperature": 22.5}
// - variables contains the device variables e.g. {"calibration": "3.5"} (both the key // value are of type string)
// The function must return an array of bytes, e.g. [225, 230, 255, 0]

function Encode(fPort, obj, variables) {
 var bytes = [];
 // Encode obj values
 var jsonString = JSON.stringify(obj); 
 // Encode the entire JSON string including quotes
 for (var i = 0; i < jsonString.length; i++) {
 bytes.push(jsonString.charCodeAt(i)); // ASCII value of each character
 }

 return bytes;
}