RAK10701-L Field Tester for LoRaWAN Quick Start Guide
The Field Tester is an inexpensive tool used to map the coverage of LoRaWAN gateways to ensure that LoRaWAN nodes can connect and send data.
It does this by sending out uplink packets then a backend server is checking which gateways receive this payload. Using the Field Tester location data and the gateways' locations, the backend then calculates an average distance and submits the min and max RSSI plus SNR values of the receiving gateways. This data is then shown on the Field Testers touch screen display.
The backend server can be a dedicated server, but it can be implemented as well using platforms like Datacake.
Prerequisites
What Do You Need?
Before going through each and every step in the installation guide of the RAK10701-L Field Tester for LoRaWAN, make sure to prepare the necessary items listed below:
Hardware Tools
- RAK10701-L Field Tester for LoRaWAN
- LoRa SubGhz Antenna with RP-SMA connector
- USB Type-C Cable
- Windows/Linux/macOS for PC or iOS/Android for mobile
Software Tools
WisToolBox for configuration and firmware update.
It is mandatory that you are within the coverage of the LoRaWAN Gateway of the network you are trying to join. Without the coverage, the Field Tester will not be useable.
Product Configuration
RAK10701-L Field Tester Physical Interface
The user interface of the RAK10701-L Field Tester for LoRaWAN is via TFT Touchscreen LCD and one push button at the side. There is also an external LoRA antenna port via RP-SMA connector and USB-C port for charging and configuration if connected to a PC.
You have to ensure that the LoRa antenna is attached before turning on the device.
- To turn on the device, you have to press and hold the button for at least five seconds.
The same button can be used to power off. You have to hold it as well for at least five seconds.
- When the device initializes, it will show the RAK logo on the screen. If there is any initialization error, it will be shown on the upper right section of the screen as well. A properly working device should not have any errors shown.
- After the successful boot up, the main home screen will be shown. Take note, that there will be no data at the first start of the device.
The field tester must be outside and has a clear view of the sky to get GPS coordinates. The GPS antenna is located on top of the device beside the RP-SMA connector of the LoRa Antenna.
If you are indoors, there will be no reception of the GPS signal. The latitude and longitude data will be empty.
-
Once fully powered on, the external button at the side can sleep or wake up the display on the LCD screen via a single press on it.
-
If the device is connected via USB-C to a computer, then the button is pressed, it will not remove the display but will lock the screen (touch screen behavior is disabled).
LoRaWAN Network Servers Guide for RAK10701-L Field Tester
The field tester supports different network servers and can be used as well on others not listed in this guide as long as the uplink and downlink packets are configured correctly.
You can check each guide on how to use the RAK10701-L Field Tester for LoRaWAN in the following network servers.
- Helium
- The Things Network
- Chirpstack (with Datacake)
- Loriot (with Datacake)
- Chirpstack (with NodeRED)
Additional information:
This section will focus on the configuration of each network server. The procedure of Device Configuration of RAK10701-L via WisToolBox is the same for all network server and will be covered in a separate section of the guide.
RAK10701-L Field Tester Guide for the Helium Network
RAK10701-L can be manually registered to Helium Console. This is a public LoRaWAN network server that you can use for your LoRaWAN end-devices powered by community-driven Helium Hotspots. This guide will show every detail of how to prepare the Helium Console for your RAK10701-L field tester.
This guide is based on disk19 guide for the Field Tester configuration for the Helium Console.
- You need to register an account and then purchase data credits (DC) to use the network. If you are a new user, there are free data credits (DC) included in your new account to get you started quickly.
- Once you are logged in, you can start adding your device. You have two ways to add a device as shown in the image.
- The newly added device parameters will be shown. You have to put a device name and click save.
The DEVEUI, APPEUI, and APPKEY are important in this step. These values must be configured on your RAK10701-L device using WisToolBox which will be covered later in this guide.
- The device will be added to the blockchain and it will show pending beside its name.
- While waiting for the device to be added to the blockchain, you can create a
Label
. This will allow you to group your device to have a common setting. This will be needed to attach the needed integrations to the backend server ofdev.disk91.com
. You have to click the folder with the + icon and add aLabel
name then clickSave Label
. The newly created label should now be shown in theDevices
console.
- Once the
Label
is created you have to associate it on the RAK10701 device. You can attach theLabel
on the device by clicking the Add Label button.
- A pop-up will be shown and you have to select the correct
Label
created for RAK10701 then click Add Label.
- After successful attachment of
Label
on the devices, it should show one (1) device is under thatLabel
. The device is properly labeled which is needed for the next steps -Integrations
andFlow
.
- To connect the backend server, you have to create an
Integration
.
- Then you must proceed to steps 2 and 3 sections of the
Integration
settings. You have to selectPOST
then on the Endpoint URL, you must puthttps://dev.disk91.com/fieldtester/helium/v3
. It is also needed to put the integration name before the clicking Add Integration button.
- After preparing the device and the integration, you can now proceed with creating the flow to connect them. You have to click
Flows
and then the+
icon onNODES
.
- You must select
Labels
andIntegrations
and then drag the correct blocks on the flows canvas.
- You then have to connect the
Label
block to theIntegration
block via the tiny connector indicated by the red arrows by using your mouse cursor and dragging the line connector.
There is no need to save the changes created on the flows canvas since it is automatically saved as you do changes.
- The final step in the setting up of the Helium Console for RAK10701 is the setting up of packets. You have to click on
Packets
and then theAdd New Packet Config
icon.
- You must also input a name on the
Packet Config Name
, selectMultiple Packets
and drag the slider, so it will showAll Available Packets
. Once done, you can now click on+ Create Packet Config
.
- You must associate the multiple packet setup with the
rak10701-devices
label. To do this, you have to go back onFlows
, double-click on therak10701-devices
label, choose thePackets
tab under rak10701-devices settings then enableALL Packets
. After this, you can now proceed with the configuration of RAK10701 using WisToolBox.
- You can now proceed on device configuration so that the proper EUIs and KEY will match the one in the Helium network.
RAK10701-L Field Tester Guide for The Things Network
This section shows how to use the RAK10701-L Field Tester for LoRaWAN to The Things Stack.
- Log in to TTNv3. To do so, head to the TTNv3 site and select your cluster. If you already have a TTN account, you can use your The Things ID credentials to log in.
- To connect RAK10701-L Field Tester to TTNv3, you should already have connected a gateway in range to TTNv3. Or, you have to be sure that you are in the range of a public gateway.
- Now that you are logged in to the platform, the next step is to create an application. In your console, click Create an application.
- To have an application registered, you need to input first the specific details and necessary information about your application then click Create application.
- If you had no error during the previous step, you should now be on the application console page. The next step is to Add end device to your TTN application.
- To register the RAK10701-L Field Tester, you need to click Manually first.
- Choose the following configurations in adding the end devices. You must choose the correct Frequency Plan and the LoRaWAN version must be 1.0.3.
- Click Show advanced activation, LoRaWAN class, and cluster settings, then select Over the air action (OTAA).
- Then input the LoRaWAN OTAA parameters. For AppEUI, you may click Fill with Zeros. For AppKey and DevEUI, you can click Generate. Then the parameters will be automatically filled by the TTS platform. Finally, click Register end device.
- You should now be able to see the device on the TTN console after you fully registered your device. Take note of these OTAA parameters, such as the
AppEUI
,DevEUI
, and theAppKey
, as they are needed in the configuration of the RAK10701-L Field Tester hardware later on in this guide.
- After adding the device to the LoRaWAN application, link it to the backend server. The first step is to create an API key.
- Configure the API key parameters. You can put any names that will easily track your API. You have to set the expiration date as well. Then you must check
Write downlink application traffic
. After the configuration, you can now clickCreate API key
.
- This step is critical. You need to copy the API key because this will be used on Webhook integration.
- With the API key created, you can proceed with creating the Webhook integration.
- Select Custom Webhook.
- Configure the necessary parameters on the Webhook. You can select any name for the webhook. You then need to set the base URL going to disk19 server
https://dev.disk91.com/fieldtester/ttn/v3
, add the API key from the previous step and lastly put a check on theUplink message
under Enabled event types.
- After setting all the configurations, you can now add the webhook.
- You should see now the newly created webhook.
-
After adding the application, device, and webhook integration to the console, you have to configure the parameters in your device to match the parameters on the TTN console. You can use WisToolBox via USB connection or wirelessly via BLE. You can now proceed on the RAK10701-L Configuration using WisToolBox. You also have the option to update device parameters directly via RUI3 AT Commands (if you prefer AT commands instead of WisToolBox).
-
Once you configured the RAK10701-L with the correct Frequency Band and EUIs/Key by following the guide on the RAK10701-L Configuration using WisToolBox, you should see the join request/accept, uplinks and downlinks to The Things Stack console. These uplinks contains the coordinates of the field tester and the downlinks contains the data calculated by the disk91 server. The uplink uses fport 1 and the downlink uses fport 2. To view the actual coordinates on the console, you need to add a payload decoder on your uplink data.
Uplink payload decoder script.
Click to view the code
function Decoder(bytes, port) {
var decoded = {};
// avoid sending Downlink ACK to integration (Cargo)
if (port === 1) {
var lonSign = (bytes[0] >> 7) & 0x01 ? -1 : 1;
var latSign = (bytes[0] >> 6) & 0x01 ? -1 : 1;
var encLat = ((bytes[0] & 0x3f) << 17) +
(bytes[1] << 9) +
(bytes[2] << 1) +
(bytes[3] >> 7);
var encLon = ((bytes[3] & 0x7f) << 16) +
(bytes[4] << 8) +
bytes[5];
var hdop = bytes[8] / 10;
var sats = bytes[9];
const maxHdop = 2;
const minSats = 5;
if ((hdop < maxHdop) && (sats >= minSats)) {
// Send only acceptable quality of position to mappers
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
} else {
decoded.error = "Need more GPS precision (hdop must be <" + maxHdop +
" & sats must be >= " + minSats + ") current hdop: " + hdop + " & sats:" + sats;
}
return decoded;
}
return null;
}
- With the correct payload decoder, you should now see GPS coordinates data which you can also use to other integration.
RAK10701-L Field Tester Guide for Chirpstack
How Does It Work?
There are two steps under the hood of the Field Tester. In step one, the Field Tester is sending out data packets over LoRaWAN. These packets are received by one or multiple gateways. These packets are forwarded from the LoRaWAN network server to another backend server. When the packets are forwarded, they include information about signal strength and the number of gateways that have received the packet.
In the second step, the backend server is calculating the minimum and maximum distance between the Field Tester Pro and the gateways that received the data. Together with the minimum and maximum RSSI levels, this information is then sent back to the Field Tester Pro as a LoRaWAN downlink.
To use Chirpstack for RAK10701-L, you must have a working installation of the Chirpstack LoRaWAN network server. It can be on a dedicated machine, Raspberry Pi, or in a cloud VPS instance. It should have a fixed IP address and port to where Datacake.co
will connect to.
- To start with Chirpstack, you must create a device profile for your RAK10701-L Field Tester device. You must select
LoRaWAN MAC version 1.0.3
which is the LoRaWAN specification version that the RAK10701 Field Tester supports.
- You must enable
Device supports OTAA
as the network join method as well.
- You can also include a custom javascript decoder under the
CODEC
tab. This will allow you to see the specific information transmitted by the device.
Here's the complete decoder script:
Click to view the code
function Decode(fPort, bytes, variables) {
var decoded = {};
// avoid sending Downlink ACK to integration (Cargo)
if ((fPort === 1) || (fPort === 2)){
var lonSign = (bytes[0] >> 7) & 0x01 ? -1 : 1;
var latSign = (bytes[0] >> 6) & 0x01 ? -1 : 1;
var encLat = ((bytes[0] & 0x3f) << 17) +
(bytes[1] << 9) +
(bytes[2] << 1) +
(bytes[3] >> 7);
var encLon = ((bytes[3] & 0x7f) << 16) +
(bytes[4] << 8) +
bytes[5];
var hdop = bytes[8] / 10;
var sats = bytes[9];
var maxHdop = 2;
var minSats = 5;
if ((hdop < maxHdop) && (sats >= minSats)) {
// Send only acceptable quality of position to mappers
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
} else {
decoded.error = "Need more GPS precision (hdop must be <" + maxHdop +
" & sats must be >= " + minSats + ") current hdop: " + hdop + " & sats:" + sats;
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
}
return decoded;
}
return null;
This decoder script can be found on RAKwireless Standardize Payload repository which also includes a custom decoder script for TTN and Helium.
- After creating the device profile, you can now create an application and add the RAK10701 device. And then attached the
Device-profile
you created. Note the DEVEUI and APPKEY in this section. These parameters must match the ones in our RAK10701 Field Tester.
- You also need to ensure that you have a Gateway registered in Chirpstack and with the correct Network Server profile.
- The next step after setting up the network server, devices, and gateway, is the integration of the Chirpstack application to Datacake. You must choose HTTP, then click
Edit
. Then you have to use this endpoint going to datacakehttps://api.datacake.co/integrations/lorawan/chirpstack/
.
- The last step on the Chirpstack side, is the creation of the API key. This is needed to allow Datacake in sending downlink packets to the RAK10701 Field Tester. Make sure the key is copied and saved somewhere, it is only retrievable during the key creation. Copy the Token and save it in a text editor.
- You can now proceed on Datacake and add a LoRaWAN device that will be linked to your RAK10701 created in ChirpStack. You have to create an account if you do not have one yet.
- Next step is to enable the downlink. This is the step where you'll be needing the previously created API key in step 7 of this guide. Take note that the
ChirpStack URL
should be based on your deployed Chirpstack network server. After doing all configurations, click update and save.
- Just below the
LoRaWAN
section in datacake.co, you'll see thePayload Decoder
. This is a very critical step to ensure that all important data will be covered.
Click to view the code
function distance(lat1, lon1, lat2, lon2) {
if ((lat1 == lat2) && (lon1 == lon2)) {
return 0;
}
else {
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) {
dist = 1;
}
dist = Math.acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
}
}
function Decoder(bytes, fPort) {
var decoded = {};
// avoid sending Downlink ACK to integration (Cargo)
if (fPort === 1) {
var lonSign = (bytes[0] >> 7) & 0x01 ? -1 : 1;
var latSign = (bytes[0] >> 6) & 0x01 ? -1 : 1;
var encLat = ((bytes[0] & 0x3f) << 17) +
(bytes[1] << 9) +
(bytes[2] << 1) +
(bytes[3] >> 7);
var encLon = ((bytes[3] & 0x7f) << 16) +
(bytes[4] << 8) +
bytes[5];
var hdop = bytes[8] / 10;
var sats = bytes[9];
var maxHdop = 2;
var minSats = 5;
if ((hdop < maxHdop) && (sats >= minSats)) {
// Send only acceptable quality of position to mappers
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
decoded.location = "(" + decoded.latitude + "," + decoded.longitude + ")";
} else {
decoded.error = "Need more GPS precision (hdop must be <" + maxHdop +
" & sats must be >= " + minSats + ") current hdop: " + hdop + " & sats:" + sats;
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
decoded.location = "(" + decoded.latitude + "," + decoded.longitude + ")";
}
// decoded.raw = rawPayload.uplink_message.rx_metadata[0].location;
decoded.num_gw = normalizedPayload.gateways.length;
decoded.minRSSI = 0;
decoded.maxRSSI = 0;
decoded.minSNR = 0;
decoded.maxSNR = 0;
decoded.minDistance = 0;
decoded.maxDistance = 0;
var server_type = 0;
// Check if payload comes from TTN
if (typeof (rawPayload.uplink_message) != "undefined") {
console.log("Found TTN format");
server_type = 1;
}
// Check if payload comes from Helium
else if (typeof (rawPayload.hotspots) != "undefined") {
console.log("Found Helium format");
server_type = 2;
}
// Check if payload comes from Chirpstack
else if (typeof (rawPayload.rxInfo) != "undefined") {
console.log("Found Chirpstack format");
server_type = 3;
decoded.is_chirpstack = 1;
}
else {
console.log("Unknown raw format");
}
var gw_lat = {};
var gw_long = {};
decoded.num_gw = 0;
for (idx_tst = 0; idx_tst < 10; idx_tst++)
{
if (typeof (normalizedPayload.gateways[idx_tst]) != "undefined")
{
console.log("Found gateway with IDX " + idx_tst);
decoded.num_gw += 1;
}
}
for (idx = 0; idx < decoded.num_gw; idx++) {
var new_rssi = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[idx] && normalizedPayload.gateways[idx].rssi) || 0;
var new_snr = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[idx] && normalizedPayload.gateways[idx].snr) || 0;
if ((new_rssi < decoded.minRSSI) || (decoded.minRSSI == 0)) {
decoded.minRSSI = new_rssi;
}
if ((new_rssi > decoded.maxRSSI) || (decoded.maxRSSI == 0)) {
decoded.maxRSSI = new_rssi;
}
if ((new_snr < decoded.minSNR) || (decoded.minSNR == 0)) {
decoded.minSNR = new_snr;
}
if ((new_snr > decoded.maxSNR) || (decoded.maxSNR == 0)) {
decoded.maxSNR = new_snr;
}
// var gw_lat = 0.0;
// var gw_long = 0.0;
switch (server_type) {
//TTN
case 1:
gw_lat[idx] = rawPayload.uplink_message.rx_metadata[idx].location.latitude;
gw_long[idx] = rawPayload.uplink_message.rx_metadata[idx].location.longitude;
break;
// Helium
case 2:
gw_lat[idx] = rawPayload.hotspots[idx].lat;
gw_long[idx] = rawPayload.hotspots[idx].long;
break;
// Chirpstack
case 3:
gw_lat[idx] = rawPayload.rxInfo[idx].location.latitude;
gw_long[idx] = rawPayload.rxInfo[idx].location.longitude;
break;
default:
console.log("Unknown LNS");
break;
}
console.log("IDX " + idx + " lat " + gw_lat[idx] + " long " + gw_long[idx]);
// decoded.gw_lat[idx] = gw_lat;
// decoded.gw_long[idx] = gw_long;
// Calculate distance
var new_distance = distance(gw_lat[idx], gw_long[idx], decoded.latitude, decoded.longitude);
if ((new_distance < decoded.minDistance) || (decoded.minDistance == 0)) {
decoded.minDistance = new_distance * 1000;
}
if ((new_distance > decoded.maxDistance) || (decoded.maxDistance == 0)) {
decoded.maxDistance = new_distance * 1000;
}
}
switch (decoded.num_gw) {
case 20:
decoded.hotspot_10 = "(" + gw_lat[19] + "," + gw_long[19] + ")";
case 19:
decoded.hotspot_09 = "(" + gw_lat[18] + "," + gw_long[18] + ")";
case 18:
decoded.hotspot_08 = "(" + gw_lat[17] + "," + gw_long[17] + ")";
case 17:
decoded.hotspot_07 = "(" + gw_lat[16] + "," + gw_long[16] + ")";
case 16:
decoded.hotspot_06 = "(" + gw_lat[15] + "," + gw_long[15] + ")";
case 15:
decoded.hotspot_05 = "(" + gw_lat[14] + "," + gw_long[14] + ")";
case 14:
decoded.hotspot_04 = "(" + gw_lat[13] + "," + gw_long[13] + ")";
case 13:
decoded.hotspot_03 = "(" + gw_lat[12] + "," + gw_long[12] + ")";
case 12:
decoded.hotspot_02 = "(" + gw_lat[11] + "," + gw_long[11] + ")";
case 11:
decoded.hotspot_01 = "(" + gw_lat[10] + "," + gw_long[10] + ")";
case 10:
decoded.hotspot_10 = "(" + gw_lat[9] + "," + gw_long[9] + ")";
case 9:
decoded.hotspot_09 = "(" + gw_lat[8] + "," + gw_long[8] + ")";
case 8:
decoded.hotspot_08 = "(" + gw_lat[7] + "," + gw_long[7] + ")";
case 7:
decoded.hotspot_07 = "(" + gw_lat[6] + "," + gw_long[6] + ")";
case 6:
decoded.hotspot_06 = "(" + gw_lat[5] + "," + gw_long[5] + ")";
case 5:
decoded.hotspot_05 = "(" + gw_lat[4] + "," + gw_long[4] + ")";
case 4:
decoded.hotspot_04 = "(" + gw_lat[3] + "," + gw_long[3] + ")";
case 3:
decoded.hotspot_03 = "(" + gw_lat[2] + "," + gw_long[2] + ")";
case 2:
decoded.hotspot_02 = "(" + gw_lat[1] + "," + gw_long[1] + ")";
case 1:
decoded.hotspot_01 = "(" + gw_lat[0] + "," + gw_long[0] + ")";
default:
break;
}
decoded.maxMod = parseInt((decoded.maxDistance / 250), 10);
decoded.minMod = parseInt((decoded.minDistance / 250), 10);
decoded.maxDistance = parseInt((decoded.maxMod * 250), 10);
decoded.minDistance = parseInt((decoded.minMod * 250), 10);
if (decoded.maxDistance <= 1) {
decoded.maxDistance = parseInt(250, 10);
}
if (decoded.minDistance <= 1) {
decoded.minDistance = parseInt(250, 10);
}
return decoded;
}
return null;
}
This decoder is not only decoding data from the LoRaWAN packet but is as well reading gateway information from the additional data that the LoRaWAN server added to the data it forwarded to Datacake.
Each LoRaWAN server uses a different format for this additional information, so there is a code section that tries to detect whether the data came from a Chirpstack LSN, from TTN, or from a Helium Console:
Click to view the code
var server_type = 0;
// Check if payload comes from TTN
if (typeof (rawPayload.uplink_message) != "undefined") {
console.log("Found TTN format");
server_type = 1;
}
// Check if payload comes from Helium
else if (typeof (rawPayload.hotspots) != "undefined") {
console.log("Found Helium format");
server_type = 2;
}
// Check if payload comes from Chirpstack
else if (typeof (rawPayload.rxInfo) != "undefined") {
console.log("Found Chirpstack format");
server_type = 3;
decoded.is_chirpstack = 1;
}
else {
console.log("Unknown raw format");
}
Once the data is extracted, it calculates the distance between the RAK10701 Field Tester location and the different gateways that received the LoRaWAN packet. This version of the decoder can handle up to 10 gateways, but it can be extended.
Click to view the code
function distance(lat1, lon1, lat2, lon2) {
if ((lat1 == lat2) && (lon1 == lon2)) {
return 0;
}
else {
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) {
dist = 1;
}
dist = Math.acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
}
}
In the next step, it analyzes the different distances and RSSI levels to find the closest and farthest gateway and the lowest and highest RSSI and SNR levels.
The result of the decoding is then put into different data fields that are used by Chirpstack for the visualization and by the rule, we will define to create the downlink to the RAK10701 Field Tester.
- The next step is to create the different data fields that are filled by the data decoder. This is done in the Fields section of the device configuration, just below the data encoder section.
The following fields are required:
Field Name | Identifier (returned value from the decoder) | Field Type |
---|---|---|
Field Tester | LOCATION | Location |
MinDistance | MINDISTANCE | Integer |
MaxDistance | MAXDISTANCE | Integer |
MinRSSI | MINRSSI | Float |
MaxRSSI | MAXRSSI | Float |
MinSNR | MINSNR | Float |
MaxSNR | MAXSNR | Float |
minMod | MINMOD | Integer |
maxMod | MAXMAD | Integer |
hotspot_01 | HOTSPOT_01 | Location |
hotspot_02 | HOTSPOT_01 | Location |
hotspot_0… | HOTSPOT_... | Location |
hotspot_09 | HOTSPOT_09 | Location |
hotspot_10 | HOTSPOT_10 | Location |
is_chirpstack | IS_CHIRPSTACK | Boolean |
There are more variables created by the decoder, but this is the minimum set required for the dashboard and to configure the download.
- This is the most critical step so that the RAK10701 will be able to display the necessary details helpful in Field Testing the LoRaWAN network. This section is responsible for the "backend-server functions". In this step, we create the automatic downlink to the device that is executed every time a data packet from the RAK10701 Field Tester arrives. Take note that port number 2 is used by RAK10701 for downlinks and
Trigger on measurements
should be checked.
In this guide, the downlink is only created when the Field Tester is connected through a Chirpstack server. When TTN or Helium is used, the downlink would be created by the original backend server.
This is controlled by the “Fields used” where you can see the IS_CHIRPSTACK.
The Payload Encoder is preparing a downlink packet that will be sent back to the RAK10701 Field Tester. The downlink packet is only 6 bytes large to avoid problems in LoRaWAN regions with limited downlink packet sizes.
This is the complete decoder script. The first byte is usually a counter, but it works well if the counter is ignored and always set to 1.
Click to view the code
function Encoder(measurements, port) {
var buf = [];
buf[0] = 1;
buf[1] = measurements.MINRSSI.value + 200;
buf[2] = measurements.MAXRSSI.value + 200;
// var temp = parseInt(measurements.MINMOD.value,10);
if (measurements.MINMOD.value == 0) {
measurements.MINMOD.value = 1;
}
console.log(measurements.MINMOD.value);
buf[3] = measurements.MINMOD.value;
if (measurements.MAXMOD.value == 0) {
measurements.MAXMOD.value = 1;
}
buf[4] = measurements.MAXMOD.value;
buf[5] = measurements.NUM_GW.value;
return buf;
}
- You can now proceed on device configuration so that the proper EUIs and KEY will match the one in the network server.
RAK10701-L Field Tester Pro Guide for LORIOT and Datacake
In this document, you will find a step-by-step guide for performing a field mapping test using LORIOT network management system and Datacake's platform to visualize your results. This solution will help you in your network planning ventures and ensure your decisions are data-driven and adequate to your surroundings.
Prerequisites
Setting LORIOT as the LNS
- Forward a gateway to LORIOT, which will be the LNS (LoRa Network Server) for this use case. For registration of the gateway to LORIOT, you will need the gateway’s MAC and EUI, which can be found on the Overview page of WisGateOS 2.
- Go to your LORIOT profile. From the menu on the left, navigate through Networks > [your_network] > +Add Gateway.
The LORIOT platform provides you with a Sample Network at the point of your profile creation. You can use it for free. If you wish to create a new one, or delete the provided one, you will need a paid plan to continue.
- For the base platform select Basics Station Semtech. You will be asked to provide eth0 MAC address and EUI, which you obtained in step 1. After filling in these values, press the Register Basics Station Semtech gateway at the bottom of the page.
- The last thing you need to do to connect your gateway with LORIOT LNS is to provide the Basics Station configuration to the gateway. This can be done by going to the gateway's web UI > LoRa > Configuration and doing a Basics station server setup.
You can find the Trust (CA Certificate), the Server URL, and the Server port in LORIOT by navigating to the newly registered Gateway > Certificate. Use the configuration provided by LORIOT as it may differ from the guide depending on your region.
- If the steps are followed correctly, the gateway should show a Connected status.
Adding the Device and LORIOT to Datacake Integration
- Add the device to LORIOT. In the LORIOT platform, navigate to Applications > [your_application] and use the Enroll Device utility from the menu on the left. Fill out your Device EUI, Join (APP) EUI, and Application Key.
The LORIOT platform provides you with a Sample Application at the point of your profile creation. You can use it for free. If you wish to create a new one or delete the provided one, you will need a paid plan to continue.
- Use the Output utility to set up the Datacake integration. For now, just give it a name. The Authorization requires additional settings that will not be covered by this guide. For more information regarding this process, refer to Datacake's guide.
- Now, you need to add the device in Datacake. To register a new device, navigate to the Devices tab in your Datacake account. Click the +Add Device button.
- Choose New Product under Datacake Product. Enter the device name in the Product name input box, and proceed by clicking Next.
- Select LORIOT as the Network Server and click Next.
-
On the next page, you will have to enter the name and DEVEUI of the device. Select the plan for Datacake according to your needs and finish the device-adding procedure.
-
Now, navigate to Configuration in the newly created device at Datacake and scroll down to the Network Server configuration. Click Change.
- You will need the LORIOT Access Token, which is generated from the LORIOT console. Navigate to LORIOT > Access Tokens and copy the token to put it in Datacake.
You can generate a new access token or use the existing one.
- If everything is done correctly, you should see a trickle of RAW data in the Debug window of Datacake.
Setting Up the Uplink Payload Decoder and the Downlink Encoder
- In the Datacake console, navigate to the Configuration tab of your RAK10701 device. At the bottom of the page, you will find the Payload Decoder field. Copy the decoder code provided below and paste it in the payload decoder field. This decoder will calculate the values displayed on the screen of the Field Tester.
Click to view the code
function distance(lat1, lon1, lat2, lon2) {
if ((lat1 == lat2) && (lon1 == lon2)) {
return 0;
}
else {
var radlat1 = Math.PI * lat1 / 180;
var radlat2 = Math.PI * lat2 / 180;
var theta = lon1 - lon2;
var radtheta = Math.PI * theta / 180;
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) {
dist = 1;
}
dist = Math.acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
}
}
function Decoder(bytes, fPort) {
var decoded = {};
// avoid sending Downlink ACK to integration (Cargo)
if (fPort === 1) {
var lonSign = (bytes[0] >> 7) & 0x01 ? -1 : 1;
var latSign = (bytes[0] >> 6) & 0x01 ? -1 : 1;
var encLat = ((bytes[0] & 0x3f) << 17) +
(bytes[1] << 9) +
(bytes[2] << 1) +
(bytes[3] >> 7);
var encLon = ((bytes[3] & 0x7f) << 16) +
(bytes[4] << 8) +
bytes[5];
var hdop = bytes[8] / 10;
var sats = bytes[9];
var maxHdop = 2;
var minSats = 5;
if ((hdop < maxHdop) && (sats >= minSats)) {
// Send only acceptable quality of position to mappers
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
decoded.location = "(" + decoded.latitude + "," + decoded.longitude + ")";
} else {
decoded.error = "Need more GPS precision (hdop must be <" + maxHdop +
" & sats must be >= " + minSats + ") current hdop: " + hdop + " & sats:" + sats;
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6] << 8) + bytes[7]) - 1000;
decoded.accuracy = (hdop * 5 + 5) / 10
decoded.hdop = hdop;
decoded.sats = sats;
decoded.location = "(" + decoded.latitude + "," + decoded.longitude + ")";
}
// decoded.raw = rawPayload.uplink_message.rx_metadata[0].location;
decoded.num_gw = normalizedPayload.gateways.length;
decoded.minRSSI = 0;
decoded.maxRSSI = 0;
decoded.minSNR = 0;
decoded.maxSNR = 0;
decoded.minDistance = 0;
decoded.maxDistance = 0;
var server_type = 0;
// Check if payload comes from TTN
if (typeof (rawPayload.uplink_message) != "undefined") {
console.log("Found TTN format");
server_type = 1;
decoded.is_chirpstack = 1;
}
// Check if payload comes from Helium
else if (typeof (rawPayload.hotspots) != "undefined") {
console.log("Found Helium format");
server_type = 2;
}
// Check if payload comes from Chirpstack
else if (typeof (rawPayload.rxInfo) != "undefined") {
console.log("Found Chirpstack format");
server_type = 3;
decoded.is_chirpstack = 1;
}
// Check if payload comes from LORIOT
else if (typeof (rawPayload.cmd) != "undefined") {
console.log("Found LORIOT format");
server_type = 4;
decoded.is_chirpstack = 1;
}
else {
console.log("Unknown raw format");
}
var gw_lat = {};
var gw_long = {};
decoded.num_gw = 0;
for (idx_tst = 0; idx_tst < 10; idx_tst++)
{
if (typeof (normalizedPayload.gateways[idx_tst]) != "undefined")
{
console.log("Found gateway with IDX " + idx_tst);
decoded.num_gw += 1;
}
}
for (idx = 0; idx < decoded.num_gw; idx++) {
var new_rssi = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[idx] && normalizedPayload.gateways[idx].rssi) || 0;
var new_snr = (!!normalizedPayload.gateways && !!normalizedPayload.gateways[idx] && normalizedPayload.gateways[idx].snr) || 0;
if ((new_rssi < decoded.minRSSI) || (decoded.minRSSI == 0)) {
decoded.minRSSI = new_rssi;
}
if ((new_rssi > decoded.maxRSSI) || (decoded.maxRSSI == 0)) {
decoded.maxRSSI = new_rssi;
}
if ((new_snr < decoded.minSNR) || (decoded.minSNR == 0)) {
decoded.minSNR = new_snr;
}
if ((new_snr > decoded.maxSNR) || (decoded.maxSNR == 0)) {
decoded.maxSNR = new_snr;
}
switch (server_type) {
//TTN
case 1:
gw_lat[idx] = rawPayload.uplink_message.rx_metadata[idx].location.latitude;
gw_long[idx] = rawPayload.uplink_message.rx_metadata[idx].location.longitude;
break;
// Helium
case 2:
gw_lat[idx] = rawPayload.hotspots[idx].lat;
gw_long[idx] = rawPayload.hotspots[idx].long;
break;
// Chirpstack
case 3:
gw_lat[idx] = rawPayload.rxInfo[idx].location.latitude;
gw_long[idx] = rawPayload.rxInfo[idx].location.longitude;
break;
//LORIOT
case 4:
gw_lat[idx] = rawPayload.gws[0].lat;
gw_long[idx] = rawPayload.gws[0].lon;
break;
default:
console.log("Unknown LNS");
break;
}
console.log("IDX " + idx + " lat " + gw_lat[idx] + " long " + gw_long[idx]);
// Calculate distance
var new_distance = distance(gw_lat[idx], gw_long[idx], decoded.latitude, decoded.longitude);
if ((new_distance * 1000 < decoded.minDistance) || (decoded.minDistance == 0)) {
decoded.minDistance = new_distance * 1000;
}
if ((new_distance * 1000 > decoded.maxDistance) || (decoded.maxDistance == 0)) {
decoded.maxDistance = new_distance * 1000;
}
}
var hotspot_name = ""
for (idx = 0; idx < decoded.num_gw; idx++) {
var index = idx + 1;
if (index < 9) {
hotspot_name = "hotspot_0" + index.toString();
} else {
hotspot_name = "hotspot_" + index.toString();
}
console.log(hotspot_name);
decoded[hotspot_name] = "(" + gw_lat[idx] + "," + gw_long[idx] + ")";
}
decoded.maxMod = 1 + parseInt((Math.round(decoded.maxDistance / 250.0)), 10);
decoded.minMod = 1 + parseInt((Math.round(decoded.minDistance / 250.0)), 10);
return decoded;
}
return null;
}
- After saving the payload decoder it is time to set the downlink payload encoder. Navigate to Downlinks and copy-paste the provided encoder in the field. Set the port to 2 and use the IS_CHIRPSTACK field to trigger the downlink.
Click to view the code
function Encoder(measurements, port) {
var buf = [];
buf[0] = 1;
buf[1] = measurements.MINRSSI.value + 200;
buf[2] = measurements.MAXRSSI.value + 200;
// var temp = parseInt(measurements.MINMOD.value,10);
if (measurements.MINMOD.value == 0) {
measurements.MINMOD.value = 1;
}
console.log(measurements.MINMOD.value);
buf[3] = measurements.MINMOD.value;
if (measurements.MAXMOD.value == 0) {
measurements.MAXMOD.value = 1;
}
buf[4] = measurements.MAXMOD.value;
buf[5] = measurements.NUM_GW.value;
return buf;
}
- You should now be able to see the data from the downlink on your Field Tester's screen.
RAK10701-L Field Tester Guide for Chirpstack and NodeRED
How Does It Work?
The Field Tester performs two steps:
- In the first step, it sends data packets over LoRaWAN, which are then received by one or multiple gateways. These packets are forwarded by the LoRaWAN network server to a backend server, including information about signal strength and the number of gateways that received the packet.
- In the second step, the backend server calculates the minimum and maximum distances from the Field Tester to the gateways, along with the minimum and maximum RSSI levels, and sends information back to the Field Tester as a LoRaWAN downlink.
To use Chirpstack and NodeRED for RAK10701-L, you need a working Chirpstack LoRaWAN network server. This can be on a dedicated machine, a Raspberry Pi, or a cloud VPS. You also need NodeRED installed and connected to the Chirpstack MQTT broker.
- To start with Chirpstack, you must create a device profile for your RAK10701-L Field Tester Pro device. You must select
LoRaWAN MAC version 1.0.3
which is the LoRaWAN specification version that the RAK10701 Field Tester supports.
- You must enable
Device supports OTAA
as the network join method as well.
- Once done with the device profile, you can now create an application and add the RAK10701 device. And then attached the
Device-profile
you created.
Take note of the DEVEUI and APPKEY in this section. These parameters must match the ones in our RAK10701 Field Tester.
- Make sure your Gateway is registered in Chirpstack with the correct Network Server profile.
- After setting up the network server, devices, and gateway, install the NodeRED. This is required to run the backend server, which is in this case a NodeRED flow.
Check the NodeRED documentation about installation options.
- Once the NodeRED is installed, start it and select a flow to add the required nodes.
- Install the Field Tester Service node
a. Before starting to set up the flow, the Field Tester Service node needs to be added to the NodeRED palette.
Use the top-right icon in NodeRED and select Manage Palette from the new menu:
b. In the new window, select the Install tab and type rakwireless/field-tester-server
in the search box. The node will show up in the search result. Install the node by clicking the Install button.
c. Once the node is installed, we can start to setup the NodeRED flow.
- Setup the input Node
a. For Chirpstack V4 we need first an input node that can receive information from Chirpstacks MQTT broker. Pull the mqtt in
node from the left side bar to your flow:
b. Then set up the MQTT connection, double click the mqtt in
node to open the setup window. Then click on the Server Edit icon.
c. In the setup window, add your server connection in the Connection tab:
d. Server can be an URL or an IP address where your Chirpstack MQTT broker can be reached. This and the port number depends on your Chirpstack installation and MQTT settings.
e. Next go to the Security tab and enter the required username and password. Again, this depends on your MQTT settings:
f. To receive the data from the MQTT broker, we need to set up the topic we want to listen to. The first step is to get the ID of the application in Chirpstack:
g. Copy the application ID, to use it in the MQTT input node to set up the topic.
h. Open the MQTT input settings in the NodeRED flow by double clicking on the icon in the flow.
Then edit the topic field. The syntax is:
application
= fixed
application ID
= from the Chirpstack LNS application
#
= get all messages
In this example the topic is:
application/57184973-d64d-4656-be1d-84d4427bcb1a/#
i. Select as Output the option a parsed JSON object
.
- Set up the output node
a. We need an output node as well to be able to send downlinks to the Chirpstack MQTT Broker.
b. Pull the mqtt out
node from the left side bar to your flow:
c. The only setup required is to select the same server that is used in the mqtt in
node.
- Setup the Field Tester Backend Node
a. Now we can add and setup the Field Tester Server node.
b. Pull the field tester service
node from the left side bar to your flow:
c. Double click on the new node to setup the parser:
For this example, the required parser is Chirpstack v3 and v4.
The Field Tester Service node can be used with other LoRaWAN servers as well. Depending on the server and the options to receive uplinks and create downlinks, additional nodes might be required to convert this data into Raw data before sending it to the Field Tester Service.
However, guides on how to use it with other LNS are not available at this time.
- Connect the nodes
- The last step is to connect the nodes:
-
For debugging, it will be helpful to add a debug output node to the flow. This helps to check whether the output of the parser is correct:
- Select complete msg object as output.
The result of parser can then be checked on the right side in the debug window:
That's all, a simple implementation of a backend server for the RAK10701 Field Tester with NodeRED.
On the other hand, the uplink packets from the Field Tester can be sent in parallel to Datacake for a visualization of the locations, but in this case, there is no need to set up the downlink procedure in Datacake.
All credits for the Field Tester Service node go to Xose from RAKwireless.
Configuration of RAK10701-L Using WisToolBox
The Field Mapper should have the correct credentials to connect to the Helium Console. This can be done using WisToolBox and also with the help of the touchscreen LCD user interface.
-
Connect the RAK10701-L to the PC via USB Type-C cable and open the WisToolBox application. You can find more info on how to install and use the WisToolbox from its documentation.
-
Click the CONNECT DEVICE button to launch WisToolBox Dashboard.
- Review the Connection settings parameters on the dashboard, then click on the CONNECT button.
- On the WisToolBox Dashboard screen, select the RAK4630 module. This is the module inside the RAK10701-L Field Tester device.
- You can now update the APPEUI, DEVEUI, and APPKEY. It must be the same as the parameters you have in the Setting up of Network Server. Then you can click APPLY COMMANDS.
These are the only parameters that you need to change via WisToolBox. Other configurations like frequency plan, the interval of uplinks, TX power, and data rate can be done on the touchscreen of RAK10701.
For the frequency plan change, the device must be restarted to activate this newly configured frequency band. There will be a notification on the UI touchscreen LCD. If you use WisToolBox to configure the band, you have to restart the device manually, and there will be no notification from the UI of the LCD.
- You will see the summary of commands that were applied successfully. If the update is unsuccessful, just resend the needed changes. After the successful update, click the CLOSE button to return to Dashboard.
- You can now remove the USB Type-C cable and proceed to the screen of RAK10701. You can click the settings icon and then update the frequency plan, the interval of uplinks, TX power, and data rate as needed. You can use the arrows for navigation and click
OK
to save changes.
Miscellaneous
This part of the guide shows the Field Tester interface and how to update the firmware.
Field Tester Display Interface
This section discusses the interfaces on the device's LCD and its pages.
Display Status and Indicator
The RAK10701-L WisNode Field Tester has status indicators that show the current state of the device.
Status:
- IDLE: RAK10701-L Field Tester state is in between the previous uplink and the next uplink. The duration of an IDLE depends on the interval configured on the device.
- JOINING: RAK10701-L Field Tester is trying to join the network. This status is triggered when a Join request is sent.
- JOINED: RAK10701-L Field Tester successfully received the Join accept the packet. This status will be displayed until refreshed when new data is sent.
- FAILED: RAK10701-L Field Tester failed to join the network. Triggered by receive timeout. There might be no available gateway reachable by the Field Tester.
- SENDING: RAK10701-L Field Tester's data such as GPS is being uploaded via an uplink. It will be displayed until the reception is completed or timed out.
Settings
The field tester has configurable parameters: Band, TX power, TX interval, backlight intensity, and DR. You can navigate the settings using the arrow widgets plus the back and ok buttons. The OTAA parameters APPEUI, DEVEUI, and APPKEY are also displayed but can't be changed on the touchscreen. WisToolBox or another Serial Port terminal tool is needed to send the AT commands to update the EUIs and key.
Data Plots
There are four different data plots on the field tester: number of gateways, RSSI, SNR, and approximate distance. These graphs are accessible by touching the respective icons assigned to the parameter.
GPS Data
The main page shows the last GPS data captured by the device.
Packet Frame Format
The Uplink packet format send on Fport 1:
Byte | Usage |
---|---|
0 - 5 | GSP position see here for details. Decoding see below |
6 - 7 | Altitude in meters + 1000 m ( 1100 = 100 m ) |
8 | HDOP * 10 (11 = 1.1) |
9 | Sats in view |
When the GPS position is invalid of GPS is disable, the frame is fill with 0's.
The downlink response format sends on Fport 2:
Byte | Usage |
---|---|
0 | Sequence ID % 255 |
1 | Min Rssi + 200 (160 = -40 dBm) |
2 | Max Rssi + 200 (160 = -40 dBm) |
3 | Min Distance step 250 m |
4 | Max Distance step 250 m |
5 | Seen hotspot |
The distance is calculated from the GPS position and the gateways position returned by LoRaWAN server meta-data. Under 250 m value is 250 m, over 32 km value is 32 km. 0 is considered as an invalid response.
The following integration and payload transformation allows to decode the gps position and report is to mapper.
Discovery uplink format send on Fport 3 (no ack):
Byte | Usage |
---|---|
0 - 5 | GPS position |
Discovery is sending 10 messages SF10 every 40 seconds. All the other information comes from the metadata provided by the network server.
Upgrading the Firmware
It is recommended to update to the latest version of the firmware. To do this, download the latest RAK10701-L WisNode Field Tester firmware and use the WisToolBox to update the custom firmware.
- Drag the downloaded firmware to the WisToolBox custom firmware section.
- After the firmware file is uploaded to the application, you can now select UPGRADE DEVICE.
- If all proceed with no error, you should see
Firmware update successful
notification, and the RAK10701-L will restart automatically.