Shoalhaven Water / Mbed OS Cloudtracker

Dependencies:   libmDot-mbed5 ISL29011

Committer:
aidanwynn
Date:
Wed Nov 11 00:27:58 2020 +0000
Revision:
44:89b8ed62c32c
Parent:
43:231de26f0302
Child:
45:0d541f98d058
new ?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mfiore 0:a151a6350d7f 1 #include "dot_util.h"
Mike Fiore 14:19fae4509473 2 #include "RadioEvent.h"
aidanwynn 44:89b8ed62c32c 3 #include "InterruptIn.h"
aidanwynn 44:89b8ed62c32c 4 #include "Callback.h"
Jason Reiss 39:76f8a75ed3ec 5
aidanwynn 44:89b8ed62c32c 6 #define CHANNEL_PLAN CP_AS923 // Uncomment for different Freq. plans.
aidanwynn 44:89b8ed62c32c 7 //#define CHANNEL_PLAN CP_AU915
aidanwynn 44:89b8ed62c32c 8 static float batMAx = 4.18; // Change for different battery set up.
aidanwynn 44:89b8ed62c32c 9 static int uplinkInterval = 15; // Value of MINUTES between transmissions
aidanwynn 44:89b8ed62c32c 10 static uint16_t locationID = 001; // Change for different locations. (1 --> 65535)
aidanwynn 44:89b8ed62c32c 11 static float rawLatitude = -34.406000; // Change for different location
aidanwynn 44:89b8ed62c32c 12 static float rawLongitude = 150.880429; // left here as a potential feature
aidanwynn 44:89b8ed62c32c 13 //// Update if different TTN application is used. ////
aidanwynn 44:89b8ed62c32c 14 static uint8_t network_id[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x03, 0x3B, 0xB9 };
aidanwynn 44:89b8ed62c32c 15 static uint8_t network_key[] = { 0x12, 0x1A, 0x81, 0x8F, 0x10, 0x6B, 0x18, 0x67, 0x54, 0xE6, 0x9E, 0x70, 0x53, 0x7C, 0xAD, 0xCF };
mfiore 0:a151a6350d7f 16
mfiore 17:d4f82e16de5f 17 /////////////////////////////////////////////////////////////////////////////
mfiore 17:d4f82e16de5f 18 // -------------------- DOT LIBRARY REQUIRED ------------------------------//
mfiore 17:d4f82e16de5f 19 // * Because these example programs can be used for both mDot and xDot //
mfiore 17:d4f82e16de5f 20 // devices, the LoRa stack is not included. The libmDot library should //
mfiore 17:d4f82e16de5f 21 // be imported if building for mDot devices. The libxDot library //
mfiore 17:d4f82e16de5f 22 // should be imported if building for xDot devices. //
mfiore 17:d4f82e16de5f 23 // * https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/ //
mfiore 17:d4f82e16de5f 24 // * https://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/ //
mfiore 17:d4f82e16de5f 25 // * https://developer.mbed.org/teams/MultiTech/code/libxDot-dev-mbed5/ //
mfiore 17:d4f82e16de5f 26 // * https://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/ //
mfiore 17:d4f82e16de5f 27 /////////////////////////////////////////////////////////////////////////////
mfiore 17:d4f82e16de5f 28
Mike Fiore 5:97ed5f2f099e 29 /////////////////////////////////////////////////////////////
Mike Fiore 5:97ed5f2f099e 30 // * these options must match the settings on your gateway //
Mike Fiore 5:97ed5f2f099e 31 // * edit their values to match your configuration //
Mike Fiore 5:97ed5f2f099e 32 // * frequency sub band is only relevant for the 915 bands //
Mike Fiore 5:97ed5f2f099e 33 // * either the network name and passphrase can be used or //
Mike Fiore 5:97ed5f2f099e 34 // the network ID (8 bytes) and KEY (16 bytes) //
Mike Fiore 5:97ed5f2f099e 35 /////////////////////////////////////////////////////////////
Evan Hosseini 28:558b703f621f 36 static std::string network_name = "MultiTech";
mfiore 3:0e3e776e2862 37 static std::string network_passphrase = "MultiTech";
mfiore 3:0e3e776e2862 38 static uint8_t frequency_sub_band = 0;
Evan Hosseini 31:b1d5811e3d5d 39 static lora::NetworkType network_type = lora::PUBLIC_LORAWAN;
aidanwynn 44:89b8ed62c32c 40 static uint8_t join_delay = 5;
Mike Fiore 15:364df461110f 41 static uint8_t ack = 0;
Mike Fiore 21:09d05faf0e13 42 static bool adr = true;
mfiore 0:a151a6350d7f 43
mfiore 0:a151a6350d7f 44 // deepsleep consumes slightly less current than sleep
mfiore 0:a151a6350d7f 45 // in sleep mode, IO state is maintained, RAM is retained, and application will resume after waking up
mfiore 0:a151a6350d7f 46 // in deepsleep mode, IOs float, RAM is lost, and application will start from beginning after waking up
mfiore 0:a151a6350d7f 47 // if deep_sleep == true, device will enter deepsleep mode
mfiore 0:a151a6350d7f 48 static bool deep_sleep = false;
aidanwynn 44:89b8ed62c32c 49 I2C i2c(PC_9, PA_8 );
mfiore 0:a151a6350d7f 50
mfiore 0:a151a6350d7f 51 mDot* dot = NULL;
Mike Fiore 21:09d05faf0e13 52 lora::ChannelPlan* plan = NULL;
mfiore 0:a151a6350d7f 53
aidanwynn 44:89b8ed62c32c 54 BufferedSerial pc(USBTX, USBRX);
mfiore 0:a151a6350d7f 55
aidanwynn 44:89b8ed62c32c 56 // Initialize I2C
aidanwynn 44:89b8ed62c32c 57 const int addr7bit = 0x40; // 7 bit I2C address
aidanwynn 44:89b8ed62c32c 58 const int addr8bit = addr7bit << 1; // 8bit I2C address, 0x80
aidanwynn 44:89b8ed62c32c 59
aidanwynn 44:89b8ed62c32c 60 volatile int _count = 0;
Evan Hosseini 30:2f5ae37e6c47 61
aidanwynn 44:89b8ed62c32c 62 void incrementCounter(){
aidanwynn 44:89b8ed62c32c 63 _count++;
aidanwynn 44:89b8ed62c32c 64 wait_us(200000); // delay for debouncing
aidanwynn 44:89b8ed62c32c 65 }
aidanwynn 44:89b8ed62c32c 66 void voidCounter(){
aidanwynn 44:89b8ed62c32c 67 wait_us(200000); // delay for debouncing
aidanwynn 44:89b8ed62c32c 68 }
aidanwynn 44:89b8ed62c32c 69 int readCounter(){
aidanwynn 44:89b8ed62c32c 70 return _count;
aidanwynn 44:89b8ed62c32c 71 }
aidanwynn 44:89b8ed62c32c 72 void clearCounter(){
aidanwynn 44:89b8ed62c32c 73 logInfo("Setting counter to 0");
aidanwynn 44:89b8ed62c32c 74 _count = 0;
aidanwynn 44:89b8ed62c32c 75 }
mfiore 0:a151a6350d7f 76
aidanwynn 44:89b8ed62c32c 77 int main(){
aidanwynn 44:89b8ed62c32c 78 AnalogIn bat(A0); // Battery % analog input pin
aidanwynn 44:89b8ed62c32c 79 DigitalIn tamp(PA_3);
aidanwynn 44:89b8ed62c32c 80
aidanwynn 44:89b8ed62c32c 81 InterruptIn in(PA_11);
aidanwynn 44:89b8ed62c32c 82 in.fall(&incrementCounter); // rise OR fall
aidanwynn 44:89b8ed62c32c 83 in.rise(&voidCounter);
aidanwynn 44:89b8ed62c32c 84 in.mode(PullUp);
aidanwynn 44:89b8ed62c32c 85 __enable_irq();
aidanwynn 44:89b8ed62c32c 86
aidanwynn 44:89b8ed62c32c 87 RadioEvent events;
aidanwynn 44:89b8ed62c32c 88
aidanwynn 44:89b8ed62c32c 89 pc.set_baud(115200);
Evan Hosseini 30:2f5ae37e6c47 90 i2c.frequency(400000);
aidanwynn 44:89b8ed62c32c 91
mfiore 0:a151a6350d7f 92 mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
aidanwynn 44:89b8ed62c32c 93
aidanwynn 43:231de26f0302 94 #if CHANNEL_PLAN == CP_AU915
Mike Fiore 21:09d05faf0e13 95 plan = new lora::ChannelPlan_AU915();
Mike Fiore 21:09d05faf0e13 96 #elif CHANNEL_PLAN == CP_AS923
Mike Fiore 21:09d05faf0e13 97 plan = new lora::ChannelPlan_AS923();
Mike Fiore 21:09d05faf0e13 98 #endif
Mike Fiore 21:09d05faf0e13 99 assert(plan);
Mike Fiore 21:09d05faf0e13 100
Mike Fiore 21:09d05faf0e13 101 dot = mDot::getInstance(plan);
Mike Fiore 21:09d05faf0e13 102 assert(dot);
mfiore 0:a151a6350d7f 103
Mike Fiore 14:19fae4509473 104 // attach the custom events handler
Mike Fiore 14:19fae4509473 105 dot->setEvents(&events);
Mike Fiore 14:19fae4509473 106
Jason Reiss 39:76f8a75ed3ec 107 if (!dot->getStandbyFlag() && !dot->getPreserveSession()) {
jreiss 33:15ea8f985c54 108 logInfo("mbed-os library version: %d.%d.%d", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
Mike Fiore 16:a3832552dfe1 109
Mike Fiore 12:ec9768677cea 110 // start from a well-known state
Mike Fiore 12:ec9768677cea 111 logInfo("defaulting Dot configuration");
Mike Fiore 12:ec9768677cea 112 dot->resetConfig();
Mike Fiore 12:ec9768677cea 113 dot->resetNetworkSession();
mfiore 0:a151a6350d7f 114
Mike Fiore 12:ec9768677cea 115 // make sure library logging is turned on
Mike Fiore 12:ec9768677cea 116 dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
Mike Fiore 12:ec9768677cea 117
Mike Fiore 12:ec9768677cea 118 // update configuration if necessary
Mike Fiore 12:ec9768677cea 119 if (dot->getJoinMode() != mDot::OTA) {
Mike Fiore 12:ec9768677cea 120 logInfo("changing network join mode to OTA");
Mike Fiore 12:ec9768677cea 121 if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) {
Mike Fiore 12:ec9768677cea 122 logError("failed to set network join mode to OTA");
Mike Fiore 12:ec9768677cea 123 }
mfiore 0:a151a6350d7f 124 }
Jason Reiss 39:76f8a75ed3ec 125
Jason Reiss 39:76f8a75ed3ec 126 // To preserve session over power-off or reset enable this flag
Jason Reiss 39:76f8a75ed3ec 127 // dot->setPreserveSession(true);
Jason Reiss 39:76f8a75ed3ec 128
aidanwynn 44:89b8ed62c32c 129 update_ota_config_id_key(network_id, network_key, frequency_sub_band, network_type, ack);
Mike Fiore 15:364df461110f 130
Mike Fiore 15:364df461110f 131 // configure network link checks
Mike Fiore 15:364df461110f 132 // network link checks are a good alternative to requiring the gateway to ACK every packet and should allow a single gateway to handle more Dots
Mike Fiore 15:364df461110f 133 // check the link every count packets
Mike Fiore 15:364df461110f 134 // declare the Dot disconnected after threshold failed link checks
Mike Fiore 21:09d05faf0e13 135 // for count = 3 and threshold = 5, the Dot will ask for a link check response every 5 packets and will consider the connection lost if it fails to receive 3 responses in a row
Mike Fiore 15:364df461110f 136 update_network_link_check_config(3, 5);
Mike Fiore 21:09d05faf0e13 137
Mike Fiore 21:09d05faf0e13 138 // enable or disable Adaptive Data Rate
Mike Fiore 21:09d05faf0e13 139 dot->setAdr(adr);
Evan Hosseini 25:56f7775c702f 140
Evan Hosseini 25:56f7775c702f 141 // Configure the join delay
Evan Hosseini 25:56f7775c702f 142 dot->setJoinDelay(join_delay);
Evan Hosseini 25:56f7775c702f 143
Mike Fiore 12:ec9768677cea 144 // save changes to configuration
Mike Fiore 12:ec9768677cea 145 logInfo("saving configuration");
Mike Fiore 12:ec9768677cea 146 if (!dot->saveConfig()) {
Mike Fiore 12:ec9768677cea 147 logError("failed to save configuration");
Mike Fiore 12:ec9768677cea 148 }
mfiore 0:a151a6350d7f 149
Mike Fiore 12:ec9768677cea 150 // display configuration
Mike Fiore 12:ec9768677cea 151 display_config();
Mike Fiore 12:ec9768677cea 152 } else {
Mike Fiore 12:ec9768677cea 153 // restore the saved session if the dot woke from deepsleep mode
Mike Fiore 12:ec9768677cea 154 // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
mfiore 0:a151a6350d7f 155 logInfo("restoring network session from NVM");
mfiore 0:a151a6350d7f 156 dot->restoreNetworkSession();
mfiore 0:a151a6350d7f 157 }
Mike Fiore 9:72d3203279b2 158
mfiore 0:a151a6350d7f 159 while (true) {
Evan Hosseini 30:2f5ae37e6c47 160 uint16_t light;
aidanwynn 44:89b8ed62c32c 161 uint16_t rain;
aidanwynn 44:89b8ed62c32c 162 uint16_t temp;
aidanwynn 44:89b8ed62c32c 163 uint16_t humid;
aidanwynn 44:89b8ed62c32c 164 uint32_t lat;
aidanwynn 44:89b8ed62c32c 165 uint32_t lon;
aidanwynn 44:89b8ed62c32c 166 uint8_t tamper;
aidanwynn 44:89b8ed62c32c 167
aidanwynn 44:89b8ed62c32c 168 char cmd[2]; // I2C command address byte 8-bit
aidanwynn 44:89b8ed62c32c 169 char my_data[2]; // I2C return address bytes 16-bit
aidanwynn 44:89b8ed62c32c 170
mfiore 0:a151a6350d7f 171 std::vector<uint8_t> tx_data;
mfiore 0:a151a6350d7f 172
aidanwynn 44:89b8ed62c32c 173 // join network if not joined
mfiore 0:a151a6350d7f 174 if (!dot->getNetworkJoinStatus()) {
mfiore 0:a151a6350d7f 175 join_network();
mfiore 0:a151a6350d7f 176 }
aidanwynn 44:89b8ed62c32c 177
aidanwynn 44:89b8ed62c32c 178 // Wake sensor /////////////////////////////////////////////////////////
aidanwynn 44:89b8ed62c32c 179 cmd[0] = 0x01;
aidanwynn 44:89b8ed62c32c 180 cmd[1] = 0x00;
aidanwynn 44:89b8ed62c32c 181 i2c.write(addr8bit, cmd, 2);
aidanwynn 44:89b8ed62c32c 182
aidanwynn 44:89b8ed62c32c 183 // Read TEMERATURE
aidanwynn 44:89b8ed62c32c 184 cmd[0] = 0xE3; // For
aidanwynn 44:89b8ed62c32c 185 i2c.write(addr8bit, cmd, 1);
aidanwynn 44:89b8ed62c32c 186 i2c.read(addr8bit, my_data, 2);
aidanwynn 44:89b8ed62c32c 187 wait_us(20000);
aidanwynn 44:89b8ed62c32c 188
aidanwynn 44:89b8ed62c32c 189 uint16_t amb = (my_data[0] << 8) | my_data[1];
aidanwynn 44:89b8ed62c32c 190 float temperature = amb;
aidanwynn 44:89b8ed62c32c 191 temperature *= 175.72;
aidanwynn 44:89b8ed62c32c 192 temperature /= 65536;
aidanwynn 44:89b8ed62c32c 193 temperature -= 46.85;
aidanwynn 44:89b8ed62c32c 194 logInfo("Temp = %4.2f*C", temperature);
aidanwynn 44:89b8ed62c32c 195
aidanwynn 44:89b8ed62c32c 196 wait_us(6000);
aidanwynn 44:89b8ed62c32c 197
aidanwynn 44:89b8ed62c32c 198 // Read HUMIDITY
aidanwynn 44:89b8ed62c32c 199 cmd[0] = 0xE5; // For
aidanwynn 44:89b8ed62c32c 200 i2c.write(addr8bit, cmd, 1);
aidanwynn 44:89b8ed62c32c 201 i2c.read( addr8bit, my_data, 2);
aidanwynn 44:89b8ed62c32c 202 wait_us(20000);
mfiore 0:a151a6350d7f 203
aidanwynn 44:89b8ed62c32c 204 uint16_t hum = (my_data[0] << 8) | my_data[1];
aidanwynn 44:89b8ed62c32c 205 float humidity = hum;
aidanwynn 44:89b8ed62c32c 206 humidity *= 125;
aidanwynn 44:89b8ed62c32c 207 humidity /= 65536;
aidanwynn 44:89b8ed62c32c 208 humidity -= 6;
aidanwynn 44:89b8ed62c32c 209 if(humidity > 100.00){
aidanwynn 44:89b8ed62c32c 210 humidity = 100.00;
aidanwynn 44:89b8ed62c32c 211 }
aidanwynn 44:89b8ed62c32c 212 logInfo("Humidity = %4.2f%", humidity);
aidanwynn 44:89b8ed62c32c 213
aidanwynn 44:89b8ed62c32c 214 // Shutdown temp sensor
aidanwynn 44:89b8ed62c32c 215 cmd[0] = 0x00;
aidanwynn 44:89b8ed62c32c 216 cmd[1] = 0x00;
aidanwynn 44:89b8ed62c32c 217 i2c.write(addr8bit, cmd, 2);
aidanwynn 44:89b8ed62c32c 218 ////////////////////////////////////////////////////////////////////////
aidanwynn 44:89b8ed62c32c 219
aidanwynn 44:89b8ed62c32c 220 float battery = bat.read();
aidanwynn 44:89b8ed62c32c 221 battery = ((3*battery)*2) / batMAx * 100; // Turn battery V to a %
aidanwynn 44:89b8ed62c32c 222 logInfo("Battery = %f", battery);
aidanwynn 44:89b8ed62c32c 223 if(battery > 100){
aidanwynn 44:89b8ed62c32c 224 battery = 100;
aidanwynn 44:89b8ed62c32c 225 }
aidanwynn 44:89b8ed62c32c 226
aidanwynn 44:89b8ed62c32c 227 // Send it to the Cloudtracker
aidanwynn 44:89b8ed62c32c 228 rain = readCounter(); // Read the pulse count
aidanwynn 44:89b8ed62c32c 229 tx_data.push_back((rain >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 230 tx_data.push_back(rain & 0xFF);
aidanwynn 44:89b8ed62c32c 231 clearCounter(); // Set pulse count back to 0
aidanwynn 44:89b8ed62c32c 232
aidanwynn 44:89b8ed62c32c 233 uint16_t battery_send = battery * 10;
aidanwynn 44:89b8ed62c32c 234 tx_data.push_back((battery_send >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 235 tx_data.push_back(battery_send & 0xFF);
aidanwynn 44:89b8ed62c32c 236
aidanwynn 44:89b8ed62c32c 237 humid = humidity * 10;
aidanwynn 44:89b8ed62c32c 238 tx_data.push_back((humid >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 239 tx_data.push_back(humid & 0xFF);
aidanwynn 44:89b8ed62c32c 240
aidanwynn 44:89b8ed62c32c 241 temp = temperature * 10;
aidanwynn 44:89b8ed62c32c 242 tx_data.push_back((temp >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 243 tx_data.push_back(temp & 0xFF);
aidanwynn 44:89b8ed62c32c 244
aidanwynn 44:89b8ed62c32c 245 tamper = 0;
aidanwynn 44:89b8ed62c32c 246 if(tamp == 0){
aidanwynn 44:89b8ed62c32c 247 tamper = 1;
aidanwynn 44:89b8ed62c32c 248 }
aidanwynn 44:89b8ed62c32c 249 tx_data.push_back(tamper & 0xFF);
aidanwynn 44:89b8ed62c32c 250
aidanwynn 44:89b8ed62c32c 251 tx_data.push_back((locationID >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 252 tx_data.push_back(locationID & 0xFF);
aidanwynn 44:89b8ed62c32c 253
aidanwynn 44:89b8ed62c32c 254 // lat = (rawLatitude * 10000) + 900000;
aidanwynn 44:89b8ed62c32c 255 // tx_data.push_back((lat >> 16) & 0xFF);
aidanwynn 44:89b8ed62c32c 256 // tx_data.push_back((lat >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 257 // tx_data.push_back(lat & 0xFF);
aidanwynn 44:89b8ed62c32c 258
aidanwynn 44:89b8ed62c32c 259 // lon = (rawLongitude * 10000) + 1800000;
aidanwynn 44:89b8ed62c32c 260 // tx_data.push_back((lon >> 16) & 0xFF);
aidanwynn 44:89b8ed62c32c 261 // tx_data.push_back((lon >> 8) & 0xFF);
aidanwynn 44:89b8ed62c32c 262 // tx_data.push_back(lon & 0xFF);
aidanwynn 44:89b8ed62c32c 263
Evan Hosseini 30:2f5ae37e6c47 264 send_data(tx_data);
aidanwynn 44:89b8ed62c32c 265
aidanwynn 44:89b8ed62c32c 266 // Send to sleep for desired time.
aidanwynn 44:89b8ed62c32c 267 ThisThread::sleep_for(uplinkInterval * 60s); // seconds
mfiore 0:a151a6350d7f 268 }
aidanwynn 44:89b8ed62c32c 269
mfiore 0:a151a6350d7f 270 return 0;
mfiore 0:a151a6350d7f 271 }