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: DHT libmDot mbed-rtos mbed
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 }
Generated on Sat Jul 16 2022 15:38:23 by
1.7.2