d

Dependencies:   BME280 DOGS102 DS1820 MMA845x_timmeh MTS-Serial libmDot_Australia915Mhz mbed-rtos mbed

Fork of mDot_TTN_OTAA_Node by Thing Innovations

Revision:
13:5369ba22389a
Parent:
12:e82913ee9c61
Child:
15:8a0ebf59b8bb
--- a/main.cpp	Sat Nov 14 20:58:36 2015 +0000
+++ b/main.cpp	Wed May 11 06:18:15 2016 +0000
@@ -1,5 +1,5 @@
-/** mDot_TTN_DS18B20 - Simple mDot temperature sensor using Dallas Semiconductors DS18B20 OneWire temperature sensor.
- * It used the MANUAL join mode with parameters for The Things Network.
+/** mDot_TTN_Node - Simple mDot temperature sensor using Dallas Semiconductors DS18B20 OneWire temperature sensor.
+ * It used the AUTO_OTA join mode with parameters for The Things Network.
  *
  *
  * Uses MultiTech mDot developer board http://www.multitech.com/models/94558010LF
@@ -7,10 +7,36 @@
  * http://www.multitech.net/developer/software/lora/conduit-mlinux-convert-to-basic-packet-forwarder/
  * http://forum.thethingsnetwork.org/t/setting-up-multitech-conduit-gateway-for-ttn/216/35
  *
+ * Register a device and generate a random AppKey for the currently used application Id:
+ *
+ *./ttnctl devices register 0080000000009FC4
+ * INFO Generating random AppKey...             
+ * INFO Registered device                        AppKey=EC22CBC24733E3397B83C4C9DEA685A8 DevEUI=0080000000009FC4
+ *
+ * or to specify the same AppKey for a new device or to reregister the same device again:
+ *
+ * ./ttnctl devices register 0080000000009FC4 EC22CBC24733E3397B83C4C9DEA685A8
+ *
+ * ./ttnctl devices info 0080000000009FC4
+ * Dynamic device:
+ *
+ *  AppEUI:  70B3D57ED00000F6
+ *           {0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x00, 0x00, 0xF6}
+ *
+ *  DevEUI:  0080000000009FC4
+ *           {0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xC4}
+ *
+ *  AppKey:  EC22CBC24733E3397B83C4C9DEA685A8
+ *           {0xEC, 0x22, 0xCB, 0xC2, 0x47, 0x33, 0xE3, 0x39, 0x7B, 0x83, 0xC4, 0xC9, 0xDE, 0xA6, 0x85, 0xA8}
+ *
+ *
+ * Copy the AppEUI and AppKey values provided in hex array notation above to the AppEUI and AppKey parameters below.
+ *
  */
 
 #include "mbed.h"
 #include "DS1820.h"
+//#include "BME280.h"
 #include "mDot.h"
 #include "MTSLog.h"
 #include "MTSText.h"
@@ -22,34 +48,50 @@
 #define MIN(a,b) (((a)<(b))?(a):(b))
 #define MAX(a,b) (((a)>(b))?(a):(b))
 
