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:05:59 2016 +0000
Revision:
18:5b57c3cb4554
Parent:
17:3dc30f4a8da2
Child:
19:a2c9c4cc4863
Code for Rain Garden Demo

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