This node was designed to map the range of Multitech Conduit gateways, It uses a Multitech mDot and Adafruit GPS breakout.

Dependencies:   MBed_Adafruit-GPS-Library libmDot-mbed5

Fork of mDot_LoRa_Connect_ABPA_DHT22_sleep by Brendan Kelly

Committer:
mcdocm1
Date:
Sat Nov 04 00:45:41 2017 +0000
Revision:
12:99d45969ec41
Parent:
11:45465d7cff1f
modified base program to use GPS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kellybs1 11:45465d7cff1f 1 /*
kellybs1 11:45465d7cff1f 2 This program:
kellybs1 11:45465d7cff1f 3 - connects to a LoRaWAN by ABP/MANUAL
kellybs1 11:45465d7cff1f 4 - reads light data from an analogue Light Dependent Resistor
kellybs1 11:45465d7cff1f 5 - reads temperaure and humidity from a DHT22 sensor
kellybs1 11:45465d7cff1f 6 - sends the recorded data onto the LoRaWAN
kellybs1 11:45465d7cff1f 7 - sets the mDot to sleep
kellybs1 11:45465d7cff1f 8 - repeats these operations in a loop
kellybs1 11:45465d7cff1f 9 */
kellybs1 11:45465d7cff1f 10
mfiore 0:09250cd371d2 11 #include "mbed.h"
mfiore 0:09250cd371d2 12 #include "mDot.h"
kellybs1 8:206e0563e1a1 13 #include "ChannelPlans.h"
mfiore 4:36e214ebfa56 14 #include "MTSLog.h"
kellybs1 10:02615da7a9fe 15 #include "dot_util.h"
kellybs1 10:02615da7a9fe 16 #include "mbed.h"
mcdocm1 12:99d45969ec41 17 #include "MBed_Adafruit_GPS.h"
mfiore 0:09250cd371d2 18 #include <string>
mfiore 0:09250cd371d2 19 #include <vector>
mfiore 4:36e214ebfa56 20 #include <algorithm>
kellybs1 10:02615da7a9fe 21 #include <sstream>
kellybs1 10:02615da7a9fe 22
mcdocm1 12:99d45969ec41 23
mcdocm1 12:99d45969ec41 24 Serial * gps_Serial;
mcdocm1 12:99d45969ec41 25 Serial pc (USBTX, USBRX);
mcdocm1 12:99d45969ec41 26
mcdocm1 12:99d45969ec41 27
mfiore 0:09250cd371d2 28
mfiore 2:6e2c378339d9 29 // these options must match the settings on your Conduit
kellybs1 10:02615da7a9fe 30 /*
kellybs1 10:02615da7a9fe 31 Current test settings
kellybs1 10:02615da7a9fe 32 dev address: 072389f7
kellybs1 10:02615da7a9fe 33 net sess key: b35aca73d283996dc3cbc0803af04547
kellybs1 10:02615da7a9fe 34 app sess key: d6f28430da4035273b9e3c07eb30c0dd
kellybs1 10:02615da7a9fe 35 */
kellybs1 11:45465d7cff1f 36 //device address
kellybs1 10:02615da7a9fe 37 static uint8_t network_address[] = { 0x07, 0x23, 0x89, 0xf7 };
kellybs1 11:45465d7cff1f 38 //network session key
kellybs1 10:02615da7a9fe 39 static uint8_t network_session_key[] = { 0xb3, 0x5a, 0xca, 0x73, 0xd2, 0x83, 0x99, 0x6d, 0xc3, 0xcb, 0xc0, 0x80, 0x3a, 0xf0, 0x45, 0x47 };
kellybs1 11:45465d7cff1f 40 //application sesssion or data session key
kellybs1 10:02615da7a9fe 41 static uint8_t data_session_key[] = { 0xd6, 0xf2, 0x84, 0x30, 0xda, 0x40, 0x35, 0x27, 0x3b, 0x9e, 0x3c, 0x07, 0xeb, 0x30, 0xc0, 0xdd };
kellybs1 11:45465d7cff1f 42 static uint8_t frequency_sub_band = 2; //VFI
kellybs1 10:02615da7a9fe 43 static bool public_network = true;
kellybs1 11:45465d7cff1f 44 //enable receipt of ackknowledge packets 0 = No, 1 = Yes
kellybs1 10:02615da7a9fe 45 static uint8_t ack = 0;
kellybs1 11:45465d7cff1f 46 //adaptive data rate enabler
kellybs1 10:02615da7a9fe 47 static bool adr = false;
mfiore 0:09250cd371d2 48
kellybs1 11:45465d7cff1f 49 //USB serial
kellybs1 9:7f7194b5b4e3 50 Serial pc(USBTX, USBRX);
kellybs1 9:7f7194b5b4e3 51
kellybs1 11:45465d7cff1f 52 //get ourselves an mDot pointer - we will assign to it in main()
kellybs1 10:02615da7a9fe 53 mDot* dot = NULL;
kellybs1 9:7f7194b5b4e3 54
kellybs1 10:02615da7a9fe 55 //converts value to string
kellybs1 10:02615da7a9fe 56 template <typename T>
kellybs1 10:02615da7a9fe 57 string ToString(T val) {
kellybs1 10:02615da7a9fe 58 stringstream stream;
kellybs1 10:02615da7a9fe 59 stream << val;
kellybs1 10:02615da7a9fe 60 return stream.str();
kellybs1 10:02615da7a9fe 61 }
kellybs1 10:02615da7a9fe 62
mfiore 0:09250cd371d2 63 int main() {
kellybs1 11:45465d7cff1f 64 //setting serial rate
kellybs1 9:7f7194b5b4e3 65 pc.baud(9600);
mfiore 2:6e2c378339d9 66
kellybs1 9:7f7194b5b4e3 67 // use AU915 plan
kellybs1 9:7f7194b5b4e3 68 lora::ChannelPlan* plan = new lora::ChannelPlan_AU915();
kellybs1 7:e29228e39982 69 assert(plan);
kellybs1 11:45465d7cff1f 70 // get a mDot handle with the plan we chose
kellybs1 10:02615da7a9fe 71 dot = mDot::getInstance(plan);
kellybs1 11:45465d7cff1f 72 assert(dot);
mfiore 4:36e214ebfa56 73
kellybs1 10:02615da7a9fe 74 if (!dot->getStandbyFlag()) {
kellybs1 10:02615da7a9fe 75 logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
kellybs1 10:02615da7a9fe 76
kellybs1 10:02615da7a9fe 77 // start from a well-known state
kellybs1 10:02615da7a9fe 78 logInfo("defaulting Dot configuration");
kellybs1 10:02615da7a9fe 79 dot->resetConfig();
kellybs1 10:02615da7a9fe 80 dot->resetNetworkSession();
kellybs1 10:02615da7a9fe 81
kellybs1 10:02615da7a9fe 82 // make sure library logging is turned on
kellybs1 10:02615da7a9fe 83 dot->setLogLevel(mts::MTSLog::DEBUG_LEVEL);
kellybs1 10:02615da7a9fe 84
kellybs1 10:02615da7a9fe 85 // update configuration if necessary
kellybs1 10:02615da7a9fe 86 if (dot->getJoinMode() != mDot::MANUAL) {
kellybs1 10:02615da7a9fe 87 logInfo("changing network join mode to MANUAL");
kellybs1 10:02615da7a9fe 88 if (dot->setJoinMode(mDot::MANUAL) != mDot::MDOT_OK) {
kellybs1 10:02615da7a9fe 89 logError("failed to set network join mode to MANUAL");
kellybs1 10:02615da7a9fe 90 }
kellybs1 10:02615da7a9fe 91 }
kellybs1 10:02615da7a9fe 92 // in MANUAL join mode there is no join request/response transaction
kellybs1 10:02615da7a9fe 93 // as long as the Dot is configured correctly and provisioned correctly on the gateway, it should be able to communicate
kellybs1 10:02615da7a9fe 94 // network address - 4 bytes (00000001 - FFFFFFFE)
kellybs1 10:02615da7a9fe 95 // network session key - 16 bytes
kellybs1 10:02615da7a9fe 96 // data session key - 16 bytes
kellybs1 10:02615da7a9fe 97 // to provision your Dot with a Conduit gateway, follow the following steps
kellybs1 10:02615da7a9fe 98 // * ssh into the Conduit
kellybs1 10:02615da7a9fe 99 // * provision the Dot using the lora-query application: http://www.multitech.net/developer/software/lora/lora-network-server/
kellybs1 10:02615da7a9fe 100 // lora-query -a 01020304 A 0102030401020304 <your Dot's device ID> 01020304010203040102030401020304 01020304010203040102030401020304
kellybs1 10:02615da7a9fe 101 // * if you change the network address, network session key, or data session key, make sure you update them on the gateway
kellybs1 10:02615da7a9fe 102 // to provision your Dot with a 3rd party gateway, see the gateway or network provider documentation
kellybs1 10:02615da7a9fe 103 update_manual_config(network_address, network_session_key, data_session_key, frequency_sub_band, public_network, ack);
kellybs1 10:02615da7a9fe 104
kellybs1 10:02615da7a9fe 105
kellybs1 10:02615da7a9fe 106 // enable or disable Adaptive Data Rate
kellybs1 10:02615da7a9fe 107 dot->setAdr(adr);
kellybs1 10:02615da7a9fe 108
kellybs1 10:02615da7a9fe 109 //* AU915 Datarates
kellybs1 10:02615da7a9fe 110 //* ---------------
kellybs1 10:02615da7a9fe 111 //* DR0 - SF10BW125 -- 11 bytes
kellybs1 10:02615da7a9fe 112 //* DR1 - SF9BW125 -- 53 bytes
kellybs1 10:02615da7a9fe 113 //* DR2 - SF8BW125 -- 129 byte
kellybs1 10:02615da7a9fe 114 //* DR3 - SF7BW125 -- 242 bytes
kellybs1 10:02615da7a9fe 115 //* DR4 - SF8BW500 -- 242 bytes
kellybs1 10:02615da7a9fe 116 dot->setTxDataRate(mDot::DR2);
kellybs1 10:02615da7a9fe 117
kellybs1 10:02615da7a9fe 118 // save changes to configuration
kellybs1 10:02615da7a9fe 119 logInfo("saving configuration");
kellybs1 10:02615da7a9fe 120 if (!dot->saveConfig()) {
kellybs1 10:02615da7a9fe 121 logError("failed to save configuration");
kellybs1 10:02615da7a9fe 122 }
kellybs1 10:02615da7a9fe 123
kellybs1 10:02615da7a9fe 124 // display configuration
kellybs1 10:02615da7a9fe 125 display_config();
kellybs1 10:02615da7a9fe 126 } else {
kellybs1 10:02615da7a9fe 127 // restore the saved session if the dot woke from deepsleep mode
kellybs1 10:02615da7a9fe 128 // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
kellybs1 10:02615da7a9fe 129 logInfo("restoring network session from NVM");
kellybs1 10:02615da7a9fe 130 dot->restoreNetworkSession();
jreiss 5:6b988a804fcb 131 }
jreiss 5:6b988a804fcb 132
kellybs1 11:45465d7cff1f 133 //this is where the magic happens
mcdocm1 12:99d45969ec41 134 pc.baud(115200); //sets virtual COM serial communication to high rate; this is to allow more time to be spent on GPS retrieval
mcdocm1 12:99d45969ec41 135
mcdocm1 12:99d45969ec41 136 gps_Serial = new Serial(p28,p27); //serial object for use w/ GPS
mcdocm1 12:99d45969ec41 137 Adafruit_GPS myGPS(gps_Serial); //object of Adafruit's GPS class
mcdocm1 12:99d45969ec41 138 char c; //when read via Adafruit_GPS::read(), the class returns single character stored here
mcdocm1 12:99d45969ec41 139 Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info?
mcdocm1 12:99d45969ec41 140 const int refresh_Time = 2000; //refresh time in ms
mcdocm1 12:99d45969ec41 141
mcdocm1 12:99d45969ec41 142 myGPS.begin(9600); //sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *)
mcdocm1 12:99d45969ec41 143 //a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf
mcdocm1 12:99d45969ec41 144
mcdocm1 12:99d45969ec41 145 myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation
mcdocm1 12:99d45969ec41 146 myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
mcdocm1 12:99d45969ec41 147 myGPS.sendCommand(PGCMD_ANTENNA);
mcdocm1 12:99d45969ec41 148
mcdocm1 12:99d45969ec41 149 pc.printf("Connection established at 115200 baud...\n");
mcdocm1 12:99d45969ec41 150
mcdocm1 12:99d45969ec41 151 wait(1);
mcdocm1 12:99d45969ec41 152
mcdocm1 12:99d45969ec41 153 refresh_Timer.start(); //starts the clock on the timer
mcdocm1 12:99d45969ec41 154
mcdocm1 12:99d45969ec41 155 while(true){
mcdocm1 12:99d45969ec41 156 c = myGPS.read(); //queries the GPS
mcdocm1 12:99d45969ec41 157
mcdocm1 12:99d45969ec41 158 if (c) { pc.printf("%c", c); } //this line will echo the GPS data if not paused
mcdocm1 12:99d45969ec41 159
mcdocm1 12:99d45969ec41 160 //check if we recieved a new message from GPS, if so, attempt to parse it,
mcdocm1 12:99d45969ec41 161 if ( myGPS.newNMEAreceived() ) {
mcdocm1 12:99d45969ec41 162 if ( !myGPS.parse(myGPS.lastNMEA()) ) {
mcdocm1 12:99d45969ec41 163 continue;
mcdocm1 12:99d45969ec41 164 }
mcdocm1 12:99d45969ec41 165 }
mcdocm1 12:99d45969ec41 166
mcdocm1 12:99d45969ec41 167 //check if enough time has passed to warrant printing GPS info to screen
mcdocm1 12:99d45969ec41 168 //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing
mcdocm1 12:99d45969ec41 169 if (refresh_Timer.read_ms() >= refresh_Time) {
mcdocm1 12:99d45969ec41 170 refresh_Timer.reset();
mcdocm1 12:99d45969ec41 171 pc.printf("Fix: %d\n", (int) myGPS.fix);
mcdocm1 12:99d45969ec41 172 if (myGPS.fix) {
mcdocm1 12:99d45969ec41 173 pc.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon);
mcdocm1 12:99d45969ec41 174 pc.printf("Altitude: %5.2f\n", myGPS.altitude);
mcdocm1 12:99d45969ec41 175 pc.printf("Satellites: %d\n", myGPS.satellites);
mcdocm1 12:99d45969ec41 176 }
mcdocm1 12:99d45969ec41 177 }
mcdocm1 12:99d45969ec41 178 }
mcdocm1 12:99d45969ec41 179
mcdocm1 12:99d45969ec41 180
mcdocm1 12:99d45969ec41 181
mfiore 0:09250cd371d2 182 while (true) {
kellybs1 10:02615da7a9fe 183
kellybs1 11:45465d7cff1f 184 //wake up
kellybs1 11:45465d7cff1f 185 wait(5);
kellybs1 10:02615da7a9fe 186 //init data variable
kellybs1 10:02615da7a9fe 187 std::vector<uint8_t> data;
kellybs1 10:02615da7a9fe 188
kellybs1 10:02615da7a9fe 189 //read LDR
kellybs1 11:45465d7cff1f 190 //read LDR as float (0.0-1.0, multiply by 1000)
kellybs1 11:45465d7cff1f 191 //read multiple times - this just smoothes the value out a little bit
kellybs1 10:02615da7a9fe 192 float ldr1 = a0.read() * 1000;
kellybs1 10:02615da7a9fe 193 wait_ms(100);
kellybs1 10:02615da7a9fe 194 float ldr2 = a0.read() * 1000;
kellybs1 10:02615da7a9fe 195 wait_ms(100);
kellybs1 10:02615da7a9fe 196 float ldr3 = a0.read() * 1000;
kellybs1 10:02615da7a9fe 197 wait_ms(100);
kellybs1 11:45465d7cff1f 198 //average the multiple readings
kellybs1 10:02615da7a9fe 199 float ldr = (ldr1 + ldr2 + ldr3) / 3;
kellybs1 10:02615da7a9fe 200
kellybs1 10:02615da7a9fe 201 //read DHT22
kellybs1 10:02615da7a9fe 202 //get dht22 sample
kellybs1 10:02615da7a9fe 203 int error = dht22.sample();
kellybs1 11:45465d7cff1f 204 //sampling is a little slow - give it time
kellybs1 10:02615da7a9fe 205 wait_ms(100);
kellybs1 10:02615da7a9fe 206 //it's required to divide these values by ten for some reason
kellybs1 10:02615da7a9fe 207 float h = (float)dht22.getHumidity() / 10;
kellybs1 10:02615da7a9fe 208 float t = (float)dht22.getTemperature() / 10;
kellybs1 10:02615da7a9fe 209
kellybs1 11:45465d7cff1f 210 //build our output string now
kellybs1 10:02615da7a9fe 211 string l_str = ToString(ldr);
kellybs1 10:02615da7a9fe 212 string h_str = ToString(h);
kellybs1 10:02615da7a9fe 213 string t_str = ToString(t);
kellybs1 10:02615da7a9fe 214 string output = "L:" + l_str + " H:" + h_str + " T:" + t_str;
kellybs1 10:02615da7a9fe 215
kellybs1 11:45465d7cff1f 216 //serial output for debugging
kellybs1 10:02615da7a9fe 217 logInfo("Sending %s", output.c_str());
kellybs1 10:02615da7a9fe 218
kellybs1 10:02615da7a9fe 219 // format data for sending to the gateway
kellybs1 10:02615da7a9fe 220 for (std::string::iterator it = output.begin(); it != output.end(); it++)
kellybs1 10:02615da7a9fe 221 data.push_back((uint8_t) *it);
kellybs1 10:02615da7a9fe 222
kellybs1 11:45465d7cff1f 223 //now send
kellybs1 10:02615da7a9fe 224 send_data(data);
mfiore 0:09250cd371d2 225
kellybs1 11:45465d7cff1f 226 // go to sleep and wake up automatically sleep_time seconds later
kellybs1 11:45465d7cff1f 227 uint32_t sleep_time = 60;
kellybs1 11:45465d7cff1f 228 //false is "don't deep sleep" - mDot doesn't do that
kellybs1 11:45465d7cff1f 229 dot->sleep(sleep_time, mDot::RTC_ALARM, false);
mfiore 0:09250cd371d2 230 }
kellybs1 10:02615da7a9fe 231
kellybs1 11:45465d7cff1f 232 return 0; //shouldn't happen
kellybs1 10:02615da7a9fe 233 }
mfiore 0:09250cd371d2 234