This is used for sending Data to receiving mDot

Dependencies:   libmDot-dev-mbed5-deprecated sd-driver ISL29011

Fork of mdot-examples by 3mdeb

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers send_main.cpp Source File

send_main.cpp

00001 /*
00002     3/27/2018 mdot version 3.1.0, mbed version 5.7.4
00003     4/14/2018 mdot version 3.1.0, mbed version 5.7.7
00004 */
00005 
00006 #include <stdlib.h>
00007 #include <iostream>
00008 #include <string.h>
00009 #include <mbed.h>
00010 #include "dot_util.h"
00011 #include "RadioEvent.h"
00012 #include "itoa.h"
00013 
00014 #define BUFFER_SIZE 10
00015 
00016 //note: added GPS functions , variables below (will organize better later ski
00017 //and gps code in main is noted
00018 
00019 
00020 
00021 ///-----------------FOR GPS------BELOW----------------------------------
00022 //
00023 
00024 #include "MBed_Adafruit_GPS.h"
00025 
00026 
00027  
00028 // how long are max NMEA lines to parse?
00029 #define MAXLINELENGTH 120
00030  
00031 // we double buffer: read one line in and leave one for the main program
00032 volatile char line1[MAXLINELENGTH];
00033 volatile char line2[MAXLINELENGTH];
00034 // our index into filling the current line
00035 volatile uint16_t lineidx=0;
00036 // pointers to the double buffers
00037 volatile char *currentline;
00038 volatile char *lastline;
00039 volatile bool recvdflag;
00040 volatile bool inStandbyMode;
00041  
00042  
00043  
00044  
00045  bool Adafruit_GPS::parse(char *nmea) {
00046   // do checksum check
00047  
00048   // first look if we even have one
00049   if (nmea[strlen(nmea)-4] == '*') {
00050     uint16_t sum = parseHex(nmea[strlen(nmea)-3]) * 16;
00051     sum += parseHex(nmea[strlen(nmea)-2]);
00052     
00053     // check checksum 
00054     for (uint8_t i=1; i < (strlen(nmea)-4); i++) {
00055       sum ^= nmea[i];
00056     }
00057     if (sum != 0) {
00058       // bad checksum :(
00059       //return false;
00060     }
00061   }
00062  
00063   // look for a few common sentences
00064   if (strstr(nmea, "$GPGGA")) {
00065     // found GGA
00066     char *p = nmea;
00067     // get time
00068     p = strchr(p, ',')+1;
00069     float timef = atof(p);
00070     uint32_t time = timef;
00071     hour = time / 10000;
00072     minute = (time % 10000) / 100;
00073     seconds = (time % 100);
00074  
00075     milliseconds = fmod((double) timef, 1.0) * 1000;
00076  
00077     // parse out latitude
00078     p = strchr(p, ',')+1;
00079     latitude = atof(p);
00080  
00081     p = strchr(p, ',')+1;
00082     if (p[0] == 'N') lat = 'N';
00083     else if (p[0] == 'S') lat = 'S';
00084     else if (p[0] == ',') lat = 0;
00085     else return false;
00086  
00087     // parse out longitude
00088     p = strchr(p, ',')+1;
00089     longitude = atof(p);
00090  
00091     p = strchr(p, ',')+1;
00092     if (p[0] == 'W') lon = 'W';
00093     else if (p[0] == 'E') lon = 'E';
00094     else if (p[0] == ',') lon = 0;
00095     else return false;
00096  
00097     p = strchr(p, ',')+1;
00098     fixquality = atoi(p);
00099  
00100     p = strchr(p, ',')+1;
00101     satellites = atoi(p);
00102  
00103     p = strchr(p, ',')+1;
00104     HDOP = atof(p);
00105  
00106     p = strchr(p, ',')+1;
00107     altitude = atof(p);
00108     p = strchr(p, ',')+1;
00109     p = strchr(p, ',')+1;
00110     geoidheight = atof(p);
00111     return true;
00112   }
00113   if (strstr(nmea, "$GPRMC")) {
00114    // found RMC
00115     char *p = nmea;
00116  
00117     // get time
00118     p = strchr(p, ',')+1;
00119     float timef = atof(p);
00120     uint32_t time = timef;
00121     hour = time / 10000;
00122     minute = (time % 10000) / 100;
00123     seconds = (time % 100);
00124  
00125     milliseconds = fmod((double) timef, 1.0) * 1000;
00126  
00127     p = strchr(p, ',')+1;
00128     // Serial.println(p);
00129     if (p[0] == 'A') 
00130       fix = true;
00131     else if (p[0] == 'V')
00132       fix = false;
00133     else
00134       return false;
00135  
00136     // parse out latitude
00137     p = strchr(p, ',')+1;
00138     latitude = atof(p);
00139  
00140     p = strchr(p, ',')+1;
00141     if (p[0] == 'N') lat = 'N';
00142     else if (p[0] == 'S') lat = 'S';
00143     else if (p[0] == ',') lat = 0;
00144     else return false;
00145  
00146     // parse out longitude
00147     p = strchr(p, ',')+1;
00148     longitude = atof(p);
00149  
00150     p = strchr(p, ',')+1;
00151     if (p[0] == 'W') lon = 'W';
00152     else if (p[0] == 'E') lon = 'E';
00153     else if (p[0] == ',') lon = 0;
00154     else return false;
00155  
00156     // speed
00157     p = strchr(p, ',')+1;
00158     speed = atof(p);
00159  
00160     // angle
00161     p = strchr(p, ',')+1;
00162     angle = atof(p);
00163  
00164     p = strchr(p, ',')+1;
00165     uint32_t fulldate = atof(p);
00166     day = fulldate / 10000;
00167     month = (fulldate % 10000) / 100;
00168     year = (fulldate % 100);
00169  
00170     // we dont parse the remaining, yet!
00171     return true;
00172   }
00173  
00174   return false;
00175 }
00176  
00177 char Adafruit_GPS::read(void) {
00178   char c = 0;
00179   
00180   if (paused) return c;
00181  
00182     if(!gpsSerial->readable()) return c;
00183     c = gpsSerial->getc();
00184  
00185   //Serial.print(c);
00186  
00187   if (c == '$') {
00188     currentline[lineidx] = 0;
00189     lineidx = 0;
00190   }
00191   if (c == '\n') {
00192     currentline[lineidx] = 0;
00193  
00194     if (currentline == line1) {
00195       currentline = line2;
00196       lastline = line1;
00197     } else {
00198       currentline = line1;
00199       lastline = line2;
00200     }
00201  
00202     lineidx = 0;
00203     recvdflag = true;
00204   }
00205  
00206   currentline[lineidx++] = c;
00207   if (lineidx >= MAXLINELENGTH)
00208     lineidx = MAXLINELENGTH-1;
00209  
00210   return c;
00211 }
00212  
00213 Adafruit_GPS::Adafruit_GPS (Serial *ser)
00214 {
00215   common_init();     // Set everything to common state, then...
00216   gpsSerial = ser; // ...override gpsSwSerial with value passed.
00217 }
00218  
00219 // Initialization code used by all constructor types
00220 void Adafruit_GPS::common_init(void) {
00221   gpsSerial = NULL;
00222   recvdflag   = false;
00223   paused      = false;
00224   lineidx     = 0;
00225   currentline = line1;
00226   lastline    = line2;
00227  
00228   hour = minute = seconds = year = month = day =
00229     fixquality = satellites = 0; // uint8_t
00230   lat = lon = mag = 0; // char
00231   fix = false; // bool
00232   milliseconds = 0; // uint16_t
00233   latitude = longitude = geoidheight = altitude =
00234     speed = angle = magvariation = HDOP = 0.0; // float
00235 }
00236  
00237 void Adafruit_GPS::begin(int baud)
00238 {
00239   gpsSerial->baud(baud);
00240   wait_ms(10);
00241 }
00242  
00243 void Adafruit_GPS::sendCommand(char *str) {
00244   gpsSerial->printf("%s",str);
00245 }
00246  
00247 bool Adafruit_GPS::newNMEAreceived(void) {
00248   return recvdflag;
00249 }
00250  
00251 void Adafruit_GPS::pause(bool p) {
00252   paused = p;
00253 }
00254  
00255 char *Adafruit_GPS::lastNMEA(void) {
00256   recvdflag = false;
00257   return (char *)lastline;
00258 }
00259  
00260 // read a Hex value and return the decimal equivalent
00261 uint8_t Adafruit_GPS::parseHex(char c) {
00262     if (c < '0')
00263       return 0;
00264     if (c <= '9')
00265       return c - '0';
00266     if (c < 'A')
00267        return 0;
00268     if (c <= 'F')
00269        return (c - 'A')+10;
00270 }
00271  
00272 bool Adafruit_GPS::waitForSentence(char *wait4me, uint8_t max) {
00273   char str[20];
00274  
00275   uint8_t i=0;
00276   while (i < max) {
00277     if (newNMEAreceived()) { 
00278       char *nmea = lastNMEA();
00279       strncpy(str, nmea, 20);
00280       str[19] = 0;
00281       i++;
00282  
00283       if (strstr(str, wait4me))
00284     return true;
00285     }
00286   }
00287  
00288   return false;
00289 }
00290  
00291 bool Adafruit_GPS::LOCUS_StartLogger(void) {
00292   sendCommand(PMTK_LOCUS_STARTLOG);
00293   recvdflag = false;
00294   return waitForSentence(PMTK_LOCUS_LOGSTARTED);
00295 }
00296  
00297 bool Adafruit_GPS::LOCUS_ReadStatus(void) {
00298   sendCommand(PMTK_LOCUS_QUERY_STATUS);
00299   
00300   if (! waitForSentence("$PMTKLOG"))
00301     return false;
00302  
00303   char *response = lastNMEA();
00304   uint16_t parsed[10];
00305   uint8_t i;
00306   
00307   for (i=0; i<10; i++) parsed[i] = -1;
00308   
00309   response = strchr(response, ',');
00310   for (i=0; i<10; i++) {
00311     if (!response || (response[0] == 0) || (response[0] == '*')) 
00312       break;
00313     response++;
00314     parsed[i]=0;
00315     while ((response[0] != ',') && 
00316        (response[0] != '*') && (response[0] != 0)) {
00317       parsed[i] *= 10;
00318       char c = response[0];
00319       if (isdigit(c))
00320         parsed[i] += c - '0';
00321       else
00322         parsed[i] = c;
00323       response++;
00324     }
00325   }
00326   LOCUS_serial = parsed[0];
00327   LOCUS_type = parsed[1];
00328   if (isalpha(parsed[2])) {
00329     parsed[2] = parsed[2] - 'a' + 10; 
00330   }
00331   LOCUS_mode = parsed[2];
00332   LOCUS_config = parsed[3];
00333   LOCUS_interval = parsed[4];
00334   LOCUS_distance = parsed[5];
00335   LOCUS_speed = parsed[6];
00336   LOCUS_status = !parsed[7];
00337   LOCUS_records = parsed[8];
00338   LOCUS_percent = parsed[9];
00339  
00340   return true;
00341 }
00342  
00343 // Standby Mode Switches
00344 bool Adafruit_GPS::standby(void) {
00345   if (inStandbyMode) {
00346     return false;  // Returns false if already in standby mode, so that you do not wake it up by sending commands to GPS
00347   }
00348   else {
00349     inStandbyMode = true;
00350     sendCommand(PMTK_STANDBY);
00351     //return waitForSentence(PMTK_STANDBY_SUCCESS);  // don't seem to be fast enough to catch the message, or something else just is not working
00352     return true;
00353   }
00354 }
00355  
00356 bool Adafruit_GPS::wakeup(void) {
00357   if (inStandbyMode) {
00358    inStandbyMode = false;
00359     sendCommand("");  // send byte to wake it up
00360     return waitForSentence(PMTK_AWAKE);
00361   }
00362   else {
00363       return false;  // Returns false if not in standby mode, nothing to wakeup
00364   }
00365 }
00366  
00367  
00368  
00369  
00370  /////FOR GPS-----------------ABOVE-------------------------------------
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384  
00385 /////////////////////////////////////////////////////////////////////////////
00386 // -------------------- DOT LIBRARY REQUIRED ------------------------------//
00387 // * Because these example programs can be used for both mDot and xDot     //
00388 //     devices, the LoRa stack is not included. The libmDot library should //
00389 //     be imported if building for mDot devices. The libxDot library       //
00390 //     should be imported if building for xDot devices.                    //
00391 // * https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/    //
00392 // * https://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/        //
00393 // * https://developer.mbed.org/teams/MultiTech/code/libxDot-dev-mbed5/    //
00394 // * https://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/        //
00395 /////////////////////////////////////////////////////////////////////////////
00396 
00397 
00398 /////////////////////////////////////////////////////////////
00399 // * these options must match between the two devices in   //
00400 //   order for communication to be successful
00401 //-------------------MDOT variables------------------------//
00402 /////////////////////////////////////////////////////////////
00403 static uint8_t network_address[] = { 0x00, 0x11, 0x22, 0x33 };
00404 static uint8_t network_session_key[] = { 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33 };
00405 static uint8_t data_session_key[] = { 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00 };
00406 
00407 mDot* dot = NULL;
00408 lora::ChannelPlan* plan = NULL;
00409 //--------------End of MDOT variables-------------------//
00410 
00411 Serial pc(USBTX, USBRX);
00412 Ticker Periodic;
00413 
00414 // ADXL372 Slave I2C
00415 I2C ADXL372(I2C_SDA, I2C_SCL);  // (D14,D15) (MISO, CS)
00416 
00417 // ADT7410 Temperature
00418 I2C ADT7410(I2C_SDA, I2C_SCL);      // Attempt at making I2C connection to slaves (D14,D15)
00419 InterruptIn ADT7410_Int(D2);    // Allow this pin for ADT7410 Interrupt critical temperature notice
00420 
00421 // DS7505s Temperature
00422 I2C DS7505(I2C_SDA, I2C_SCL);      // Attempt at making I2C connection to slaves (D14,D15)
00423 
00424 // Create reocurring interrupt function that could be used to periodically take temperatures
00425 // Not working right now due to some mutex initialize error
00426 // Suspect that it is due to it having be a RTOS task thing
00427 // Should probably go back to using an in processor timer interrupt instead of mbed
00428 
00429 const int ADT7410_Address_7BIT = 0x49;  // A0 set HIGH and A1 set LOW
00430 const int ADT7410_Address_8BIT = ADT7410_Address_7BIT << 1; // Shift 1 bit to left for R/~W bit, and basic I2C format
00431 
00432 const int ADXL372_Address_7bit = 0x1D;      // Address for the I2C if MISO pulled low, 0x53 if pulled high
00433 const int ADXL372_Address_8bit = ADXL372_Address_7bit << 1; // Same
00434 
00435 const int DS7505s_Address_7bit = 0x48;  // A0 set LOR, A1 set LOW, A2 set LOW
00436 const int DS7505s_Address_8bit = DS7505s_Address_7bit << 1; // Same
00437 
00438 
00439 int regAddress; // Used by all sensors
00440 
00441 /*
00442  *  Variables used for ADT7410 Temperature
00443  */
00444 // Points to the returned char pointer from called functions
00445 char * rawTempValues;           // Could change to uint8_t, same for other char pointers
00446 uint16_t convertedTempValue;    // Data values must be uint16_t for conversion and send prep
00447 uint16_t temperatureBuffer[BUFFER_SIZE];
00448 
00449 
00450 /*
00451  *  Variables used for mDot
00452  */
00453 
00454 
00455 uint32_t tx_frequency;
00456 uint8_t tx_datarate;
00457 uint8_t tx_power;
00458 uint8_t frequency_band;
00459 
00460 
00461 
00462 /*
00463  *  Variables used for ADXL372 Accelerometer
00464  */
00465 char *accelValues;
00466 char Xmsb;  // Gets most significant byte
00467 char Xlsb;  // Gets least significant byte
00468 char Ymsb;
00469 char Ylsb;
00470 char Zmsb;
00471 char Zlsb;
00472 uint16_t XData;
00473 uint16_t YData;
00474 uint16_t ZData;
00475 
00476 uint16_t XDataInterrupt[BUFFER_SIZE];
00477 uint16_t YDataInterrupt[BUFFER_SIZE];
00478 uint16_t ZDataInterrupt[BUFFER_SIZE];
00479 
00480 
00481 
00482 /*
00483  *  Variables used for interrupt triggers
00484  */
00485 bool takeTemperature = false;   // Trigger temperature reading
00486 bool takeAccelerometer = false; // Trigger accelerometer reading
00487 bool periodicReadingTrigger = false;  // Trigger reading both accelerometer and temperature
00488 
00489 /*
00490  *  Prototype functions
00491  */
00492  
00493 char twosComplementConversion(char value);
00494 
00495 void ADXL372Initialize(void);
00496 void ADXL372Reset(void);
00497 void I2CSelfTest(void);
00498 void accelerometerI2CWrite(int hexAddress, int hexData);
00499 char * accelerometerI2CRead(int hexAddress);
00500 
00501 void ADT7410Initialize(void);
00502 void ADT7410Write(unsigned char registerAddress, unsigned char data);
00503 char * ADT7410Read(int hex);
00504 
00505 
00506 /*
00507  *  Interrupt functions
00508  */
00509 void CriticalTemperatureInterrupt(void){   
00510     takeTemperature = true; // Take temperature because something happened
00511 }
00512 
00513 void CriticalAccelerometerInterrupt(void){
00514     takeAccelerometer = true;   // Take accelerometer because something happened
00515 }
00516 
00517 void takePeriodicReading(std::vector<uint8_t> tx_data){
00518         pc.printf("Regular periodic reading \n\r");
00519         /*
00520          *  Taking accelerometer data
00521          */
00522         regAddress = 0x08;  // This is the register address for XData
00523         accelValues = accelerometerI2CRead(regAddress);
00524         Xmsb = *(accelValues + 0);
00525         Xlsb = *(accelValues + 1);
00526         Ymsb = *(accelValues + 2);
00527         Ylsb = *(accelValues + 3);
00528         Zmsb = *(accelValues + 4);
00529         Zlsb = *(accelValues + 5);
00530         
00531         XData = (Xmsb << 8 | Xlsb) >> 4;  // Combine two bytes into short int, remove last 4 flag bits
00532         YData = (Ymsb << 8 | Ylsb) >> 4;
00533         ZData = (Zmsb << 8 | Zlsb) >> 4;
00534         
00535         XData = twosComplementConversion(XData);
00536         YData = twosComplementConversion(YData);
00537         ZData = twosComplementConversion(ZData);
00538         
00539         /*
00540          *  Taking temperature data
00541          */
00542         regAddress = 0x00;
00543         rawTempValues = ADT7410Read(regAddress);
00544         convertedTempValue = ((*(rawTempValues + 0) << 8) | *(rawTempValues + 1)) >> 3; // Combine the two bytes into 
00545                                                                                         // a short int variable(16 bits), remove last 3 bits
00546         pc.printf("Accelerometer::: ");
00547         pc.printf("X: 0x%x | Y: 0x%x | Z: 0x%x\n\r", XData, YData, ZData);
00548         pc.printf("Temperature::: ");
00549         pc.printf("Celsius: 0x%x\n\r", convertedTempValue);
00550         
00551         
00552         
00553         tx_data.push_back((convertedTempValue >> 8) & 0xFF);
00554         tx_data.push_back(convertedTempValue & 0xFF);
00555         logInfo("Temperautre: %lu [0x%04X]", convertedTempValue, convertedTempValue);
00556         send_data(tx_data);
00557         periodicReadingTrigger = false; // Flip back to no trigger
00558 }
00559 
00560 void takePeriodicReadingTicker(void){
00561         periodicReadingTrigger = true;
00562 }
00563 
00564 ////////////////////////////////////////////////////////////////////////////////
00565 /*                              _     
00566                ____ ___  ____ _(_)___ 
00567               / __ `__ \/ __ `/ / __ \
00568              / / / / / / /_/ / / / / /
00569             /_/ /_/ /_/\__,_/_/_/ /_/ 
00570                           
00571  *//////////////////////////////////////////////////////////////////////////////
00572 int main(void)
00573 {
00574     // Custom event handler for automatically displaying RX data
00575     //interruptEverything.attach(&interruptReadTemperature, 7.0);
00576     RadioEvent events;
00577     // Change baud rate in serial terminal to this value
00578     pc.baud(115200);
00579     ADXL372.frequency(300000);  // I2C devices are connected to the same clock
00580     ADT7410.frequency(300000);  // Redundant but whatever
00581     ADT7410_Int.rise(&CriticalTemperatureInterrupt);
00582     
00583     
00584     mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
00585     
00586     // Sometimes when calling this, it creates error: type specifier expected
00587     // Even with identical include files I would get this in another workspace.
00588     plan = new lora::ChannelPlan_US915();
00589 
00590     logInfo("Now asserting");
00591     assert(plan);
00592 
00593     // Careful when using this. The production ready libmdot-mbed5 has a void constructor
00594     // Therefore, can only use the libmDot-dev-mbed5 version, for now.
00595     dot = mDot::getInstance(plan);
00596     assert(dot);
00597 
00598     logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
00599 
00600     // start from a well-known state
00601     logInfo("defaulting Dot configuration");
00602     dot->resetConfig();
00603 
00604     // make sure library logging is turned on
00605     dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
00606 
00607     // attach the custom events handler
00608     dot->setEvents(&events);
00609 
00610     // update configuration if necessary
00611     if (dot->getJoinMode() != mDot::PEER_TO_PEER) {
00612         logInfo("changing network join mode to PEER_TO_PEER");
00613         if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) {
00614             logError("failed to set network join mode to PEER_TO_PEER");
00615         }
00616     }
00617     
00618     /*
00619      *  Get the Frequency and then choose transfer frequency, datarate, and power accordingly
00620      *
00621      */
00622     ////////////////////////////////////////////////////////////////////////////////
00623     frequency_band = dot->getFrequencyBand();
00624     switch (frequency_band) {
00625         case lora::ChannelPlan::EU868_OLD:
00626         case lora::ChannelPlan::EU868:
00627             // 250kHz channels achieve higher throughput
00628             // DR_6 : SF7 @ 250kHz
00629             // DR_0 - DR_5 (125kHz channels) available but much slower
00630             tx_frequency = 869850000;
00631             tx_datarate = lora::DR_6;
00632             // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7
00633             tx_power = 4;
00634             break;
00635 
00636         case lora::ChannelPlan::US915_OLD:
00637         case lora::ChannelPlan::US915:
00638         case lora::ChannelPlan::AU915_OLD:
00639         case lora::ChannelPlan::AU915:
00640             // 500kHz channels achieve highest throughput
00641             // DR_8 : SF12 @ 500kHz
00642             // DR_9 : SF11 @ 500kHz
00643             // DR_10 : SF10 @ 500kHz
00644             // DR_11 : SF9 @ 500kHz
00645             // DR_12 : SF8 @ 500kHz
00646             // DR_13 : SF7 @ 500kHz
00647             // DR_0 - DR_3 (125kHz channels) available but much slower
00648             tx_frequency = 915500000;
00649             tx_datarate = lora::DR_13;
00650             // 915 bands have no duty cycle restrictions, set tx power to max
00651             tx_power = 20;
00652             break;
00653 
00654         case lora::ChannelPlan::AS923:
00655         case lora::ChannelPlan::AS923_JAPAN:
00656             // 250kHz channels achieve higher throughput
00657             // DR_6 : SF7 @ 250kHz
00658             // DR_0 - DR_5 (125kHz channels) available but much slower
00659             tx_frequency = 924800000;
00660             tx_datarate = lora::DR_6;
00661             tx_power = 16;
00662             break;
00663 
00664         case lora::ChannelPlan::KR920:
00665             // DR_5 : SF7 @ 125kHz
00666             tx_frequency = 922700000;
00667             tx_datarate = lora::DR_5;
00668             tx_power = 14;
00669             break;
00670 
00671         default:
00672             while (true) {
00673                 logFatal("no known channel plan in use - extra configuration is needed!");
00674                 wait(5);
00675             }
00676             break;
00677     }
00678     /////////////////////////////////////////////////////////////////////////////////////
00679 
00680     // in PEER_TO_PEER mode there is no join request/response transaction
00681     // as long as both Dots are configured correctly, they should be able to communicate
00682     update_peer_to_peer_config(network_address, network_session_key, data_session_key, tx_frequency, tx_datarate, tx_power);
00683     
00684     // save changes to configuration
00685     logInfo("saving configuration");
00686     if (!dot->saveConfig()) {
00687         logError("failed to save configuration");
00688     }
00689     // Display configuration
00690     // It's gonna output a lot of information onto the Serial Terminal
00691     display_config();
00692 // ******************************************GPS
00693 
00694     Serial * gps_Serial;
00695     //Initalize using pa2 and pa3 (D0 and D1 on the mdot) (D0->TX on gps) (D1->RX on gps)
00696     gps_Serial = new Serial(PA_2,PA_3); //serial object for use w/ GPS USING PA_2 and PA_3
00697     Adafruit_GPS myGPS(gps_Serial); //object of Adafruit's GPS class
00698     char c; //when read via Adafruit_GPS::read(), the class returns single character stored here
00699     Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info?
00700     const int refresh_Time = 2000; //refresh time in ms
00701     
00702     myGPS.begin(9600);  //sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *)
00703                         //a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf
00704     
00705     myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation
00706     myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
00707     myGPS.sendCommand(PGCMD_ANTENNA);
00708     
00709     pc.printf("Connection established at 115200 baud...\n\r");
00710     
00711     wait(1);
00712 
00713  refresh_Timer.start();  //starts the clock on the timer
00714     
00715     while(true){
00716         c = myGPS.read();   //queries the GPS
00717           
00718         if (c) { pc.printf("%c", c); } //this line will echo the GPS data if not paused
00719          //check if we recieved a new message from GPS, if so, attempt to parse it,
00720         if ( myGPS.newNMEAreceived() ) {
00721             if ( !myGPS.parse(myGPS.lastNMEA()) ) {
00722                 continue;   
00723             }    
00724         }
00725         
00726          //check if enough time has passed to warrant printing GPS info to screen
00727         //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing
00728         if (refresh_Timer.read_ms() >= refresh_Time) {
00729             pc.printf("Refresh Timer: %d\n\r", refresh_Timer.read_ms());
00730             refresh_Timer.reset();
00731         
00732          pc.printf("Time: %d:%d:%d.%u\n\r", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds);   
00733             pc.printf("Date: %d/%d/20%d\n\r", myGPS.day, myGPS.month, myGPS.year);
00734             pc.printf("Fix: %d\n\r", (int) myGPS.fix);
00735             pc.printf("Quality: %d\n\r", (int) myGPS.fixquality);
00736          if (myGPS.fix) {
00737                 pc.printf("Location: %5.2f%c, %5.2f%c\n\r", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon);
00738                 pc.printf("Speed: %5.2f knots\n\r", myGPS.speed);
00739                 pc.printf("Angle: %5.2f\n\r", myGPS.angle);
00740                 pc.printf("Altitude: %5.2f\n\r", myGPS.altitude);
00741                 pc.printf("Satellites: %d\n\r", myGPS.satellites);
00742             }
00743         }
00744       }//end while
00745 
00746 
00747 
00748 
00749 // ******************************************end GPS
00750 
00751 
00752 
00753 
00754 
00755 
00756 //below is acc,temp sensors
00757     ADT7410Initialize();
00758     ADXL372Initialize();
00759     
00760     Periodic.attach(&takePeriodicReadingTicker,5);
00761     
00762     while(1){
00763         // Create a vector of uint8_t elements to be sent later
00764         
00765         std::vector<uint8_t> tx_data;
00766         
00767         
00768         if(periodicReadingTrigger)
00769         {
00770             takePeriodicReading(tx_data);
00771         }
00772         
00773         if(takeAccelerometer || takeTemperature){
00774             pc.printf("INTERRUPTEDDDDDDDD: ");
00775             if(takeTemperature) pc.printf("Temperature triggered!!!!!!!!!!!!\n\r");
00776             else if(takeAccelerometer) pc.printf("AccelerometerTriggered!!!!!!!!!!!!!\n\r");
00777             
00778             for(int i = 0; i < BUFFER_SIZE; ++i){
00779                 /*
00780                 *   Taking accelerometer data
00781                 */
00782                 regAddress = 0x08;  // This is the register address for XData
00783                 accelValues = accelerometerI2CRead(regAddress);
00784                 Xmsb = *(accelValues + 0);
00785                 Xlsb = *(accelValues + 1);
00786                 Ymsb = *(accelValues + 2);
00787                 Ylsb = *(accelValues + 3);
00788                 Zmsb = *(accelValues + 4);
00789                 Zlsb = *(accelValues + 5);
00790     
00791                 XDataInterrupt[i] = (Xmsb << 8 | Xlsb) >> 4;  // Combine two bytes into short int, remove last 4 flag bits
00792                 YDataInterrupt[i] = (Ymsb << 8 | Ylsb) >> 4;
00793                 ZDataInterrupt[i] = (Zmsb << 8 | Zlsb) >> 4;
00794     
00795                 XDataInterrupt[i] = twosComplementConversion(XDataInterrupt[i]);
00796                 YDataInterrupt[i] = twosComplementConversion(YDataInterrupt[i]);
00797                 ZDataInterrupt[i] = twosComplementConversion(ZDataInterrupt[i]);
00798     
00799                 /*
00800                 *   Taking temperature data
00801                 */
00802                 regAddress = 0x00;
00803                 rawTempValues = ADT7410Read(regAddress);
00804                 temperatureBuffer[i] = ((*(rawTempValues + 0) << 8) | *(rawTempValues + 1)) >> 3; // Combine the two bytes into 
00805                                                                                                 // a short int variable(16 bits), remove last 3 bits    
00806             }
00807             
00808             for(int i = 0; i < BUFFER_SIZE; ++i){
00809                 pc.printf("Accelerometer::: ");
00810                 pc.printf("X: 0x%x | Y: 0x%x | Z: 0x%x\n\r", XDataInterrupt[i], YDataInterrupt[i], ZDataInterrupt[i]);
00811                 pc.printf("Temperature::: ");
00812                 pc.printf("Celsius: 0x%x\n\r", temperatureBuffer[i]);   
00813             }
00814             //wait(0.2);
00815             takeAccelerometer = false;  // Flip back to no trigger
00816             takeTemperature = false;    // Flip back to no trigger
00817             
00818         }
00819         
00820         
00821         
00822         
00823         //wait(1);
00824     }
00825     
00826     return 0;
00827 }
00828 
00829 /*******************************************************************************
00830  *  Not really used at the moment
00831  *  Not really needed. But keep just in case because I don't want to rewrite it
00832  ******************************************************************************/
00833 ////////////////////////////////////////////////////////////////////////////////
00834 char twosComplementConversion(char value)
00835 {
00836     /*
00837      * Go from bit 0 to bit 7 and invert them
00838      * Then finally add 1
00839      */
00840     char mask = value & 0x80;
00841     if(mask == 0x80){   // Check for sign
00842         value = ~value + 1;
00843         return value;
00844     } 
00845     return value;
00846 }
00847 ////////////////////////////////////////////////////////////////////////////////
00848 
00849 /*******************************************************************************
00850  *  Initializes whatever settings you want for the accelerometer
00851  *  Can change it to use the previous I2C write function instead of all this mess
00852  *
00853  ******************************************************************************/  
00854 ////////////////////////////////////////////////////////////////////////////////
00855 void ADXL372Initialize(void){
00856     pc.printf("Initializing ADXL372 accelerometer\n\r");
00857     accelerometerI2CWrite(0x3F, 0x0F);  // Enable I2C highspeed,Low Pass, High pass and full bandwidth measurement mode
00858     accelerometerI2CWrite(0x38, 0x01);  // Enable the High pass filter corner 1 at register 0x38
00859 /*     accelerometerI2CWrite(0x24, 0x01);  // X used for activity threshold
00860     accelerometerI2CWrite(0x26, 0x01);  // Y used for activity threshold
00861     accelerometerI2CWrite(0x28, 0x01);  // Z used for activity threshold  */
00862     pc.printf("\n\n\r");
00863 }
00864 ////////////////////////////////////////////////////////////////////////////////
00865 
00866 
00867 /*******************************************************************************
00868  *  ADT7410 Initializing function
00869  *  Make critical temperature 24 celsius
00870  *  Make CRIT pin active high
00871  ******************************************************************************/
00872 ////////////////////////////////////////////////////////////////////////////////
00873 void ADT7410Initialize(void){
00874     pc.printf("Initializing ADT7410 Temperature\n\r");
00875     // Make critical temperature be 24 celsius
00876     ADT7410Write(0x08, 0x01);   // MSB of Temperature Crit value
00877     ADT7410Write(0x09, 0x80);   // LSB of Temperature Crit value
00878     
00879     // Make CRIT pin active high
00880     ADT7410Write(0x03, 0x08);   // Turn INT HIGH, works for the interrupt pin
00881     pc.printf("\n\n\r");
00882 }
00883 ////////////////////////////////////////////////////////////////////////////////
00884 
00885 /*******************************************************************************
00886  *  ADXL372 reset function
00887  *  Resets all registers and settings back to default
00888  *  Basically the same as the previous ADXL372 I2C write function
00889  *
00890  ******************************************************************************/
00891 ////////////////////////////////////////////////////////////////////////////////
00892 void ADXL372Reset(void){
00893     int flag;
00894 //--------- One full writing cycle for ADXL372 for Z Enable ------------------//
00895 /*    '0' - NAK was received
00896  *    '1' - ACK was received, <---- This good
00897  *    '2' - timeout
00898  */
00899     ADXL372.start();
00900     flag = ADXL372.write(ADXL372_Address_8bit | 0);
00901     if(flag == 1)
00902     {
00903         //pc.printf("Write to I2C address success\n\r");
00904         
00905         flag = ADXL372.write(0x41);
00906         if(flag == 1)
00907         {
00908             //pc.printf("Write to 0x41 register address success\n\r");
00909             flag = ADXL372.write(0x52);                             // Set bit 0
00910             if(flag == 1)
00911             {
00912                 pc.printf("Everything has been reset\n\r");
00913                 ADXL372.stop();
00914             }
00915         }
00916     }
00917     else ADXL372.stop();
00918 // ---------------- End of writing cycle --------------------------//
00919 }
00920 ////////////////////////////////////////////////////////////////////////////////
00921 
00922 /*
00923  *
00924  *  Self-test to see if the accelerometer is working as intended
00925  *  Wait 300 ms.
00926  *  Check bit 2 for a 1 for success. Bit 1 for completion of self-test.    
00927  *  Returns whole register
00928  */
00929 ////////////////////////////////////////////////////////////////////////////////
00930 void I2CSelfTest(void){
00931     char *result;
00932     uint8_t check;
00933     accelerometerI2CWrite(0x3F, 0x0F);
00934     accelerometerI2CWrite(0x40, 0x01);
00935     wait(0.3);
00936     result = accelerometerI2CRead(0x40);
00937     check = result[0];
00938     if(check & 0x04){
00939         pc.printf("Passed\n\r");
00940     }else {pc.printf("FAILED\n\r");}
00941 }
00942 ////////////////////////////////////////////////////////////////////////////////
00943 
00944 /*******************************************************************************
00945  *                                                                             
00946  *  I2C function for the the ADXL372 accelerometer for a write sequence
00947  *  Param:
00948  *      hexAddress: Pass the hexadecimal value for what register you want
00949  *      hexData: Pass the hexadecimal value for what data you want to send
00950  *               i.e. hexadecimal represenatation of certain bits
00951  *  Returns from mbed library write function            
00952  *      0: NAK was reveived
00953  *      1: ACK was received <---- Good for us
00954  *      2: Timeout     
00955  ******************************************************************************/
00956 ////////////////////////////////////////////////////////////////////////////////
00957 void accelerometerI2CWrite(int hexAddress, int hexData){
00958 
00959     int flag;
00960     int registerAddress = hexAddress;
00961     int data = hexData;
00962     
00963     ADXL372.start();
00964     flag = ADXL372.write(ADXL372_Address_8bit);
00965     if(flag == 1)
00966     {
00967         //pc.printf("Write to I2C address success\n\r");
00968         wait(0.1);
00969         flag = ADXL372.write(registerAddress);
00970         if(flag == 1)
00971         {
00972             //pc.printf("Write to register 0x%x address success\n\r", registerAddress);
00973             flag = ADXL372.write(data);
00974             if(flag == 1)
00975             {
00976                 pc.printf("Writing data 0x%x to register address 0x%d success\n\r", data, registerAddress);
00977                 ADXL372.stop();
00978                 return;
00979             }else {ADXL372.stop();} 
00980         }else {ADXL372.stop();}
00981     }else ADXL372.stop();
00982    
00983 }
00984 ////////////////////////////////////////////////////////////////////////////////
00985 
00986 /*******************************************************************************
00987  *  I2C read sequence for the accelerometer
00988  *  Param:
00989  *      hexAddress: pass the hexadecimal representation of desired Register address
00990  *  Return:
00991  *      Char pointer to the array of read data. 
00992  *
00993  *  Right now it works only for the XData, YData, ZData because I wrote it to read
00994  *  6 bytes(6 registers).
00995  *  Should change it to be 1 byte at a time
00996  ******************************************************************************/
00997 ////////////////////////////////////////////////////////////////////////////////
00998 char * accelerometerI2CRead(int hexAddress){
00999     char accelData[6];
01000     char registerAddress[1];
01001     registerAddress[0] = hexAddress;
01002     
01003     // Perform mbed's way sending a start bit, then device address[r/~w], and then the register address
01004     // Also if it succeeds, continue to the next operation
01005     if(ADXL372.write(ADXL372_Address_8bit, registerAddress, 1) == 0){
01006         
01007         // If previous sequence works, get 6 bytes into char array accelData
01008         // Char array because it uses 1 byte(8bits)
01009         // Should probably change it to uint8_t type
01010         if(ADXL372.read(ADXL372_Address_8bit, accelData, 6) == 0){
01011             return accelData;
01012         }else pc.printf("Failed to read\n\r");
01013     }else pc.printf("Failed to write\n\r");
01014     return 0; // Only if it fails completely 
01015 }
01016 ////////////////////////////////////////////////////////////////////////////////
01017 
01018 
01019 
01020 
01021 /*******************************************************************************
01022  *  Performs one byte write I2C protocol
01023  *  PARAM:
01024  *      registerAddress: register you want access to in device, one byte char hex format
01025  *      data: one byte data that you want to write to device register
01026  *  Return results from mbed library function:
01027  *      0: failure at writing i2c address
01028  *      1: successful write
01029  *      2: failure at writing data
01030  *      
01031  ******************************************************************************/
01032 ////////////////////////////////////////////////////////////////////////////////
01033 void ADT7410Write(unsigned char registerAddress, unsigned char data){
01034     int flag;
01035     ADT7410.start();
01036     flag = ADT7410.write(ADT7410_Address_8BIT);
01037     if(flag == 1)
01038     {
01039         
01040         wait(0.1);
01041         flag = ADT7410.write(registerAddress);
01042         if(flag == 1)
01043         {
01044            
01045             flag = ADT7410.write(data);
01046             if(flag == 1)
01047             {
01048                 pc.printf("Writing data 0x%x to register address 0x%x success\n\r", data, registerAddress);
01049                 ADT7410.stop();
01050                 
01051             }else {ADT7410.stop();} 
01052         }else {ADT7410.stop();} 
01053     }else ADT7410.stop();
01054        
01055     
01056 }
01057 ////////////////////////////////////////////////////////////////////////////////
01058 
01059 
01060 /*******************************************************************************
01061  *  I2C Read function for ADT7410 Temperature sensor
01062  *  Param:
01063  *      hex: hexadecimal representation for desired register
01064  *  Return:
01065  *      Char pointer to the array of data values.
01066  *  Could also change from a char pointer to a uint8_t pointer.
01067  *
01068  ******************************************************************************/
01069 ////////////////////////////////////////////////////////////////////////////////
01070 char * ADT7410Read(int hex){
01071     //short int convertedVal;
01072     char data[2] = {0, 0};
01073     char cmd[1];
01074     cmd[0] = hex;
01075     //pc.printf("Register Addres is: %x \n\r", cmd[0]); 
01076     if(ADT7410.write(ADT7410_Address_8BIT, cmd,1) == 0){
01077         if(ADT7410.read(ADT7410_Address_8BIT, data, 2) == 0){
01078             
01079             return data;
01080             //return (data[0] << 8 | data[1])>>3;     // Explained here: https://stackoverflow.com/a/141576 SOOO GREAT
01081             
01082         }else {pc.printf("Failed to read \n\r"); return data;}
01083     }else {pc.printf("Failed to write \n\r"); return data;}
01084     
01085 }
01086 ////////////////////////////////////////////////////////////////////////////////
01087