mdot UDK & STMicro MEMS Shield Sensor packet example
Dependencies: libmDot-mbed5 DOGS102 ISL29011 MMA845x MPL3115A2 NCP5623B X_NUCLEO_IKS01A1 Senet_Packet
Fork of MTDOT-UDKDemo_Senet by
Diff: main.cpp
- Branch:
- develop
- Revision:
- 27:1753a44fa9ec
- Child:
- 28:4fd8a894a403
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Aug 24 17:56:53 2017 -0400
@@ -0,0 +1,314 @@
+/***
+ * _____ _
+ * / ____| | |
+ * | (___ ___ _ __ ___ | |_
+ * \___ \ / _ \ | '_ \ / _ \ | __|
+ * ____) | | __/ | | | | | __/ | |_
+ * |_____/ \___| |_| |_| \___| \__|
+ * (C) 2016 Senet, Inc
+ *
+ */
+
+#include "board.h"
+#include "senet_packet.h"
+
+/******************************************************************************
+ * LoRaWAN Configuration *
+ ******************************************************************************/
+ // Senet Developer Portal Application EUI
+static uint8_t APP_EUI[8] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01};
+
+// Get Application Key from Senet Developer Portal Device Edit page
+static uint8_t APP_KEY[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+#define DATARATE mDot::DR0
+#define TXPOWER 20
+#define JOIN_RETRIES 1
+
+static std::vector<uint8_t> appEUI(APP_EUI,APP_EUI+sizeof(APP_EUI)/sizeof(uint8_t));
+static std::vector<uint8_t> appKey(APP_KEY,APP_KEY+sizeof(APP_KEY)/sizeof(uint8_t));
+static uint8_t fsb = 0;
+static bool adrOn = true;
+
+/******************************************************************************/
+
+#define APP_TX_DUTY_CYCLE_NORMAL 300000 // 5 min
+#define APP_TX_DUTY_CYCLE_ALARM 15000 // 15 s
+
+// Backend configured state. Set true to enable alarm rate transmits until backend response
+static bool BackendEnabled = false;
+
+#define HORIZONTAL_ORIENTATION_VALUE 1 // transmitted value when device is horizontal
+#define VERTICAL_ORIENTATION_VALUE 2 // transmitted value when device is vertical
+
+// Transmit rate related variables
+static bool NextTx = true;
+static uint32_t AppTxDutyCycle = APP_TX_DUTY_CYCLE_NORMAL;
+
+static Ticker joinTicker;
+static Ticker nextTxTimer;
+static BoardSensorData sensorData;
+static BoardOrientation orientation;
+
+
+// Backend service state (set to false if backend is not configured)
+static bool BackendSynchronized = true;
+BoardOrientation BackendOrientation;
+
+// Forward
+static void log_error(mDot* dot, const char* msg, int32_t retval);
+static void joinLedToggle();
+static void onNextTxTimerEvent();
+static void ReceiveData(std::vector<uint8_t> frame);
+
+void JoinNetwork()
+{
+ bool ok;
+ int32_t mdot_ret;
+
+ do{
+ ok = true;
+
+ // reset to default config so we know what state we're in
+ mDotPtr->resetConfig();
+ mDotPtr->setLogLevel(6);
+ mDotPtr->setAntennaGain(-3);
+
+ // Read node ID
+ std::vector<uint8_t> mdot_EUI;
+ mdot_EUI = mDotPtr->getDeviceId();
+ printf("mDot EUI = ");
+
+ for (uint8_t i=0; i<mdot_EUI.size(); i++)
+ printf("%02x ", mdot_EUI[i]);
+ printf("\n\r");
+
+ /*
+ * This call sets up private or public mode on the MTDOT. Set the function to true if
+ * connecting to a public network
+ */
+ printf("setting Public Network Mode\r\n");
+ if ((mdot_ret = mDotPtr->setPublicNetwork(true)) != mDot::MDOT_OK)
+ log_error(mDotPtr, "failed to set Public Network Mode", mdot_ret);
+
+ mDotPtr->setTxDataRate(DATARATE);
+ mDotPtr->setTxPower(TXPOWER);
+ mDotPtr->setJoinRetries(JOIN_RETRIES);
+ mDotPtr->setJoinMode(mDot::OTA);
+
+ /*
+ * Frequency sub-band is valid for NAM only and for Private networks should be set to a value
+ * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only.
+ * This function can be commented out for EU networks
+ */
+ printf("setting frequency sub band\r\n");
+ if ((mdot_ret = mDotPtr->setFrequencySubBand(fsb)) != mDot::MDOT_OK) {
+ log_error(mDotPtr, "failed to set frequency sub band", mdot_ret);
+ ok = false;
+ }
+
+ printf("setting ADR\r\n");
+ if ((mdot_ret = mDotPtr->setAdr(adrOn)) != mDot::MDOT_OK) {
+ log_error(mDotPtr, "failed to set ADR", mdot_ret);
+ ok = false;
+ }
+
+ /*
+ * setNetworkName is used for private networks.
+ * Use setNetworkID(AppID) for public networks
+ */
+ printf("setting network name\r\n");
+ if ((mdot_ret = mDotPtr->setNetworkId(appEUI)) != mDot::MDOT_OK) {
+ log_error(mDotPtr, "failed to set network name", mdot_ret);
+ ok = false;
+ }
+
+ /*
+ * setNetworkPassphrase is used for private networks
+ * Use setNetworkKey for public networks
+ */
+ printf("setting network key\r\n");
+ if ((mdot_ret = mDotPtr->setNetworkKey(appKey)) != mDot::MDOT_OK) {
+ log_error(mDotPtr, "failed to set network password", mdot_ret);
+ ok = false;
+ }
+
+ BoardCheckForExit(true);
+
+ } while(ok == false);
+
+ joinTicker.attach(joinLedToggle,1);
+
+ // attempt to join the network
+ printf("joining network\r\n");
+ while ((mdot_ret = mDotPtr->joinNetwork()) != mDot::MDOT_OK)
+ {
+ BoardCheckForExit(true);
+
+ log_error(mDotPtr,"failed to join network:", mdot_ret);
+ uint32_t delay_s = (mDotPtr->getNextTxMs() / 1000) + 1;
+ wait(delay_s);
+ }
+
+ printf("network joined\r\n");
+
+ joinTicker.detach();
+ appLED=1;
+}
+
+void SendFrame()
+{
+ std::vector<uint8_t> frame;
+ int32_t mdot_ret;
+ uint8_t buffer[20];
+ SensorPacket packet(buffer, sizeof(buffer));
+
+ // Sensor packet type serialized to the frame buffer
+ packet.setPrimarySensor(orientation.horizontal ? HORIZONTAL_ORIENTATION_VALUE : VERTICAL_ORIENTATION_VALUE);
+ packet.setTemperature(sensorData.temperature);
+ packet.setPressure(sensorData.pressure);
+ packet.serialize();
+
+ frame.assign(packet.payload(), packet.payload() + packet.length());
+ if ((mdot_ret = mDotPtr->send(frame)) != mDot::MDOT_OK)
+ {
+ log_error(mDotPtr, "failed to send", mdot_ret);
+ }
+ else
+ {
+ printf("successfully sent data\r\n");
+ frame.clear();
+ if ((mdot_ret = mDotPtr->recv(frame)) == mDot::MDOT_OK)
+ {
+ printf("recv data: ");
+ for(uint32_t i = 0;i < frame.size();i++)
+ printf("%02X",frame[i]);
+ printf("\r\n");
+
+ ReceiveData(frame);
+ }
+ }
+}
+
+void ReceiveData(std::vector<uint8_t> frame)
+{
+ BackendOrientation.horizontal = (frame[0] == HORIZONTAL_ORIENTATION_VALUE);
+
+ if( BackendOrientation.horizontal == orientation.horizontal )
+ BackendSynchronized = true;
+}
+
+
+int main()
+{
+ time_t lastTxT;
+
+ // Initialize Board
+ BoardSetState(Board_init);
+
+ // Join Network
+ JoinNetwork();
+
+ // Start Board sensors
+ BoardSetState(Board_start);
+
+ // Initialize board orientation
+ BoardReadSensors(sensorData);
+ orientation = sensorData.orientation;
+
+ BackendSynchronized = false;
+
+ // Start transmit timer
+ nextTxTimer.attach_us(onNextTxTimerEvent, AppTxDutyCycle * 1e3);
+
+ while( !BoardCheckForExit(false) )
+ {
+ // Update device orientation
+ if( ( BackendSynchronized == true ) && ( sensorData.orientation.horizontal != orientation.horizontal ) )
+ {
+ BackendSynchronized = false;
+ orientation = sensorData.orientation;
+
+ // Get elapsed time since last transmit
+ time_t currT = time(NULL);
+ time_t elapsedT = ( currT - lastTxT ) * 1e3;
+
+ // Transmit now if elapsed time since last tx is greater than alarm mode dutycycle
+ if( elapsedT >= APP_TX_DUTY_CYCLE_ALARM )
+ {
+ nextTxTimer.detach();
+ NextTx = true;
+ }
+ // Otherwise wait until alarm dutycycle time has elapased
+ else
+ {
+ nextTxTimer.detach();
+ nextTxTimer.attach_us(onNextTxTimerEvent, (APP_TX_DUTY_CYCLE_ALARM - elapsedT)* 1e3);
+ }
+
+ AppTxDutyCycle = APP_TX_DUTY_CYCLE_ALARM;
+ }
+
+ if ( NextTx == true )
+ {
+ /* Backend synchronized flag set true when
+ * - backend not enabled
+ * - Downlink received containing last known orientation
+ */
+ BackendSynchronized = !BackendEnabled;
+
+ // Transmit application frame
+ SendFrame();
+ lastTxT = time(NULL);
+
+ NextTx = false;
+
+ // Fast transmit rate while backend is out of sync with device state
+ if(BackendSynchronized == false)
+ {
+ if( ( AppTxDutyCycle != APP_TX_DUTY_CYCLE_ALARM ) )
+ {
+ AppTxDutyCycle = APP_TX_DUTY_CYCLE_ALARM;
+ nextTxTimer.detach();
+ nextTxTimer.attach_us(onNextTxTimerEvent, APP_TX_DUTY_CYCLE_ALARM * 1e3);
+ }
+ }
+ else if( AppTxDutyCycle != APP_TX_DUTY_CYCLE_NORMAL )
+ {
+ AppTxDutyCycle = APP_TX_DUTY_CYCLE_NORMAL;
+ nextTxTimer.detach();
+ nextTxTimer.attach_us(onNextTxTimerEvent, APP_TX_DUTY_CYCLE_NORMAL * 1e3);
+ }
+ }
+
+ // Delay before next sensor poll
+ osDelay(2000);
+
+ // Read sensors
+ BoardReadSensors(sensorData);
+ }
+
+ BoardSetState(Board_stop);
+
+ return 0;
+}
+
+
+/*
+ * prints of mDot error
+ */
+void log_error(mDot* dot, const char* msg, int32_t retval)
+{
+ printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str());
+}
+
+void joinLedToggle()
+{
+ appLED= !appLED;
+}
+
+void onNextTxTimerEvent( void )
+{
+ NextTx = true;
+}
+
