Demo of DHT11->mDot->TTN

Dependencies:   DHT11 libmDot mbed-rtos mbed

Committer:
merckeng
Date:
Tue Nov 29 15:59:18 2016 +0000
Revision:
17:3dc30f4a8da2
Parent:
16:01a1058d9c8e
Working with Terry's Catena packet format, and fake data. Reading from sensors is TODO.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
merckeng 14:e4574212176a 1 /** mDot_TTN_DHT11 -- The Things Network Temperature & Humidity Sensor
merckeng 16:01a1058d9c8e 2 *
merckeng 16:01a1058d9c8e 3 * This is a rough demo of mDot+DHT11 on The Things Network.
merckeng 16:01a1058d9c8e 4 * This code is not indended as a reference design.
merckeng 16:01a1058d9c8e 5 * In particular, it lacks:
merckeng 16:01a1058d9c8e 6 * (1) power management
merckeng 16:01a1058d9c8e 7 * (2) reasonable transmission period
merckeng 16:01a1058d9c8e 8 * (3) adaptive data rate
merckeng 16:01a1058d9c8e 9 *
SomeRandomBloke 0:5a0b43f3b143 10 * Uses MultiTech mDot developer board http://www.multitech.com/models/94558010LF
SomeRandomBloke 0:5a0b43f3b143 11 * Requires a MultiTech MultiConnect Conduit http://www.multitech.com/models/94557203LF
SomeRandomBloke 5:48eb9245a914 12 * http://www.multitech.net/developer/software/lora/conduit-mlinux-convert-to-basic-packet-forwarder/
SomeRandomBloke 5:48eb9245a914 13 * http://forum.thethingsnetwork.org/t/setting-up-multitech-conduit-gateway-for-ttn/216/35
SomeRandomBloke 0:5a0b43f3b143 14 *
merckeng 15:c61c5f1533e8 15 * To receive and visualize this data,
merckeng 15:c61c5f1533e8 16 * consider using InitialState and the bridge code here:
merckeng 15:c61c5f1533e8 17 * https://github.com/things-nyc/initial-state-example
SomeRandomBloke 0:5a0b43f3b143 18 */
SomeRandomBloke 0:5a0b43f3b143 19
SomeRandomBloke 0:5a0b43f3b143 20 #include "mbed.h"
merckeng 14:e4574212176a 21 #include "DHT11.h"
SomeRandomBloke 0:5a0b43f3b143 22 #include "mDot.h"
SomeRandomBloke 0:5a0b43f3b143 23 #include "MTSLog.h"
SomeRandomBloke 0:5a0b43f3b143 24 #include "MTSText.h"
SomeRandomBloke 0:5a0b43f3b143 25 #include <string>
SomeRandomBloke 0:5a0b43f3b143 26 #include <vector>
SomeRandomBloke 0:5a0b43f3b143 27
SomeRandomBloke 0:5a0b43f3b143 28 using namespace mts;
SomeRandomBloke 0:5a0b43f3b143 29
SomeRandomBloke 4:f649ab1b61d1 30 #define MIN(a,b) (((a)<(b))?(a):(b))
SomeRandomBloke 4:f649ab1b61d1 31 #define MAX(a,b) (((a)>(b))?(a):(b))
SomeRandomBloke 4:f649ab1b61d1 32
SomeRandomBloke 8:8070e9d660e4 33
merckeng 14:e4574212176a 34 /** ABP
merckeng 14:e4574212176a 35 * Register your device and update these values:
merckeng 14:e4574212176a 36 * https://account.thethingsnetwork.org/
merckeng 14:e4574212176a 37 */
merckeng 17:3dc30f4a8da2 38 uint8_t AppSKey[16]= { 0x11, 0x6F, 0xA9, 0x2A, 0x46, 0xDE, 0xE6, 0x1D, 0x11, 0xE3, 0x71, 0x37, 0x24, 0xBC, 0x44, 0x1A };
merckeng 17:3dc30f4a8da2 39 uint8_t NwkSKey[16]= { 0xF1, 0xA4, 0x78, 0x09, 0x75, 0xE2, 0x3C, 0x2B, 0x76, 0x8F, 0x9F, 0x8D, 0xE0, 0x5E, 0xAA, 0x64 };
merckeng 17:3dc30f4a8da2 40 uint8_t NetworkAddr[4]= { 0x68, 0x8E, 0x64, 0xE5 };
SomeRandomBloke 8:8070e9d660e4 41
SomeRandomBloke 8:8070e9d660e4 42
SomeRandomBloke 8:8070e9d660e4 43 // Some defines for the LoRa configuration
merckeng 14:e4574212176a 44 #define LORA_SF mDot::SF_7
SomeRandomBloke 8:8070e9d660e4 45 #define LORA_ACK 0
merckeng 14:e4574212176a 46 #define LORA_TXPOWER 20
merckeng 14:e4574212176a 47 static uint8_t config_frequency_sub_band = 2;
SomeRandomBloke 5:48eb9245a914 48
merckeng 14:e4574212176a 49 // functions for ensuring network endianness (little-endian)
merckeng 14:e4574212176a 50 uint16_t hton16(const uint16_t x)
merckeng 14:e4574212176a 51 {
merckeng 14:e4574212176a 52 uint16_t t = x;
merckeng 14:e4574212176a 53 uint8_t * a = (uint8_t*)&t;
merckeng 14:e4574212176a 54 a[0] = x>>(8*1);
merckeng 14:e4574212176a 55 a[1] = x>>(8*0);
merckeng 14:e4574212176a 56 return t;
merckeng 14:e4574212176a 57 }
merckeng 14:e4574212176a 58 void hton16(uint16_t * x)
merckeng 14:e4574212176a 59 {
merckeng 14:e4574212176a 60 *x = hton16(*x);
merckeng 14:e4574212176a 61 }
merckeng 14:e4574212176a 62
SomeRandomBloke 0:5a0b43f3b143 63
merckeng 17:3dc30f4a8da2 64
merckeng 17:3dc30f4a8da2 65 // build a transmit buffer (from https://raw.githubusercontent.com/mcci-catena/Catena4410-Sketches/master/catena4410_sensor1/catena4410_sensor1.ino)
merckeng 17:3dc30f4a8da2 66 class TxBuffer_t
merckeng 17:3dc30f4a8da2 67 {
merckeng 17:3dc30f4a8da2 68 public:
merckeng 17:3dc30f4a8da2 69 uint8_t buf[32]; // this sets the largest buffer size
merckeng 17:3dc30f4a8da2 70 uint8_t *p;
merckeng 17:3dc30f4a8da2 71
merckeng 17:3dc30f4a8da2 72 TxBuffer_t() : p(buf) {};
merckeng 17:3dc30f4a8da2 73 void begin()
merckeng 17:3dc30f4a8da2 74 {
merckeng 17:3dc30f4a8da2 75 p = buf;
merckeng 17:3dc30f4a8da2 76 }
merckeng 17:3dc30f4a8da2 77 void put(uint8_t c)
merckeng 17:3dc30f4a8da2 78 {
merckeng 17:3dc30f4a8da2 79 if (p < buf + sizeof(buf))
merckeng 17:3dc30f4a8da2 80 *p++ = c;
merckeng 17:3dc30f4a8da2 81 }
merckeng 17:3dc30f4a8da2 82 void put1u(int32_t v)
merckeng 17:3dc30f4a8da2 83 {
merckeng 17:3dc30f4a8da2 84 if (v > 0xFF)
merckeng 17:3dc30f4a8da2 85 v = 0xFF;
merckeng 17:3dc30f4a8da2 86 else if (v < 0)
merckeng 17:3dc30f4a8da2 87 v = 0;
merckeng 17:3dc30f4a8da2 88 put((uint8_t) v);
merckeng 17:3dc30f4a8da2 89 }
merckeng 17:3dc30f4a8da2 90 void put2(uint32_t v)
merckeng 17:3dc30f4a8da2 91 {
merckeng 17:3dc30f4a8da2 92 if (v > 0xFFFF)
merckeng 17:3dc30f4a8da2 93 v = 0xFFFF;
merckeng 17:3dc30f4a8da2 94
merckeng 17:3dc30f4a8da2 95 put((uint8_t) (v >> 8));
merckeng 17:3dc30f4a8da2 96 put((uint8_t) v);
merckeng 17:3dc30f4a8da2 97 }
merckeng 17:3dc30f4a8da2 98 void put2(int32_t v)
merckeng 17:3dc30f4a8da2 99 {
merckeng 17:3dc30f4a8da2 100 if (v < -0x8000)
merckeng 17:3dc30f4a8da2 101 v = -0x8000;
merckeng 17:3dc30f4a8da2 102 else if (v > 0x7FFF)
merckeng 17:3dc30f4a8da2 103 v = 0x7FFF;
merckeng 17:3dc30f4a8da2 104
merckeng 17:3dc30f4a8da2 105 put2((uint32_t) v);
merckeng 17:3dc30f4a8da2 106 }
merckeng 17:3dc30f4a8da2 107 void put3(uint32_t v)
merckeng 17:3dc30f4a8da2 108 {
merckeng 17:3dc30f4a8da2 109 if (v > 0xFFFFFF)
merckeng 17:3dc30f4a8da2 110 v = 0xFFFFFF;
merckeng 17:3dc30f4a8da2 111
merckeng 17:3dc30f4a8da2 112 put((uint8_t) (v >> 16));
merckeng 17:3dc30f4a8da2 113 put((uint8_t) (v >> 8));
merckeng 17:3dc30f4a8da2 114 put((uint8_t) v);
merckeng 17:3dc30f4a8da2 115 }
merckeng 17:3dc30f4a8da2 116 void put2u(int32_t v)
merckeng 17:3dc30f4a8da2 117 {
merckeng 17:3dc30f4a8da2 118 if (v < 0)
merckeng 17:3dc30f4a8da2 119 v = 0;
merckeng 17:3dc30f4a8da2 120 else if (v > 0xFFFF)
merckeng 17:3dc30f4a8da2 121 v = 0xFFFF;
merckeng 17:3dc30f4a8da2 122 put2((uint32_t) v);
merckeng 17:3dc30f4a8da2 123 }
merckeng 17:3dc30f4a8da2 124 void put3(int32_t v)
merckeng 17:3dc30f4a8da2 125 {
merckeng 17:3dc30f4a8da2 126 if (v < -0x800000)
merckeng 17:3dc30f4a8da2 127 v = -0x800000;
merckeng 17:3dc30f4a8da2 128 else if (v > 0x7FFFFF)
merckeng 17:3dc30f4a8da2 129 v = 0x7FFFFF;
merckeng 17:3dc30f4a8da2 130 put3((uint32_t) v);
merckeng 17:3dc30f4a8da2 131 }
merckeng 17:3dc30f4a8da2 132 uint8_t *getp(void)
merckeng 17:3dc30f4a8da2 133 {
merckeng 17:3dc30f4a8da2 134 return p;
merckeng 17:3dc30f4a8da2 135 }
merckeng 17:3dc30f4a8da2 136 size_t getn(void)
merckeng 17:3dc30f4a8da2 137 {
merckeng 17:3dc30f4a8da2 138 return p - buf;
merckeng 17:3dc30f4a8da2 139 }
merckeng 17:3dc30f4a8da2 140 uint8_t *getbase(void)
merckeng 17:3dc30f4a8da2 141 {
merckeng 17:3dc30f4a8da2 142 return buf;
merckeng 17:3dc30f4a8da2 143 }
merckeng 17:3dc30f4a8da2 144 void put2sf(float v)
merckeng 17:3dc30f4a8da2 145 {
merckeng 17:3dc30f4a8da2 146 int32_t iv;
merckeng 17:3dc30f4a8da2 147
merckeng 17:3dc30f4a8da2 148 if (v > 32766.5f)
merckeng 17:3dc30f4a8da2 149 iv = 0x7fff;
merckeng 17:3dc30f4a8da2 150 else if (v < -32767.5f)
merckeng 17:3dc30f4a8da2 151 iv = -0x8000;
merckeng 17:3dc30f4a8da2 152 else
merckeng 17:3dc30f4a8da2 153 iv = (int32_t)(v + 0.5f);
merckeng 17:3dc30f4a8da2 154
merckeng 17:3dc30f4a8da2 155 put2(iv);
merckeng 17:3dc30f4a8da2 156 }
merckeng 17:3dc30f4a8da2 157 void put2uf(float v)
merckeng 17:3dc30f4a8da2 158 {
merckeng 17:3dc30f4a8da2 159 uint32_t iv;
merckeng 17:3dc30f4a8da2 160
merckeng 17:3dc30f4a8da2 161 if (v > 65535.5f)
merckeng 17:3dc30f4a8da2 162 iv = 0xffff;
merckeng 17:3dc30f4a8da2 163 else if (v < 0.5f)
merckeng 17:3dc30f4a8da2 164 iv = 0;
merckeng 17:3dc30f4a8da2 165 else
merckeng 17:3dc30f4a8da2 166 iv = (uint32_t)(v + 0.5f);
merckeng 17:3dc30f4a8da2 167
merckeng 17:3dc30f4a8da2 168 put2(iv);
merckeng 17:3dc30f4a8da2 169 }
merckeng 17:3dc30f4a8da2 170 void put1uf(float v)
merckeng 17:3dc30f4a8da2 171 {
merckeng 17:3dc30f4a8da2 172 uint8_t c;
merckeng 17:3dc30f4a8da2 173
merckeng 17:3dc30f4a8da2 174 if (v > 254.5)
merckeng 17:3dc30f4a8da2 175 c = 0xFF;
merckeng 17:3dc30f4a8da2 176 else if (v < 0.5)
merckeng 17:3dc30f4a8da2 177 c = 0;
merckeng 17:3dc30f4a8da2 178 else
merckeng 17:3dc30f4a8da2 179 c = (uint8_t) v;
merckeng 17:3dc30f4a8da2 180
merckeng 17:3dc30f4a8da2 181 put(c);
merckeng 17:3dc30f4a8da2 182 }
merckeng 17:3dc30f4a8da2 183 void putT(float T)
merckeng 17:3dc30f4a8da2 184 {
merckeng 17:3dc30f4a8da2 185 put2sf(T * 256.0f + 0.5f);
merckeng 17:3dc30f4a8da2 186 }
merckeng 17:3dc30f4a8da2 187 void putRH(float RH)
merckeng 17:3dc30f4a8da2 188 {
merckeng 17:3dc30f4a8da2 189 put1uf((RH / 0.390625f) + 0.5f);
merckeng 17:3dc30f4a8da2 190 }
merckeng 17:3dc30f4a8da2 191 void putV(float V)
merckeng 17:3dc30f4a8da2 192 {
merckeng 17:3dc30f4a8da2 193 put2sf(V * 4096.0f + 0.5f);
merckeng 17:3dc30f4a8da2 194 }
merckeng 17:3dc30f4a8da2 195 void putP(float P)
merckeng 17:3dc30f4a8da2 196 {
merckeng 17:3dc30f4a8da2 197 put2uf(P / 4.0f + 0.5f);
merckeng 17:3dc30f4a8da2 198 }
merckeng 17:3dc30f4a8da2 199 void putLux(float Lux)
merckeng 17:3dc30f4a8da2 200 {
merckeng 17:3dc30f4a8da2 201 put2uf(Lux);
merckeng 17:3dc30f4a8da2 202 }
merckeng 17:3dc30f4a8da2 203 };
merckeng 17:3dc30f4a8da2 204
merckeng 17:3dc30f4a8da2 205 /* the magic byte at the front of the buffer */
merckeng 17:3dc30f4a8da2 206 enum {
merckeng 17:3dc30f4a8da2 207 FormatSensor1 = 0x11,
merckeng 17:3dc30f4a8da2 208 };
merckeng 17:3dc30f4a8da2 209
merckeng 17:3dc30f4a8da2 210 /* the flags for the second byte of the buffer */
merckeng 17:3dc30f4a8da2 211 enum {
merckeng 17:3dc30f4a8da2 212 FlagVbat = 1 << 0,
merckeng 17:3dc30f4a8da2 213 FlagVcc = 1 << 1,
merckeng 17:3dc30f4a8da2 214 FlagTPH = 1 << 2,
merckeng 17:3dc30f4a8da2 215 FlagLux = 1 << 3,
merckeng 17:3dc30f4a8da2 216 FlagWater = 1 << 4,
merckeng 17:3dc30f4a8da2 217 FlagSoilTH = 1 << 5,
merckeng 17:3dc30f4a8da2 218 };
merckeng 17:3dc30f4a8da2 219
SomeRandomBloke 0:5a0b43f3b143 220
SomeRandomBloke 3:367aa95f9771 221 // Temperature sensor object
merckeng 14:e4574212176a 222 #define DHT_PIN PB_1
merckeng 14:e4574212176a 223 DHT11 dht(DHT_PIN);
SomeRandomBloke 0:5a0b43f3b143 224
SomeRandomBloke 3:367aa95f9771 225 // Serial via USB for debugging only
SomeRandomBloke 0:5a0b43f3b143 226 Serial pc(USBTX,USBRX);
SomeRandomBloke 0:5a0b43f3b143 227
SomeRandomBloke 0:5a0b43f3b143 228 int main()
SomeRandomBloke 0:5a0b43f3b143 229 {
merckeng 17:3dc30f4a8da2 230 TxBuffer_t b;
merckeng 14:e4574212176a 231
SomeRandomBloke 0:5a0b43f3b143 232 int32_t ret;
SomeRandomBloke 0:5a0b43f3b143 233 mDot* dot;
SomeRandomBloke 0:5a0b43f3b143 234 std::vector<uint8_t> send_data;
SomeRandomBloke 0:5a0b43f3b143 235 std::vector<uint8_t> recv_data;
SomeRandomBloke 5:48eb9245a914 236 std::vector<uint8_t> nwkSKey;
merckeng 14:e4574212176a 237 std::vector<uint8_t> appSKey;
SomeRandomBloke 5:48eb9245a914 238 std::vector<uint8_t> nodeAddr;
SomeRandomBloke 6:0a7760eeaba9 239 std::vector<uint8_t> networkAddr;
SomeRandomBloke 0:5a0b43f3b143 240
SomeRandomBloke 0:5a0b43f3b143 241 float temperature = 0.0;
SomeRandomBloke 1:45cec6aea002 242
SomeRandomBloke 0:5a0b43f3b143 243 pc.baud(115200);
merckeng 14:e4574212176a 244 pc.printf("TTN mDot LoRa Temperature & Humidity Sensor\n\r");
SomeRandomBloke 1:45cec6aea002 245
SomeRandomBloke 0:5a0b43f3b143 246 // get a mDot handle
SomeRandomBloke 0:5a0b43f3b143 247 dot = mDot::getInstance();
SomeRandomBloke 0:5a0b43f3b143 248
merckeng 14:e4574212176a 249 // dot->setLogLevel(MTSLog::WARNING_LEVEL);
merckeng 14:e4574212176a 250 dot->setLogLevel(MTSLog::TRACE_LEVEL);
SomeRandomBloke 0:5a0b43f3b143 251
SomeRandomBloke 1:45cec6aea002 252 logInfo("Checking Config");
SomeRandomBloke 1:45cec6aea002 253
SomeRandomBloke 1:45cec6aea002 254 // Test if we've already saved the config
SomeRandomBloke 1:45cec6aea002 255 std::string configNetworkName = dot->getNetworkName();
SomeRandomBloke 5:48eb9245a914 256
SomeRandomBloke 5:48eb9245a914 257 uint8_t *it = NwkSKey;
SomeRandomBloke 5:48eb9245a914 258 for (uint8_t i = 0; i<16; i++)
SomeRandomBloke 5:48eb9245a914 259 nwkSKey.push_back((uint8_t) *it++);
merckeng 14:e4574212176a 260
merckeng 14:e4574212176a 261 it = AppSKey;
merckeng 14:e4574212176a 262 for (uint8_t i = 0; i<16; i++)
merckeng 14:e4574212176a 263 appSKey.push_back((uint8_t) *it++);
SomeRandomBloke 5:48eb9245a914 264
SomeRandomBloke 6:0a7760eeaba9 265 it = NetworkAddr;
SomeRandomBloke 5:48eb9245a914 266 for (uint8_t i = 0; i<4; i++)
SomeRandomBloke 6:0a7760eeaba9 267 networkAddr.push_back((uint8_t) *it++);
SomeRandomBloke 1:45cec6aea002 268
SomeRandomBloke 9:086351e54b57 269 logInfo("Resetting Config");
SomeRandomBloke 9:086351e54b57 270 // reset to default config so we know what state we're in
SomeRandomBloke 9:086351e54b57 271 dot->resetConfig();
SomeRandomBloke 1:45cec6aea002 272
SomeRandomBloke 5:48eb9245a914 273 // Set byte order - AEP less than 1.0.30
SomeRandomBloke 8:8070e9d660e4 274 // dot->setJoinByteOrder(mDot::LSB);
SomeRandomBloke 8:8070e9d660e4 275 dot->setJoinByteOrder(mDot::MSB); // This is default for > 1.0.30 Conduit
SomeRandomBloke 0:5a0b43f3b143 276
merckeng 14:e4574212176a 277
SomeRandomBloke 5:48eb9245a914 278
SomeRandomBloke 5:48eb9245a914 279 logInfo("Set TxPower");
SomeRandomBloke 8:8070e9d660e4 280 if((ret = dot->setTxPower( LORA_TXPOWER )) != mDot::MDOT_OK) {
SomeRandomBloke 5:48eb9245a914 281 logError("Failed to set Tx Power %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 282 }
SomeRandomBloke 5:48eb9245a914 283
SomeRandomBloke 7:2a704d1a30e1 284 logInfo("Set Public mode");
SomeRandomBloke 7:2a704d1a30e1 285 if((ret = dot->setPublicNetwork(true)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 286 logError("failed to set Public Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 7:2a704d1a30e1 287 }
SomeRandomBloke 7:2a704d1a30e1 288
SomeRandomBloke 7:2a704d1a30e1 289 logInfo("Set MANUAL Join mode");
SomeRandomBloke 7:2a704d1a30e1 290 if((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 291 logError("Failed to set MANUAL Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 7:2a704d1a30e1 292 }
SomeRandomBloke 7:2a704d1a30e1 293
SomeRandomBloke 5:48eb9245a914 294 logInfo("Set Ack");
SomeRandomBloke 5:48eb9245a914 295 // 1 retries on Ack, 0 to disable
SomeRandomBloke 8:8070e9d660e4 296 if((ret = dot->setAck( LORA_ACK)) != mDot::MDOT_OK) {
SomeRandomBloke 5:48eb9245a914 297 logError("Failed to set Ack %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 298 }
SomeRandomBloke 3:367aa95f9771 299
merckeng 13:761b9c929a3f 300 //Not applicable for 868MHz in EU
merckeng 13:761b9c929a3f 301 if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
merckeng 13:761b9c929a3f 302 logError("failed to set frequency sub band", ret);
merckeng 13:761b9c929a3f 303 }
SomeRandomBloke 1:45cec6aea002 304
SomeRandomBloke 6:0a7760eeaba9 305 logInfo("Set Network Address");
SomeRandomBloke 6:0a7760eeaba9 306 if ((ret = dot->setNetworkAddress(networkAddr)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 307 logError("Failed to set Network Address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 7:2a704d1a30e1 308 }
SomeRandomBloke 7:2a704d1a30e1 309
SomeRandomBloke 7:2a704d1a30e1 310 logInfo("Set Data Session Key");
merckeng 14:e4574212176a 311 if ((ret = dot->setDataSessionKey(appSKey)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 312 logError("Failed to set Data Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 313 }
SomeRandomBloke 0:5a0b43f3b143 314
SomeRandomBloke 5:48eb9245a914 315 logInfo("Set Network Session Key");
SomeRandomBloke 5:48eb9245a914 316 if ((ret = dot->setNetworkSessionKey(nwkSKey)) != mDot::MDOT_OK) {
SomeRandomBloke 5:48eb9245a914 317 logError("Failed to set Network Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 318 }
SomeRandomBloke 5:48eb9245a914 319
SomeRandomBloke 5:48eb9245a914 320 logInfo("Saving Config");
SomeRandomBloke 5:48eb9245a914 321 // Save config
SomeRandomBloke 5:48eb9245a914 322 if (! dot->saveConfig()) {
SomeRandomBloke 5:48eb9245a914 323 logError("failed to save configuration");
SomeRandomBloke 0:5a0b43f3b143 324 }
SomeRandomBloke 5:48eb9245a914 325
SomeRandomBloke 5:48eb9245a914 326 // Display what is set
SomeRandomBloke 5:48eb9245a914 327 std::vector<uint8_t> tmp = dot->getNetworkSessionKey();
SomeRandomBloke 5:48eb9245a914 328 pc.printf("Network Session Key: ");
SomeRandomBloke 5:48eb9245a914 329 pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
SomeRandomBloke 5:48eb9245a914 330
SomeRandomBloke 5:48eb9245a914 331 tmp = dot->getDataSessionKey();
SomeRandomBloke 5:48eb9245a914 332 pc.printf("Data Session Key: ");
SomeRandomBloke 5:48eb9245a914 333 pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
SomeRandomBloke 0:5a0b43f3b143 334
SomeRandomBloke 6:0a7760eeaba9 335 pc.printf("Device ID ");
SomeRandomBloke 6:0a7760eeaba9 336 std::vector<uint8_t> deviceId;
SomeRandomBloke 6:0a7760eeaba9 337 deviceId = dot->getDeviceId();
SomeRandomBloke 6:0a7760eeaba9 338 for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it)
SomeRandomBloke 5:48eb9245a914 339 pc.printf("%2.2x",*it );
SomeRandomBloke 6:0a7760eeaba9 340 pc.printf("\r\n");
SomeRandomBloke 5:48eb9245a914 341
SomeRandomBloke 6:0a7760eeaba9 342 std::vector<uint8_t> netAddress;
SomeRandomBloke 9:086351e54b57 343
SomeRandomBloke 6:0a7760eeaba9 344 pc.printf("Network Address ");
SomeRandomBloke 6:0a7760eeaba9 345 netAddress = dot->getNetworkAddress();
SomeRandomBloke 6:0a7760eeaba9 346 for (std::vector<uint8_t>::iterator it = netAddress.begin() ; it != netAddress.end(); ++it)
SomeRandomBloke 5:48eb9245a914 347 pc.printf("%2.2x",*it );
SomeRandomBloke 5:48eb9245a914 348
SomeRandomBloke 5:48eb9245a914 349 pc.printf("\r\n");
SomeRandomBloke 5:48eb9245a914 350
SomeRandomBloke 5:48eb9245a914 351 // Display LoRa parameters
SomeRandomBloke 5:48eb9245a914 352 // Display label and values in different colours, show pretty values not numeric values where applicable
SomeRandomBloke 5:48eb9245a914 353 pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") );
SomeRandomBloke 5:48eb9245a914 354 pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() );
SomeRandomBloke 5:48eb9245a914 355 pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() );
SomeRandomBloke 5:48eb9245a914 356 pc.printf("Join Mode: %s\r\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() );
SomeRandomBloke 6:0a7760eeaba9 357 pc.printf("Join Retries: %d\r\n", dot->getJoinRetries() );
SomeRandomBloke 6:0a7760eeaba9 358 pc.printf("Join Byte Order: %s\r\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") );
SomeRandomBloke 5:48eb9245a914 359 pc.printf("Link Check Count: %d\r\n", dot->getLinkCheckCount() );
SomeRandomBloke 7:2a704d1a30e1 360 pc.printf("Link Check Thold: %d\r\n", dot->getLinkCheckThreshold() );
SomeRandomBloke 5:48eb9245a914 361 pc.printf("Tx Data Rate: %s\r\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() );
SomeRandomBloke 5:48eb9245a914 362 pc.printf("Tx Power: %d\r\n", dot->getTxPower() );
SomeRandomBloke 6:0a7760eeaba9 363 pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" ));
SomeRandomBloke 5:48eb9245a914 364 pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") );
SomeRandomBloke 5:48eb9245a914 365 pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N") );
SomeRandomBloke 5:48eb9245a914 366
SomeRandomBloke 9:086351e54b57 367 logInfo("Joining Network");
SomeRandomBloke 6:0a7760eeaba9 368
SomeRandomBloke 9:086351e54b57 369 while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
SomeRandomBloke 9:086351e54b57 370 logError("failed to join network [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 9:086351e54b57 371 wait_ms(dot->getNextTxMs() + 1);
SomeRandomBloke 9:086351e54b57 372 }
SomeRandomBloke 6:0a7760eeaba9 373
SomeRandomBloke 9:086351e54b57 374 logInfo("Joined Network");
SomeRandomBloke 6:0a7760eeaba9 375
SomeRandomBloke 0:5a0b43f3b143 376 char dataBuf[50];
merckeng 14:e4574212176a 377 uint16_t seq = 0;
merckeng 14:e4574212176a 378 char * sf_str;
SomeRandomBloke 0:5a0b43f3b143 379 while( 1 ) {
merckeng 14:e4574212176a 380
merckeng 14:e4574212176a 381 /* cycle through spreading factors */
merckeng 14:e4574212176a 382 uint8_t sf;
merckeng 14:e4574212176a 383 switch (seq % 4) {
merckeng 14:e4574212176a 384 case 0:
merckeng 14:e4574212176a 385 sf = mDot::SF_7;
merckeng 14:e4574212176a 386 sf_str = "SF7";
merckeng 14:e4574212176a 387 break;
merckeng 14:e4574212176a 388 case 1:
merckeng 14:e4574212176a 389 sf = mDot::SF_8;
merckeng 14:e4574212176a 390 sf_str = "SF8";
merckeng 14:e4574212176a 391 break;
merckeng 14:e4574212176a 392 case 2:
merckeng 14:e4574212176a 393 sf = mDot::SF_9;
merckeng 14:e4574212176a 394 sf_str = "SF9";
merckeng 14:e4574212176a 395 break;
merckeng 14:e4574212176a 396 case 3:
merckeng 14:e4574212176a 397 sf = mDot::SF_10;
merckeng 14:e4574212176a 398 sf_str = "SF10";
merckeng 14:e4574212176a 399 break;
merckeng 14:e4574212176a 400 }
merckeng 14:e4574212176a 401 // Set Spreading Factor, higher is lower data rate, smaller packets but longer range
merckeng 14:e4574212176a 402 // Lower is higher data rate, larger packets and shorter range.
merckeng 14:e4574212176a 403 logInfo("Set SF: %s",sf_str);
merckeng 14:e4574212176a 404 if((ret = dot->setTxDataRate( sf )) != mDot::MDOT_OK) {
merckeng 14:e4574212176a 405 logError("Failed to set SF %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
merckeng 14:e4574212176a 406 }
merckeng 14:e4574212176a 407
merckeng 14:e4574212176a 408 /* set default data values */
merckeng 14:e4574212176a 409 int temp = 0;
merckeng 14:e4574212176a 410 int humid = -1;
merckeng 14:e4574212176a 411
merckeng 14:e4574212176a 412 /* read from sensor */
merckeng 14:e4574212176a 413 int r = dht.readData();
merckeng 14:e4574212176a 414 switch (r) {
merckeng 14:e4574212176a 415 case DHT11::OK:
merckeng 14:e4574212176a 416 {
merckeng 14:e4574212176a 417 temp = dht.readTemperature();
merckeng 14:e4574212176a 418 humid = dht.readHumidity();
merckeng 14:e4574212176a 419 pc.printf("[DHT] T %d degC H %d %%\r\n",temp,humid);
merckeng 14:e4574212176a 420 break;
merckeng 14:e4574212176a 421 }
merckeng 14:e4574212176a 422 default:
merckeng 14:e4574212176a 423 {
merckeng 14:e4574212176a 424 pc.printf("[DHT] ERROR %d\r\n",r);
merckeng 14:e4574212176a 425 break;
merckeng 14:e4574212176a 426 }
merckeng 14:e4574212176a 427 };
merckeng 14:e4574212176a 428
merckeng 14:e4574212176a 429 /* build packet */
merckeng 17:3dc30f4a8da2 430 b.begin();
merckeng 17:3dc30f4a8da2 431 uint8_t flag = 0;
merckeng 17:3dc30f4a8da2 432 b.put(FormatSensor1);
merckeng 17:3dc30f4a8da2 433 uint8_t * const pFlag = b.getp(); // save pointer to flag location
merckeng 17:3dc30f4a8da2 434 b.put(0x00); // placeholder for flags
merckeng 17:3dc30f4a8da2 435
merckeng 17:3dc30f4a8da2 436 // TODO: read battery voltage
merckeng 17:3dc30f4a8da2 437 b.putV(13.8);
merckeng 17:3dc30f4a8da2 438 flag |= FlagVbat;
merckeng 17:3dc30f4a8da2 439
merckeng 17:3dc30f4a8da2 440 // TODO: read from Bme280 sensor:
merckeng 17:3dc30f4a8da2 441 b.putT(27.0); // air temp
merckeng 17:3dc30f4a8da2 442 b.putP(1010.0); // air pressure
merckeng 17:3dc30f4a8da2 443 b.putRH(66.0); // air humidity
merckeng 17:3dc30f4a8da2 444 flag |= FlagTPH;
merckeng 17:3dc30f4a8da2 445
merckeng 17:3dc30f4a8da2 446 // TODO: read from light sensor
merckeng 17:3dc30f4a8da2 447 b.putLux(1234); // ambient light
merckeng 17:3dc30f4a8da2 448 flag |= FlagLux;
merckeng 17:3dc30f4a8da2 449
merckeng 17:3dc30f4a8da2 450 // TODO: read water temperature
merckeng 17:3dc30f4a8da2 451 b.putT(22.0); // water temperature
merckeng 17:3dc30f4a8da2 452 flag |= FlagWater;
merckeng 17:3dc30f4a8da2 453
merckeng 17:3dc30f4a8da2 454 // TODO: read soil sensor
merckeng 17:3dc30f4a8da2 455 b.putT(25.2); // soil temperature
merckeng 17:3dc30f4a8da2 456 b.putRH(82.0); // soil humidity
merckeng 17:3dc30f4a8da2 457 flag |= FlagSoilTH;
merckeng 17:3dc30f4a8da2 458
merckeng 17:3dc30f4a8da2 459 // write flag byte
merckeng 17:3dc30f4a8da2 460 *pFlag = flag;
merckeng 14:e4574212176a 461
merckeng 14:e4574212176a 462 /* load vector */
merckeng 17:3dc30f4a8da2 463 send_data.clear();
merckeng 17:3dc30f4a8da2 464 uint8_t c;
merckeng 17:3dc30f4a8da2 465 int n = b.getn();
merckeng 17:3dc30f4a8da2 466 for( int i=0; i< n; i++ ) {
merckeng 17:3dc30f4a8da2 467 c = b.buf[i];
merckeng 17:3dc30f4a8da2 468 send_data.push_back( c );
merckeng 17:3dc30f4a8da2 469 }
SomeRandomBloke 0:5a0b43f3b143 470
merckeng 14:e4574212176a 471 /* send packet */
SomeRandomBloke 0:5a0b43f3b143 472 if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
SomeRandomBloke 0:5a0b43f3b143 473 logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 0:5a0b43f3b143 474 } else {
merckeng 17:3dc30f4a8da2 475 logInfo("data len: %d, send data: %s", n, Text::bin2hexString(send_data).c_str());
SomeRandomBloke 0:5a0b43f3b143 476 }
SomeRandomBloke 0:5a0b43f3b143 477
merckeng 14:e4574212176a 478 /* sleep */
merckeng 14:e4574212176a 479 uint32_t sleep_time = MAX((dot->getNextTxMs() / 1000), 10 /* use 6000 for 10min */);
SomeRandomBloke 2:9db840d12557 480 logInfo("going to sleep for %d seconds", sleep_time);
merckeng 14:e4574212176a 481 wait_ms(10*1000);
merckeng 14:e4574212176a 482
merckeng 14:e4574212176a 483 seq++;
SomeRandomBloke 0:5a0b43f3b143 484 }
SomeRandomBloke 2:9db840d12557 485
SomeRandomBloke 0:5a0b43f3b143 486 return 0;
SomeRandomBloke 0:5a0b43f3b143 487 }