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: BME280 SerialGPS libmDot mbed-rtos mbed
main.cpp
00001 /****************************************************** 00002 * A Program to interface the Grove Base Shielf V2 00003 * to the mDot UDK. 00004 * Additionally sample code to compress the data 00005 * for use with LPWANs such as LoRa 00006 * Uses Standard Firmware from Multitech 00007 * 00008 *****************************************************/ 00009 00010 #include "mbed.h" 00011 #include "mDot.h" 00012 #include "MTSLog.h" 00013 #include "MTSText.h" 00014 #include <string> 00015 #include "LoRa.h" 00016 #include "BME280.h" 00017 //#include "SerialGPS.h" 00018 00019 //using namespace mts; 00020 00021 #define MIN(a,b) (((a)<(b))?(a):(b)) 00022 #define MAX(a,b) (((a)>(b))?(a):(b)) 00023 00024 // mDot UDK Specific 00025 // MDot Pinout: https://developer.mbed.org/platforms/MTS-mDot-F411/#pinout-diagram 00026 // Uncomment this line if using a full sized UDK2.0 instead of a Micro UDK 00027 00028 #define UDK2 1 00029 #ifdef UDK2 00030 DigitalOut led(LED1); 00031 #else 00032 DigitalOut led(XBEE_RSSI); 00033 #endif 00034 00035 //SerialGPS gps(PA_2, PA_3); 00036 //BME280 sensor(I2C_SDA, I2C_SCL) 00037 // MDot UDK - I2C_SDA and I2C_SCL connected to PC_9/PA_* 00038 BME280 b280(PC_9, PA_8); 00039 AnalogIn light(PB_0); // This corresponds to A1 Connector on the Grove Shield 00040 00041 00042 // Function Declarations 00043 void endLessTestLoop(); 00044 void setUpLEDBlink(); 00045 void blink(); 00046 void readandprintBME280(); 00047 float readLightSensor(); 00048 void mDotConfig(); 00049 void mDotGotoDeepSleep(int seconds, bool sleepState); 00050 void mDotConfigPrint(); 00051 void initSerialGPS(); 00052 void setupNetwork(); 00053 void joinNetwork(); 00054 void sendData(); 00055 00056 // Globals 00057 Ticker tick; 00058 mDot* dot; 00059 float llevel; 00060 00061 /***************************************************** 00062 * MAIN 00063 *****************************************************/ 00064 int main(){ 00065 00066 // Simple Test Functions, "Hello World on UDK 00067 //setUpLEDBlink(); 00068 00069 mDotConfig(); 00070 // setupNetwork(); // Moved to mDotConfig 00071 joinNetwork(); 00072 sendData(); 00073 //endLessTestLoop(); 00074 00075 return 0; 00076 } 00077 00078 void sendData() { 00079 std::vector<uint8_t> data; 00080 std::string data_str = "hello!"; 00081 char string_buffer[64]; 00082 std::string separator_str = ","; 00083 std::string temp_cls = "TC"; 00084 float temperature; 00085 float pressure; 00086 float humidity; 00087 int32_t ret; 00088 00089 while (true) { 00090 data.clear(); 00091 00092 // Temperature 00093 temperature = b280.getTemperature(); 00094 sprintf(string_buffer, "%s%3.2f", "TC:", temperature); 00095 logInfo("The temperature is %s", string_buffer); 00096 for (int i = 0; i<strlen(string_buffer); i++) 00097 { 00098 data.push_back(((char*)string_buffer)[i]); 00099 } 00100 00101 logDebug("Sending LoRa message, length: %d", data.size()); 00102 logDebug("sending data: "); 00103 for(int i = 0; i < data.size(); i++) 00104 { 00105 printf("%c", data[i]); 00106 } 00107 printf("\n"); 00108 00109 // send the data to the gateway 00110 if ((ret = dot->send(data)) != mDot::MDOT_OK) { 00111 logError("failed to send", ret, mDot::getReturnCodeString(ret).c_str()); 00112 } else { 00113 logInfo("successfully sent data to gateway"); 00114 } 00115 00116 // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again 00117 osDelay(std::max((uint32_t)5000, (uint32_t)dot->getNextTxMs())); 00118 data.clear(); 00119 00120 // Pressure 00121 pressure = b280.getPressure(); 00122 sprintf(string_buffer, "%s%04.2f", "hPa:", pressure); 00123 logInfo("The pressure is %s", string_buffer); 00124 for (int i = 0; i<strlen(string_buffer); i++) 00125 { 00126 data.push_back(((char*)string_buffer)[i]); 00127 } 00128 00129 logDebug("Sending LoRa message, length: %d", data.size()); 00130 logDebug("sending data: "); 00131 for(int i = 0; i < data.size(); i++) 00132 { 00133 printf("%c", data[i]); 00134 } 00135 printf("\n"); 00136 00137 // send the data to the gateway 00138 if ((ret = dot->send(data)) != mDot::MDOT_OK) { 00139 logError("failed to send", ret, mDot::getReturnCodeString(ret).c_str()); 00140 } else { 00141 logInfo("successfully sent data to gateway"); 00142 } 00143 00144 // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again 00145 osDelay(std::max((uint32_t)5000, (uint32_t)dot->getNextTxMs())); 00146 00147 data.clear(); 00148 00149 // Humidity 00150 humidity = b280.getHumidity(); 00151 sprintf(string_buffer, "%s%03.2f", "H%:", humidity); 00152 logInfo("The humidty is %s", string_buffer); 00153 00154 for (int i = 0; i<strlen(string_buffer); i++) 00155 { 00156 data.push_back(((char*)string_buffer)[i]); 00157 } 00158 00159 logDebug("Sending LoRa message, length: %d", data.size()); 00160 logDebug("sending data: "); 00161 for(int i = 0; i < data.size(); i++) 00162 { 00163 printf("%c", data[i]); 00164 } 00165 printf("\n"); 00166 00167 // send the data to the gateway 00168 if ((ret = dot->send(data)) != mDot::MDOT_OK) { 00169 logError("failed to send", ret, mDot::getReturnCodeString(ret).c_str()); 00170 } else { 00171 logInfo("successfully sent data to gateway"); 00172 } 00173 00174 // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again 00175 osDelay(std::max((uint32_t)5000, (uint32_t)dot->getNextTxMs())); 00176 00177 data.clear(); 00178 00179 // Light Level 00180 llevel = readLightSensor(); 00181 sprintf(string_buffer, "%s%5.1f", "LL:", llevel); 00182 for (int i = 0; i<strlen(string_buffer); i++) 00183 { 00184 data.push_back(((char*)string_buffer)[i]); 00185 } 00186 logDebug("Sending LoRa message, length: %d", data.size()); 00187 logDebug("sending data: "); 00188 for(int i = 0; i < data.size(); i++) 00189 { 00190 printf("%c", data[i]); 00191 } 00192 printf("\n"); 00193 00194 // send the data to the gateway 00195 if ((ret = dot->send(data)) != mDot::MDOT_OK) { 00196 logError("failed to send", ret, mDot::getReturnCodeString(ret).c_str()); 00197 } else { 00198 logInfo("successfully sent data to gateway"); 00199 } 00200 00201 // Goto Sleep, commenting out the osDelay since next Tx would be after waking up 00202 mDotGotoDeepSleep(60, false); 00203 00204 // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again 00205 //osDelay(std::max((uint32_t)5000, (uint32_t)dot->getNextTxMs())); 00206 00207 } 00208 00209 } 00210 00211 00212 /***************************************************** 00213 * mDot Functions 00214 ****************************************************/ 00215 00216 00217 void mDotConfig() { 00218 // get a mDot handle 00219 dot = mDot::getInstance(); 00220 // Test if we've already saved the config 00221 logInfo("Checking Config"); 00222 00223 std::string configNetworkName = dot->getNetworkName(); 00224 printf("Network Name is %s: \n", (char*)configNetworkName.c_str()); 00225 printf("Network Name is %s: \n", (char*)(config_network_name.c_str())); 00226 00227 if (configNetworkName.compare(config_network_name) != 0) { 00228 logInfo("Setting Up Config"); 00229 setupNetwork(); 00230 00231 } else { 00232 logInfo("Config is good, skipping setting up... "); 00233 } 00234 } 00235 00236 void mDotGotoDeepSleep(int seconds, bool sleepState) { 00237 00238 // Should sleep here and wakeup after a set interval. 00239 uint32_t sleep_time = MAX((dot->getNextTxMs() / 1000), seconds); 00240 logInfo("Going to sleep for %d seconds", sleep_time); 00241 00242 // go to sleep and wake up automatically sleep_time seconds later 00243 dot->sleep(sleep_time, mDot::RTC_ALARM, sleepState); 00244 00245 } 00246 void setupNetwork(){ 00247 int32_t ret; 00248 std::vector<uint8_t> send_data; 00249 std::vector<uint8_t> recv_data; 00250 std::vector<uint8_t> nwkSKey; 00251 std::vector<uint8_t> appSKey; 00252 std::vector<uint8_t> nodeAddr; 00253 std::vector<uint8_t> networkAddr; 00254 // from OTAA 00255 std::vector<uint8_t> appEUI; 00256 std::vector<uint8_t> appKey; 00257 00258 00259 //******************************************* 00260 // configuration 00261 //******************************************* 00262 00263 uint8_t *it = NwkSKey; 00264 for (uint8_t i = 0; i<16; i++) 00265 nwkSKey.push_back((uint8_t) *it++); 00266 it = AppSKey; 00267 for (uint8_t i = 0; i<16; i++) 00268 appSKey.push_back((uint8_t) *it++); 00269 00270 00271 it = AppEUI; 00272 for (uint8_t i = 0; i<8; i++) 00273 appEUI.push_back((uint8_t) *it++); 00274 00275 it = AppKey; 00276 for (uint8_t i = 0; i<16; i++) 00277 appKey.push_back((uint8_t) *it++); 00278 00279 it = NetworkAddr; 00280 for (uint8_t i = 0; i<4; i++) 00281 networkAddr.push_back((uint8_t) *it++); 00282 00283 logInfo("Resetting Config"); 00284 // reset to default config so we know what state we're in 00285 dot->resetConfig(); 00286 00287 //dot->setLogLevel(mts::MTSLog::INFO_LEVEL); 00288 dot->setLogLevel(mts::MTSLog::TRACE_LEVEL); 00289 00290 logInfo("Setting Network name"); 00291 if ((ret = dot->setNetworkName(config_network_name)) != mDot::MDOT_OK) { 00292 logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00293 } 00294 00295 logInfo("Setting Network password"); 00296 if ((ret = dot->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) { 00297 logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00298 } 00299 00300 // Set byte order 00301 dot->setJoinByteOrder(mDot::LSB); 00302 00303 // Set Spreading Factor, higher is lower data rate, smaller packets but longer range 00304 // Lower is higher data rate, larger packets and shorter range. 00305 logInfo("Set SF"); 00306 if((ret = dot->setTxDataRate( mDot::SF_10 )) != mDot::MDOT_OK) { 00307 //if((ret = dot->setTxDataRate( mDot::SF_8 )) != mDot::MDOT_OK) { 00308 logError("Failed to set SF %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00309 } 00310 00311 //logInfo("Set TxPower"); 00312 //if((ret = dot->setTxPower( LORA_TXPOWER )) != mDot::MDOT_OK) { 00313 // logError("Failed to set Tx Power %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00314 //} 00315 00316 logInfo("Set Public mode"); 00317 if((ret = dot->setPublicNetwork(true)) != mDot::MDOT_OK) { 00318 logError("failed to set Public Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00319 } 00320 00321 //logInfo("Set MANUAL Join mode"); 00322 //if((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) { 00323 // logError("Failed to set MANUAL Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00324 //} 00325 00326 logInfo("Set AUTO_OTA Join mode"); 00327 if((ret = dot->setJoinMode(mDot::AUTO_OTA)) != mDot::MDOT_OK) { 00328 logError("Failed to set AUTO_OTA Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00329 } 00330 00331 logInfo("Set Ack"); 00332 // 1 retries on Ack, 0 to disable 00333 if((ret = dot->setAck( LORA_ACK)) != mDot::MDOT_OK) { 00334 logError("Failed to set Ack %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00335 } 00336 00337 // Not applicable for 868MHz in EU 00338 if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { 00339 logError("Failed to set frequency sub band %s", ret); 00340 } 00341 00342 logInfo("Set Network Address"); 00343 if ((ret = dot->setNetworkAddress(networkAddr)) != mDot::MDOT_OK) { 00344 logError("Failed to set Network Address %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00345 } 00346 00347 logInfo("Set Data Session Key"); 00348 if ((ret = dot->setDataSessionKey(appSKey)) != mDot::MDOT_OK) { 00349 logError("Failed to set Data Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00350 } 00351 00352 logInfo("Set Network Session Key"); 00353 if ((ret = dot->setNetworkSessionKey(nwkSKey)) != mDot::MDOT_OK) { 00354 logError("Failed to set Network Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00355 } 00356 00357 logInfo("Set Network Id"); 00358 if ((ret = dot->setNetworkId(appEUI)) != mDot::MDOT_OK) { 00359 logError("Failed to set Network Id %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00360 } 00361 logInfo("Set Network Key"); 00362 if ((ret = dot->setNetworkKey(appKey)) != mDot::MDOT_OK) { 00363 logError("Failed to set Network Id %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); 00364 } 00365 00366 logInfo("Saving Config"); 00367 // Save config 00368 if (! dot->saveConfig()) { 00369 logError("failed to save configuration"); 00370 } 00371 00372 //******************************************* 00373 // end of configuration 00374 //******************************************* 00375 00376 mDotConfigPrint(); 00377 00378 } 00379 00380 void joinNetwork() { 00381 int32_t ret; 00382 00383 logInfo("Joining Network"); 00384 while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) { 00385 logError("failed to join network [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str()); 00386 //wait_ms(dot->getNextTxMs() + 1); 00387 osDelay(std::max((uint32_t)1000, (uint32_t)dot->getNextTxMs())); 00388 } 00389 00390 logInfo("Joined Network"); 00391 00392 } 00393 00394 void mDotConfigPrint() { 00395 00396 // Display what is set 00397 printf("\r\n"); 00398 printf(" ********** mDot Configuration ************ \n"); 00399 // print library version information 00400 logInfo("Firmware Version: %s", dot->getId().c_str()); 00401 00402 std::vector<uint8_t> tmp = dot->getNetworkSessionKey(); 00403 printf("Network Session Key: "); 00404 printf("%s\n", mts::Text::bin2hexString(tmp, " ").c_str()); 00405 00406 tmp = dot->getDataSessionKey(); 00407 printf("Data Session Key: "); 00408 printf("%s\n", mts::Text::bin2hexString(tmp, " ").c_str()); 00409 00410 tmp = dot->getNetworkId(); 00411 printf("App EUI: "); 00412 printf("%s\n", mts::Text::bin2hexString(tmp, " ").c_str()); 00413 00414 tmp = dot->getNetworkKey(); 00415 printf("App Key: "); 00416 printf("%s\n", mts::Text::bin2hexString(tmp, " ").c_str()); 00417 00418 printf("Device ID "); 00419 std::vector<uint8_t> deviceId; 00420 deviceId = dot->getDeviceId(); 00421 for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it) 00422 printf("%2.2x",*it ); 00423 printf("\n"); 00424 std::vector<uint8_t> netAddress; 00425 00426 printf("Network Address "); 00427 netAddress = dot->getNetworkAddress(); 00428 for (std::vector<uint8_t>::iterator it = netAddress.begin() ; it != netAddress.end(); ++it) 00429 printf("%2.2x",*it ); 00430 printf("\n"); 00431 00432 // Display LoRa parameters 00433 // Display label and values in different colours, show pretty values not numeric values where applicable 00434 00435 printf("Network Name: %s\n", (char *)(dot->getNetworkName()).c_str()); 00436 printf("Network Name: %s\n", (char *)(dot->getNetworkPassphrase()).c_str()); 00437 printf("Public Network: %s\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") ); 00438 printf("Frequency: %s\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() ); 00439 printf("Sub Band: %s\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() ); 00440 printf("Join Mode: %s\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() ); 00441 printf("Join Retries: %d\n", dot->getJoinRetries() ); 00442 printf("Join Byte Order: %s\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") ); 00443 printf("Link Check Count: %d\n", dot->getLinkCheckCount() ); 00444 printf("Link Check Thold: %d\n", dot->getLinkCheckThreshold() ); 00445 printf("Tx Data Rate: %s\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() ); 00446 printf("Tx Power: %d\n", dot->getTxPower() ); 00447 printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" )); 00448 printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") ); 00449 printf("Ack: %s\n", (dot->getAck() ? "Y" : "N") ); 00450 00451 } 00452 00453 /***************************************************** 00454 * Sensor Functions 00455 ****************************************************/ 00456 00457 00458 void readandprintBME280() { 00459 float temperature; 00460 float pressure; 00461 float humidity; 00462 char string_buffer[64]; 00463 //time_t secs; 00464 00465 //secs = time(NULL); 00466 //printf("Seconds since January 1, 1970: %d\n", secs); 00467 //printf("Time as a basic string = %s", ctime(&secs)); 00468 00469 // Temperature 00470 temperature = b280.getTemperature(); 00471 sprintf(string_buffer, "%s%3.2f", "TC:", temperature); 00472 logInfo("The temperature is %s", string_buffer); 00473 // Pressure 00474 pressure = b280.getPressure(); 00475 sprintf(string_buffer, "%s%04.2f", "hPa:", pressure); 00476 logInfo("The pressure is %s", string_buffer); 00477 // Humidity 00478 humidity = b280.getHumidity(); 00479 sprintf(string_buffer, "%s%03.2f", "H%:", humidity); 00480 logInfo("The humidty is %s", string_buffer); 00481 00482 //printf("%2.2f degC, %04.2f hPa, %2.2f %%\n", temperature, pressure, humidity); 00483 } 00484 00485 float readLightSensor() { 00486 float sensorValue; 00487 float rsensor; 00488 sensorValue = light.read(); 00489 rsensor = (float)(1023-sensorValue)*10/sensorValue; 00490 printf("Sensor reading: %2.2f - %2.2f\r\n", sensorValue, rsensor); 00491 00492 return rsensor; 00493 00494 } 00495 00496 /***************************************************** 00497 * FUNCTIONS for Simple Testing 00498 ****************************************************/ 00499 00500 void setUpLEDBlink(){ 00501 // configure the Ticker to blink the LED on 500ms interval 00502 tick.attach(&blink, 0.5); 00503 } 00504 00505 void endLessTestLoop() { 00506 while(true) { 00507 // printf("Hello world!\r\n"); 00508 //printf("BME280 Sensor: \n"); 00509 readandprintBME280(); 00510 00511 mDotGotoDeepSleep(60, true); 00512 //wait(10); 00513 00514 } 00515 } 00516 00517 // Callback function to change LED state 00518 void blink() { 00519 led = !led; 00520 } 00521 00522
Generated on Sat Jul 16 2022 22:45:26 by
1.7.2