Campbell McDowall / Mbed OS mdotGps

Dependencies:   MBed_Adafruit-GPS-Library libmDot-mbed5

Fork of mDot_LoRa_Connect_ABPA_DHT22_sleep by Brendan Kelly

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 This program:
00003  - connects to a LoRaWAN by ABP/MANUAL
00004  - reads light data from an analogue Light Dependent Resistor
00005  - reads temperaure and humidity from a DHT22 sensor
00006  - sends the recorded data onto the LoRaWAN
00007  - sets the mDot to sleep
00008  - repeats these operations in a loop
00009 */
00010 
00011 #include "mbed.h"
00012 #include "mDot.h"
00013 #include "ChannelPlans.h"
00014 #include "MTSLog.h"
00015 #include "dot_util.h"
00016 #include "mbed.h"
00017 #include "MBed_Adafruit_GPS.h"
00018 #include <string>
00019 #include <vector>
00020 #include <algorithm>
00021 #include <sstream>
00022  
00023  
00024 Serial * gps_Serial;
00025 Serial pc (USBTX, USBRX);
00026 
00027 
00028 
00029 // these options must match the settings on your Conduit
00030 /*
00031 Current test settings
00032 dev address: 072389f7
00033 net sess key: b35aca73d283996dc3cbc0803af04547
00034 app sess key: d6f28430da4035273b9e3c07eb30c0dd
00035 */
00036 //device address
00037 static uint8_t network_address[] = { 0x07, 0x23, 0x89, 0xf7 };
00038 //network session key
00039 static uint8_t network_session_key[] = { 0xb3, 0x5a, 0xca, 0x73, 0xd2, 0x83, 0x99, 0x6d, 0xc3, 0xcb, 0xc0, 0x80, 0x3a, 0xf0, 0x45, 0x47 };
00040 //application sesssion or data session key
00041 static uint8_t data_session_key[] = { 0xd6, 0xf2, 0x84, 0x30, 0xda, 0x40, 0x35, 0x27, 0x3b, 0x9e, 0x3c, 0x07, 0xeb, 0x30, 0xc0, 0xdd };
00042 static uint8_t frequency_sub_band = 2; //VFI
00043 static bool public_network = true;
00044 //enable receipt of ackknowledge packets 0 = No, 1 = Yes
00045 static uint8_t ack = 0;
00046 //adaptive data rate enabler
00047 static bool adr = false;
00048 
00049 //USB serial 
00050 Serial pc(USBTX, USBRX);
00051 
00052 //get ourselves an mDot pointer - we will assign to it in main()
00053 mDot* dot = NULL;
00054 
00055 //converts value to string
00056 template <typename T>
00057 string ToString(T val) {
00058     stringstream stream;
00059     stream << val;
00060     return stream.str();
00061 }
00062 
00063 int main() {
00064     //setting serial rate
00065     pc.baud(9600);
00066     
00067     // use AU915 plan
00068     lora::ChannelPlan* plan = new lora::ChannelPlan_AU915();
00069     assert(plan);
00070     // get a mDot handle with the plan we chose
00071     dot = mDot::getInstance(plan);
00072     assert(dot); 
00073     
00074     if (!dot->getStandbyFlag()) {
00075         logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
00076 
00077         // start from a well-known state
00078         logInfo("defaulting Dot configuration");
00079         dot->resetConfig();
00080         dot->resetNetworkSession();
00081 
00082         // make sure library logging is turned on
00083         dot->setLogLevel(mts::MTSLog::DEBUG_LEVEL);
00084 
00085         // update configuration if necessary
00086         if (dot->getJoinMode() != mDot::MANUAL) {
00087             logInfo("changing network join mode to MANUAL");
00088             if (dot->setJoinMode(mDot::MANUAL) != mDot::MDOT_OK) {
00089                 logError("failed to set network join mode to MANUAL");
00090             }
00091         }
00092         // in MANUAL join mode there is no join request/response transaction
00093         // as long as the Dot is configured correctly and provisioned correctly on the gateway, it should be able to communicate
00094         // network address - 4 bytes (00000001 - FFFFFFFE)
00095         // network session key - 16 bytes
00096         // data session key - 16 bytes
00097         // to provision your Dot with a Conduit gateway, follow the following steps
00098         //   * ssh into the Conduit
00099         //   * provision the Dot using the lora-query application: http://www.multitech.net/developer/software/lora/lora-network-server/
00100         //      lora-query -a 01020304 A 0102030401020304 <your Dot's device ID> 01020304010203040102030401020304 01020304010203040102030401020304
00101         //   * if you change the network address, network session key, or data session key, make sure you update them on the gateway
00102         // to provision your Dot with a 3rd party gateway, see the gateway or network provider documentation
00103         update_manual_config(network_address, network_session_key, data_session_key, frequency_sub_band, public_network, ack);
00104 
00105 
00106         // enable or disable Adaptive Data Rate
00107         dot->setAdr(adr);
00108         
00109         //* AU915 Datarates
00110         //* ---------------
00111         //* DR0 - SF10BW125 -- 11 bytes
00112         //* DR1 - SF9BW125 -- 53 bytes
00113         //* DR2 - SF8BW125 -- 129 byte
00114         //* DR3 - SF7BW125 -- 242 bytes
00115         //* DR4 - SF8BW500 -- 242 bytes
00116         dot->setTxDataRate(mDot::DR2);
00117         
00118         // save changes to configuration
00119         logInfo("saving configuration");
00120         if (!dot->saveConfig()) {
00121             logError("failed to save configuration");
00122         }
00123 
00124         // display configuration
00125         display_config();
00126     } else {
00127         // restore the saved session if the dot woke from deepsleep mode
00128         // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
00129         logInfo("restoring network session from NVM");
00130         dot->restoreNetworkSession();
00131     }
00132     
00133     //this is where the magic happens
00134      pc.baud(115200); //sets virtual COM serial communication to high rate; this is to allow more time to be spent on GPS retrieval
00135     
00136     gps_Serial = new Serial(p28,p27); //serial object for use w/ GPS
00137     Adafruit_GPS myGPS(gps_Serial); //object of Adafruit's GPS class
00138     char c; //when read via Adafruit_GPS::read(), the class returns single character stored here
00139     Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info?
00140     const int refresh_Time = 2000; //refresh time in ms
00141     
00142     myGPS.begin(9600);  //sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *)
00143                         //a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf
00144     
00145     myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation
00146     myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
00147     myGPS.sendCommand(PGCMD_ANTENNA);
00148     
00149     pc.printf("Connection established at 115200 baud...\n");
00150     
00151     wait(1);
00152     
00153     refresh_Timer.start();  //starts the clock on the timer
00154     
00155     while(true){
00156         c = myGPS.read();   //queries the GPS
00157         
00158         if (c) { pc.printf("%c", c); } //this line will echo the GPS data if not paused
00159         
00160         //check if we recieved a new message from GPS, if so, attempt to parse it,
00161         if ( myGPS.newNMEAreceived() ) {
00162             if ( !myGPS.parse(myGPS.lastNMEA()) ) {
00163                 continue;   
00164             }    
00165         }
00166         
00167         //check if enough time has passed to warrant printing GPS info to screen
00168         //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing
00169         if (refresh_Timer.read_ms() >= refresh_Time) {
00170             refresh_Timer.reset();
00171             pc.printf("Fix: %d\n", (int) myGPS.fix);
00172             if (myGPS.fix) {
00173                 pc.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon);
00174                 pc.printf("Altitude: %5.2f\n", myGPS.altitude);
00175                 pc.printf("Satellites: %d\n", myGPS.satellites);
00176             }
00177         }
00178     }
00179     
00180     
00181     
00182     while (true) {
00183     
00184         //wake up
00185         wait(5);
00186         //init data variable
00187         std::vector<uint8_t> data;
00188         
00189         //read LDR
00190         //read LDR as float (0.0-1.0, multiply by 1000)
00191         //read multiple times - this just smoothes the value out a little bit
00192         float ldr1 = a0.read() * 1000;
00193         wait_ms(100);
00194         float ldr2 = a0.read() * 1000;
00195         wait_ms(100);
00196         float ldr3 = a0.read() * 1000;
00197         wait_ms(100);
00198         //average the multiple readings
00199         float ldr = (ldr1 + ldr2 + ldr3) / 3;
00200         
00201         //read DHT22
00202         //get dht22 sample
00203         int error = dht22.sample();
00204         //sampling is a little slow - give it time
00205         wait_ms(100);
00206         //it's required to divide these values by ten for some reason
00207         float h = (float)dht22.getHumidity() / 10;
00208         float t = (float)dht22.getTemperature() / 10;
00209     
00210         //build our output string now
00211         string l_str = ToString(ldr);
00212         string h_str = ToString(h);
00213         string t_str = ToString(t);
00214         string output = "L:" + l_str + " H:" + h_str + " T:" + t_str; 
00215     
00216         //serial output for debugging
00217         logInfo("Sending %s", output.c_str());
00218         
00219         // format data for sending to the gateway
00220         for (std::string::iterator it = output.begin(); it != output.end(); it++)
00221             data.push_back((uint8_t) *it);
00222     
00223         //now send
00224         send_data(data);
00225 
00226         // go to sleep and wake up automatically sleep_time seconds later 
00227         uint32_t sleep_time = 60;
00228         //false is "don't deep sleep" - mDot doesn't do that 
00229         dot->sleep(sleep_time, mDot::RTC_ALARM, false);
00230     }
00231  
00232     return 0; //shouldn't happen
00233 }
00234