Two way data over LoRaWAN using Multitech mDot

Dependencies:   libmDot-mbed5

This is example firmware for the Multitech mDot. It demonstrates how to:

  • Do two-way data.
  • Sleep aggressively and only wake up when the wake-up pin is triggered.
  • Handle errors, retries and duty cycle errors.
  • Cache data in non-volatile storage.

Based on mbed OS 5.1, hard faults against mbed OS 5.3 unfortunately. Can be compiled with GCC and ARMCC (but not IAR).

To do a new transmission, short pin D6 / PA_1.

Revision:
2:ff17ce021cfb
Parent:
0:20fbd6f66b11
--- a/parse_keys.h	Tue Jan 03 13:30:12 2017 +0000
+++ b/parse_keys.h	Tue Jan 03 16:05:47 2017 +0000
@@ -5,7 +5,7 @@
 
 class ParseKeys {
 public:
-    static bool initialize(mDot* dot, const char* aDevAddr, const char* aNwkSKey, const char* aAppSKey) {
+    static bool initializePersonalized(mDot* dot, const char* aDevAddr, const char* aNwkSKey, const char* aAppSKey) {
         int32_t ret;
 
         // parse devkey
@@ -32,6 +32,12 @@
             loriot_dev_addr[ai] = strtoul(hex, NULL, 16);
         }
 
+        // set join mode to MANUAL so the mDot doesn't have to rejoin after sleeping
+        logInfo("setting join mode to MANUAL");
+        if ((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
+            logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+        }
+
         logInfo("setting network address");
         if ((ret = dot->setNetworkAddress(loriot_dev_addr)) != mDot::MDOT_OK) {
             logError("failed to set network address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
@@ -52,6 +58,46 @@
 
         return true;
     }
+
+    static bool initializeOta(mDot* dot, const char* aAppEui, const char* aAppKey) {
+        int32_t ret;
+
+        // parse app key
+        std::vector<uint8_t> loriot_app_key(16);
+        for (uint8_t ni = 0; ni < 16; ni++)
+        {
+            const char hex[] = { '0', 'x', aAppKey[ni * 2], aAppKey[ni * 2 + 1], '\0' };
+            loriot_app_key[ni] = strtoul(hex, NULL, 16);
+        }
+
+        // parse app eui
+        std::vector<uint8_t> loriot_app_eui(8);
+        for (uint8_t ai = 0; ai < 8; ai++)
+        {
+            const char hex[] = { '0', 'x', aAppEui[ai * 2], aAppEui[ai * 2 + 1], '\0' };
+            loriot_app_eui[ai] = strtoul(hex, NULL, 16);
+        }
+
+        // set join mode to OTA so the mDot doesn't have to rejoin after sleeping
+        logInfo("setting join mode to OTA");
+        if ((ret = dot->setJoinMode(mDot::OTA)) != mDot::MDOT_OK) {
+            logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+        }
+
+        logInfo("setting network id");
+        if ((ret = dot->setNetworkId(loriot_app_eui)) != mDot::MDOT_OK) {
+            logError("failed to set network id %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+            return false;
+        }
+
+        logInfo("setting network key");
+        if ((ret = dot->setNetworkKey(loriot_app_key)) != mDot::MDOT_OK) {
+            logError("failed to set network key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+            return false;
+        }
+
+        return true;
+    }
 };
 
 #endif // DISPENSER_PARSE_KEYS_H