Rak7200 Payload Hex Setup (Helium)

Issue: Cant find a way to configure the sensor to send HEX format message with the GPS coordinates over to the server using the “at+send=lora:X:YYY” command.

My question is: Does is send the captured parameters over the payload automatically or do i have to set it up? If i need to set up, how do i set those? I GPS, accelerometer and gyro do report correctly on the sensor but i cant get to relate it to the console.

Setup:

RAK 7200 Tracker
OK Work Mode: LoRaWAN
Region: US915
Send_interval: 60s
Auto send status: true.
Send_interval work at sleep
Join_mode: OTAA
DevEui: 9ABB7EF724C08FD2
AppEui: F79B485F5CC913B9
AppKey: 3D98420BE3C5BD4E57A55597571F7F5A
Class: A
Joined Network:true
IsConfirm: confirm
AdrEnable: true
EnableRepeaterSupport: false
RX2_CHANNEL_FREQUENCY: 923300000, RX2_CHANNEL_DR:0
RX_WINDOW_DURATION: 3000ms
RECEIVE_DELAY_1: 1000ms
RECEIVE_DELAY_2: 2000ms
JOIN_ACCEPT_DELAY_1: 5000ms
JOIN_ACCEPT_DELAY_2: 6000ms
Current Datarate: 0
Primeval Datarate: 3
ChannelsTxPower: 5
UpLinkCounter: 3864
DownLinkCounter: 3766

Server: Helium Console + TTN DECODER for Helium Cargo Function

