Demo of DHT11->mDot->TTN

Dependencies:   DHT11 libmDot mbed-rtos mbed

Committer:
SomeRandomBloke
Date:
Tue Sep 22 13:58:59 2015 +0000
Revision:
3:367aa95f9771
Parent:
2:9db840d12557
Child:
4:f649ab1b61d1
Code clean up and add reset config option.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SomeRandomBloke 2:9db840d12557 1 /** mDot_DS18B20 - Simple mDot temperature sensor using Dallas Semiconductors DS18B20 OneWire temperature sensor.
SomeRandomBloke 3:367aa95f9771 2 * It used the OTA_AUTO join mode using saved parameters. If the config is to be reset then pin A2 on the
SomeRandomBloke 3:367aa95f9771 3 * dev board must be held low during a reset or power up.
SomeRandomBloke 2:9db840d12557 4 *
SomeRandomBloke 0:5a0b43f3b143 5 * Uses MultiTech mDot developer board http://www.multitech.com/models/94558010LF
SomeRandomBloke 0:5a0b43f3b143 6 * Requires a MultiTech MultiConnect Conduit http://www.multitech.com/models/94557203LF
SomeRandomBloke 0:5a0b43f3b143 7 *
SomeRandomBloke 0:5a0b43f3b143 8 * Example JSON received on Conduit:
SomeRandomBloke 0:5a0b43f3b143 9 { "chan": 5, "codr": "4/5", "datr": "SF9BW125", "freq": "869.5",
SomeRandomBloke 0:5a0b43f3b143 10 "lsnr": "8.8", "modu": "LORA", "rfch": 1, "rssi": -41, "seqn": 13,
SomeRandomBloke 0:5a0b43f3b143 11 "size": 12, "timestamp": "2015-07-22T21:19:11Z", "tmst": 517590990,
SomeRandomBloke 2:9db840d12557 12 "payload": "{\"tmp\":21.3}", "eui": "00:80:00:00:00:00:9a:63", "_msg
SomeRandomBloke 0:5a0b43f3b143 13 id": "73bcd8dd.8c4328" }
SomeRandomBloke 0:5a0b43f3b143 14 *
SomeRandomBloke 0:5a0b43f3b143 15 */
SomeRandomBloke 0:5a0b43f3b143 16
SomeRandomBloke 0:5a0b43f3b143 17 #include "mbed.h"
SomeRandomBloke 0:5a0b43f3b143 18 #include "DS1820.h"
SomeRandomBloke 0:5a0b43f3b143 19 #include "mDot.h"
SomeRandomBloke 0:5a0b43f3b143 20 #include "MTSLog.h"
SomeRandomBloke 0:5a0b43f3b143 21 #include "MTSText.h"
SomeRandomBloke 0:5a0b43f3b143 22 #include <string>
SomeRandomBloke 0:5a0b43f3b143 23 #include <vector>
SomeRandomBloke 0:5a0b43f3b143 24
SomeRandomBloke 0:5a0b43f3b143 25 using namespace mts;
SomeRandomBloke 0:5a0b43f3b143 26
SomeRandomBloke 0:5a0b43f3b143 27 // these options must match the settings on your Conduit in
SomeRandomBloke 0:5a0b43f3b143 28 // /var/config/lora/lora-network-server.conf
SomeRandomBloke 3:367aa95f9771 29 static std::string config_network_name = "<network name>";
SomeRandomBloke 3:367aa95f9771 30 static std::string config_network_pass = "<network password>";
SomeRandomBloke 3:367aa95f9771 31 // Ignoring sub band for EU modules.
SomeRandomBloke 1:45cec6aea002 32 //static uint8_t config_frequency_sub_band = 1;
SomeRandomBloke 0:5a0b43f3b143 33
SomeRandomBloke 0:5a0b43f3b143 34 // mDot/dev board activity LED
SomeRandomBloke 1:45cec6aea002 35 //#define ACTIVITY_LED PA_0
SomeRandomBloke 2:9db840d12557 36
SomeRandomBloke 2:9db840d12557 37 // DS18B20 OneWire pin
SomeRandomBloke 3:367aa95f9771 38 // D13 on Dev Board, pin 18 on mDot
SomeRandomBloke 1:45cec6aea002 39 #define DATA_PIN PA_5
SomeRandomBloke 3:367aa95f9771 40 // A0 on Dev Board, pin 20 on mDot
SomeRandomBloke 1:45cec6aea002 41 //#define DATA_PIN PB_1
SomeRandomBloke 0:5a0b43f3b143 42
SomeRandomBloke 3:367aa95f9771 43 // A2 - input to reset LoRaWAN config. Pin 15 om mDot.
SomeRandomBloke 3:367aa95f9771 44 #define CONFIG_RESET PC_1
SomeRandomBloke 3:367aa95f9771 45
SomeRandomBloke 3:367aa95f9771 46 // Config Reset intput
SomeRandomBloke 3:367aa95f9771 47 DigitalIn configReset(CONFIG_RESET);
SomeRandomBloke 3:367aa95f9771 48
SomeRandomBloke 3:367aa95f9771 49 // Temperature sensor object
SomeRandomBloke 0:5a0b43f3b143 50 DS1820 probe(DATA_PIN);
SomeRandomBloke 0:5a0b43f3b143 51
SomeRandomBloke 3:367aa95f9771 52 // Serial via USB for debugging only
SomeRandomBloke 0:5a0b43f3b143 53 Serial pc(USBTX,USBRX);
SomeRandomBloke 0:5a0b43f3b143 54
SomeRandomBloke 0:5a0b43f3b143 55
SomeRandomBloke 0:5a0b43f3b143 56 int main()
SomeRandomBloke 0:5a0b43f3b143 57 {
SomeRandomBloke 0:5a0b43f3b143 58 int32_t ret;
SomeRandomBloke 0:5a0b43f3b143 59 mDot* dot;
SomeRandomBloke 0:5a0b43f3b143 60 std::vector<uint8_t> send_data;
SomeRandomBloke 0:5a0b43f3b143 61 std::vector<uint8_t> recv_data;
SomeRandomBloke 0:5a0b43f3b143 62
SomeRandomBloke 0:5a0b43f3b143 63 float temperature = 0.0;
SomeRandomBloke 1:45cec6aea002 64
SomeRandomBloke 3:367aa95f9771 65 // Enable internal pullup on input pin
SomeRandomBloke 3:367aa95f9771 66 configReset.mode(PullUp);
SomeRandomBloke 3:367aa95f9771 67
SomeRandomBloke 0:5a0b43f3b143 68 pc.baud(115200);
SomeRandomBloke 0:5a0b43f3b143 69 pc.printf("mDot LoRa Temperature sensor\n\r");
SomeRandomBloke 1:45cec6aea002 70
SomeRandomBloke 0:5a0b43f3b143 71 // get a mDot handle
SomeRandomBloke 0:5a0b43f3b143 72 dot = mDot::getInstance();
SomeRandomBloke 0:5a0b43f3b143 73
SomeRandomBloke 3:367aa95f9771 74 dot->setLogLevel(MTSLog::WARNING_LEVEL);
SomeRandomBloke 3:367aa95f9771 75 // dot->setLogLevel(MTSLog::TRACE_LEVEL);
SomeRandomBloke 0:5a0b43f3b143 76
SomeRandomBloke 1:45cec6aea002 77 logInfo("Checking Config");
SomeRandomBloke 1:45cec6aea002 78
SomeRandomBloke 1:45cec6aea002 79 // Test if we've already saved the config
SomeRandomBloke 1:45cec6aea002 80 std::string configNetworkName = dot->getNetworkName();
SomeRandomBloke 1:45cec6aea002 81
SomeRandomBloke 3:367aa95f9771 82 // Reset config if network name is different or pin is low then reset config.
SomeRandomBloke 3:367aa95f9771 83 if( config_network_name.compare(configNetworkName) != 0 || !configReset ) {
SomeRandomBloke 1:45cec6aea002 84 // Not saved config, reset
SomeRandomBloke 1:45cec6aea002 85 logInfo("Setting Config");
SomeRandomBloke 0:5a0b43f3b143 86
SomeRandomBloke 1:45cec6aea002 87 // reset to default config so we know what state we're in
SomeRandomBloke 1:45cec6aea002 88 dot->resetConfig();
SomeRandomBloke 1:45cec6aea002 89
SomeRandomBloke 1:45cec6aea002 90 // Set byte order - AEP less than 1.0.30
SomeRandomBloke 1:45cec6aea002 91 // dot->setJoinByteOrder(mDot::MSB);
SomeRandomBloke 1:45cec6aea002 92 dot->setJoinByteOrder(mDot::LSB);
SomeRandomBloke 0:5a0b43f3b143 93
SomeRandomBloke 1:45cec6aea002 94 logInfo("setting Join mode");
SomeRandomBloke 1:45cec6aea002 95 if ((ret = dot->setJoinMode(mDot::AUTO_OTA)) != mDot::MDOT_OK) {
SomeRandomBloke 1:45cec6aea002 96 logError("failed to set Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 1:45cec6aea002 97 }
SomeRandomBloke 1:45cec6aea002 98
SomeRandomBloke 1:45cec6aea002 99 // If on developer board then you can enable activity LED
SomeRandomBloke 1:45cec6aea002 100 // Currently no spare pins that LEDs are connected too.
SomeRandomBloke 0:5a0b43f3b143 101 // dot->setActivityLedPin( ACTIVITY_LED );
SomeRandomBloke 0:5a0b43f3b143 102 // dot->setActivityLedEnable(false);
SomeRandomBloke 0:5a0b43f3b143 103
SomeRandomBloke 2:9db840d12557 104 // Have a decent nubmer of retries in connecting to LoRaWAN
SomeRandomBloke 2:9db840d12557 105 dot->setJoinRetries( 3 );
SomeRandomBloke 2:9db840d12557 106
SomeRandomBloke 2:9db840d12557 107 // Set Spreading Factor, higher is lower data rate, smaller packets but longer range
SomeRandomBloke 2:9db840d12557 108 // Lower is higher data rate, larger packets and shorter range.
SomeRandomBloke 2:9db840d12557 109 // dot->setTxDataRate( mDot::SF_9 );
SomeRandomBloke 3:367aa95f9771 110 dot->setTxDataRate( mDot::SF_12 );
SomeRandomBloke 1:45cec6aea002 111 dot->setTxPower( 14 );
SomeRandomBloke 1:45cec6aea002 112 dot->setAck( 0 ); // 1 retries on Ack, 0 to disable
SomeRandomBloke 3:367aa95f9771 113
SomeRandomBloke 1:45cec6aea002 114 // Not applicable for 868MHz in EU
SomeRandomBloke 1:45cec6aea002 115 // if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
SomeRandomBloke 1:45cec6aea002 116 // initStatus = false;
SomeRandomBloke 0:5a0b43f3b143 117 // logError(dot, "failed to set frequency sub band", ret);
SomeRandomBloke 1:45cec6aea002 118 // }
SomeRandomBloke 1:45cec6aea002 119
SomeRandomBloke 1:45cec6aea002 120 if ((ret = dot->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
SomeRandomBloke 1:45cec6aea002 121 logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 1:45cec6aea002 122 }
SomeRandomBloke 0:5a0b43f3b143 123
SomeRandomBloke 1:45cec6aea002 124 if ((ret = dot->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
SomeRandomBloke 1:45cec6aea002 125 logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 1:45cec6aea002 126 }
SomeRandomBloke 1:45cec6aea002 127
SomeRandomBloke 2:9db840d12557 128 if ((ret = dot->setJoinMode( mDot::AUTO_OTA )) != mDot::MDOT_OK) {
SomeRandomBloke 2:9db840d12557 129 logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 2:9db840d12557 130 }
SomeRandomBloke 2:9db840d12557 131
SomeRandomBloke 1:45cec6aea002 132 logInfo("Saving Config");
SomeRandomBloke 1:45cec6aea002 133
SomeRandomBloke 1:45cec6aea002 134 // Save config
SomeRandomBloke 1:45cec6aea002 135 if (! dot->saveConfig()) {
SomeRandomBloke 1:45cec6aea002 136 logError("failed to save configuration");
SomeRandomBloke 1:45cec6aea002 137 }
SomeRandomBloke 1:45cec6aea002 138 } else {
SomeRandomBloke 1:45cec6aea002 139 logInfo("Using existing Config");
SomeRandomBloke 0:5a0b43f3b143 140 }
SomeRandomBloke 0:5a0b43f3b143 141
SomeRandomBloke 0:5a0b43f3b143 142 while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
SomeRandomBloke 0:5a0b43f3b143 143 logError("failed to join network [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 0:5a0b43f3b143 144 wait_ms(dot->getNextTxMs() + 1);
SomeRandomBloke 0:5a0b43f3b143 145 }
SomeRandomBloke 1:45cec6aea002 146
SomeRandomBloke 0:5a0b43f3b143 147 probe.setResolution(9);
SomeRandomBloke 0:5a0b43f3b143 148
SomeRandomBloke 0:5a0b43f3b143 149 char dataBuf[50];
SomeRandomBloke 0:5a0b43f3b143 150 while( 1 ) {
SomeRandomBloke 0:5a0b43f3b143 151 // This takes upto 750mS, way too long. Change to 9 bit resolution if not already used.
SomeRandomBloke 1:45cec6aea002 152
SomeRandomBloke 0:5a0b43f3b143 153 probe.convertTemperature(true, DS1820::all_devices); //Start temperature conversion, wait until ready
SomeRandomBloke 0:5a0b43f3b143 154 // printf("It is %3.1fC\r\n", probe.temperature());
SomeRandomBloke 3:367aa95f9771 155 // Output data as JSON e.g. {"tmp":21.3}
SomeRandomBloke 0:5a0b43f3b143 156 temperature = probe.temperature();
SomeRandomBloke 1:45cec6aea002 157 sprintf(dataBuf, "{\"tmp\":%3.1f}", temperature );
SomeRandomBloke 0:5a0b43f3b143 158 send_data.clear();
SomeRandomBloke 0:5a0b43f3b143 159 // probably not the most efficent way to do this
SomeRandomBloke 0:5a0b43f3b143 160 for( int i=0; i< strlen(dataBuf); i++ )
SomeRandomBloke 0:5a0b43f3b143 161 send_data.push_back( dataBuf[i] );
SomeRandomBloke 0:5a0b43f3b143 162
SomeRandomBloke 0:5a0b43f3b143 163 if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
SomeRandomBloke 0:5a0b43f3b143 164 logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 0:5a0b43f3b143 165 } else {
SomeRandomBloke 0:5a0b43f3b143 166 logInfo("send data: %s", Text::bin2hexString(send_data).c_str());
SomeRandomBloke 0:5a0b43f3b143 167 }
SomeRandomBloke 0:5a0b43f3b143 168
SomeRandomBloke 1:45cec6aea002 169 // Should sleep here and wakeup after a set interval.
SomeRandomBloke 2:9db840d12557 170 uint32_t sleep_time = (dot->getNextTxMs() / 1000) + 60;
SomeRandomBloke 2:9db840d12557 171 logInfo("going to sleep for %d seconds", sleep_time);
SomeRandomBloke 0:5a0b43f3b143 172
SomeRandomBloke 1:45cec6aea002 173 // go to sleep and wake up automatically sleep_time seconds later
SomeRandomBloke 2:9db840d12557 174 dot->sleep(sleep_time, mDot::RTC_ALARM);
SomeRandomBloke 2:9db840d12557 175
SomeRandomBloke 0:5a0b43f3b143 176 }
SomeRandomBloke 2:9db840d12557 177
SomeRandomBloke 0:5a0b43f3b143 178 return 0;
SomeRandomBloke 0:5a0b43f3b143 179 }