test _oliver

Dependencies:   libmDot-mbed5

Revision:
0:20fbd6f66b11
Child:
2:ff17ce021cfb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jan 03 13:20:36 2017 +0000
@@ -0,0 +1,220 @@
+#include "mbed.h"
+#include "mDot.h"
+#include "MTSLog.h"
+#include <string>
+#include <vector>
+#include <algorithm>
+#include "mbed.h"
+#include "parse_keys.h"
+
+#define BUILTIN_LED_ON          0
+#define BUILTIN_LED_OFF         1
+
+static const char LORIOT_DEV_ADDR[]  = "01F83E96"; // Use the big endian version here
+static const char LORIOT_NWK_S_KEY[] = "6B11E4D0814BE7BC5707920B4B3545D6"; // NWKSKEY
+static const char LORIOT_APP_S_KEY[] = "5C79DCD7E2CCB93A83730BC7A9BC6CFE"; // APPSKEY
+
+static mDot* dot;
+
+// so we have some state
+static uint16_t counter = 0;            // always persisted to non-volatile mem
+
+static bool woke_from_interrupt = false;
+
+static InterruptIn btn(PA_1); /* D6 */
+static DigitalOut led(PC_13, BUILTIN_LED_OFF); /* D2 */
+
+static void read_counter() {
+    char buffer[2];
+    bool res = dot->readUserFile("counter", &buffer, 2);
+    if (res) {
+        counter = (buffer[0] << 8) + buffer[1];
+    }
+    else {
+        counter = 0;
+    }
+}
+
+static void up_counter() {
+    logInfo("up counter");
+
+    read_counter();
+
+    counter++;
+
+    char buffer[2];
+    buffer[0] = counter >> 8 & 0xff;
+    buffer[1] = counter & 0xff;
+
+    logInfo("new counter value is: %d", counter);
+
+    dot->saveUserFile("counter", &buffer, 2);
+}
+
+static void btn_rise() {
+    woke_from_interrupt = true; // will be woken by STM32
+}
+
+static bool send_data(void) {
+    int32_t ret;
+
+    std::vector<uint8_t> data;
+    data.push_back(counter >> 8 & 0xff);
+    data.push_back(counter & 0xff);
+
+    logInfo("sending %d bytes", data.size());
+    if ((ret = dot->send(data)) != mDot::MDOT_OK) {
+        logError("failed to send %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+        return false;
+    } else {
+        logInfo("successfully sent data to gateway");
+
+        std::vector<uint8_t> recv_data;
+        if ((ret = dot->recv(recv_data)) != mDot::MDOT_OK) {
+            logError("failed to recv %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+            return true; // sending succeeded, just recv failed
+        }
+        
+        if (recv_data.size() > 0) {
+            printf("[INFO] received %d bytes:", recv_data.size());
+            for (size_t ix = 0; ix < recv_data.size(); ix++) {
+                printf(" %02x", recv_data[ix]);
+            }
+            printf("\r\n");
+            
+            if (recv_data[0] == 1) {
+                led = BUILTIN_LED_ON;
+            }
+            else {
+                led = BUILTIN_LED_OFF;
+            }
+        }
+        
+        return true;
+    }
+}
+
+static void wakeUpCallback() {
+    logInfo("woke up, fromInterrupt=%d", woke_from_interrupt);
+    
+    bool wfi = woke_from_interrupt;
+    
+    // if we were woken up by RTC_ALARM, first up the counter
+    if (wfi) {
+        // reset the interrupt var
+        woke_from_interrupt = false;
+
+        up_counter();
+    }
+        
+
+    bool sent = send_data();
+    // not sent? try again in 5 minutes...
+    if (!sent) {
+        uint32_t sleep_time = 5 * 60;
+        
+        // if woke from button press, check duty cycle first...
+        if (wfi) {
+            // hmm.. something went wrong. Probably duty cycle, see next Tx frame
+            // get the next transmission frame (in whole seconds)
+            sleep_time = ceil(static_cast<float>(dot->getNextTxMs()) / 1000.0f);
+            
+            // Tx window open, but no success? Try again in 30s.
+            if (sleep_time == 0) sleep_time = 30;
+        }
+        
+        logInfo("Going back to sleep (RTC_ALARM), time=%d", sleep_time);
+        dot->sleep(sleep_time, mDot::RTC_ALARM, false);
+    }
+    else {
+        logInfo("Going back to sleep (INTERRUPT)");
+
+        // go back to sleep (wait for an interrupt to happen)
+        dot->sleep(0, mDot::INTERRUPT, false);
+    }
+}
+
+
+int main() {
+    int32_t ret;
+    printf("Entering main()\r\n");
+
+    btn.rise(&btn_rise);
+
+    // get a mDot handle
+    dot = mDot::getInstance();
+
+    dot->setLogLevel(mts::MTSLog::DEBUG_LEVEL);
+
+    // print library version information
+    logInfo("version: %s", dot->getId().c_str());
+
+    //*******************************************
+    // configuration
+    //*******************************************
+    // reset to default config so we know what state we're in
+    dot->resetConfig();
+
+    logInfo("frequencyBand: %d", dot->getFrequencyBand());
+
+    // set up the mDot with our network information: frequency sub band, network name, and network password
+    // these can all be saved in NVM so they don't need to be set every time - see mDot::saveConfig()
+
+    // 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 public network");
+    if ((ret = dot->setPublicNetwork(true)) != mDot::MDOT_OK) {
+        logError("failed to set public network %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+
+    logInfo("setting tx power to 20");
+    if ((ret = dot->setTxPower(18)) != mDot::MDOT_OK) {
+        logError("failed to set tx power %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+
+    // set up the network keys
+    ParseKeys::initialize(dot, LORIOT_DEV_ADDR, LORIOT_NWK_S_KEY, LORIOT_APP_S_KEY);
+
+    // a higher spreading factor allows for longer range but lower throughput
+    // in the 915 (US) frequency band, spreading factors 7 - 10 are available
+    // in the 868 (EU) frequency band, spreading factors 7 - 12 are available
+    logInfo("setting TX spreading factor");
+    if ((ret = dot->setTxDataRate(mDot::SF_9)) != mDot::MDOT_OK) {
+        logError("failed to set TX datarate %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+
+    // request receive confirmation of packets from the gateway
+    logInfo("enabling ACKs");
+    if ((ret = dot->setAck(1)) != mDot::MDOT_OK) {
+        logError("failed to enable ACKs %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+
+    logInfo("enabling ADR");
+    if ((ret = dot->setAdr(1)) != mDot::MDOT_OK) {
+        logError("failed to enable ADR %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+
+    // save this configuration to the mDot's NVM
+    logInfo("saving config");
+    if (! dot->saveConfig()) {
+        logError("failed to save configuration");
+    }
+
+    //*******************************************
+    // end of configuration
+    //*******************************************
+
+    read_counter();
+
+    dot->setWakeupCallback(&wakeUpCallback);
+
+    dot->sleep(0, mDot::INTERRUPT, false);
+
+    while (true) {
+        wait_ms(1000);
+    }
+}