Demo of DHT11->mDot->TTN

Dependencies:   DHT22 DS18B20_1wire SHTx TSL2561_I2C libmDot mbed-rtos mbed

Fork of mDot_TTN_DHT11 by Chris Merck

Committer:
merckeng
Date:
Sat Dec 03 22:30:43 2016 +0000
Revision:
19:a2c9c4cc4863
Parent:
18:5b57c3cb4554
remove keys;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
merckeng 18:5b57c3cb4554 1 /** mDot_TTN_Raingarden -- Rain Garden Sensor by The Things Network New York
merckeng 16:01a1058d9c8e 2 *
merckeng 18:5b57c3cb4554 3 * This firmware runs an mDot dev board, with the following sensors:
merckeng 18:5b57c3cb4554 4 * - DHT22 - air temp & humidity
merckeng 18:5b57c3cb4554 5 * - TSL2561 - ambient light
merckeng 18:5b57c3cb4554 6 * - SHT10 - soil temp & humidity
merckeng 18:5b57c3cb4554 7 * - DS18B20 - water temp
merckeng 16:01a1058d9c8e 8 *
SomeRandomBloke 0:5a0b43f3b143 9 * Uses MultiTech mDot developer board http://www.multitech.com/models/94558010LF
SomeRandomBloke 0:5a0b43f3b143 10 * Requires a MultiTech MultiConnect Conduit http://www.multitech.com/models/94557203LF
SomeRandomBloke 5:48eb9245a914 11 * http://www.multitech.net/developer/software/lora/conduit-mlinux-convert-to-basic-packet-forwarder/
SomeRandomBloke 5:48eb9245a914 12 * http://forum.thethingsnetwork.org/t/setting-up-multitech-conduit-gateway-for-ttn/216/35
SomeRandomBloke 0:5a0b43f3b143 13 *
merckeng 18:5b57c3cb4554 14 * To receive and visualize this data:
merckeng 18:5b57c3cb4554 15 *
SomeRandomBloke 0:5a0b43f3b143 16 */
SomeRandomBloke 0:5a0b43f3b143 17
SomeRandomBloke 0:5a0b43f3b143 18 #include "mbed.h"
SomeRandomBloke 0:5a0b43f3b143 19 #include "mDot.h"
SomeRandomBloke 0:5a0b43f3b143 20 #include "MTSLog.h"
SomeRandomBloke 0:5a0b43f3b143 21 #include "MTSText.h"
merckeng 18:5b57c3cb4554 22 #include "DHT22.h"
merckeng 18:5b57c3cb4554 23 #include "TSL2561_I2C.h"
merckeng 18:5b57c3cb4554 24 #include "sht15.hpp"
merckeng 18:5b57c3cb4554 25 #include "DS18B20.h"
SomeRandomBloke 0:5a0b43f3b143 26 #include <string>
SomeRandomBloke 0:5a0b43f3b143 27 #include <vector>
SomeRandomBloke 0:5a0b43f3b143 28
SomeRandomBloke 0:5a0b43f3b143 29 using namespace mts;
SomeRandomBloke 0:5a0b43f3b143 30
merckeng 18:5b57c3cb4554 31 /* Pin definitions */
merckeng 18:5b57c3cb4554 32
merckeng 18:5b57c3cb4554 33 // air temp/humid sensor
merckeng 18:5b57c3cb4554 34 #define DHT_PIN PA_1
merckeng 18:5b57c3cb4554 35 DHT22 dht(DHT_PIN);
merckeng 18:5b57c3cb4554 36
merckeng 18:5b57c3cb4554 37 // water temp sensor
merckeng 18:5b57c3cb4554 38 #define DS_PIN PA_11
merckeng 18:5b57c3cb4554 39 DS18B20 thermom(DS_PIN, DS18B20::RES_12_BIT);
merckeng 18:5b57c3cb4554 40
merckeng 18:5b57c3cb4554 41 // soil temp/humid sensor
merckeng 18:5b57c3cb4554 42 #define SHT_DATA_PIN PA_4
merckeng 18:5b57c3cb4554 43 #define SHT_SCK_PIN PC_13
merckeng 18:5b57c3cb4554 44 SHTx::SHT15 sht(SHT_DATA_PIN, SHT_SCK_PIN);
merckeng 18:5b57c3cb4554 45
merckeng 18:5b57c3cb4554 46 // light sensor
merckeng 18:5b57c3cb4554 47 #define TSL_DATA_PIN PC_9
merckeng 18:5b57c3cb4554 48 #define TSL_SCK_PIN PA_8
merckeng 18:5b57c3cb4554 49 TSL2561_I2C tsl(TSL_DATA_PIN, TSL_SCK_PIN);
merckeng 18:5b57c3cb4554 50
merckeng 18:5b57c3cb4554 51 // LEDs
merckeng 18:5b57c3cb4554 52 #define STATUS PB_1
merckeng 18:5b57c3cb4554 53
SomeRandomBloke 4:f649ab1b61d1 54 #define MIN(a,b) (((a)<(b))?(a):(b))
SomeRandomBloke 4:f649ab1b61d1 55 #define MAX(a,b) (((a)>(b))?(a):(b))
SomeRandomBloke 4:f649ab1b61d1 56
SomeRandomBloke 8:8070e9d660e4 57
merckeng 14:e4574212176a 58 /** ABP
merckeng 14:e4574212176a 59 * Register your device and update these values:
merckeng 14:e4574212176a 60 * https://account.thethingsnetwork.org/
merckeng 14:e4574212176a 61 */
SomeRandomBloke 8:8070e9d660e4 62
merckeng 19:a2c9c4cc4863 63 uint8_t AppSKey[16] = /* replace with Application Session Key in MSB format from TTN dashboard */;
merckeng 19:a2c9c4cc4863 64 uint8_t NwkSKey[16] = /* replace with Network Session Key in MSB format from TTN dashboard */;
merckeng 19:a2c9c4cc4863 65 uint8_t NetworkAddr[4] = /* replace with 4-byte Device Address from TTN dashboard */;
SomeRandomBloke 8:8070e9d660e4 66
SomeRandomBloke 8:8070e9d660e4 67 // Some defines for the LoRa configuration
merckeng 14:e4574212176a 68 #define LORA_SF mDot::SF_7
SomeRandomBloke 8:8070e9d660e4 69 #define LORA_ACK 0
merckeng 14:e4574212176a 70 #define LORA_TXPOWER 20
merckeng 14:e4574212176a 71 static uint8_t config_frequency_sub_band = 2;
SomeRandomBloke 5:48eb9245a914 72
merckeng 14:e4574212176a 73 // functions for ensuring network endianness (little-endian)
merckeng 14:e4574212176a 74 uint16_t hton16(const uint16_t x)
merckeng 14:e4574212176a 75 {
merckeng 14:e4574212176a 76 uint16_t t = x;
merckeng 14:e4574212176a 77 uint8_t * a = (uint8_t*)&t;
merckeng 14:e4574212176a 78 a[0] = x>>(8*1);
merckeng 14:e4574212176a 79 a[1] = x>>(8*0);
merckeng 14:e4574212176a 80 return t;
merckeng 14:e4574212176a 81 }
merckeng 14:e4574212176a 82 void hton16(uint16_t * x)
merckeng 14:e4574212176a 83 {
merckeng 14:e4574212176a 84 *x = hton16(*x);
merckeng 14:e4574212176a 85 }
merckeng 14:e4574212176a 86
SomeRandomBloke 0:5a0b43f3b143 87
merckeng 17:3dc30f4a8da2 88
merckeng 17:3dc30f4a8da2 89 // build a transmit buffer (from https://raw.githubusercontent.com/mcci-catena/Catena4410-Sketches/master/catena4410_sensor1/catena4410_sensor1.ino)
merckeng 17:3dc30f4a8da2 90 class TxBuffer_t
merckeng 17:3dc30f4a8da2 91 {
merckeng 17:3dc30f4a8da2 92 public:
merckeng 17:3dc30f4a8da2 93 uint8_t buf[32]; // this sets the largest buffer size
merckeng 17:3dc30f4a8da2 94 uint8_t *p;
merckeng 17:3dc30f4a8da2 95
merckeng 17:3dc30f4a8da2 96 TxBuffer_t() : p(buf) {};
merckeng 17:3dc30f4a8da2 97 void begin()
merckeng 17:3dc30f4a8da2 98 {
merckeng 17:3dc30f4a8da2 99 p = buf;
merckeng 17:3dc30f4a8da2 100 }
merckeng 17:3dc30f4a8da2 101 void put(uint8_t c)
merckeng 17:3dc30f4a8da2 102 {
merckeng 17:3dc30f4a8da2 103 if (p < buf + sizeof(buf))
merckeng 17:3dc30f4a8da2 104 *p++ = c;
merckeng 17:3dc30f4a8da2 105 }
merckeng 17:3dc30f4a8da2 106 void put1u(int32_t v)
merckeng 17:3dc30f4a8da2 107 {
merckeng 17:3dc30f4a8da2 108 if (v > 0xFF)
merckeng 17:3dc30f4a8da2 109 v = 0xFF;
merckeng 17:3dc30f4a8da2 110 else if (v < 0)
merckeng 17:3dc30f4a8da2 111 v = 0;
merckeng 17:3dc30f4a8da2 112 put((uint8_t) v);
merckeng 17:3dc30f4a8da2 113 }
merckeng 17:3dc30f4a8da2 114 void put2(uint32_t v)
merckeng 17:3dc30f4a8da2 115 {
merckeng 17:3dc30f4a8da2 116 if (v > 0xFFFF)
merckeng 17:3dc30f4a8da2 117 v = 0xFFFF;
merckeng 17:3dc30f4a8da2 118
merckeng 17:3dc30f4a8da2 119 put((uint8_t) (v >> 8));
merckeng 17:3dc30f4a8da2 120 put((uint8_t) v);
merckeng 17:3dc30f4a8da2 121 }
merckeng 17:3dc30f4a8da2 122 void put2(int32_t v)
merckeng 17:3dc30f4a8da2 123 {
merckeng 17:3dc30f4a8da2 124 if (v < -0x8000)
merckeng 17:3dc30f4a8da2 125 v = -0x8000;
merckeng 17:3dc30f4a8da2 126 else if (v > 0x7FFF)
merckeng 17:3dc30f4a8da2 127 v = 0x7FFF;
merckeng 17:3dc30f4a8da2 128
merckeng 17:3dc30f4a8da2 129 put2((uint32_t) v);
merckeng 17:3dc30f4a8da2 130 }
merckeng 17:3dc30f4a8da2 131 void put3(uint32_t v)
merckeng 17:3dc30f4a8da2 132 {
merckeng 17:3dc30f4a8da2 133 if (v > 0xFFFFFF)
merckeng 17:3dc30f4a8da2 134 v = 0xFFFFFF;
merckeng 17:3dc30f4a8da2 135
merckeng 17:3dc30f4a8da2 136 put((uint8_t) (v >> 16));
merckeng 17:3dc30f4a8da2 137 put((uint8_t) (v >> 8));
merckeng 17:3dc30f4a8da2 138 put((uint8_t) v);
merckeng 17:3dc30f4a8da2 139 }
merckeng 17:3dc30f4a8da2 140 void put2u(int32_t v)
merckeng 17:3dc30f4a8da2 141 {
merckeng 17:3dc30f4a8da2 142 if (v < 0)
merckeng 17:3dc30f4a8da2 143 v = 0;
merckeng 17:3dc30f4a8da2 144 else if (v > 0xFFFF)
merckeng 17:3dc30f4a8da2 145 v = 0xFFFF;
merckeng 17:3dc30f4a8da2 146 put2((uint32_t) v);
merckeng 17:3dc30f4a8da2 147 }
merckeng 17:3dc30f4a8da2 148 void put3(int32_t v)
merckeng 17:3dc30f4a8da2 149 {
merckeng 17:3dc30f4a8da2 150 if (v < -0x800000)
merckeng 17:3dc30f4a8da2 151 v = -0x800000;
merckeng 17:3dc30f4a8da2 152 else if (v > 0x7FFFFF)
merckeng 17:3dc30f4a8da2 153 v = 0x7FFFFF;
merckeng 17:3dc30f4a8da2 154 put3((uint32_t) v);
merckeng 17:3dc30f4a8da2 155 }
merckeng 17:3dc30f4a8da2 156 uint8_t *getp(void)
merckeng 17:3dc30f4a8da2 157 {
merckeng 17:3dc30f4a8da2 158 return p;
merckeng 17:3dc30f4a8da2 159 }
merckeng 17:3dc30f4a8da2 160 size_t getn(void)
merckeng 17:3dc30f4a8da2 161 {
merckeng 17:3dc30f4a8da2 162 return p - buf;
merckeng 17:3dc30f4a8da2 163 }
merckeng 17:3dc30f4a8da2 164 uint8_t *getbase(void)
merckeng 17:3dc30f4a8da2 165 {
merckeng 17:3dc30f4a8da2 166 return buf;
merckeng 17:3dc30f4a8da2 167 }
merckeng 17:3dc30f4a8da2 168 void put2sf(float v)
merckeng 17:3dc30f4a8da2 169 {
merckeng 17:3dc30f4a8da2 170 int32_t iv;
merckeng 17:3dc30f4a8da2 171
merckeng 17:3dc30f4a8da2 172 if (v > 32766.5f)
merckeng 17:3dc30f4a8da2 173 iv = 0x7fff;
merckeng 17:3dc30f4a8da2 174 else if (v < -32767.5f)
merckeng 17:3dc30f4a8da2 175 iv = -0x8000;
merckeng 17:3dc30f4a8da2 176 else
merckeng 17:3dc30f4a8da2 177 iv = (int32_t)(v + 0.5f);
merckeng 17:3dc30f4a8da2 178
merckeng 17:3dc30f4a8da2 179 put2(iv);
merckeng 17:3dc30f4a8da2 180 }
merckeng 17:3dc30f4a8da2 181 void put2uf(float v)
merckeng 17:3dc30f4a8da2 182 {
merckeng 17:3dc30f4a8da2 183 uint32_t iv;
merckeng 17:3dc30f4a8da2 184
merckeng 17:3dc30f4a8da2 185 if (v > 65535.5f)
merckeng 17:3dc30f4a8da2 186 iv = 0xffff;
merckeng 17:3dc30f4a8da2 187 else if (v < 0.5f)
merckeng 17:3dc30f4a8da2 188 iv = 0;
merckeng 17:3dc30f4a8da2 189 else
merckeng 17:3dc30f4a8da2 190 iv = (uint32_t)(v + 0.5f);
merckeng 17:3dc30f4a8da2 191
merckeng 17:3dc30f4a8da2 192 put2(iv);
merckeng 17:3dc30f4a8da2 193 }
merckeng 17:3dc30f4a8da2 194 void put1uf(float v)
merckeng 17:3dc30f4a8da2 195 {
merckeng 17:3dc30f4a8da2 196 uint8_t c;
merckeng 17:3dc30f4a8da2 197
merckeng 17:3dc30f4a8da2 198 if (v > 254.5)
merckeng 17:3dc30f4a8da2 199 c = 0xFF;
merckeng 17:3dc30f4a8da2 200 else if (v < 0.5)
merckeng 17:3dc30f4a8da2 201 c = 0;
merckeng 17:3dc30f4a8da2 202 else
merckeng 17:3dc30f4a8da2 203 c = (uint8_t) v;
merckeng 17:3dc30f4a8da2 204
merckeng 17:3dc30f4a8da2 205 put(c);
merckeng 17:3dc30f4a8da2 206 }
merckeng 17:3dc30f4a8da2 207 void putT(float T)
merckeng 17:3dc30f4a8da2 208 {
merckeng 17:3dc30f4a8da2 209 put2sf(T * 256.0f + 0.5f);
merckeng 17:3dc30f4a8da2 210 }
merckeng 17:3dc30f4a8da2 211 void putRH(float RH)
merckeng 17:3dc30f4a8da2 212 {
merckeng 17:3dc30f4a8da2 213 put1uf((RH / 0.390625f) + 0.5f);
merckeng 17:3dc30f4a8da2 214 }
merckeng 17:3dc30f4a8da2 215 void putV(float V)
merckeng 17:3dc30f4a8da2 216 {
merckeng 17:3dc30f4a8da2 217 put2sf(V * 4096.0f + 0.5f);
merckeng 17:3dc30f4a8da2 218 }
merckeng 17:3dc30f4a8da2 219 void putP(float P)
merckeng 17:3dc30f4a8da2 220 {
merckeng 17:3dc30f4a8da2 221 put2uf(P / 4.0f + 0.5f);
merckeng 17:3dc30f4a8da2 222 }
merckeng 17:3dc30f4a8da2 223 void putLux(float Lux)
merckeng 17:3dc30f4a8da2 224 {
merckeng 17:3dc30f4a8da2 225 put2uf(Lux);
merckeng 17:3dc30f4a8da2 226 }
merckeng 17:3dc30f4a8da2 227 };
merckeng 17:3dc30f4a8da2 228
merckeng 17:3dc30f4a8da2 229 /* the magic byte at the front of the buffer */
merckeng 17:3dc30f4a8da2 230 enum {
merckeng 17:3dc30f4a8da2 231 FormatSensor1 = 0x11,
merckeng 17:3dc30f4a8da2 232 };
merckeng 17:3dc30f4a8da2 233
merckeng 17:3dc30f4a8da2 234 /* the flags for the second byte of the buffer */
merckeng 17:3dc30f4a8da2 235 enum {
merckeng 17:3dc30f4a8da2 236 FlagVbat = 1 << 0,
merckeng 17:3dc30f4a8da2 237 FlagVcc = 1 << 1,
merckeng 17:3dc30f4a8da2 238 FlagTPH = 1 << 2,
merckeng 17:3dc30f4a8da2 239 FlagLux = 1 << 3,
merckeng 17:3dc30f4a8da2 240 FlagWater = 1 << 4,
merckeng 17:3dc30f4a8da2 241 FlagSoilTH = 1 << 5,
merckeng 17:3dc30f4a8da2 242 };
merckeng 17:3dc30f4a8da2 243
SomeRandomBloke 0:5a0b43f3b143 244
SomeRandomBloke 0:5a0b43f3b143 245
SomeRandomBloke 3:367aa95f9771 246 // Serial via USB for debugging only
SomeRandomBloke 0:5a0b43f3b143 247 Serial pc(USBTX,USBRX);
SomeRandomBloke 0:5a0b43f3b143 248
SomeRandomBloke 0:5a0b43f3b143 249 int main()
SomeRandomBloke 0:5a0b43f3b143 250 {
merckeng 17:3dc30f4a8da2 251 TxBuffer_t b;
merckeng 14:e4574212176a 252
SomeRandomBloke 0:5a0b43f3b143 253 int32_t ret;
SomeRandomBloke 0:5a0b43f3b143 254 mDot* dot;
SomeRandomBloke 0:5a0b43f3b143 255 std::vector<uint8_t> send_data;
SomeRandomBloke 0:5a0b43f3b143 256 std::vector<uint8_t> recv_data;
SomeRandomBloke 5:48eb9245a914 257 std::vector<uint8_t> nwkSKey;
merckeng 14:e4574212176a 258 std::vector<uint8_t> appSKey;
SomeRandomBloke 5:48eb9245a914 259 std::vector<uint8_t> nodeAddr;
SomeRandomBloke 6:0a7760eeaba9 260 std::vector<uint8_t> networkAddr;
SomeRandomBloke 0:5a0b43f3b143 261
SomeRandomBloke 0:5a0b43f3b143 262 float temperature = 0.0;
SomeRandomBloke 1:45cec6aea002 263
merckeng 18:5b57c3cb4554 264 DigitalInOut status_led(STATUS);
merckeng 18:5b57c3cb4554 265 status_led.output();
merckeng 18:5b57c3cb4554 266
SomeRandomBloke 0:5a0b43f3b143 267 pc.baud(115200);
merckeng 18:5b57c3cb4554 268 pc.printf("TTN mDot LoRa Temperature & Humidity Sensor\n\r");
SomeRandomBloke 1:45cec6aea002 269
SomeRandomBloke 0:5a0b43f3b143 270 // get a mDot handle
SomeRandomBloke 0:5a0b43f3b143 271 dot = mDot::getInstance();
SomeRandomBloke 0:5a0b43f3b143 272
merckeng 14:e4574212176a 273 // dot->setLogLevel(MTSLog::WARNING_LEVEL);
merckeng 14:e4574212176a 274 dot->setLogLevel(MTSLog::TRACE_LEVEL);
SomeRandomBloke 0:5a0b43f3b143 275
SomeRandomBloke 1:45cec6aea002 276 logInfo("Checking Config");
SomeRandomBloke 1:45cec6aea002 277
SomeRandomBloke 1:45cec6aea002 278 // Test if we've already saved the config
SomeRandomBloke 1:45cec6aea002 279 std::string configNetworkName = dot->getNetworkName();
SomeRandomBloke 5:48eb9245a914 280
SomeRandomBloke 5:48eb9245a914 281 uint8_t *it = NwkSKey;
SomeRandomBloke 5:48eb9245a914 282 for (uint8_t i = 0; i<16; i++)
SomeRandomBloke 5:48eb9245a914 283 nwkSKey.push_back((uint8_t) *it++);
merckeng 14:e4574212176a 284
merckeng 14:e4574212176a 285 it = AppSKey;
merckeng 14:e4574212176a 286 for (uint8_t i = 0; i<16; i++)
merckeng 14:e4574212176a 287 appSKey.push_back((uint8_t) *it++);
SomeRandomBloke 5:48eb9245a914 288
SomeRandomBloke 6:0a7760eeaba9 289 it = NetworkAddr;
SomeRandomBloke 5:48eb9245a914 290 for (uint8_t i = 0; i<4; i++)
SomeRandomBloke 6:0a7760eeaba9 291 networkAddr.push_back((uint8_t) *it++);
SomeRandomBloke 1:45cec6aea002 292
SomeRandomBloke 9:086351e54b57 293 logInfo("Resetting Config");
SomeRandomBloke 9:086351e54b57 294 // reset to default config so we know what state we're in
SomeRandomBloke 9:086351e54b57 295 dot->resetConfig();
SomeRandomBloke 1:45cec6aea002 296
SomeRandomBloke 5:48eb9245a914 297 // Set byte order - AEP less than 1.0.30
SomeRandomBloke 8:8070e9d660e4 298 // dot->setJoinByteOrder(mDot::LSB);
SomeRandomBloke 8:8070e9d660e4 299 dot->setJoinByteOrder(mDot::MSB); // This is default for > 1.0.30 Conduit
SomeRandomBloke 0:5a0b43f3b143 300
merckeng 14:e4574212176a 301
SomeRandomBloke 5:48eb9245a914 302
SomeRandomBloke 5:48eb9245a914 303 logInfo("Set TxPower");
SomeRandomBloke 8:8070e9d660e4 304 if((ret = dot->setTxPower( LORA_TXPOWER )) != mDot::MDOT_OK) {
SomeRandomBloke 5:48eb9245a914 305 logError("Failed to set Tx Power %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 306 }
SomeRandomBloke 5:48eb9245a914 307
SomeRandomBloke 7:2a704d1a30e1 308 logInfo("Set Public mode");
SomeRandomBloke 7:2a704d1a30e1 309 if((ret = dot->setPublicNetwork(true)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 310 logError("failed to set Public Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 7:2a704d1a30e1 311 }
SomeRandomBloke 7:2a704d1a30e1 312
SomeRandomBloke 7:2a704d1a30e1 313 logInfo("Set MANUAL Join mode");
SomeRandomBloke 7:2a704d1a30e1 314 if((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 315 logError("Failed to set MANUAL Join Mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 7:2a704d1a30e1 316 }
SomeRandomBloke 7:2a704d1a30e1 317
SomeRandomBloke 5:48eb9245a914 318 logInfo("Set Ack");
SomeRandomBloke 5:48eb9245a914 319 // 1 retries on Ack, 0 to disable
SomeRandomBloke 8:8070e9d660e4 320 if((ret = dot->setAck( LORA_ACK)) != mDot::MDOT_OK) {
SomeRandomBloke 5:48eb9245a914 321 logError("Failed to set Ack %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 322 }
SomeRandomBloke 3:367aa95f9771 323
merckeng 13:761b9c929a3f 324 //Not applicable for 868MHz in EU
merckeng 13:761b9c929a3f 325 if ((ret = dot->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
merckeng 13:761b9c929a3f 326 logError("failed to set frequency sub band", ret);
merckeng 13:761b9c929a3f 327 }
SomeRandomBloke 1:45cec6aea002 328
SomeRandomBloke 6:0a7760eeaba9 329 logInfo("Set Network Address");
SomeRandomBloke 6:0a7760eeaba9 330 if ((ret = dot->setNetworkAddress(networkAddr)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 331 logError("Failed to set Network Address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 7:2a704d1a30e1 332 }
SomeRandomBloke 7:2a704d1a30e1 333
SomeRandomBloke 7:2a704d1a30e1 334 logInfo("Set Data Session Key");
merckeng 14:e4574212176a 335 if ((ret = dot->setDataSessionKey(appSKey)) != mDot::MDOT_OK) {
SomeRandomBloke 7:2a704d1a30e1 336 logError("Failed to set Data Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 337 }
SomeRandomBloke 0:5a0b43f3b143 338
SomeRandomBloke 5:48eb9245a914 339 logInfo("Set Network Session Key");
SomeRandomBloke 5:48eb9245a914 340 if ((ret = dot->setNetworkSessionKey(nwkSKey)) != mDot::MDOT_OK) {
SomeRandomBloke 5:48eb9245a914 341 logError("Failed to set Network Session Key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 5:48eb9245a914 342 }
SomeRandomBloke 5:48eb9245a914 343
SomeRandomBloke 5:48eb9245a914 344 logInfo("Saving Config");
SomeRandomBloke 5:48eb9245a914 345 // Save config
SomeRandomBloke 5:48eb9245a914 346 if (! dot->saveConfig()) {
SomeRandomBloke 5:48eb9245a914 347 logError("failed to save configuration");
SomeRandomBloke 0:5a0b43f3b143 348 }
SomeRandomBloke 5:48eb9245a914 349
SomeRandomBloke 5:48eb9245a914 350 // Display what is set
SomeRandomBloke 5:48eb9245a914 351 std::vector<uint8_t> tmp = dot->getNetworkSessionKey();
SomeRandomBloke 5:48eb9245a914 352 pc.printf("Network Session Key: ");
SomeRandomBloke 5:48eb9245a914 353 pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
SomeRandomBloke 5:48eb9245a914 354
SomeRandomBloke 5:48eb9245a914 355 tmp = dot->getDataSessionKey();
SomeRandomBloke 5:48eb9245a914 356 pc.printf("Data Session Key: ");
SomeRandomBloke 5:48eb9245a914 357 pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str());
SomeRandomBloke 0:5a0b43f3b143 358
SomeRandomBloke 6:0a7760eeaba9 359 pc.printf("Device ID ");
SomeRandomBloke 6:0a7760eeaba9 360 std::vector<uint8_t> deviceId;
SomeRandomBloke 6:0a7760eeaba9 361 deviceId = dot->getDeviceId();
SomeRandomBloke 6:0a7760eeaba9 362 for (std::vector<uint8_t>::iterator it = deviceId.begin() ; it != deviceId.end(); ++it)
SomeRandomBloke 5:48eb9245a914 363 pc.printf("%2.2x",*it );
SomeRandomBloke 6:0a7760eeaba9 364 pc.printf("\r\n");
SomeRandomBloke 5:48eb9245a914 365
SomeRandomBloke 6:0a7760eeaba9 366 std::vector<uint8_t> netAddress;
SomeRandomBloke 9:086351e54b57 367
SomeRandomBloke 6:0a7760eeaba9 368 pc.printf("Network Address ");
SomeRandomBloke 6:0a7760eeaba9 369 netAddress = dot->getNetworkAddress();
SomeRandomBloke 6:0a7760eeaba9 370 for (std::vector<uint8_t>::iterator it = netAddress.begin() ; it != netAddress.end(); ++it)
SomeRandomBloke 5:48eb9245a914 371 pc.printf("%2.2x",*it );
SomeRandomBloke 5:48eb9245a914 372
SomeRandomBloke 5:48eb9245a914 373 pc.printf("\r\n");
SomeRandomBloke 5:48eb9245a914 374
SomeRandomBloke 5:48eb9245a914 375 // Display LoRa parameters
SomeRandomBloke 5:48eb9245a914 376 // Display label and values in different colours, show pretty values not numeric values where applicable
SomeRandomBloke 5:48eb9245a914 377 pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") );
SomeRandomBloke 5:48eb9245a914 378 pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() );
SomeRandomBloke 5:48eb9245a914 379 pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() );
SomeRandomBloke 5:48eb9245a914 380 pc.printf("Join Mode: %s\r\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() );
SomeRandomBloke 6:0a7760eeaba9 381 pc.printf("Join Retries: %d\r\n", dot->getJoinRetries() );
SomeRandomBloke 6:0a7760eeaba9 382 pc.printf("Join Byte Order: %s\r\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") );
SomeRandomBloke 5:48eb9245a914 383 pc.printf("Link Check Count: %d\r\n", dot->getLinkCheckCount() );
SomeRandomBloke 7:2a704d1a30e1 384 pc.printf("Link Check Thold: %d\r\n", dot->getLinkCheckThreshold() );
SomeRandomBloke 5:48eb9245a914 385 pc.printf("Tx Data Rate: %s\r\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() );
SomeRandomBloke 5:48eb9245a914 386 pc.printf("Tx Power: %d\r\n", dot->getTxPower() );
SomeRandomBloke 6:0a7760eeaba9 387 pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" ));
SomeRandomBloke 5:48eb9245a914 388 pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") );
SomeRandomBloke 5:48eb9245a914 389 pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N") );
SomeRandomBloke 5:48eb9245a914 390
SomeRandomBloke 9:086351e54b57 391 logInfo("Joining Network");
SomeRandomBloke 9:086351e54b57 392 while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) {
SomeRandomBloke 9:086351e54b57 393 logError("failed to join network [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 9:086351e54b57 394 wait_ms(dot->getNextTxMs() + 1);
SomeRandomBloke 9:086351e54b57 395 }
merckeng 18:5b57c3cb4554 396 logInfo("Joined Network");
merckeng 18:5b57c3cb4554 397 wait_ms(500);
merckeng 18:5b57c3cb4554 398
merckeng 18:5b57c3cb4554 399 /* Setup Sensors */
merckeng 18:5b57c3cb4554 400
merckeng 18:5b57c3cb4554 401 logInfo("Configure Soil Sensor (SHT)");
merckeng 18:5b57c3cb4554 402 /* DigitalInOut sht_data(SHT_DATA_PIN);
merckeng 18:5b57c3cb4554 403 DigitalInOut sht_sck(SHT_SCK_PIN);
merckeng 18:5b57c3cb4554 404 sht_data.output();
merckeng 18:5b57c3cb4554 405 sht_sck.output();
merckeng 18:5b57c3cb4554 406 while (1) {
merckeng 18:5b57c3cb4554 407 sht_data.write(1);
merckeng 18:5b57c3cb4554 408 wait_ms(1);
merckeng 18:5b57c3cb4554 409 sht_data.write(0);
merckeng 18:5b57c3cb4554 410 wait_ms(1);
merckeng 18:5b57c3cb4554 411 }*/
merckeng 18:5b57c3cb4554 412
merckeng 18:5b57c3cb4554 413 //logInfo("Configure Air Sensor (DHT)");
merckeng 18:5b57c3cb4554 414 // no config needed for DHT
merckeng 18:5b57c3cb4554 415 logInfo("Configure Water Sensor (DS)");
merckeng 18:5b57c3cb4554 416 wait_ms(500);
merckeng 18:5b57c3cb4554 417 DS18B20::ROM_Code_t ROM_Code;
merckeng 18:5b57c3cb4554 418 wait_ms(500);
merckeng 18:5b57c3cb4554 419 thermom.ReadROM(&ROM_Code);
merckeng 18:5b57c3cb4554 420 logInfo("Family code: 0x%X\n\r", ROM_Code.BYTES.familyCode);
merckeng 18:5b57c3cb4554 421 wait_ms(500);
merckeng 18:5b57c3cb4554 422 logInfo("Serial Number: ");
merckeng 18:5b57c3cb4554 423 for (unsigned i = 6; i != 0; --i) {
merckeng 18:5b57c3cb4554 424 logInfo("%02X%s", ROM_Code.BYTES.serialNo[i-1], (i != 1)?":":"\r\n");
merckeng 18:5b57c3cb4554 425 }
merckeng 18:5b57c3cb4554 426 logInfo("CRC: 0x%X\r\n", ROM_Code.BYTES.VTV);
SomeRandomBloke 6:0a7760eeaba9 427
merckeng 18:5b57c3cb4554 428 wait_ms(500);
merckeng 18:5b57c3cb4554 429 logInfo("Configure Light Sensor (TSL)");
merckeng 18:5b57c3cb4554 430 tsl.enablePower();
SomeRandomBloke 6:0a7760eeaba9 431
SomeRandomBloke 0:5a0b43f3b143 432 char dataBuf[50];
merckeng 14:e4574212176a 433 uint16_t seq = 0;
merckeng 14:e4574212176a 434 char * sf_str;
SomeRandomBloke 0:5a0b43f3b143 435 while( 1 ) {
merckeng 14:e4574212176a 436
merckeng 14:e4574212176a 437 /* cycle through spreading factors */
merckeng 14:e4574212176a 438 uint8_t sf;
merckeng 18:5b57c3cb4554 439 seq = 0; /* force SF7 */
merckeng 14:e4574212176a 440 switch (seq % 4) {
merckeng 14:e4574212176a 441 case 0:
merckeng 14:e4574212176a 442 sf = mDot::SF_7;
merckeng 14:e4574212176a 443 sf_str = "SF7";
merckeng 14:e4574212176a 444 break;
merckeng 14:e4574212176a 445 case 1:
merckeng 14:e4574212176a 446 sf = mDot::SF_8;
merckeng 14:e4574212176a 447 sf_str = "SF8";
merckeng 14:e4574212176a 448 break;
merckeng 14:e4574212176a 449 case 2:
merckeng 14:e4574212176a 450 sf = mDot::SF_9;
merckeng 14:e4574212176a 451 sf_str = "SF9";
merckeng 14:e4574212176a 452 break;
merckeng 14:e4574212176a 453 case 3:
merckeng 14:e4574212176a 454 sf = mDot::SF_10;
merckeng 14:e4574212176a 455 sf_str = "SF10";
merckeng 14:e4574212176a 456 break;
merckeng 14:e4574212176a 457 }
merckeng 14:e4574212176a 458 // Set Spreading Factor, higher is lower data rate, smaller packets but longer range
merckeng 14:e4574212176a 459 // Lower is higher data rate, larger packets and shorter range.
merckeng 14:e4574212176a 460 logInfo("Set SF: %s",sf_str);
merckeng 14:e4574212176a 461 if((ret = dot->setTxDataRate( sf )) != mDot::MDOT_OK) {
merckeng 14:e4574212176a 462 logError("Failed to set SF %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
merckeng 14:e4574212176a 463 }
merckeng 14:e4574212176a 464
merckeng 14:e4574212176a 465 /* set default data values */
merckeng 14:e4574212176a 466 int temp = 0;
merckeng 14:e4574212176a 467 int humid = -1;
merckeng 14:e4574212176a 468
merckeng 14:e4574212176a 469 /* build packet */
merckeng 17:3dc30f4a8da2 470 b.begin();
merckeng 17:3dc30f4a8da2 471 uint8_t flag = 0;
merckeng 17:3dc30f4a8da2 472 b.put(FormatSensor1);
merckeng 17:3dc30f4a8da2 473 uint8_t * const pFlag = b.getp(); // save pointer to flag location
merckeng 17:3dc30f4a8da2 474 b.put(0x00); // placeholder for flags
merckeng 17:3dc30f4a8da2 475
merckeng 17:3dc30f4a8da2 476 // TODO: read battery voltage
merckeng 17:3dc30f4a8da2 477 b.putV(13.8);
merckeng 17:3dc30f4a8da2 478 flag |= FlagVbat;
merckeng 17:3dc30f4a8da2 479
merckeng 18:5b57c3cb4554 480 // read from Bme280 sensor:
merckeng 18:5b57c3cb4554 481 float air_temp=0, air_humid=0;
merckeng 18:5b57c3cb4554 482 bool dht_success = dht.sample();
merckeng 18:5b57c3cb4554 483 wait_ms(100);
merckeng 18:5b57c3cb4554 484 logInfo("Air Sensor Status: %s", dht_success?"OK":"ERROR");
merckeng 18:5b57c3cb4554 485 wait_ms(100);
merckeng 18:5b57c3cb4554 486 air_temp = (float)dht.getTemperature()/10.0;
merckeng 18:5b57c3cb4554 487 air_humid = (float)dht.getHumidity()/10.0;
merckeng 18:5b57c3cb4554 488 logInfo("Air Temp: %1.01fC Air Humid: %1.01f%%", air_temp, air_humid);
merckeng 18:5b57c3cb4554 489
merckeng 18:5b57c3cb4554 490
merckeng 18:5b57c3cb4554 491 b.putT(air_temp); // air temp
merckeng 17:3dc30f4a8da2 492 b.putP(1010.0); // air pressure
merckeng 18:5b57c3cb4554 493 b.putRH(air_humid); // air humidity
merckeng 17:3dc30f4a8da2 494 flag |= FlagTPH;
merckeng 17:3dc30f4a8da2 495
merckeng 18:5b57c3cb4554 496 wait_ms(100);
merckeng 18:5b57c3cb4554 497 // read from light sensor
merckeng 18:5b57c3cb4554 498 float lux = tsl.getLux();
merckeng 18:5b57c3cb4554 499 logInfo("Ambient Light: %.4f", lux);
merckeng 18:5b57c3cb4554 500 wait_ms(100);
merckeng 18:5b57c3cb4554 501 b.putLux(lux*100); // ambient light
merckeng 17:3dc30f4a8da2 502 flag |= FlagLux;
merckeng 17:3dc30f4a8da2 503
merckeng 18:5b57c3cb4554 504 // read water temperature
merckeng 18:5b57c3cb4554 505 wait_ms(100);
merckeng 18:5b57c3cb4554 506 logInfo("Running temperature conversion...");
merckeng 18:5b57c3cb4554 507 float water_temp = thermom.GetTemperature();
merckeng 18:5b57c3cb4554 508 logInfo("Water Temperature: %.4fC", water_temp);
merckeng 18:5b57c3cb4554 509 wait_ms(100);
merckeng 18:5b57c3cb4554 510 b.putT(water_temp); // water temperature
merckeng 17:3dc30f4a8da2 511 flag |= FlagWater;
merckeng 17:3dc30f4a8da2 512
merckeng 18:5b57c3cb4554 513 // read soil sensor
merckeng 18:5b57c3cb4554 514 wait_ms(100);
merckeng 18:5b57c3cb4554 515 logInfo("sht.ready = %s", sht.ready?"true":"false");
merckeng 18:5b57c3cb4554 516 sht.ready = true; // override error...
merckeng 18:5b57c3cb4554 517 sht.reset();
merckeng 18:5b57c3cb4554 518 wait_ms(50);
merckeng 18:5b57c3cb4554 519 bool sht_success = sht.update();
merckeng 18:5b57c3cb4554 520 logInfo("Soil Sensor Status: %s", sht_success?"OK":"ERROR");
merckeng 18:5b57c3cb4554 521 float soil_temp = (float)sht.getTemperature();
merckeng 18:5b57c3cb4554 522 float soil_humid = (float)(sht.humidity)/(float)35.0;
merckeng 18:5b57c3cb4554 523 logInfo("sht->humid = %d",sht.humidity);
merckeng 18:5b57c3cb4554 524 logInfo("Soil Temp: %1.01fC Soil Humid: %1.01f%%", soil_temp, soil_humid);
merckeng 18:5b57c3cb4554 525 b.putT(soil_temp); // soil temperature
merckeng 18:5b57c3cb4554 526 b.putRH(soil_humid); // soil humidityupdate
merckeng 18:5b57c3cb4554 527
merckeng 17:3dc30f4a8da2 528 flag |= FlagSoilTH;
merckeng 17:3dc30f4a8da2 529
merckeng 17:3dc30f4a8da2 530 // write flag byte
merckeng 17:3dc30f4a8da2 531 *pFlag = flag;
merckeng 14:e4574212176a 532
merckeng 14:e4574212176a 533 /* load vector */
merckeng 17:3dc30f4a8da2 534 send_data.clear();
merckeng 17:3dc30f4a8da2 535 uint8_t c;
merckeng 17:3dc30f4a8da2 536 int n = b.getn();
merckeng 17:3dc30f4a8da2 537 for( int i=0; i< n; i++ ) {
merckeng 17:3dc30f4a8da2 538 c = b.buf[i];
merckeng 17:3dc30f4a8da2 539 send_data.push_back( c );
merckeng 17:3dc30f4a8da2 540 }
SomeRandomBloke 0:5a0b43f3b143 541
merckeng 18:5b57c3cb4554 542 wait_ms(100);
merckeng 14:e4574212176a 543 /* send packet */
SomeRandomBloke 0:5a0b43f3b143 544 if ((ret = dot->send(send_data)) != mDot::MDOT_OK) {
SomeRandomBloke 0:5a0b43f3b143 545 logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str());
SomeRandomBloke 0:5a0b43f3b143 546 } else {
merckeng 17:3dc30f4a8da2 547 logInfo("data len: %d, send data: %s", n, Text::bin2hexString(send_data).c_str());
SomeRandomBloke 0:5a0b43f3b143 548 }
SomeRandomBloke 0:5a0b43f3b143 549
merckeng 14:e4574212176a 550 /* sleep */
merckeng 14:e4574212176a 551 uint32_t sleep_time = MAX((dot->getNextTxMs() / 1000), 10 /* use 6000 for 10min */);
SomeRandomBloke 2:9db840d12557 552 logInfo("going to sleep for %d seconds", sleep_time);
merckeng 18:5b57c3cb4554 553
merckeng 18:5b57c3cb4554 554 status_led.write(1);
merckeng 18:5b57c3cb4554 555 wait_ms(1*1000);
merckeng 18:5b57c3cb4554 556 status_led.write(0);
merckeng 18:5b57c3cb4554 557 wait_ms(4*1000);
merckeng 14:e4574212176a 558
merckeng 14:e4574212176a 559 seq++;
SomeRandomBloke 0:5a0b43f3b143 560 }
SomeRandomBloke 2:9db840d12557 561
SomeRandomBloke 0:5a0b43f3b143 562 return 0;
SomeRandomBloke 0:5a0b43f3b143 563 }