Ashu Joshi / Mbed 2 deprecated SensorInterface

Dependencies:   BME280 SerialGPS libmDot mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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