Gaston Lieutier / Mbed 2 deprecated mDot_TTN_DHT22

Dependencies:   DHT libmDot mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /** mDot_TTN_DS18B20 - Simple mDot temperature sensor using Dallas Semiconductors DS18B20 OneWire temperature sensor.
00002  * It used the MANUAL join mode with parameters for The Things Network.
00003  *
00004  *
00005  * Uses MultiTech mDot developer board http://www.multitech.com/models/94558010LF
00006  * Requires a MultiTech MultiConnect Conduit http://www.multitech.com/models/94557203LF
00007  * http://www.multitech.net/developer/software/lora/conduit-mlinux-convert-to-basic-packet-forwarder/
00008  * http://forum.thethingsnetwork.org/t/setting-up-multitech-conduit-gateway-for-ttn/216/35
00009  *
00010  */
00011 
00012 #include "mbed.h"
00013 #include "DHT.h"
00014 #include "mDot.h"
00015 #include "MTSLog.h"
00016 #include "MTSText.h"
00017 #include <string>
00018 #include <vector>
00019 
00020 using namespace mts;
00021 
00022 #define MIN(a,b) (((a)<(b))?(a):(b))
00023 #define MAX(a,b) (((a)>(b))?(a):(b))
00024 
00025 // Values as used by The Things Network
00026 //const uint8_t AppKey[16]={0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
00027 // Application session key
00028 uint8_t AppSKey[16]= {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
00029 // Network session key
00030 uint8_t NwkSKey[16]= {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
00031 
00032 // Network Address - Get your own address range at http://thethingsnetwork.org/wiki/AddressSpace
00033 uint8_t NetworkAddr[4]= {0x02,0x01,0x2D,0x00};      // Our Network address or Node ID
00034 
00035 
00036 // Some defines for the LoRa configuration
00037 #define LORA_SF mDot::SF_9
00038 #define LORA_ACK 0
00039 #define LORA_TXPOWER 14
00040 
00041 // Ignoring sub band for EU modules.
00042 static uint8_t config_frequency_sub_band = 7;
00043 
00044 // DS18B20 OneWire pin
00045 // D13 on Dev Board, pin 18 on mDot, Compatible with Oxford Flood Network PCB temperature sensor.
00046 #define DATA_PIN     PA_5
00047 // A0 on Dev Board, pin 20 on mDot
00048 //#define DATA_PIN     PB_1
00049 
00050 // Temperature sensor object
00051 #define DHTTYPE DHT22
00052 
00053 DHT sensor(DATA_PIN, DHTTYPE);
00054 
00055 // Serial via USB for debugging only
00056 Serial pc(USBTX,USBRX);
00057 
00058 int main()
00059 {
00060     int initStatus;
00061     int32_t ret;
00062     mDot* dot;
00063     std::vector<uint8_t> send_data;
00064     std::vector<uint8_t> recv_data;
00065     std::vector<uint8_t> nwkSKey;
00066     std::vector<uint8_t> nodeAddr;
00067     std::vector<uint8_t> networkAddr;
00068 
00069     float temperature = 0.0;
00070 
00071     pc.baud(115200);
00072     pc.printf("TTN mDot LoRa Temperature sensor\n\r");
00073 
00074     // get a mDot handle
00075     dot = mDot::getInstance();
00076 
00077     dot->setLogLevel(MTSLog::WARNING_LEVEL);
00078 //    dot->setLogLevel(MTSLog::TRACE_LEVEL);
00079 
00080     logInfo("Checking Config");
00081 
00082     // Test if we've already saved the config
00083     std::string configNetworkName = dot->getNetworkName();
00084 
00085     uint8_t *it = NwkSKey;
00086     for (uint8_t i = 0; i<16; i++)
00087         nwkSKey.push_back((uint8_t) *it++);
00088 
00089     it = NetworkAddr;
00090     for (uint8_t i = 0; i<4; i++)
00091         networkAddr.push_back((uint8_t) *it++);
00092 
00093     logInfo("Resetting Config");
00094     // reset to default config so we know what state we're in
00095     dot->resetConfig();
00096 
00097     // Set byte order - AEP less than 1.0.30
00098 //    dot->setJoinByteOrder(mDot::LSB);
00099     dot->setJoinByteOrder(mDot::MSB);       // This is default for > 1.0.30 Conduit
00100 
00101     // Set Spreading Factor, higher is lower data rate, smaller packets but longer range
00102     // Lower is higher data rate, larger packets and shorter range.
00103     logInfo("Set SF");
00104     if((ret = dot->setTxDataRate( LORA_SF )) != mDot::MDOT_OK) {
00105         logError("Failed to set SF %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00106     }
00107 
00108     logInfo("Set TxPower");
00109     if((ret = dot->setTxPower( LORA_TXPOWER )) != mDot::MDOT_OK) {
00110         logError("Failed to set Tx Power %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00111     }
00112 
00113     logInfo("Set Public mode");
00114     if((ret = dot->setPublicNetwork(true)) != mDot::MDOT_OK) {
00115         logError("failed to set Public Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00116     }
00117 
00118     logInfo("Set MANUAL Join mode");
00119     if((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
00120         logError("Failed to set MANUAL Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00121     }
00122 
00123     logInfo("Set Ack");
00124     // 1 retries on Ack, 0 to disable
00125     if((ret = dot->setAck( LORA_ACK)) != mDot::MDOT_OK) {
00126         logError("Failed to set Ack %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00127     }
00128 
00129 //    Not applicable for 868MHz in EU
00130     if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
00131         initStatus = false;
00132         logError("failed to set frequency sub band", ret, mDot::getReturnCodeString(ret).c_str());
00133     }
00134 
00135     logInfo("Set Network Address");
00136     if ((ret = dot->setNetworkAddress(networkAddr)) != mDot::MDOT_OK) {
00137         logError("Failed to set Network Address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00138     }
00139 
00140     logInfo("Set Data Session Key");
00141     if ((ret = dot->setDataSessionKey(nwkSKey)) != mDot::MDOT_OK) {
00142         logError("Failed to set Data Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00143     }
00144 
00145     logInfo("Set Network Session Key");
00146     if ((ret = dot->setNetworkSessionKey(nwkSKey)) != mDot::MDOT_OK) {
00147         logError("Failed to set Network Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
00148     }
00149 
00150     logInfo("Saving Config");
00151     // Save config
00152     if (! dot->saveConfig()) {
00153         logError("failed to save configuration");
00154     }
00155 
00156     // Display what is set
00157     std::vector<uint8_t> tmp = dot->getNetworkSessionKey();
00158     pc.printf("Network Session Key: ");
00159     pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
00160 
00161     tmp = dot->getDataSessionKey();
00162     pc.printf("Data Session Key: ");
00163     pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
00164 
00165     pc.printf("Device ID ");
00166     std::vector<uint8_t> deviceId;
00167     deviceId = dot->getDeviceId();
00168     for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it)
00169         pc.printf("%2.2x",*it );
00170     pc.printf("\r\n");
00171 
00172     std::vector<uint8_t> netAddress;
00173 
00174     pc.printf("Network Address ");
00175     netAddress = dot->getNetworkAddress();
00176     for (std::vector<uint8_t>::iterator it = netAddress.begin() ; it != netAddress.end(); ++it)
00177         pc.printf("%2.2x",*it );
00178 
00179     pc.printf("\r\n");
00180 
00181     // Display LoRa parameters
00182     // Display label and values in different colours, show pretty values not numeric values where applicable
00183     pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") );
00184     pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() );
00185     pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() );
00186     pc.printf("Join Mode: %s\r\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() );
00187     pc.printf("Join Retries: %d\r\n", dot->getJoinRetries() );
00188     pc.printf("Join Byte Order: %s\r\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") );
00189     pc.printf("Link Check Count: %d\r\n", dot->getLinkCheckCount() );
00190     pc.printf("Link Check Thold: %d\r\n", dot->getLinkCheckThreshold() );
00191     pc.printf("Tx Data Rate: %s\r\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() );
00192     pc.printf("Tx Power: %d\r\n", dot->getTxPower() );
00193     pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" ));
00194     pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") );
00195     pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N")  );
00196 
00197     logInfo("Joining Network");
00198 
00199     while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
00200         logError("failed to join network [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
00201         wait_ms(dot->getNextTxMs() + 1);
00202     }
00203 
00204     logInfo("Joined Network");
00205 
00206     // Set the Temperature sesnor resolution, 9 bits is enough and makes it faster to provide a reading.
00207 
00208 
00209 
00210     char dataBuf[50];
00211     while( 1 ) {
00212     int err;
00213         err = sensor.readData();        
00214  //       if (err == 0) {
00215             // Output data as JSON e.g. {"t":21.3}
00216             temperature = sensor.ReadTemperature(CELCIUS);        
00217             sprintf(dataBuf, "{\"t\":%4.2f C}", temperature );
00218             send_data.clear();
00219             // probably not the most efficent way to do this
00220             for( int i=0; i< strlen(dataBuf); i++ )
00221                 send_data.push_back( dataBuf[i] );
00222     
00223             if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
00224                 logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
00225             } else {
00226                 logInfo("send data: %s", Text::bin2hexString(send_data).c_str());
00227                 logError("send data: %d %s", err, Text::bin2hexString(send_data).c_str());   
00228             }
00229 //        } else {
00230 //                logError("failed to read Temp: [%d][%s]", err, mDot::getReturnCodeString(err).c_str());
00231        
00232  //       }       
00233 
00234 
00235 
00236         // Should  sleep here and wakeup after a set 5 minute interval.
00237         uint32_t sleep_time = MAX((dot->getNextTxMs() / 1000), 60);
00238         logInfo("going to sleep for %d seconds", sleep_time);
00239 
00240         // go to sleep and wake up automatically sleep_time seconds later
00241         dot->sleep(sleep_time, mDot::RTC_ALARM);
00242     }
00243 
00244     return 0;
00245 }