-// Values as used by The Things Network
-//const uint8_t AppKey[16]={0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
-// Application session key
-uint8_t AppSKey[16]= {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
-// Network session key
-uint8_t NwkSKey[16]= {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
-
-// Network Address - Get your own address range at http://thethingsnetwork.org/wiki/AddressSpace
-uint8_t NetworkAddr[4]= {0x02,0x01,0x00,0x00};      // Our Network address or Node ID
-
+// AppEUI
+uint8_t AppEUI[8]={0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x00, 0x00, 0xF6};
+// AppKey
+uint8_t AppKey[16]={0xEC, 0x22, 0xCB, 0xC2, 0x47, 0x33, 0xE3, 0x39, 0x7B, 0x83, 0xC4, 0xC9, 0xDE, 0xA6, 0x85, 0xA8};
 
 // Some defines for the LoRa configuration
-#define LORA_SF mDot::SF_12
+/*
+ * EU868 Datarates
+ * ---------------
+ * DR0 - SF12BW125
+ * DR1 - SF11BW125
+ * DR2 - SF10BW125
+ * DR3 - SF9BW125
+ * DR4 - SF8BW125
+ * DR5 - SF7BW125
+ * DR6 - SF7BW250
+ *
+ * US915 Datarates
+ * ---------------
+ * DR0 - SF10BW125
+ * DR1 - SF9BW125
+ * DR2 - SF8BW125
+ * DR3 - SF7BW125
+ * DR4 - SF8BW500
+ */
+#define LORA_SF mDot::DR5
 #define LORA_ACK 0
 #define LORA_TXPOWER 14
 
 // Ignoring sub band for EU modules.
-//static uint8_t config_frequency_sub_band = 1;
+static uint8_t config_frequency_sub_band = 1;
 
 // DS18B20 OneWire pin
 // D13 on Dev Board, pin 18 on mDot, Compatible with Oxford Flood Network PCB temperature sensor.
-#define DATA_PIN     PA_5
-// A0 on Dev Board, pin 20 on mDot
-//#define DATA_PIN     PB_1
+//#define DATA_PIN     PA_5
+// A1 on Dev Board, pin 19 on mDot
+#define DATA_PIN     PC_13
 
 // Temperature sensor object
 DS1820 probe(DATA_PIN);
 
+// BME280 Temperature/Humidity/Pressure sensor
+//BME280 sensor(I2C_SDA, I2C_SCL);
+
 // Serial via USB for debugging only
 Serial pc(USBTX,USBRX);
 
@@ -59,42 +101,36 @@
     mDot* dot;
     std::vector<uint8_t> send_data;
     std::vector<uint8_t> recv_data;
-    std::vector<uint8_t> nwkSKey;
-    std::vector<uint8_t> nodeAddr;
-    std::vector<uint8_t> networkAddr;
+    std::vector<uint8_t> nwkId;
+    std::vector<uint8_t> nwkKey;
 
     float temperature = 0.0;
+    float humidity = 0.0;
+    float pressure = 0.0;
 
     pc.baud(115200);
-    pc.printf("TTN mDot LoRa Temperature sensor\n\r");
+    pc.printf("TTN OTAA mDot LoRa Temperature sensor\n\r");
 
     // get a mDot handle
     dot = mDot::getInstance();
 
-    dot->setLogLevel(MTSLog::WARNING_LEVEL);
-//    dot->setLogLevel(MTSLog::TRACE_LEVEL);
+//    dot->setLogLevel(MTSLog::WARNING_LEVEL);
+    dot->setLogLevel(MTSLog::TRACE_LEVEL);
 
     logInfo("Checking Config");
 
-    // Test if we've already saved the config
-    std::string configNetworkName = dot->getNetworkName();
-
-    uint8_t *it = NwkSKey;
+    uint8_t *it = AppEUI;
+    for (uint8_t i = 0; i<8; i++)
+        nwkId.push_back((uint8_t) *it++);
+    
+    it = AppKey;
     for (uint8_t i = 0; i<16; i++)
-        nwkSKey.push_back((uint8_t) *it++);
-
-    it = NetworkAddr;
-    for (uint8_t i = 0; i<4; i++)
-        networkAddr.push_back((uint8_t) *it++);
+        nwkKey.push_back((uint8_t) *it++);
 
     logInfo("Resetting Config");
     // reset to default config so we know what state we're in
     dot->resetConfig();
 
-    // Set byte order - AEP less than 1.0.30
-//    dot->setJoinByteOrder(mDot::LSB);
-    dot->setJoinByteOrder(mDot::MSB);       // This is default for > 1.0.30 Conduit
-
     // Set Spreading Factor, higher is lower data rate, smaller packets but longer range
     // Lower is higher data rate, larger packets and shorter range.
     logInfo("Set SF");
@@ -112,9 +148,9 @@
         logError("failed to set Public Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
     }
 
-    logInfo("Set MANUAL Join mode");
-    if((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
-        logError("Failed to set MANUAL Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    logInfo("Set AUTO_OTA Join mode");
+    if((ret = dot->setJoinMode(mDot::AUTO_OTA)) != mDot::MDOT_OK) {
+        logError("Failed to set AUTO_OTA Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
     }
 
     logInfo("Set Ack");
@@ -123,25 +159,18 @@
         logError("Failed to set Ack %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
     }
 
-//    Not applicable for 868MHz in EU
-//    if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
-//        initStatus = false;
-//        logError(dot, "failed to set frequency sub band", ret);
-//    }
-
-    logInfo("Set Network Address");
-    if ((ret = dot->setNetworkAddress(networkAddr)) != mDot::MDOT_OK) {
-        logError("Failed to set Network Address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    // Library ignores the frequency sub band for 868MHz in EU
+    if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
+        logError("Failed to set frequency sub band %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
     }
 
-    logInfo("Set Data Session Key");
-    if ((ret = dot->setDataSessionKey(nwkSKey)) != mDot::MDOT_OK) {
-        logError("Failed to set Data Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    logInfo("Set Network Id");
+    if ((ret = dot->setNetworkId(nwkId)) != mDot::MDOT_OK) {
+        logError("Failed to set Network Id %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
     }
-
-    logInfo("Set Network Session Key");
-    if ((ret = dot->setNetworkSessionKey(nwkSKey)) != mDot::MDOT_OK) {
-        logError("Failed to set Network Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    logInfo("Set Network Key");
+    if ((ret = dot->setNetworkKey(nwkKey)) != mDot::MDOT_OK) {
+        logError("Failed to set Network Id %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
     }
 
     logInfo("Saving Config");
@@ -150,33 +179,36 @@
         logError("failed to save configuration");
     }
 
-    // Display what is set
-    std::vector<uint8_t> tmp = dot->getNetworkSessionKey();
-    pc.printf("Network Session Key: ");
-    pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
-
-    tmp = dot->getDataSessionKey();
-    pc.printf("Data Session Key: ");
-    pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
-
-    pc.printf("Device ID ");
+    pc.printf("Device ID {");
     std::vector<uint8_t> deviceId;
     deviceId = dot->getDeviceId();
-    for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it)
-        pc.printf("%2.2x",*it );
-    pc.printf("\r\n");
-
-    std::vector<uint8_t> netAddress;
+    for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it) {
+        pc.printf("0x%2.2X",*it );
+        pc.printf("%s", it != (deviceId.end() -1 ) ? ", " : " " );
+    }
+    pc.printf("}\r\n");
 
-    pc.printf("Network Address ");
-    netAddress = dot->getNetworkAddress();
-    for (std::vector<uint8_t>::iterator it = netAddress.begin() ; it != netAddress.end(); ++it)
-        pc.printf("%2.2x",*it );
+    std::vector<uint8_t> netId;
+    pc.printf("Network Id/App EUI {");
+    netId = dot->getNetworkId();
+    for (std::vector<uint8_t>::iterator it = netId.begin() ; it != netId.end(); ++it) {
+        pc.printf("0x%2.2X", *it );
+        pc.printf("%s", it != (netId.end() -1 ) ? ", " : " " );
+    }
+    pc.printf("}\r\n");
 
-    pc.printf("\r\n");
+    std::vector<uint8_t> netKey;
+    pc.printf("Network Key/App Key {");
+    netKey = dot->getNetworkKey();
+    for (std::vector<uint8_t>::iterator it = netKey.begin() ; it != netKey.end(); ++it) {
+        pc.printf("0x%2.2X", *it );
+        pc.printf("%s", it != (netKey.end() -1 ) ? ", " : " " );
+    }
+    pc.printf("}\r\n");
 
     // Display LoRa parameters
     // Display label and values in different colours, show pretty values not numeric values where applicable
+/*
     pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") );
     pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() );
     pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() );
@@ -190,7 +222,7 @@
     pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" ));
     pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") );
     pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N")  );
-
+*/
     logInfo("Joining Network");
 
     while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
@@ -200,34 +232,50 @@
 
     logInfo("Joined Network");
 
+    // Display Network session key and data session key from Join command
+/*
+    std::vector<uint8_t> tmp = dot->getNetworkSessionKey();
+    pc.printf("Network Session Key: ");
+    pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
+
+    tmp = dot->getDataSessionKey();
+    pc.printf("Data Session Key: ");
+    pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
+*/
     // Set the Temperature sesnor resolution, 9 bits is enough and makes it faster to provide a reading.
     probe.setResolution(9);
 
     char dataBuf[50];
     while( 1 ) {
-        //Start temperature conversion, wait until ready
+            // Output data as JSON e.g. {"t":21.3}
+//            temperature = sensor.getTemperature();
+//            humidity = sensor.getHumidity();
+//            pressure = sensor.getPressure();
+
+            //Start temperature conversion, wait until ready
         probe.convertTemperature(true, DS1820::all_devices);
-        // Output data as JSON e.g. {"t":21.3}
+            // Output data as JSON e.g. {"t":21.3}
         temperature = probe.temperature();
         sprintf(dataBuf, "{\"t\":%3.1f}", temperature );
-        send_data.clear();
-        // probably not the most efficent way to do this
-        for( int i=0; i< strlen(dataBuf); i++ )
-            send_data.push_back( dataBuf[i] );
+//            sprintf(dataBuf, "%3.1f,%3.1f,%04.2f", temperature,humidity,pressure );
+        pc.printf("%s\n",dataBuf);
+            send_data.clear();
+            // probably not the most efficent way to do this
+            for( int i=0; i< strlen(dataBuf); i++ )
+                send_data.push_back( dataBuf[i] );
 
-        if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
-            logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
-        } else {
-            logInfo("send data: %s", Text::bin2hexString(send_data).c_str());
-        }
+            if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
+                logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
+            } else {
+                logInfo("send data: %s", Text::bin2hexString(send_data).c_str());
+            }
 
-        // Should  sleep here and wakeup after a set 10 minute interval.
-        uint32_t sleep_time = MAX((dot->getNextTxMs() / 1000), 600);
-        logInfo("going to sleep for %d seconds", sleep_time);
-
-        // go to sleep and wake up automatically sleep_time seconds later
-        dot->sleep(sleep_time, mDot::RTC_ALARM);
+           // Should  sleep here and wakeup after a set 5 minute interval.
+            // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again
+            uint32_t sleep_time = std::max((uint32_t)300000, (uint32_t)dot->getNextTxMs()) / 1000;
+//wait_ms(2000);
+            // go to sleep and wake up automatically sleep_time seconds later
+            dot->sleep(sleep_time, mDot::RTC_ALARM);
     }
 
-    return 0;
 }