edge / Mbed 2 deprecated testReed

Dependencies:   libmDot mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
waltertakens
Date:
Thu Jun 02 12:27:37 2016 +0000
Parent:
4:0fb159501a04
Commit message:
met lora

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
payload.h Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Thu May 19 11:53:35 2016 +0000
+++ b/main.cpp	Thu Jun 02 12:27:37 2016 +0000
@@ -1,168 +1,279 @@
 #include "mbed.h"
-#include "rtos.h"
 #include "mDot.h"
 #include "MTSLog.h"
-#include "MTSText.h"
-
-using namespace mts;
+#include <string>
+#include <vector>
+#include <algorithm>
 
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-// http://www.multitech.net/developer/forums/topic/mdot-pinout-associate-and-onsleep/
-// Keep in mind that if you want to put the device in deepsleep mode
-// and wake up with an interrupt, pin D3/XBEE_CTS/XBEE_DIO7/PA_0 is
-// the only pin that can be used.
+#include "payload.h"
 
 #define REED_PORT   PA_0
-#define MINIMAL_SECONDS_BETEEN_CONTACT      10
-#define MAXIMAL_SECONDS_BETEEN_CONTACT      60
-
-// https://developer.mbed.org/users/mbed_official/code/mbed/docs/252557024ec3/classmbed_1_1RawSerial.html
-RawSerial pc(PA_2,NC);
-//RawSerial pc(USBTX,USBRX);
-//DigitalIn reed_gpio(REED_PORT);
 
-
-
+// PA_0 = WKUP
+// wakeup on rising edge
+// reeed on PA_0 to Vss (3.3V)
+// no internal pull in sleep mode
+DigitalIn reed_sensor(PA_0, PullNone);
 volatile int reed_has_changed = 0;
-int reed_value_to_send = 0;
-int reed_value_last_sent = 0;
-int reed_gpio_value = 0;
 
