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 canuck lehead

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;
+}
+