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
main.cpp
00001 /* _____ _ 00002 * / ____| | | 00003 * | (___ ___ _ __ ___ | |_ 00004 * \___ \ / _ \ | '_ \ / _ \ | __| 00005 * ____) | | __/ | | | | | __/ | |_ 00006 * |_____/ \___| |_| |_| \___| \__| 00007 * (C) 2016 Senet, Inc 00008 * 00009 */ 00010 00011 #include "board.h" 00012 #include "senet_packet.h" 00013 00014 00015 /****************************************************************************** 00016 * LoRaWAN Configuration * 00017 ******************************************************************************/ 00018 // Senet Developer Portal Application EUI 00019 static uint8_t APP_EUI[8] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01}; 00020 00021 // Get Application Key from Senet Developer Portal Device Edit page 00022 static uint8_t APP_KEY[16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 00023 00024 #define DATARATE mDot::DR0 00025 #define TXPOWER 20 00026 #define JOIN_RETRIES 1 00027 00028 static std::vector<uint8_t> appEUI(APP_EUI,APP_EUI+sizeof(APP_EUI)/sizeof(uint8_t)); 00029 static std::vector<uint8_t> appKey(APP_KEY,APP_KEY+sizeof(APP_KEY)/sizeof(uint8_t)); 00030 static uint8_t fsb = 0; 00031 static bool adrOn = true; 00032 /******************************************************************************/ 00033 00034 00035 /****************************************************************************** 00036 * Application Configuration * 00037 ******************************************************************************/ 00038 #define APP_TX_DUTY_CYCLE_NORMAL 300000 // 5 min 00039 #define APP_TX_DUTY_CYCLE_ALARM 15000 // 15 s 00040 00041 // Backend configured state. Set true to enable alarm rate transmits until backend response 00042 static bool BackendEnabled = false; 00043 /******************************************************************************/ 00044 00045 // Transmitted orientation values 00046 #define HORIZONTAL_ORIENTATION_VALUE 1 // transmitted value when device is horizontal 00047 #define VERTICAL_ORIENTATION_VALUE 2 // transmitted value when device is vertical 00048 00049 00050 // Set to true when backend is synchronized 00051 static bool BackendSynchronized = true; 00052 // Set to true to force backend resync 00053 static bool OrientationInit = true; 00054 static bool DisplayBackendState = true; 00055 static BoardOrientation BackendOrientation; 00056 static Ticker joinTicker; 00057 static Ticker nextTxTimer; 00058 static BoardSensorData sensorData; 00059 static BoardOrientation txOrientation; 00060 static BoardOrientation lastOrientation; 00061 static bool NextTx = true; 00062 static uint32_t AppTxDutyCycle = APP_TX_DUTY_CYCLE_NORMAL; 00063 static uint32_t orientationChangeCount = 0; 00064 00065 // Orientation comparison 00066 inline bool orientationIsEqual(BoardOrientation &a, BoardOrientation &b) 00067 { 00068 // For this application only vertical/horizontal state is tested 00069 return ( a.vertical == b.vertical ); 00070 } 00071 00072 static void log_error(mDot* dot, const char* msg, int32_t retval); 00073 static void joinLedToggle(); 00074 static void onNextTxTimerEvent(); 00075 static void ReceiveData(std::vector<uint8_t> frame); 00076 00077 00078 void JoinNetwork() 00079 { 00080 bool ok; 00081 int32_t mdot_ret; 00082 00083 do{ 00084 ok = true; 00085 00086 // reset to default config so we know what state we're in 00087 mDotPtr->resetConfig(); 00088 mDotPtr->setLogLevel(6); 00089 mDotPtr->setAntennaGain(-3); 00090 00091 // Read node ID 00092 std::vector<uint8_t> mdot_EUI; 00093 mdot_EUI = mDotPtr->getDeviceId(); 00094 printf("mDot EUI = "); 00095 00096 for (uint8_t i=0; i<mdot_EUI.size(); i++) 00097 printf("%02x ", mdot_EUI[i]); 00098 printf("\n\r"); 00099 00100 /* 00101 * This call sets up private or public mode on the MTDOT. Set the function to true if 00102 * connecting to a public network 00103 */ 00104 printf("setting Public Network Mode\r\n"); 00105 if ((mdot_ret = mDotPtr->setPublicNetwork(true)) != mDot::MDOT_OK) 00106 log_error(mDotPtr, "failed to set Public Network Mode", mdot_ret); 00107 00108 mDotPtr->setTxDataRate(DATARATE); 00109 mDotPtr->setTxPower(TXPOWER); 00110 mDotPtr->setJoinRetries(JOIN_RETRIES); 00111 mDotPtr->setJoinMode(mDot::OTA); 00112 00113 /* 00114 * Frequency sub-band is valid for NAM only and for Private networks should be set to a value 00115 * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only. 00116 * This function can be commented out for EU networks 00117 */ 00118 printf("setting frequency sub band\r\n"); 00119 if ((mdot_ret = mDotPtr->setFrequencySubBand(fsb)) != mDot::MDOT_OK) { 00120 log_error(mDotPtr, "failed to set frequency sub band", mdot_ret); 00121 ok = false; 00122 } 00123 00124 printf("setting ADR\r\n"); 00125 if ((mdot_ret = mDotPtr->setAdr(adrOn)) != mDot::MDOT_OK) { 00126 log_error(mDotPtr, "failed to set ADR", mdot_ret); 00127 ok = false; 00128 } 00129 00130 /* 00131 * setNetworkName is used for private networks. 00132 * Use setNetworkID(AppID) for public networks 00133 */ 00134 printf("setting network name\r\n"); 00135 if ((mdot_ret = mDotPtr->setNetworkId(appEUI)) != mDot::MDOT_OK) { 00136 log_error(mDotPtr, "failed to set network name", mdot_ret); 00137 ok = false; 00138 } 00139 00140 /* 00141 * setNetworkPassphrase is used for private networks 00142 * Use setNetworkKey for public networks 00143 */ 00144 printf("setting network key\r\n"); 00145 if ((mdot_ret = mDotPtr->setNetworkKey(appKey)) != mDot::MDOT_OK) { 00146 log_error(mDotPtr, "failed to set network password", mdot_ret); 00147 ok = false; 00148 } 00149 00150 } while(ok == false); 00151 00152 joinTicker.attach(joinLedToggle, 5); 00153 00154 // attempt to join the network 00155 printf("joining network\r\n"); 00156 while ((mdot_ret = mDotPtr->joinNetwork()) != mDot::MDOT_OK) 00157 { 00158 log_error(mDotPtr,"failed to join network:", mdot_ret); 00159 uint32_t delay_s = (mDotPtr->getNextTxMs() / 1000) + 1; 00160 wait(delay_s); 00161 } 00162 00163 printf("network joined\r\n"); 00164 00165 joinTicker.detach(); 00166 CBoard::SetLED(1, false); 00167 } 00168 00169 void SendFrame() 00170 { 00171 std::vector<uint8_t> frame; 00172 int32_t mdot_ret; 00173 uint8_t buffer[20]; 00174 SensorPacket packet(buffer, sizeof(buffer)); 00175 00176 // Sensor packet type serialized to the frame buffer 00177 packet.setPrimarySensor(txOrientation.vertical ? VERTICAL_ORIENTATION_VALUE : HORIZONTAL_ORIENTATION_VALUE); 00178 packet.setTemperature(sensorData.temperature); 00179 packet.setPressure(sensorData.pressure); 00180 packet.serialize(); 00181 00182 frame.assign(packet.payload(), packet.payload() + packet.length()); 00183 if ((mdot_ret = mDotPtr->send(frame)) != mDot::MDOT_OK) 00184 { 00185 log_error(mDotPtr, "failed to send", mdot_ret); 00186 } 00187 else 00188 { 00189 printf("successfully sent data\r\n"); 00190 frame.clear(); 00191 if ((mdot_ret = mDotPtr->recv(frame)) == mDot::MDOT_OK) 00192 { 00193 printf("recv data: "); 00194 for(uint32_t i = 0;i < frame.size();i++) 00195 printf("%02X",frame[i]); 00196 printf("\r\n"); 00197 00198 ReceiveData(frame); 00199 } 00200 } 00201 } 00202 00203 void ReceiveData(std::vector<uint8_t> frame) 00204 { 00205 BackendOrientation.vertical = (frame[0] == VERTICAL_ORIENTATION_VALUE); 00206 BackendSynchronized = !BackendEnabled || orientationIsEqual(BackendOrientation, txOrientation); 00207 00208 // Blink LED 00209 bool ledState = false; 00210 for(uint8_t i=0; i<3; i++) 00211 { 00212 CBoard::SetLED(1, ledState); 00213 ledState = !ledState; 00214 osDelay(500); 00215 } 00216 } 00217 00218 static void onButtonPress(uint8_t buttonNum) 00219 { 00220 DisplayBackendState = true; 00221 00222 if(buttonNum == 1) 00223 { 00224 OrientationInit = true; 00225 BackendEnabled = !BackendEnabled; 00226 00227 // Start next transmit immediately 00228 if( BackendEnabled && !NextTx ) 00229 { 00230 nextTxTimer.detach(); 00231 nextTxTimer.attach_us(onNextTxTimerEvent, 1000); 00232 } 00233 } 00234 } 00235 00236 int main() 00237 { 00238 time_t lastTxT; 00239 00240 // Initialize Board 00241 BoardInit(); 00242 00243 // Register pushbutton handler 00244 CBoard::SetButtonCallback(onButtonPress); 00245 00246 // Join Network 00247 JoinNetwork(); 00248 00249 // Start Board sensors 00250 CBoard::Start(); 00251 00252 while( true ) 00253 { 00254 // Read sensors 00255 if( CBoard::ReadSensors(sensorData) == Board_Ok ) 00256 { 00257 if( !orientationIsEqual(sensorData.orientation, lastOrientation) || OrientationInit) 00258 { 00259 orientationChangeCount++; 00260 lastOrientation = sensorData.orientation; 00261 } 00262 } 00263 00264 // Initialize orientation state 00265 if( OrientationInit ) 00266 { 00267 OrientationInit = false; 00268 orientationChangeCount = 1; 00269 // Set tx orientation to opposite of current as it will be toggled before transmit 00270 txOrientation.vertical = !lastOrientation.vertical; 00271 // Set backend to be out of sync 00272 BackendOrientation.vertical = txOrientation.vertical; 00273 } 00274 00275 // Display backend enabled state 00276 if(DisplayBackendState) 00277 { 00278 DisplayBackendState = false; 00279 00280 uint8_t ledToggleCount = BackendEnabled ? 3 : 2; 00281 CBoard::SetLED(1, false); 00282 // blink LED to indicate backend state 00283 for(uint32_t i=0; i < ledToggleCount*2; i++) 00284 { 00285 osDelay(1000); 00286 CBoard::ToggleLED(1); 00287 } 00288 00289 // Set LED to reflect Backend synchronized state 00290 CBoard::SetLED(1, BackendOrientation.vertical != txOrientation.vertical); 00291 } 00292 00293 // Get next orientation change to transmit after backend sync of the last transmitted orientation is finished 00294 if( ( BackendSynchronized == true ) && ( orientationChangeCount != 0 ) ) 00295 { 00296 BackendSynchronized = false; 00297 00298 // Set transmit orientation 00299 txOrientation.vertical = !txOrientation.vertical; 00300 orientationChangeCount--; 00301 00302 // Turn on out-of-sync LED 00303 CBoard::SetLED(1, true); 00304 00305 // Get elapsed time since last transmit 00306 time_t currT = time(NULL); 00307 time_t elapsedT = ( currT - lastTxT ) * 1e3; 00308 00309 // Stop transmit timer 00310 AppTxDutyCycle = 0; 00311 nextTxTimer.detach(); 00312 00313 // Wait to transmit until elapsed time is greater than alarm mode dutycycle 00314 NextTx = ( elapsedT >= APP_TX_DUTY_CYCLE_ALARM ); 00315 if( !NextTx ) 00316 { 00317 AppTxDutyCycle = APP_TX_DUTY_CYCLE_ALARM - elapsedT; 00318 nextTxTimer.attach_us(onNextTxTimerEvent, AppTxDutyCycle * 1e3); 00319 } 00320 } 00321 00322 if ( NextTx == true ) 00323 { 00324 NextTx = false; 00325 00326 /* Backend synchronized flag set true when 00327 * o Backend not enabled 00328 * o Backend in sync 00329 */ 00330 BackendSynchronized = !BackendEnabled || orientationIsEqual(BackendOrientation, txOrientation); 00331 00332 // Transmit application frame 00333 SendFrame(); 00334 00335 // Update transmit timestamp 00336 lastTxT = time(NULL); 00337 00338 // Set next transmit time 00339 if( BackendSynchronized == false ) 00340 { 00341 if( ( AppTxDutyCycle != APP_TX_DUTY_CYCLE_ALARM ) ) 00342 { 00343 AppTxDutyCycle = APP_TX_DUTY_CYCLE_ALARM; 00344 nextTxTimer.detach(); 00345 nextTxTimer.attach_us(onNextTxTimerEvent, AppTxDutyCycle * 1e3); 00346 } 00347 } 00348 else if( AppTxDutyCycle != APP_TX_DUTY_CYCLE_NORMAL ) 00349 { 00350 AppTxDutyCycle = APP_TX_DUTY_CYCLE_NORMAL; 00351 nextTxTimer.detach(); 00352 nextTxTimer.attach_us(onNextTxTimerEvent, AppTxDutyCycle * 1e3); 00353 } 00354 00355 // Set LED to reflect Backend synchronized state 00356 CBoard::SetLED(1, BackendOrientation.vertical != txOrientation.vertical); 00357 } 00358 00359 // Delay before next sensor poll 00360 osDelay(2000); 00361 } 00362 } 00363 00364 00365 /* 00366 * prints of mDot error 00367 */ 00368 void log_error(mDot* dot, const char* msg, int32_t retval) 00369 { 00370 printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str()); 00371 } 00372 00373 void joinLedToggle() { CBoard::ToggleLED(1); } 00374 00375 void onNextTxTimerEvent( void ) { NextTx = true; }
Generated on Sun Jul 24 2022 22:57:48 by
1.7.2