Details: Here the details of the decoder (tested from my rak7200 console and works(

// ttn application function to decode uplink data.
// Decode decodes an array of bytes into an object.
// - port contains the LoRaWAN fPort number
// - bytes is an array of bytes, e.g. [225, 230, 255, 0]
// The function must return an object, e.g. {“temperature”: 22.5}
function Decoder(bytes, port) {
var decoded = {};
var hexString=bin2HexStr(bytes);
return rakSensorDataDecode(hexString);
}

The 7200 has a fixed format that includes the GPS data:

https://doc.rakwireless.com/rak7200-lora-tracker/analyzing-the-data-from-rak7200

Your decoder function seems rather short, do you have all the code?

Hi Nick,

Yes i spend few more hours and i figured that the data is fixed and is sent straight from the sensor over to the network like that.

My problem now (im guessing) is that I am able to decode the payload but the order in which the payload is decoded or sent is not correct and the “Helium Cargo API” cant located the GPS. (displays GPS NOT FIX)

HOWEVER, if i take the HEX string tester from the decoder and i send it via the RAK Console with the at+send=lora:1:0188053797109D5900DC140802017A0768580673256D0267011D040214AF0371FFFFFFDDFC2E im able to get the data correctly.

Based on the Helium Dev Release Notes they point out that the payload has to be in the following order:

Total Payload:

12 Bytes without Battery Voltage
14 Bytes with Battery Voltage
Packed in the following order:

Order of Payload:

int32_t Latitude in Degrees
int32_t Longitude in Degrees
int16_t Elevation in Meters
int16_t Speed in mph
uint16_t Battery Voltage (Optional)

But the decoded payload comes in on the debuger like this:

 *"decoded": {*
*              "payload": {*
*                "altitude": "340.5m",*
*                "latitude": "13.3239°",*
*                "longitude": "-747.291°"*

Here is the whole function for the decoder i have set up:

*> // ttn application function to decode uplink data.*
*    > // Decode decodes an array of bytes into an object.*
*    > //  - port contains the LoRaWAN fPort number*
*    > //  - bytes is an array of bytes, e.g. [225, 230, 255, 0]*
*    > // The function must return an object*
*    > // for RAK, return {*
*    > //                     "DecodeDataHex": {} // RAK5205 sensor data in Hex format*
*    > //                     "DecodeDataObj": {} // RAK5205 sensor data object.*
*    > //                 }*
*    > // The function prototype cannot be modified.*
*    > function Decoder(bytes, port) {*
*    >   var decoded = {"DecodeDataHex": {}, "DecodeDataObj": {}};*
*    >   var hexString=bin2HexStr(bytes);*
*    >   decoded.DecodeDataHex = hexString;*
*    >   decoded.DecodeDataObj = rakSensorDataDecode(hexString);*
*    > *
*    >   return decoded;*
*    > }*
*    > *
*    > // convert array of bytes to hex string.*
*    > // e.g: 0188053797109D5900DC140802017A0768580673256D0267011D040214AF0371FFFFFFDDFC2E*
*    > function bin2HexStr(bytesArr) {*
*    >   var str = "";*
*    >   for(var i=0; i<bytesArr.length; i++) {*
*    >     var tmp = (bytesArr[i] & 0xff).toString(16);*
*    >     if(tmp.length == 1) {*
*    >       tmp = "0" + tmp;*
*    >     }*
*    >     str += tmp;*
*    >   }*
*    >   return str;*
*    > }*
*    > *
*    > // convert string to short integer*
*    > function parseShort(str, base) {*
*    >   var n = parseInt(str, base);*
*    >   return (n << 16) >> 16;*
*    > }*
*    > *
*    > // convert string to triple bytes integer*
*    > function parseTriple(str, base) {*
*    >   var n = parseInt(str, base);*
*    >   return (n << 8) >> 8;*
*    > }*
*    > *
*    > // decode Hex sensor string data to object*
*    > function rakSensorDataDecode(hexStr) {*
*    >   var str = hexStr;*
*    >   var myObj = {};*
*    >   var environment = {};*
*    >   var magnetometer = {};*
*    > *
*    >   while (str.length > 4) {*
*    >     var flag = parseInt(str.substring(0, 4), 16);*
*    >     switch (flag) {*
*    >       case 0x0768:// Humidity*
*    >         environment.humidity = ((parseShort(str.substring(4, 6), 16) * 0.01 / 2) * 100).toFixed(1) + '% RH';*
*    >         str = str.substring(6);*
*    >         break;*
*    >       case 0x0673:// Atmospheric pressure*
*    >         environment.barometer = (parseShort(str.substring(4, 8), 16) * 0.1).toFixed(2) + "hPa";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       case 0x0267:// Temperature*
*    >         environment.temperature = (parseShort(str.substring(4, 8), 16) * 0.1).toFixed(2) + "°C";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       case 0x0188:// GPS*
*    >         var gps = {};*
*    >         gps.latitude = (parseTriple(str.substring(4, 10), 16) * 0.0001).toFixed(4) + "°";*
*    >         gps.longitude = (parseTriple(str.substring(10, 16), 16) * 0.0001).toFixed(4) + "°";*
*    >         gps.altitude = (parseTriple(str.substring(16, 22), 16) * 0.01).toFixed(1) + "m";*
*    >         myObj.gps = gps;*
*    >         str = str.substring(22);*
*    >         break;*
*    >       case 0x0371:// Triaxial acceleration*
*    >         var acceleration = {};*
*    >         acceleration.x = (parseShort(str.substring(4, 8), 16) * 0.001).toFixed(3) + "g";*
*    >         acceleration.y = (parseShort(str.substring(8, 12), 16) * 0.001).toFixed(3) + "g";*
*    >         acceleration.z = (parseShort(str.substring(12, 16), 16) * 0.001).toFixed(3) + "g";*
*    >         myObj.acceleration = acceleration;*
*    >         str = str.substring(16);*
*    >         break;*
*    >       case 0x0402:// air resistance*
*    >         environment.gasResistance = (parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2)  + "KΩ";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       case 0x0802:// Battery Voltage*
*    >         myObj.battery = (parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2) + "V";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       case 0x0586:// gyroscope*
*    >         var gyroscope = {};*
*    >         gyroscope.x = (parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2) + "°/s";*
*    >         gyroscope.y = (parseShort(str.substring(8, 12), 16) * 0.01).toFixed(2) + "°/s";*
*    >         gyroscope.z = (parseShort(str.substring(12, 16), 16) * 0.01).toFixed(2) + "°/s";*
*    >         myObj.gyroscope = gyroscope;*
*    >         str = str.substring(16);*
*    >         break;*
*    >       case 0x0902:// magnetometer x*
*    >         magnetometer.x = (parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2) + "μT";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       case 0x0a02:// magnetometer y*
*    >         magnetometer.y = (parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2) + "μT";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       case 0x0b02:// magnetometer z*
*    >         magnetometer.z = (parseShort(str.substring(4, 8), 16) * 0.01).toFixed(2) + "μT";*
*    >         str = str.substring(8);*
*    >         break;*
*    >       default:*
*    >         str = str.substring(7);*
*    >         break;*
*    >     }*
*    >   }*
*    >   if(Object.getOwnPropertyNames(environment).length > 0) {*
*    >     myObj.environment = environment;*
*    >   }*
*    >   if(Object.getOwnPropertyNames(magnetometer).length > 0) {*
*    >     myObj.magnetometer = magnetometer;*
*    >   }*
*    > *
*    >   return myObj;*
*    > }*

Here a screenshot when the sensor send it automatically and get decoded using the tool:

Any idea why am i getting the decoded message is that order instead of the correct one?

Thast the second screenshot:

Dear,

RAK7200 sends data automatically, you can’t have any other sending operations during the sending of data.

Yes nicholas, im aware of that. But the please refer to my previous reply for the current issue.

I cant seem to have the right order on the Lat, Lon, Altitutde settings when it comes to the console.

I’ve briefly reviewed the Cargo payload format docs. It looks like it wants the data as a sequence of hex bytes that it decodes itself, rather than sending a payload and processing it through the JavaScript decoder which turns it in to a JS object which is a very different data format.

So the bit you quoted as decoded is the JS object / JSON format which won’t work ever, even if we could influence the order the key/values were added or presented.

It’s not clear if the integration on Helium happens AFTER the decoder or if it bypasses it. If the former, then you can rewrite the decoder to use the decoded object to create a hex string to suit the integration. If the latter, then you are unlikely to enjoy success any time soon - the 7200 sends it’s data, it can be decoded, but if it Helium don’t provide a way to re-process it before it gets to the Cargo integration, then it’s game over.

1 Like

Dear,

GPS data is not successfully obtained from your serial port, but displayed on the platform. Is this data virtual?

Nick,

Thanks so much for taking a look, I definitely going to look into the first option you were mentioning. Not sure if you saw this on Heliums GitHub page for the Cargo integration:

I contacted the Helium Devs and they confirmed that the RAK7200 should have full support without any decoders… so im going to remove everything and re setup everything to run some test.

I will let you know what happens.

Again thanks for checking that out.

@nmcc I went to test the new settings but i found the Sensor offline since yesterday afternoon.

I check the battery with the voltmeter, also checked the pin connectors on the board they are okay and transmit power.

I tried the hard reboot button on the sensor as well as the boot0 and reset buttons but nothing, no leds no light. When I plug the USB the driver shows up but the Console doesn’t report anything. Looks like the device is “dead”. Do you have any advice or things to look at?

Leave it to charge for an hour - when I completely flatten mine it takes a while for the circuitry to provide enough power to the MCU as well as the charging circuit.

Then I just reset it.

Mine has been taken apart several times and I’ve yet to brick it - so go with the charging first.

Hm… got it. Im gonna do that now. Thanks again! As soon as i get it running i have to check it with the console. One of the Helium Devs already told me that their Cargo api should read the native payload without decoding. Cant wait to check.

Just wondering if you managed to resolve this - if so do you mind to share the outcome as I’m in the same situation.

It’s not clear which of the several issues proceeding you are referring to - please elaborate.

thanks- specifically if this was confirmed or if there was success.
i managed to get a payload working so i will push on with testing and poke around the forums.

  • the 7200 sends it’s data, it can be decoded, but if it Helium don’t provide a way to re-process it before it gets to the Cargo integration, then it’s game over.