This is used for sending Data to receiving mDot
Dependencies: libmDot-dev-mbed5-deprecated sd-driver ISL29011
Fork of mdot-examples by
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
Generated on Tue Jul 12 2022 18:56:55 by 1.7.2