- void isr_reed_sensor_change(void) {
+void isr_reed_sensor_change(void) {
     reed_has_changed++;
 }
 
-int has_reed_changed(void) {
-    
-    int change;
-    
-    change = reed_has_changed;
-    reed_has_changed = 0;
-    //reed_gpio_value = reed_gpio.read();
+#define NODETYPE_OPENCLOSE  1
+
+static std::string config_network_name = "edgelorareed2";
+static std::string config_network_pass = "edgeIsGaaf";
+
 
-    return(change);
-}
-    
-int has_reed_changed_since_last_sent(void) {
-    
-    int change;
+static struct {
+  uint8_t openorclosedid;
+  uint8_t closedvalue;          //open=1 close-0
+  
+}  payloadOpenClose;
 
-    has_reed_changed();
-    
-    change = reed_gpio_value != reed_value_last_sent;
-    
-    pc.printf("%d: REED = %d (was %d)\r\n",time(NULL),reed_gpio_value,reed_value_last_sent);
-    
-    return(change);
+
+
+int DoNode1 (uint8_t*b,uint8_t v){
+    *b++=NODETYPE_OPENCLOSE;
+    *b++=v; 
+    return(sizeof(payloadOpenClose));          
 }
 
-void send_reed(void) {
-    
-    //reed_value_last_sent = reed_gpio.read();
-    
-    pc.printf("%d: Sending REED = %d\r\n",time(NULL),reed_value_last_sent);
-    
-    Thread::wait(10);
-}
-    
+
+// these options must match the settings on your Conduit
+// uncomment the following lines and edit their values to match your configuration
+
+//static uint8_t config_network_addr[] = { 0x02, 0x02, 0x02, 0x02 };
+  static uint8_t config_network_addr[] = { 0x02, 0x02, 0x02, 0x02 };
+  
+//static uint8_t config_network_nskey[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
+  static uint8_t config_network_nskey[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
+
+// static uint8_t config_network_dskey[] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+   static uint8_t config_network_dskey[] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+
+
+//WBT commentout, only for 915 Mhz    static uint8_t config_frequency_sub_band = 1;
 
 int main() {
-    
+    int32_t ret;
     mDot* dot;
-    long last_sent = 0;
-    long last_sent_change = 0;
+    std::vector<uint8_t> data;
+    
+    //std::string data_str = "hello this is Edge calling!";
+    std::string data_str = "hello!";
+    
+    DigitalIn enable(PA_3);
+    
+    InterruptIn reed_sensor_change(REED_PORT);
+    reed_sensor_change.fall(&isr_reed_sensor_change);
+    reed_sensor_change.rise(&isr_reed_sensor_change);
+    reed_sensor_change.mode(PullNone);
     
-    pc.baud(115200);
+    logInfo("\n\n\n\n\n");
+    wait(5);
+    logInfo("\n\n\n***************************************\nStarting\n");
+    wait(5);
+    logInfo("Started version 1.1 2 june 14.25 \n");
+    logInfo(        "* Build: " __DATE__ ", " __TIME__" *\r\n");
+    
+     time_t seconds = time(NULL);
+     uint32_t boottime=(uint32_t) seconds;
+    
+    
+    // get a mDot handle
+    dot = mDot::getInstance();
     
-    pc.printf("\r\n\r\n********************************\r\n");
-    pc.printf(        "*                              *\r\n");
-    pc.printf(        "*            Edge Reed         *\r\n");
-    pc.printf(        "*                              *\r\n");
-    pc.printf(        "* Build: " __DATE__ ", " __TIME__" *\r\n");
-    pc.printf(        "********************************\r\n\r\n");
+    // Test if we've already saved the config
+    std::string configNetworkName = dot->getNetworkName();
+        // Reset config if network name is different or pin is low then reset config.
+    if( config_network_name.compare(configNetworkName) != 0 ) {
+        // Not saved config, reset
+        logInfo("Setting Config");
+        // reset to default config so we know what state we're in
+        dot->resetConfig();
+    }
+    else {
+         logInfo("Resume with old  Config");
+    }
+    
+        // clear the EWUP state
+    if(dot->getStandbyFlag()){
+        logInfo("clearing standby flag\r\n");
+        PWR->CSR &= ~PWR_CSR_EWUP;
+    }
+    
+    dot->setLogLevel(mts::MTSLog::TRACE_LEVEL);
+   
+    logError("JoinMode= %d\n", dot->getJoinMode());
+    
+    // print library version information
+    logInfo("version: %s", dot->getId().c_str());
+    
+    if ((ret = dot->setNetworkName("edgeedge")) != mDot::MDOT_OK) {
+            logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+     }
+ 
+    if ((ret = dot->setNetworkPassphrase("svensven")) != mDot::MDOT_OK) {
+            logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+     }
+ 
+    logInfo("Name: %s\r\n", dot->getNetworkName());
+    dot->setPublicNetwork(true);
+    
 
-    //reed_gpio.mode(PullUp);
+    //*******************************************
+    // configuration
+    //*******************************************
 
-    for(int i=0;i<10;i++) {
-        //pc.printf("after int %d (%d)\r\n",reed_gpio.read(),reed_has_changed);
-        pc.printf("after int %d\r\n",reed_has_changed);
-        Thread::wait(1000);
+    // 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()
+    
+    // frequency sub band is only applicable in the 915 (US) frequency band
+    // if using a MultiTech Conduit gateway, use the same sub band as your Conduit (1-8) - the mDot will use the 8 channels in that sub band
+    // if using a gateway that supports all 64 channels, use sub band 0 - the mDot will use all 64 channels
+    
+    //WBT logInfo("setting frequency sub band");
+    // 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());
+    //}
+    
+    
+    
+    std::vector<uint8_t> temp;
+    
+    for (int i = 0; i < 4; i++) {
+        temp.push_back(config_network_addr[i]);    
+    }
+    
+    logInfo("setting network addr");
+    if ((ret = dot->setNetworkAddress(temp)) != mDot::MDOT_OK) {
+        logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    temp.clear();
+    for (int i = 0; i < 16; i++) {
+        temp.push_back(config_network_nskey[i]);    
+    }
+    
+    logInfo("setting network password");
+    if ((ret = dot->setNetworkSessionKey(temp)) != mDot::MDOT_OK) {
+        logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    temp.clear();
+    for (int i = 0; i < 16; i++) {
+        temp.push_back(config_network_dskey[i]);    
     }
-        
-    dot = mDot::getInstance();
-    dot->setLogLevel(MTSLog::TRACE_LEVEL);
+    
+    logInfo("setting network password");
+    if ((ret = dot->setDataSessionKey(temp)) != mDot::MDOT_OK) {
+        logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    // 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_10)) != mDot::MDOT_OK) {
+        logError("failed to set TX datarate %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    // WBT DONT request receive confirmation of packets from the gateway
+    //logInfo("WBT DONT enabling ACKs");
+    //if ((ret = dot->setAck(0)) != mDot::MDOT_OK) {
+        //logError("failed to NOT enable ACKs %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    //}
+    
+    /*
+    logInfo("WBT DO enabling ACKs");
+    if ((ret = dot->setAck(1)) != mDot::MDOT_OK) {
+        logError("failed to  enable ACKs %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    */
+    logInfo("WBT UNABLE ACKs");
+    if ((ret = dot->setAck(0)) != mDot::MDOT_OK) {
+        logError("failed to  unnable ACKs %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+    
+    //     TODO   Command(dot, "Rx Output", "AT+RXO", "Set the Rx output type (0:hexadecimal, 1:raw)"), _serial(serial)
+    
+    
+  
+  /*  
+    logInfo("WBT SET JOIN");
+    if ((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
+        logError("failed to set to manual %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+    }
+      
+    logInfo("WBT GET JOIN");
+    ret = dot->getJoinMode();
+    logError("WBTGET JOIN %d\n", ret);
 
-    InterruptIn *reed_sensor_change;
-    reed_sensor_change = new InterruptIn(PA_0);
-    reed_sensor_change->fall(&isr_reed_sensor_change);
-    reed_sensor_change->rise(&isr_reed_sensor_change);
-    reed_sensor_change->mode(PullUp);
+    */
      
-    for(int i=0;i<10;i++) {
-        //pc.printf("after int %d (%d)\r\n",reed_gpio.read(),reed_has_changed);
-        pc.printf("after int %d\r\n",reed_has_changed);
-        Thread::wait(1000);
+    
+    // save this configuration to the mDot's NVM
+    logInfo("saving config");
+    if (! dot->saveConfig()) {
+        logError("failed to save configuration");
     }
+    //*******************************************
+    // end of configuration
+    //*******************************************
+/*
+    // attempt to join the network
+    logInfo("joining network");
+    while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
+        logError("failed to join network %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
+        // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again
+        osDelay(std::max((uint32_t)1000, (uint32_t)dot->getNextTxMs()));
         
+        //WBT
+        wait(60);
+    }
+    */
+
+     uint32_t now = (uint32_t)seconds - boottime;
+    
+    
+    //debugformat data for sending to the gateway
+    for (std::string::iterator it = data_str.begin(); it != data_str.end(); it++)
+        data.push_back((uint8_t) *it);
+    
     while (true) {
         
-        int wakeup_time = last_sent + MAXIMAL_SECONDS_BETEEN_CONTACT;
-        int time_since_last_sent = time(NULL) - last_sent;
-        int time_since_last_sent_change = time(NULL) - last_sent_change;
+        //for now fake the absolute value of reed_has_changed into battery level
+        //(to avoid that only 0/1 are valid values
+        
+        //setBatteryLevel(reed_has_changed);
+        //getDataAndUpdate(&data);
         
-        if(time_since_last_sent >= MAXIMAL_SECONDS_BETEEN_CONTACT) {
-            
-            pc.printf("%d: Sending because max-time\r\n",time(NULL));
-            
-            has_reed_changed();
-            send_reed();
-            last_sent = time(NULL);
-            wakeup_time = last_sent + MAXIMAL_SECONDS_BETEEN_CONTACT;
-            
-        } else if(has_reed_changed() || has_reed_changed_since_last_sent()) {
-            
-            pc.printf("%d: Change!\r\n",time(NULL));
-            
-            if(time_since_last_sent_change >= MINIMAL_SECONDS_BETEEN_CONTACT) {
-           
-                int b=100;
-                
-                while(has_reed_changed()&&(b--)) {
-                
-                    Thread::wait(10);
-                }
-           
-                if(has_reed_changed_since_last_sent()) {
-           
-                    pc.printf("%d: Sending because of change\r\n",time(NULL));
-           
-                    send_reed();
-                    last_sent_change = time(NULL);
-                    wakeup_time = last_sent_change + MAXIMAL_SECONDS_BETEEN_CONTACT;
-                    
-                } else {
-                    
-                    pc.printf("%d: No change after debounce\r\n",time(NULL));
-                }
-                
-            } else {
-                
-                    pc.printf("%d: Not sending because min-time\r\n",time(NULL));
-                     
-                    wakeup_time = MIN(wakeup_time, last_sent_change + MINIMAL_SECONDS_BETEEN_CONTACT);
-            }
+        // meet
+        logInfo("Reed = %d", reed_has_changed);
+        
+        
+        
+        // send the data to the gateway
+        if ((ret = dot->send(data)) != mDot::MDOT_OK) {
+            logError("failed to send err=%d errs=%s", ret, mDot::getReturnCodeString(ret).c_str());
+        } else {
+            logInfo("successfully sent data to gateway");
         }
         
-        int sleep_time = wakeup_time - time(NULL);
-        
-        pc.printf("%d: Sleeping %d seconds\r\n",time(NULL),sleep_time);
-        
-        Thread::wait(10);
+        // inpired by https://developer.mbed.org/teams/MultiTech/code/mDot_AT_firmware/file/6a12bf1f6723/CommandTerminal/CmdReceiveOnce.cpp
+        //if we asked for an ack, then the send will have returned with the ack recption and data is ready ???
+        if (dot->recv(data) == mDot::MDOT_OK) {
+                printf("data received=\n");
+                //printf("data received= %s\n", dot->getRxOutput().c_str(););    
+        }
+                
+        // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again
+        //osDelay(std::max((uint32_t)5000, (uint32_t)dot->getNextTxMs()));
         
-        dot->sleep(sleep_time, mDot::RTC_ALARM_OR_INTERRUPT, false);
-        
-        pc.printf("%d: Woke up\r\n",time(NULL));
+        //deepsleep
+        dot->sleep((int)60, mDot::RTC_ALARM_OR_INTERRUPT, true);
     }
-}
\ No newline at end of file
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/payload.h	Thu Jun 02 12:27:37 2016 +0000
@@ -0,0 +1,92 @@
+// automagically generated (version 20160519)
+// by: http://iot.edgetech.nl/iot/node/includeFile?node=0x01
+// on: 20160519
+#include <Semaphore.h>
+
+enum NodeStates { development = 0, preproduction = 1, production = 2};
+#define NODE_ID                     0x01
+#define NODE_STATE           development
+
+#define CONTACT_NOACK_MIN          10000
+#undef  CONTACT_NOACK_MAX   
+#define CONTACT_ACK_MIN          3600000
+#define CONTACT_ACK_MAX          3600000
+
+#define CONTACT_MAX_TOTAL_PER_DAY    100
+
+#pragma pack(push, 1)
+typedef struct payloadvalues{
+  unsigned char node_id;
+  unsigned char reed_sensor_value: 1;
+  unsigned char change_in_last_ack_window: 1; 
+  unsigned char low_battery: 1;
+  unsigned char battery_level;
+}  PayloadValues;
+
+typedef union payload {
+   PayloadValues values;
+   char b[sizeof(PayloadValues)];
+} Payload;
+
+Payload payload_new = {NODE_ID,0,0};
+Payload payload_last = {NODE_ID,0,0};
+#pragma pack(pop)
+
+Semaphore payload_protect(1);
+
+int setReedSensorValue(unsigned char value) {
+    if(value>1) {
+        return(0);
+    }
+    payload_protect.wait();
+    payload_new.values.reed_sensor_value = value;
+    payload_protect.release();
+    return(1);
+}
+
+int setChangeInLastAckWindow(unsigned char value) {
+    if(value>1) {
+        return(0);
+    }
+    payload_protect.wait();
+    payload_new.values.change_in_last_ack_window = value;
+    payload_protect.release();
+    return(1);
+}
+
+int setLowBattery(unsigned char value) {
+    if(value>1) {
+        return(0);
+    }
+    payload_protect.wait();
+    payload_new.values.low_battery = value;
+    payload_protect.release();
+    return(1);
+}
+
+int setBatteryLevel(unsigned char value) {
+    payload_protect.wait();
+    payload_new.values.battery_level = value;
+    payload_protect.release();
+    return(1);
+}
+
+int hasChanges() {
+    payload_protect.wait();
+    for(int i=1;i<sizeof(Payload);i++) {
+        if(payload_new.b[i]!=payload_last.b[i]) {
+            payload_protect.release();
+            return(1);
+        }
+    }
+    payload_protect.release();
+    return(0);
+}
+
+void getDataAndUpdate(std::vector<uint8_t> *b) {
+    payload_protect.wait();
+    std::copy(payload_new.b, payload_new.b + sizeof(Payload), b->begin());
+    std::copy(payload_new.b, payload_new.b + sizeof(Payload), payload_last.b);
+    payload_protect.release();
+}
+