Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: libmDot mbed-rtos mbed
Revision 5:5654666925e1, committed 2016-06-02
- 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();
+}
+