This is used for sending Data to receiving mDot
Dependencies: libmDot-dev-mbed5-deprecated ISL29011
Fork of mdot-examples by
send_main.cpp@29:0f0a059f023e, 2018-04-13 (annotated)
- Committer:
- SDesign2018
- Date:
- Fri Apr 13 00:08:44 2018 +0000
- Revision:
- 29:0f0a059f023e
- Parent:
- 28:29702434319d
- Child:
- 30:218c795a8081
SD stopped working, GPS not working, others work. Update
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
SDesign2018 | 26:15df8f054d11 | 1 | /* |
SDesign2018 | 26:15df8f054d11 | 2 | 3/27/2018 mdot version = 3.0.2, mbed version = 5.5.7 WORKS |
SDesign2018 | 26:15df8f054d11 | 3 | 3/27/2018 mdot version = 3.1.0, mbed version = 5.7.4 WORKS |
SDesign2018 | 29:0f0a059f023e | 4 | 4/12/2018 mdot version = 3.1.0, mbed version = 5.7.4 Eh |
SDesign2018 | 26:15df8f054d11 | 5 | */ |
SDesign2018 | 26:15df8f054d11 | 6 | |
SDesign2018 | 26:15df8f054d11 | 7 | #include <stdlib.h> |
SDesign2018 | 26:15df8f054d11 | 8 | #include <iostream> |
SDesign2018 | 26:15df8f054d11 | 9 | #include <string.h> |
SDesign2018 | 26:15df8f054d11 | 10 | #include <mbed.h> |
SDesign2018 | 26:15df8f054d11 | 11 | #include "dot_util.h" |
SDesign2018 | 26:15df8f054d11 | 12 | #include "RadioEvent.h" |
SDesign2018 | 26:15df8f054d11 | 13 | #include "itoa.h" |
SDesign2018 | 28:29702434319d | 14 | #include <sstream> |
SDesign2018 | 28:29702434319d | 15 | |
SDesign2018 | 28:29702434319d | 16 | // For time Keeping |
SDesign2018 | 28:29702434319d | 17 | #include <ctime> |
SDesign2018 | 28:29702434319d | 18 | |
SDesign2018 | 28:29702434319d | 19 | #include <errno.h> // For SD card error checking |
SDesign2018 | 28:29702434319d | 20 | #include "platform/FilePath.h" // For SD card struct stat |
SDesign2018 | 28:29702434319d | 21 | |
SDesign2018 | 28:29702434319d | 22 | // Headers for the SD card |
SDesign2018 | 28:29702434319d | 23 | #include "SDBlockDevice.h" |
SDesign2018 | 28:29702434319d | 24 | #include "FATFileSystem.h" |
SDesign2018 | 26:15df8f054d11 | 25 | |
SDesign2018 | 26:15df8f054d11 | 26 | #define BUFFER_SIZE 10 |
SDesign2018 | 26:15df8f054d11 | 27 | |
SDesign2018 | 28:29702434319d | 28 | //------------------------------SD CARD------------------------------------// |
SDesign2018 | 28:29702434319d | 29 | |
SDesign2018 | 28:29702434319d | 30 | SDBlockDevice sd(D11, D12, D13, D10); // mosi, miso, sclk, cs |
SDesign2018 | 28:29702434319d | 31 | FATFileSystem fs("sd"); |
SDesign2018 | 28:29702434319d | 32 | |
SDesign2018 | 28:29702434319d | 33 | FILE *fp; |
SDesign2018 | 28:29702434319d | 34 | |
SDesign2018 | 28:29702434319d | 35 | // Error checking SD stuff |
SDesign2018 | 28:29702434319d | 36 | int err; |
SDesign2018 | 28:29702434319d | 37 | |
SDesign2018 | 26:15df8f054d11 | 38 | //note: added GPS functions , variables below (will organize better later ski |
SDesign2018 | 26:15df8f054d11 | 39 | //and gps code in main is noted |
SDesign2018 | 26:15df8f054d11 | 40 | |
SDesign2018 | 26:15df8f054d11 | 41 | |
SDesign2018 | 26:15df8f054d11 | 42 | |
SDesign2018 | 28:29702434319d | 43 | |
SDesign2018 | 26:15df8f054d11 | 44 | ///-----------------FOR GPS------BELOW---------------------------------- |
SDesign2018 | 26:15df8f054d11 | 45 | // |
SDesign2018 | 26:15df8f054d11 | 46 | |
SDesign2018 | 26:15df8f054d11 | 47 | #include "MBed_Adafruit_GPS.h" |
SDesign2018 | 26:15df8f054d11 | 48 | |
SDesign2018 | 26:15df8f054d11 | 49 | |
SDesign2018 | 26:15df8f054d11 | 50 | Serial * gps_Serial = new Serial(PA_2,PA_3); |
SDesign2018 | 26:15df8f054d11 | 51 | //Initalize using pa2 and pa3 (D0 and D1 on the mdot) (D0->TX on gps) (D1->RX on gps) |
SDesign2018 | 26:15df8f054d11 | 52 | //gps_Serial = new Serial(PA_2,PA_3); //serial object for use w/ GPS USING PA_2 and PA_3 |
SDesign2018 | 26:15df8f054d11 | 53 | Adafruit_GPS myGPS(gps_Serial); //object of Adafruit's GPS class |
SDesign2018 | 26:15df8f054d11 | 54 | char c; //when read via Adafruit_GPS::read(), the class returns single character stored here |
SDesign2018 | 26:15df8f054d11 | 55 | Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info? |
SDesign2018 | 26:15df8f054d11 | 56 | const int refresh_Time = 2000; //refresh time in ms |
SDesign2018 | 26:15df8f054d11 | 57 | |
SDesign2018 | 26:15df8f054d11 | 58 | |
SDesign2018 | 26:15df8f054d11 | 59 | |
SDesign2018 | 26:15df8f054d11 | 60 | // how long are max NMEA lines to parse? |
SDesign2018 | 26:15df8f054d11 | 61 | #define MAXLINELENGTH 120 |
SDesign2018 | 26:15df8f054d11 | 62 | |
SDesign2018 | 26:15df8f054d11 | 63 | // we double buffer: read one line in and leave one for the main program |
SDesign2018 | 26:15df8f054d11 | 64 | volatile char line1[MAXLINELENGTH]; |
SDesign2018 | 26:15df8f054d11 | 65 | volatile char line2[MAXLINELENGTH]; |
SDesign2018 | 26:15df8f054d11 | 66 | // our index into filling the current line |
SDesign2018 | 26:15df8f054d11 | 67 | volatile uint16_t lineidx=0; |
SDesign2018 | 26:15df8f054d11 | 68 | // pointers to the double buffers |
SDesign2018 | 26:15df8f054d11 | 69 | volatile char *currentline; |
SDesign2018 | 26:15df8f054d11 | 70 | volatile char *lastline; |
SDesign2018 | 26:15df8f054d11 | 71 | volatile bool recvdflag; |
SDesign2018 | 26:15df8f054d11 | 72 | volatile bool inStandbyMode; |
SDesign2018 | 26:15df8f054d11 | 73 | |
SDesign2018 | 26:15df8f054d11 | 74 | |
SDesign2018 | 26:15df8f054d11 | 75 | |
SDesign2018 | 26:15df8f054d11 | 76 | |
SDesign2018 | 26:15df8f054d11 | 77 | bool Adafruit_GPS::parse(char *nmea) { |
SDesign2018 | 26:15df8f054d11 | 78 | // do checksum check |
SDesign2018 | 26:15df8f054d11 | 79 | |
SDesign2018 | 26:15df8f054d11 | 80 | // first look if we even have one |
SDesign2018 | 26:15df8f054d11 | 81 | if (nmea[strlen(nmea)-4] == '*') { |
SDesign2018 | 26:15df8f054d11 | 82 | uint16_t sum = parseHex(nmea[strlen(nmea)-3]) * 16; |
SDesign2018 | 26:15df8f054d11 | 83 | sum += parseHex(nmea[strlen(nmea)-2]); |
SDesign2018 | 26:15df8f054d11 | 84 | |
SDesign2018 | 26:15df8f054d11 | 85 | // check checksum |
SDesign2018 | 26:15df8f054d11 | 86 | for (uint8_t i=1; i < (strlen(nmea)-4); i++) { |
SDesign2018 | 26:15df8f054d11 | 87 | sum ^= nmea[i]; |
SDesign2018 | 26:15df8f054d11 | 88 | } |
SDesign2018 | 26:15df8f054d11 | 89 | if (sum != 0) { |
SDesign2018 | 26:15df8f054d11 | 90 | // bad checksum :( |
SDesign2018 | 26:15df8f054d11 | 91 | //return false; |
SDesign2018 | 26:15df8f054d11 | 92 | } |
SDesign2018 | 26:15df8f054d11 | 93 | } |
SDesign2018 | 26:15df8f054d11 | 94 | |
SDesign2018 | 26:15df8f054d11 | 95 | // look for a few common sentences |
SDesign2018 | 26:15df8f054d11 | 96 | if (strstr(nmea, "$GPGGA")) { |
SDesign2018 | 26:15df8f054d11 | 97 | // found GGA |
SDesign2018 | 26:15df8f054d11 | 98 | char *p = nmea; |
SDesign2018 | 26:15df8f054d11 | 99 | // get time |
SDesign2018 | 26:15df8f054d11 | 100 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 101 | float timef = atof(p); |
SDesign2018 | 26:15df8f054d11 | 102 | uint32_t time = timef; |
SDesign2018 | 26:15df8f054d11 | 103 | hour = time / 10000; |
SDesign2018 | 26:15df8f054d11 | 104 | minute = (time % 10000) / 100; |
SDesign2018 | 26:15df8f054d11 | 105 | seconds = (time % 100); |
SDesign2018 | 26:15df8f054d11 | 106 | |
SDesign2018 | 26:15df8f054d11 | 107 | milliseconds = fmod((double) timef, 1.0) * 1000; |
SDesign2018 | 26:15df8f054d11 | 108 | |
SDesign2018 | 26:15df8f054d11 | 109 | // parse out latitude |
SDesign2018 | 26:15df8f054d11 | 110 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 111 | latitude = atof(p); |
SDesign2018 | 26:15df8f054d11 | 112 | |
SDesign2018 | 26:15df8f054d11 | 113 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 114 | if (p[0] == 'N') lat = 'N'; |
SDesign2018 | 26:15df8f054d11 | 115 | else if (p[0] == 'S') lat = 'S'; |
SDesign2018 | 26:15df8f054d11 | 116 | else if (p[0] == ',') lat = 0; |
SDesign2018 | 26:15df8f054d11 | 117 | else return false; |
SDesign2018 | 26:15df8f054d11 | 118 | |
SDesign2018 | 26:15df8f054d11 | 119 | // parse out longitude |
SDesign2018 | 26:15df8f054d11 | 120 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 121 | longitude = atof(p); |
SDesign2018 | 26:15df8f054d11 | 122 | |
SDesign2018 | 26:15df8f054d11 | 123 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 124 | if (p[0] == 'W') lon = 'W'; |
SDesign2018 | 26:15df8f054d11 | 125 | else if (p[0] == 'E') lon = 'E'; |
SDesign2018 | 26:15df8f054d11 | 126 | else if (p[0] == ',') lon = 0; |
SDesign2018 | 26:15df8f054d11 | 127 | else return false; |
SDesign2018 | 26:15df8f054d11 | 128 | |
SDesign2018 | 26:15df8f054d11 | 129 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 130 | fixquality = atoi(p); |
SDesign2018 | 26:15df8f054d11 | 131 | |
SDesign2018 | 26:15df8f054d11 | 132 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 133 | satellites = atoi(p); |
SDesign2018 | 26:15df8f054d11 | 134 | |
SDesign2018 | 26:15df8f054d11 | 135 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 136 | HDOP = atof(p); |
SDesign2018 | 26:15df8f054d11 | 137 | |
SDesign2018 | 26:15df8f054d11 | 138 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 139 | altitude = atof(p); |
SDesign2018 | 26:15df8f054d11 | 140 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 141 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 142 | geoidheight = atof(p); |
SDesign2018 | 26:15df8f054d11 | 143 | return true; |
SDesign2018 | 26:15df8f054d11 | 144 | } |
SDesign2018 | 26:15df8f054d11 | 145 | if (strstr(nmea, "$GPRMC")) { |
SDesign2018 | 26:15df8f054d11 | 146 | // found RMC |
SDesign2018 | 26:15df8f054d11 | 147 | char *p = nmea; |
SDesign2018 | 26:15df8f054d11 | 148 | |
SDesign2018 | 26:15df8f054d11 | 149 | // get time |
SDesign2018 | 26:15df8f054d11 | 150 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 151 | float timef = atof(p); |
SDesign2018 | 26:15df8f054d11 | 152 | uint32_t time = timef; |
SDesign2018 | 26:15df8f054d11 | 153 | hour = time / 10000; |
SDesign2018 | 26:15df8f054d11 | 154 | minute = (time % 10000) / 100; |
SDesign2018 | 26:15df8f054d11 | 155 | seconds = (time % 100); |
SDesign2018 | 26:15df8f054d11 | 156 | |
SDesign2018 | 26:15df8f054d11 | 157 | milliseconds = fmod((double) timef, 1.0) * 1000; |
SDesign2018 | 26:15df8f054d11 | 158 | |
SDesign2018 | 26:15df8f054d11 | 159 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 160 | // Serial.println(p); |
SDesign2018 | 26:15df8f054d11 | 161 | if (p[0] == 'A') |
SDesign2018 | 26:15df8f054d11 | 162 | fix = true; |
SDesign2018 | 26:15df8f054d11 | 163 | else if (p[0] == 'V') |
SDesign2018 | 26:15df8f054d11 | 164 | fix = false; |
SDesign2018 | 26:15df8f054d11 | 165 | else |
SDesign2018 | 26:15df8f054d11 | 166 | return false; |
SDesign2018 | 26:15df8f054d11 | 167 | |
SDesign2018 | 26:15df8f054d11 | 168 | // parse out latitude |
SDesign2018 | 26:15df8f054d11 | 169 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 170 | latitude = atof(p); |
SDesign2018 | 26:15df8f054d11 | 171 | |
SDesign2018 | 26:15df8f054d11 | 172 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 173 | if (p[0] == 'N') lat = 'N'; |
SDesign2018 | 26:15df8f054d11 | 174 | else if (p[0] == 'S') lat = 'S'; |
SDesign2018 | 26:15df8f054d11 | 175 | else if (p[0] == ',') lat = 0; |
SDesign2018 | 26:15df8f054d11 | 176 | else return false; |
SDesign2018 | 26:15df8f054d11 | 177 | |
SDesign2018 | 26:15df8f054d11 | 178 | // parse out longitude |
SDesign2018 | 26:15df8f054d11 | 179 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 180 | longitude = atof(p); |
SDesign2018 | 26:15df8f054d11 | 181 | |
SDesign2018 | 26:15df8f054d11 | 182 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 183 | if (p[0] == 'W') lon = 'W'; |
SDesign2018 | 26:15df8f054d11 | 184 | else if (p[0] == 'E') lon = 'E'; |
SDesign2018 | 26:15df8f054d11 | 185 | else if (p[0] == ',') lon = 0; |
SDesign2018 | 26:15df8f054d11 | 186 | else return false; |
SDesign2018 | 26:15df8f054d11 | 187 | |
SDesign2018 | 26:15df8f054d11 | 188 | // speed |
SDesign2018 | 26:15df8f054d11 | 189 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 190 | speed = atof(p); |
SDesign2018 | 26:15df8f054d11 | 191 | |
SDesign2018 | 26:15df8f054d11 | 192 | // angle |
SDesign2018 | 26:15df8f054d11 | 193 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 194 | angle = atof(p); |
SDesign2018 | 26:15df8f054d11 | 195 | |
SDesign2018 | 26:15df8f054d11 | 196 | p = strchr(p, ',')+1; |
SDesign2018 | 26:15df8f054d11 | 197 | uint32_t fulldate = atof(p); |
SDesign2018 | 26:15df8f054d11 | 198 | day = fulldate / 10000; |
SDesign2018 | 26:15df8f054d11 | 199 | month = (fulldate % 10000) / 100; |
SDesign2018 | 26:15df8f054d11 | 200 | year = (fulldate % 100); |
SDesign2018 | 26:15df8f054d11 | 201 | |
SDesign2018 | 26:15df8f054d11 | 202 | // we dont parse the remaining, yet! |
SDesign2018 | 26:15df8f054d11 | 203 | return true; |
SDesign2018 | 26:15df8f054d11 | 204 | } |
SDesign2018 | 26:15df8f054d11 | 205 | |
SDesign2018 | 26:15df8f054d11 | 206 | return false; |
SDesign2018 | 26:15df8f054d11 | 207 | } |
SDesign2018 | 26:15df8f054d11 | 208 | |
SDesign2018 | 26:15df8f054d11 | 209 | char Adafruit_GPS::read(void) { |
SDesign2018 | 26:15df8f054d11 | 210 | char c = 0; |
SDesign2018 | 26:15df8f054d11 | 211 | |
SDesign2018 | 26:15df8f054d11 | 212 | if (paused) return c; |
SDesign2018 | 26:15df8f054d11 | 213 | |
SDesign2018 | 26:15df8f054d11 | 214 | if(!gpsSerial->readable()) return c; |
SDesign2018 | 26:15df8f054d11 | 215 | c = gpsSerial->getc(); |
SDesign2018 | 26:15df8f054d11 | 216 | |
SDesign2018 | 26:15df8f054d11 | 217 | //Serial.print(c); |
SDesign2018 | 26:15df8f054d11 | 218 | |
SDesign2018 | 26:15df8f054d11 | 219 | if (c == '$') { |
SDesign2018 | 26:15df8f054d11 | 220 | currentline[lineidx] = 0; |
SDesign2018 | 26:15df8f054d11 | 221 | lineidx = 0; |
SDesign2018 | 26:15df8f054d11 | 222 | } |
SDesign2018 | 26:15df8f054d11 | 223 | if (c == '\n') { |
SDesign2018 | 26:15df8f054d11 | 224 | currentline[lineidx] = 0; |
SDesign2018 | 26:15df8f054d11 | 225 | |
SDesign2018 | 26:15df8f054d11 | 226 | if (currentline == line1) { |
SDesign2018 | 26:15df8f054d11 | 227 | currentline = line2; |
SDesign2018 | 26:15df8f054d11 | 228 | lastline = line1; |
SDesign2018 | 26:15df8f054d11 | 229 | } else { |
SDesign2018 | 26:15df8f054d11 | 230 | currentline = line1; |
SDesign2018 | 26:15df8f054d11 | 231 | lastline = line2; |
SDesign2018 | 26:15df8f054d11 | 232 | } |
SDesign2018 | 26:15df8f054d11 | 233 | |
SDesign2018 | 26:15df8f054d11 | 234 | lineidx = 0; |
SDesign2018 | 26:15df8f054d11 | 235 | recvdflag = true; |
SDesign2018 | 26:15df8f054d11 | 236 | } |
SDesign2018 | 26:15df8f054d11 | 237 | |
SDesign2018 | 26:15df8f054d11 | 238 | currentline[lineidx++] = c; |
SDesign2018 | 26:15df8f054d11 | 239 | if (lineidx >= MAXLINELENGTH) |
SDesign2018 | 26:15df8f054d11 | 240 | lineidx = MAXLINELENGTH-1; |
SDesign2018 | 26:15df8f054d11 | 241 | |
SDesign2018 | 26:15df8f054d11 | 242 | return c; |
SDesign2018 | 26:15df8f054d11 | 243 | } |
SDesign2018 | 26:15df8f054d11 | 244 | |
SDesign2018 | 26:15df8f054d11 | 245 | Adafruit_GPS::Adafruit_GPS (Serial *ser) |
SDesign2018 | 26:15df8f054d11 | 246 | { |
SDesign2018 | 26:15df8f054d11 | 247 | common_init(); // Set everything to common state, then... |
SDesign2018 | 26:15df8f054d11 | 248 | gpsSerial = ser; // ...override gpsSwSerial with value passed. |
SDesign2018 | 26:15df8f054d11 | 249 | } |
SDesign2018 | 26:15df8f054d11 | 250 | |
SDesign2018 | 26:15df8f054d11 | 251 | // Initialization code used by all constructor types |
SDesign2018 | 26:15df8f054d11 | 252 | void Adafruit_GPS::common_init(void) { |
SDesign2018 | 26:15df8f054d11 | 253 | gpsSerial = NULL; |
SDesign2018 | 26:15df8f054d11 | 254 | recvdflag = false; |
SDesign2018 | 26:15df8f054d11 | 255 | paused = false; |
SDesign2018 | 26:15df8f054d11 | 256 | lineidx = 0; |
SDesign2018 | 26:15df8f054d11 | 257 | currentline = line1; |
SDesign2018 | 26:15df8f054d11 | 258 | lastline = line2; |
SDesign2018 | 26:15df8f054d11 | 259 | |
SDesign2018 | 26:15df8f054d11 | 260 | hour = minute = seconds = year = month = day = |
SDesign2018 | 26:15df8f054d11 | 261 | fixquality = satellites = 0; // uint8_t |
SDesign2018 | 26:15df8f054d11 | 262 | lat = lon = mag = 0; // char |
SDesign2018 | 26:15df8f054d11 | 263 | fix = false; // bool |
SDesign2018 | 26:15df8f054d11 | 264 | milliseconds = 0; // uint16_t |
SDesign2018 | 26:15df8f054d11 | 265 | latitude = longitude = geoidheight = altitude = |
SDesign2018 | 26:15df8f054d11 | 266 | speed = angle = magvariation = HDOP = 0.0; // float |
SDesign2018 | 26:15df8f054d11 | 267 | } |
SDesign2018 | 26:15df8f054d11 | 268 | |
SDesign2018 | 26:15df8f054d11 | 269 | void Adafruit_GPS::begin(int baud) |
SDesign2018 | 26:15df8f054d11 | 270 | { |
SDesign2018 | 26:15df8f054d11 | 271 | gpsSerial->baud(baud); |
SDesign2018 | 26:15df8f054d11 | 272 | wait_ms(10); |
SDesign2018 | 26:15df8f054d11 | 273 | } |
SDesign2018 | 26:15df8f054d11 | 274 | |
SDesign2018 | 26:15df8f054d11 | 275 | void Adafruit_GPS::sendCommand(char *str) { |
SDesign2018 | 26:15df8f054d11 | 276 | gpsSerial->printf("%s",str); |
SDesign2018 | 26:15df8f054d11 | 277 | } |
SDesign2018 | 26:15df8f054d11 | 278 | |
SDesign2018 | 26:15df8f054d11 | 279 | bool Adafruit_GPS::newNMEAreceived(void) { |
SDesign2018 | 26:15df8f054d11 | 280 | return recvdflag; |
SDesign2018 | 26:15df8f054d11 | 281 | } |
SDesign2018 | 26:15df8f054d11 | 282 | |
SDesign2018 | 26:15df8f054d11 | 283 | void Adafruit_GPS::pause(bool p) { |
SDesign2018 | 26:15df8f054d11 | 284 | paused = p; |
SDesign2018 | 26:15df8f054d11 | 285 | } |
SDesign2018 | 26:15df8f054d11 | 286 | |
SDesign2018 | 26:15df8f054d11 | 287 | char *Adafruit_GPS::lastNMEA(void) { |
SDesign2018 | 26:15df8f054d11 | 288 | recvdflag = false; |
SDesign2018 | 26:15df8f054d11 | 289 | return (char *)lastline; |
SDesign2018 | 26:15df8f054d11 | 290 | } |
SDesign2018 | 26:15df8f054d11 | 291 | |
SDesign2018 | 26:15df8f054d11 | 292 | // read a Hex value and return the decimal equivalent |
SDesign2018 | 26:15df8f054d11 | 293 | uint8_t Adafruit_GPS::parseHex(char c) { |
SDesign2018 | 26:15df8f054d11 | 294 | if (c < '0') |
SDesign2018 | 26:15df8f054d11 | 295 | return 0; |
SDesign2018 | 26:15df8f054d11 | 296 | if (c <= '9') |
SDesign2018 | 26:15df8f054d11 | 297 | return c - '0'; |
SDesign2018 | 26:15df8f054d11 | 298 | if (c < 'A') |
SDesign2018 | 26:15df8f054d11 | 299 | return 0; |
SDesign2018 | 26:15df8f054d11 | 300 | if (c <= 'F') |
SDesign2018 | 26:15df8f054d11 | 301 | return (c - 'A')+10; |
SDesign2018 | 26:15df8f054d11 | 302 | } |
SDesign2018 | 26:15df8f054d11 | 303 | |
SDesign2018 | 26:15df8f054d11 | 304 | bool Adafruit_GPS::waitForSentence(char *wait4me, uint8_t max) { |
SDesign2018 | 26:15df8f054d11 | 305 | char str[20]; |
SDesign2018 | 26:15df8f054d11 | 306 | |
SDesign2018 | 26:15df8f054d11 | 307 | uint8_t i=0; |
SDesign2018 | 26:15df8f054d11 | 308 | while (i < max) { |
SDesign2018 | 26:15df8f054d11 | 309 | if (newNMEAreceived()) { |
SDesign2018 | 26:15df8f054d11 | 310 | char *nmea = lastNMEA(); |
SDesign2018 | 26:15df8f054d11 | 311 | strncpy(str, nmea, 20); |
SDesign2018 | 26:15df8f054d11 | 312 | str[19] = 0; |
SDesign2018 | 26:15df8f054d11 | 313 | i++; |
SDesign2018 | 26:15df8f054d11 | 314 | |
SDesign2018 | 26:15df8f054d11 | 315 | if (strstr(str, wait4me)) |
SDesign2018 | 26:15df8f054d11 | 316 | return true; |
SDesign2018 | 26:15df8f054d11 | 317 | } |
SDesign2018 | 26:15df8f054d11 | 318 | } |
SDesign2018 | 26:15df8f054d11 | 319 | |
SDesign2018 | 26:15df8f054d11 | 320 | return false; |
SDesign2018 | 26:15df8f054d11 | 321 | } |
SDesign2018 | 26:15df8f054d11 | 322 | |
SDesign2018 | 26:15df8f054d11 | 323 | bool Adafruit_GPS::LOCUS_StartLogger(void) { |
SDesign2018 | 26:15df8f054d11 | 324 | sendCommand(PMTK_LOCUS_STARTLOG); |
SDesign2018 | 26:15df8f054d11 | 325 | recvdflag = false; |
SDesign2018 | 26:15df8f054d11 | 326 | return waitForSentence(PMTK_LOCUS_LOGSTARTED); |
SDesign2018 | 26:15df8f054d11 | 327 | } |
SDesign2018 | 26:15df8f054d11 | 328 | |
SDesign2018 | 26:15df8f054d11 | 329 | bool Adafruit_GPS::LOCUS_ReadStatus(void) { |
SDesign2018 | 26:15df8f054d11 | 330 | sendCommand(PMTK_LOCUS_QUERY_STATUS); |
SDesign2018 | 26:15df8f054d11 | 331 | |
SDesign2018 | 26:15df8f054d11 | 332 | if (! waitForSentence("$PMTKLOG")) |
SDesign2018 | 26:15df8f054d11 | 333 | return false; |
SDesign2018 | 26:15df8f054d11 | 334 | |
SDesign2018 | 26:15df8f054d11 | 335 | char *response = lastNMEA(); |
SDesign2018 | 26:15df8f054d11 | 336 | uint16_t parsed[10]; |
SDesign2018 | 26:15df8f054d11 | 337 | uint8_t i; |
SDesign2018 | 26:15df8f054d11 | 338 | |
SDesign2018 | 26:15df8f054d11 | 339 | for (i=0; i<10; i++) parsed[i] = -1; |
SDesign2018 | 26:15df8f054d11 | 340 | |
SDesign2018 | 26:15df8f054d11 | 341 | response = strchr(response, ','); |
SDesign2018 | 26:15df8f054d11 | 342 | for (i=0; i<10; i++) { |
SDesign2018 | 26:15df8f054d11 | 343 | if (!response || (response[0] == 0) || (response[0] == '*')) |
SDesign2018 | 26:15df8f054d11 | 344 | break; |
SDesign2018 | 26:15df8f054d11 | 345 | response++; |
SDesign2018 | 26:15df8f054d11 | 346 | parsed[i]=0; |
SDesign2018 | 26:15df8f054d11 | 347 | while ((response[0] != ',') && |
SDesign2018 | 26:15df8f054d11 | 348 | (response[0] != '*') && (response[0] != 0)) { |
SDesign2018 | 26:15df8f054d11 | 349 | parsed[i] *= 10; |
SDesign2018 | 26:15df8f054d11 | 350 | char c = response[0]; |
SDesign2018 | 26:15df8f054d11 | 351 | if (isdigit(c)) |
SDesign2018 | 26:15df8f054d11 | 352 | parsed[i] += c - '0'; |
SDesign2018 | 26:15df8f054d11 | 353 | else |
SDesign2018 | 26:15df8f054d11 | 354 | parsed[i] = c; |
SDesign2018 | 26:15df8f054d11 | 355 | response++; |
SDesign2018 | 26:15df8f054d11 | 356 | } |
SDesign2018 | 26:15df8f054d11 | 357 | } |
SDesign2018 | 26:15df8f054d11 | 358 | LOCUS_serial = parsed[0]; |
SDesign2018 | 26:15df8f054d11 | 359 | LOCUS_type = parsed[1]; |
SDesign2018 | 26:15df8f054d11 | 360 | if (isalpha(parsed[2])) { |
SDesign2018 | 26:15df8f054d11 | 361 | parsed[2] = parsed[2] - 'a' + 10; |
SDesign2018 | 26:15df8f054d11 | 362 | } |
SDesign2018 | 26:15df8f054d11 | 363 | LOCUS_mode = parsed[2]; |
SDesign2018 | 26:15df8f054d11 | 364 | LOCUS_config = parsed[3]; |
SDesign2018 | 26:15df8f054d11 | 365 | LOCUS_interval = parsed[4]; |
SDesign2018 | 26:15df8f054d11 | 366 | LOCUS_distance = parsed[5]; |
SDesign2018 | 26:15df8f054d11 | 367 | LOCUS_speed = parsed[6]; |
SDesign2018 | 26:15df8f054d11 | 368 | LOCUS_status = !parsed[7]; |
SDesign2018 | 26:15df8f054d11 | 369 | LOCUS_records = parsed[8]; |
SDesign2018 | 26:15df8f054d11 | 370 | LOCUS_percent = parsed[9]; |
SDesign2018 | 26:15df8f054d11 | 371 | |
SDesign2018 | 26:15df8f054d11 | 372 | return true; |
SDesign2018 | 26:15df8f054d11 | 373 | } |
SDesign2018 | 26:15df8f054d11 | 374 | |
SDesign2018 | 26:15df8f054d11 | 375 | // Standby Mode Switches |
SDesign2018 | 26:15df8f054d11 | 376 | bool Adafruit_GPS::standby(void) { |
SDesign2018 | 26:15df8f054d11 | 377 | if (inStandbyMode) { |
SDesign2018 | 26:15df8f054d11 | 378 | return false; // Returns false if already in standby mode, so that you do not wake it up by sending commands to GPS |
SDesign2018 | 26:15df8f054d11 | 379 | } |
SDesign2018 | 26:15df8f054d11 | 380 | else { |
SDesign2018 | 26:15df8f054d11 | 381 | inStandbyMode = true; |
SDesign2018 | 26:15df8f054d11 | 382 | sendCommand(PMTK_STANDBY); |
SDesign2018 | 26:15df8f054d11 | 383 | //return waitForSentence(PMTK_STANDBY_SUCCESS); // don't seem to be fast enough to catch the message, or something else just is not working |
SDesign2018 | 26:15df8f054d11 | 384 | return true; |
SDesign2018 | 26:15df8f054d11 | 385 | } |
SDesign2018 | 26:15df8f054d11 | 386 | } |
SDesign2018 | 26:15df8f054d11 | 387 | |
SDesign2018 | 26:15df8f054d11 | 388 | bool Adafruit_GPS::wakeup(void) { |
SDesign2018 | 26:15df8f054d11 | 389 | if (inStandbyMode) { |
SDesign2018 | 26:15df8f054d11 | 390 | inStandbyMode = false; |
SDesign2018 | 26:15df8f054d11 | 391 | sendCommand(""); // send byte to wake it up |
SDesign2018 | 26:15df8f054d11 | 392 | return waitForSentence(PMTK_AWAKE); |
SDesign2018 | 26:15df8f054d11 | 393 | } |
SDesign2018 | 26:15df8f054d11 | 394 | else { |
SDesign2018 | 26:15df8f054d11 | 395 | return false; // Returns false if not in standby mode, nothing to wakeup |
SDesign2018 | 26:15df8f054d11 | 396 | } |
SDesign2018 | 26:15df8f054d11 | 397 | } |
SDesign2018 | 26:15df8f054d11 | 398 | |
SDesign2018 | 26:15df8f054d11 | 399 | |
SDesign2018 | 26:15df8f054d11 | 400 | |
SDesign2018 | 26:15df8f054d11 | 401 | |
SDesign2018 | 26:15df8f054d11 | 402 | /////FOR GPS-----------------ABOVE------------------------------------- |
SDesign2018 | 26:15df8f054d11 | 403 | |
SDesign2018 | 26:15df8f054d11 | 404 | |
SDesign2018 | 26:15df8f054d11 | 405 | ///////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 406 | // -------------------- DOT LIBRARY REQUIRED ------------------------------// |
SDesign2018 | 26:15df8f054d11 | 407 | // * Because these example programs can be used for both mDot and xDot // |
SDesign2018 | 26:15df8f054d11 | 408 | // devices, the LoRa stack is not included. The libmDot library should // |
SDesign2018 | 26:15df8f054d11 | 409 | // be imported if building for mDot devices. The libxDot library // |
SDesign2018 | 26:15df8f054d11 | 410 | // should be imported if building for xDot devices. // |
SDesign2018 | 26:15df8f054d11 | 411 | // * https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/ // |
SDesign2018 | 26:15df8f054d11 | 412 | // * https://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/ // |
SDesign2018 | 26:15df8f054d11 | 413 | // * https://developer.mbed.org/teams/MultiTech/code/libxDot-dev-mbed5/ // |
SDesign2018 | 26:15df8f054d11 | 414 | // * https://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/ // |
SDesign2018 | 26:15df8f054d11 | 415 | ///////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 416 | |
SDesign2018 | 26:15df8f054d11 | 417 | |
SDesign2018 | 26:15df8f054d11 | 418 | ///////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 419 | // * these options must match between the two devices in // |
SDesign2018 | 26:15df8f054d11 | 420 | // order for communication to be successful |
SDesign2018 | 26:15df8f054d11 | 421 | //-------------------MDOT variables------------------------// |
SDesign2018 | 26:15df8f054d11 | 422 | ///////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 423 | static uint8_t network_address[] = { 0x00, 0x11, 0x22, 0x33 }; |
SDesign2018 | 26:15df8f054d11 | 424 | static uint8_t network_session_key[] = { 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33 }; |
SDesign2018 | 26:15df8f054d11 | 425 | static uint8_t data_session_key[] = { 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00, 0x33, 0x22, 0x11, 0x00 }; |
SDesign2018 | 26:15df8f054d11 | 426 | |
SDesign2018 | 26:15df8f054d11 | 427 | mDot* dot = NULL; |
SDesign2018 | 26:15df8f054d11 | 428 | lora::ChannelPlan* plan = NULL; |
SDesign2018 | 26:15df8f054d11 | 429 | //--------------End of MDOT variables-------------------// |
SDesign2018 | 26:15df8f054d11 | 430 | |
SDesign2018 | 28:29702434319d | 431 | // PC serial communication |
SDesign2018 | 26:15df8f054d11 | 432 | Serial pc(USBTX, USBRX); |
SDesign2018 | 26:15df8f054d11 | 433 | |
SDesign2018 | 26:15df8f054d11 | 434 | // ADXL372 Slave I2C |
SDesign2018 | 26:15df8f054d11 | 435 | I2C ADXL372(I2C_SDA, I2C_SCL); // (D14,D15) (MISO, CS) |
SDesign2018 | 26:15df8f054d11 | 436 | |
SDesign2018 | 26:15df8f054d11 | 437 | // ADT7410 Temperature |
SDesign2018 | 26:15df8f054d11 | 438 | I2C ADT7410(I2C_SDA, I2C_SCL); // Attempt at making I2C connection to slaves (D14,D15) |
SDesign2018 | 26:15df8f054d11 | 439 | InterruptIn ADT7410_Int(D2); // Allow this pin for ADT7410 Interrupt critical temperature notice |
SDesign2018 | 26:15df8f054d11 | 440 | |
SDesign2018 | 26:15df8f054d11 | 441 | // DS7505s Temperature |
SDesign2018 | 26:15df8f054d11 | 442 | I2C DS7505(I2C_SDA, I2C_SCL); // Attempt at making I2C connection to slaves (D14,D15) |
SDesign2018 | 26:15df8f054d11 | 443 | |
SDesign2018 | 26:15df8f054d11 | 444 | // Create reocurring interrupt function that could be used to periodically take temperatures |
SDesign2018 | 26:15df8f054d11 | 445 | // Not working right now due to some mutex initialize error |
SDesign2018 | 26:15df8f054d11 | 446 | // Suspect that it is due to it having be a RTOS task thing |
SDesign2018 | 26:15df8f054d11 | 447 | // Should probably go back to using an in processor timer interrupt instead of mbed |
SDesign2018 | 26:15df8f054d11 | 448 | |
SDesign2018 | 26:15df8f054d11 | 449 | const int ADT7410_Address_7BIT = 0x49; // A0 set HIGH and A1 set LOW |
SDesign2018 | 26:15df8f054d11 | 450 | const int ADT7410_Address_8BIT = ADT7410_Address_7BIT << 1; // Shift 1 bit to left for R/~W bit, and basic I2C format |
SDesign2018 | 26:15df8f054d11 | 451 | |
SDesign2018 | 26:15df8f054d11 | 452 | const int ADXL372_Address_7bit = 0x1D; // Address for the I2C if MISO pulled low, 0x53 if pulled high |
SDesign2018 | 26:15df8f054d11 | 453 | const int ADXL372_Address_8bit = ADXL372_Address_7bit << 1; // Same |
SDesign2018 | 26:15df8f054d11 | 454 | |
SDesign2018 | 28:29702434319d | 455 | // Used by all sensors to pass register address of device |
SDesign2018 | 28:29702434319d | 456 | int regAddress; |
SDesign2018 | 26:15df8f054d11 | 457 | |
SDesign2018 | 26:15df8f054d11 | 458 | /* |
SDesign2018 | 26:15df8f054d11 | 459 | * Variables used for ADT7410 Temperature |
SDesign2018 | 26:15df8f054d11 | 460 | */ |
SDesign2018 | 26:15df8f054d11 | 461 | // Points to the returned char pointer from called functions |
SDesign2018 | 26:15df8f054d11 | 462 | char * rawTempValues; // Could change to uint8_t, same for other char pointers |
SDesign2018 | 26:15df8f054d11 | 463 | uint16_t convertedTempValue; // Data values must be uint16_t for conversion and send prep |
SDesign2018 | 26:15df8f054d11 | 464 | uint16_t temperatureBuffer[BUFFER_SIZE]; |
SDesign2018 | 26:15df8f054d11 | 465 | |
SDesign2018 | 26:15df8f054d11 | 466 | |
SDesign2018 | 26:15df8f054d11 | 467 | /* |
SDesign2018 | 26:15df8f054d11 | 468 | * Variables used for mDot |
SDesign2018 | 26:15df8f054d11 | 469 | */ |
SDesign2018 | 26:15df8f054d11 | 470 | uint32_t tx_frequency; |
SDesign2018 | 26:15df8f054d11 | 471 | uint8_t tx_datarate; |
SDesign2018 | 26:15df8f054d11 | 472 | uint8_t tx_power; |
SDesign2018 | 26:15df8f054d11 | 473 | uint8_t frequency_band; |
SDesign2018 | 26:15df8f054d11 | 474 | |
SDesign2018 | 26:15df8f054d11 | 475 | |
SDesign2018 | 26:15df8f054d11 | 476 | |
SDesign2018 | 26:15df8f054d11 | 477 | /* |
SDesign2018 | 26:15df8f054d11 | 478 | * Variables used for ADXL372 Accelerometer |
SDesign2018 | 26:15df8f054d11 | 479 | */ |
SDesign2018 | 26:15df8f054d11 | 480 | char *accelValues; |
SDesign2018 | 26:15df8f054d11 | 481 | char Xmsb; // Gets most significant byte |
SDesign2018 | 26:15df8f054d11 | 482 | char Xlsb; // Gets least significant byte |
SDesign2018 | 26:15df8f054d11 | 483 | char Ymsb; |
SDesign2018 | 26:15df8f054d11 | 484 | char Ylsb; |
SDesign2018 | 26:15df8f054d11 | 485 | char Zmsb; |
SDesign2018 | 26:15df8f054d11 | 486 | char Zlsb; |
SDesign2018 | 26:15df8f054d11 | 487 | uint16_t XData; |
SDesign2018 | 26:15df8f054d11 | 488 | uint16_t YData; |
SDesign2018 | 26:15df8f054d11 | 489 | uint16_t ZData; |
SDesign2018 | 26:15df8f054d11 | 490 | |
SDesign2018 | 27:5db200a4d496 | 491 | |
SDesign2018 | 26:15df8f054d11 | 492 | uint16_t XDataInterrupt[BUFFER_SIZE]; |
SDesign2018 | 26:15df8f054d11 | 493 | uint16_t YDataInterrupt[BUFFER_SIZE]; |
SDesign2018 | 26:15df8f054d11 | 494 | uint16_t ZDataInterrupt[BUFFER_SIZE]; |
SDesign2018 | 26:15df8f054d11 | 495 | |
SDesign2018 | 26:15df8f054d11 | 496 | |
SDesign2018 | 26:15df8f054d11 | 497 | |
SDesign2018 | 26:15df8f054d11 | 498 | /* |
SDesign2018 | 26:15df8f054d11 | 499 | * Variables used for interrupt triggers |
SDesign2018 | 26:15df8f054d11 | 500 | */ |
SDesign2018 | 26:15df8f054d11 | 501 | bool takeTemperature = false; // Trigger temperature reading |
SDesign2018 | 26:15df8f054d11 | 502 | bool takeAccelerometer = false; // Trigger accelerometer reading |
SDesign2018 | 26:15df8f054d11 | 503 | bool periodicReadingTrigger = false; // Trigger reading both accelerometer and temperature |
SDesign2018 | 26:15df8f054d11 | 504 | |
SDesign2018 | 26:15df8f054d11 | 505 | /* |
SDesign2018 | 26:15df8f054d11 | 506 | * Prototype functions |
SDesign2018 | 26:15df8f054d11 | 507 | */ |
SDesign2018 | 26:15df8f054d11 | 508 | |
SDesign2018 | 28:29702434319d | 509 | std::string convertInt(int number); |
SDesign2018 | 26:15df8f054d11 | 510 | char twosComplementConversion(char value); |
SDesign2018 | 26:15df8f054d11 | 511 | |
SDesign2018 | 26:15df8f054d11 | 512 | void ADXL372Initialize(void); |
SDesign2018 | 26:15df8f054d11 | 513 | void ADXL372Reset(void); |
SDesign2018 | 26:15df8f054d11 | 514 | void I2CSelfTest(void); |
SDesign2018 | 26:15df8f054d11 | 515 | void accelerometerI2CWrite(uint8_t hexAddress, uint8_t hexData); |
SDesign2018 | 26:15df8f054d11 | 516 | char * accelerometerI2CRead(int hexAddress); |
SDesign2018 | 26:15df8f054d11 | 517 | |
SDesign2018 | 26:15df8f054d11 | 518 | void ADT7410Initialize(void); |
SDesign2018 | 26:15df8f054d11 | 519 | void ADT7410Write(unsigned char registerAddress, unsigned char data); |
SDesign2018 | 26:15df8f054d11 | 520 | char * ADT7410Read(int hex); |
SDesign2018 | 26:15df8f054d11 | 521 | |
SDesign2018 | 26:15df8f054d11 | 522 | |
SDesign2018 | 26:15df8f054d11 | 523 | /* |
SDesign2018 | 26:15df8f054d11 | 524 | * Interrupt functions |
SDesign2018 | 26:15df8f054d11 | 525 | */ |
SDesign2018 | 26:15df8f054d11 | 526 | void CriticalTemperatureInterrupt(void){ |
SDesign2018 | 26:15df8f054d11 | 527 | takeTemperature = true; // Take temperature because something happened |
SDesign2018 | 26:15df8f054d11 | 528 | } |
SDesign2018 | 26:15df8f054d11 | 529 | |
SDesign2018 | 26:15df8f054d11 | 530 | void CriticalAccelerometerInterrupt(void){ |
SDesign2018 | 26:15df8f054d11 | 531 | takeAccelerometer = true; // Take accelerometer because something happened |
SDesign2018 | 26:15df8f054d11 | 532 | } |
SDesign2018 | 26:15df8f054d11 | 533 | |
SDesign2018 | 28:29702434319d | 534 | // This is where all the reading and sending takes place |
SDesign2018 | 26:15df8f054d11 | 535 | void takePeriodicReading(std::vector<uint8_t> tx_data){ |
SDesign2018 | 26:15df8f054d11 | 536 | pc.printf("Regular periodic reading \n\r"); |
SDesign2018 | 26:15df8f054d11 | 537 | /* |
SDesign2018 | 26:15df8f054d11 | 538 | * Taking accelerometer data |
SDesign2018 | 26:15df8f054d11 | 539 | */ |
SDesign2018 | 26:15df8f054d11 | 540 | regAddress = 0x08; // This is the register address for XData |
SDesign2018 | 26:15df8f054d11 | 541 | accelValues = accelerometerI2CRead(regAddress); // Get the dadta |
SDesign2018 | 26:15df8f054d11 | 542 | // Raw Data |
SDesign2018 | 26:15df8f054d11 | 543 | Xmsb = *(accelValues + 0); |
SDesign2018 | 26:15df8f054d11 | 544 | Xlsb = *(accelValues + 1); |
SDesign2018 | 26:15df8f054d11 | 545 | Ymsb = *(accelValues + 2); |
SDesign2018 | 26:15df8f054d11 | 546 | Ylsb = *(accelValues + 3); |
SDesign2018 | 26:15df8f054d11 | 547 | Zmsb = *(accelValues + 4); |
SDesign2018 | 26:15df8f054d11 | 548 | Zlsb = *(accelValues + 5); |
SDesign2018 | 26:15df8f054d11 | 549 | |
SDesign2018 | 26:15df8f054d11 | 550 | // Combine two bytes into short int, remove last 4 bits because 12bit resolution |
SDesign2018 | 26:15df8f054d11 | 551 | XData = (Xmsb << 8 | Xlsb) >> 4; |
SDesign2018 | 26:15df8f054d11 | 552 | YData = (Ymsb << 8 | Ylsb) >> 4; |
SDesign2018 | 26:15df8f054d11 | 553 | ZData = (Zmsb << 8 | Zlsb) >> 4; |
SDesign2018 | 26:15df8f054d11 | 554 | |
SDesign2018 | 26:15df8f054d11 | 555 | // Check if twos complement is needed |
SDesign2018 | 26:15df8f054d11 | 556 | //XData = twosComplementConversion(XData); |
SDesign2018 | 26:15df8f054d11 | 557 | //YData = twosComplementConversion(YData); |
SDesign2018 | 26:15df8f054d11 | 558 | //ZData = twosComplementConversion(ZData); |
SDesign2018 | 26:15df8f054d11 | 559 | |
SDesign2018 | 26:15df8f054d11 | 560 | // Split Complemented Data |
SDesign2018 | 26:15df8f054d11 | 561 | Xlsb = XData & 0xff; // Split the lower 8 bits here |
SDesign2018 | 26:15df8f054d11 | 562 | Xmsb = XData >> 8; // Split the higher 8 bits here |
SDesign2018 | 26:15df8f054d11 | 563 | |
SDesign2018 | 26:15df8f054d11 | 564 | Ylsb = YData & 0xff; // Split the lower 8 bits here |
SDesign2018 | 26:15df8f054d11 | 565 | Ymsb = YData >> 8; // Split the higher 8 bits here |
SDesign2018 | 26:15df8f054d11 | 566 | |
SDesign2018 | 26:15df8f054d11 | 567 | Zlsb = ZData & 0xff; // Split the lower 8bits here |
SDesign2018 | 26:15df8f054d11 | 568 | Zmsb = ZData >> 8; // Split the higher 8bits here |
SDesign2018 | 26:15df8f054d11 | 569 | |
SDesign2018 | 27:5db200a4d496 | 570 | |
SDesign2018 | 27:5db200a4d496 | 571 | |
SDesign2018 | 26:15df8f054d11 | 572 | /* |
SDesign2018 | 26:15df8f054d11 | 573 | * Taking temperature data |
SDesign2018 | 26:15df8f054d11 | 574 | */ |
SDesign2018 | 26:15df8f054d11 | 575 | regAddress = 0x00; |
SDesign2018 | 26:15df8f054d11 | 576 | rawTempValues = ADT7410Read(regAddress); |
SDesign2018 | 26:15df8f054d11 | 577 | convertedTempValue = ((*(rawTempValues + 0) << 8) | *(rawTempValues + 1)) >> 3; // Combine the two bytes into |
SDesign2018 | 26:15df8f054d11 | 578 | // a short int variable(16 bits), remove last 3 bits |
SDesign2018 | 26:15df8f054d11 | 579 | |
SDesign2018 | 26:15df8f054d11 | 580 | |
SDesign2018 | 26:15df8f054d11 | 581 | c = myGPS.read(); //queries the GPS |
SDesign2018 | 26:15df8f054d11 | 582 | |
SDesign2018 | 26:15df8f054d11 | 583 | // if (c) { pc.printf("%c", c); } //this line will echo the GPS data if not paused |
SDesign2018 | 26:15df8f054d11 | 584 | //check if we recieved a new message from GPS, if so, attempt to parse it, |
SDesign2018 | 26:15df8f054d11 | 585 | if ( myGPS.newNMEAreceived() ) { |
SDesign2018 | 26:15df8f054d11 | 586 | if ( !myGPS.parse(myGPS.lastNMEA()) ) { |
SDesign2018 | 26:15df8f054d11 | 587 | |
SDesign2018 | 26:15df8f054d11 | 588 | } |
SDesign2018 | 26:15df8f054d11 | 589 | } |
SDesign2018 | 29:0f0a059f023e | 590 | pc.printf("Refresh timer: %d\n\r", refresh_Timer.read_ms()); |
SDesign2018 | 26:15df8f054d11 | 591 | //check if enough time has passed to warrant printing GPS info to screen |
SDesign2018 | 26:15df8f054d11 | 592 | //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing |
SDesign2018 | 26:15df8f054d11 | 593 | if (refresh_Timer.read_ms() >= refresh_Time) { |
SDesign2018 | 26:15df8f054d11 | 594 | refresh_Timer.reset(); |
SDesign2018 | 26:15df8f054d11 | 595 | |
SDesign2018 | 26:15df8f054d11 | 596 | /* pc.printf("Time: %d:%d:%d.%u\n", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); |
SDesign2018 | 26:15df8f054d11 | 597 | pc.printf("Date: %d/%d/20%d\n", myGPS.day, myGPS.month, myGPS.year); |
SDesign2018 | 26:15df8f054d11 | 598 | pc.printf("Fix: %d\n", (int) myGPS.fix); |
SDesign2018 | 26:15df8f054d11 | 599 | pc.printf("Quality: %d\n", (int) myGPS.fixquality);*/ |
SDesign2018 | 26:15df8f054d11 | 600 | if (myGPS.fix) { |
SDesign2018 | 26:15df8f054d11 | 601 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 602 | pc.printf("GPS log:\n"); |
SDesign2018 | 26:15df8f054d11 | 603 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 604 | pc.printf("Time(GMT): %d:%d:%d.%u\n", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); |
SDesign2018 | 26:15df8f054d11 | 605 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 606 | pc.printf("Date: %d/%d/20%d\n", myGPS.day, myGPS.month, myGPS.year); |
SDesign2018 | 26:15df8f054d11 | 607 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 608 | pc.printf("Fix: %d\n", (int) myGPS.fix); |
SDesign2018 | 26:15df8f054d11 | 609 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 610 | pc.printf("Quality: %d\n", (int) myGPS.fixquality); |
SDesign2018 | 26:15df8f054d11 | 611 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 612 | pc.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); |
SDesign2018 | 26:15df8f054d11 | 613 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 614 | pc.printf("Speed: %5.2f knots\n", myGPS.speed); |
SDesign2018 | 26:15df8f054d11 | 615 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 616 | pc.printf("Angle: %5.2f\n", myGPS.angle); |
SDesign2018 | 26:15df8f054d11 | 617 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 618 | pc.printf("Altitude: %5.2f\n", myGPS.altitude); |
SDesign2018 | 26:15df8f054d11 | 619 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 620 | pc.printf("Satellites: %d\n", myGPS.satellites); |
SDesign2018 | 26:15df8f054d11 | 621 | pc.printf("\r"); |
SDesign2018 | 26:15df8f054d11 | 622 | } |
SDesign2018 | 26:15df8f054d11 | 623 | } |
SDesign2018 | 26:15df8f054d11 | 624 | |
SDesign2018 | 26:15df8f054d11 | 625 | pc.printf("Accelerometer::: "); |
SDesign2018 | 26:15df8f054d11 | 626 | pc.printf("X: 0x%x | Y: 0x%x | Z: 0x%x\n\r", XData, YData, ZData); |
SDesign2018 | 26:15df8f054d11 | 627 | //pc.printf("X: 0x%x %x | Y: 0x%x %x | Z: 0x%x %x\n\r", Xmsb, Xlsb, Ymsb, Ylsb,Zmsb, Zlsb); |
SDesign2018 | 26:15df8f054d11 | 628 | pc.printf("Temperature::: "); |
SDesign2018 | 26:15df8f054d11 | 629 | pc.printf("Celsius: 0x%x\n\r", convertedTempValue); |
SDesign2018 | 26:15df8f054d11 | 630 | |
SDesign2018 | 26:15df8f054d11 | 631 | |
SDesign2018 | 26:15df8f054d11 | 632 | // Push 1 for temperature |
SDesign2018 | 26:15df8f054d11 | 633 | tx_data.push_back(1); |
SDesign2018 | 26:15df8f054d11 | 634 | tx_data.push_back((convertedTempValue >> 8) & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 635 | tx_data.push_back(convertedTempValue & 0xFF); |
SDesign2018 | 29:0f0a059f023e | 636 | |
SDesign2018 | 26:15df8f054d11 | 637 | // Push 2 for AccelerometerX |
SDesign2018 | 26:15df8f054d11 | 638 | tx_data.push_back(2); |
SDesign2018 | 26:15df8f054d11 | 639 | tx_data.push_back((XData >> 8) & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 640 | tx_data.push_back(XData & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 641 | // Push 3 for AccelerometerY |
SDesign2018 | 26:15df8f054d11 | 642 | tx_data.push_back(3); |
SDesign2018 | 26:15df8f054d11 | 643 | tx_data.push_back((YData >> 8) & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 644 | tx_data.push_back(YData & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 645 | // Push 4 for AccelerometerZ |
SDesign2018 | 26:15df8f054d11 | 646 | tx_data.push_back(4); |
SDesign2018 | 26:15df8f054d11 | 647 | tx_data.push_back((ZData >> 8) & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 648 | tx_data.push_back(ZData & 0xFF); |
SDesign2018 | 26:15df8f054d11 | 649 | logInfo("Temperautre: %lu [0x%04X]", convertedTempValue, convertedTempValue); |
SDesign2018 | 26:15df8f054d11 | 650 | send_data(tx_data); |
SDesign2018 | 28:29702434319d | 651 | |
SDesign2018 | 29:0f0a059f023e | 652 | // Time |
SDesign2018 | 29:0f0a059f023e | 653 | //tx_data.push_back(7); |
SDesign2018 | 29:0f0a059f023e | 654 | //tx_data.push_back(); |
SDesign2018 | 29:0f0a059f023e | 655 | // GPS |
SDesign2018 | 29:0f0a059f023e | 656 | |
SDesign2018 | 29:0f0a059f023e | 657 | |
SDesign2018 | 29:0f0a059f023e | 658 | |
SDesign2018 | 28:29702434319d | 659 | |
SDesign2018 | 28:29702434319d | 660 | // Save data |
SDesign2018 | 28:29702434319d | 661 | // fprintf(fp,"%d,%d,%d,%d,%f,%f,%d/%d/%d,%d:%d:%d:%d\n", |
SDesign2018 | 28:29702434319d | 662 | // convertedTempValue, |
SDesign2018 | 28:29702434319d | 663 | // XData, YData, ZData, |
SDesign2018 | 28:29702434319d | 664 | // myGPS.longitude, myGPS.latitude, |
SDesign2018 | 28:29702434319d | 665 | // myGPS.month, myGPS.day, myGPS.year, |
SDesign2018 | 28:29702434319d | 666 | // myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); |
SDesign2018 | 28:29702434319d | 667 | // periodicReadingTrigger = false; // Flip back to no trigger |
SDesign2018 | 28:29702434319d | 668 | |
SDesign2018 | 26:15df8f054d11 | 669 | } |
SDesign2018 | 26:15df8f054d11 | 670 | |
SDesign2018 | 26:15df8f054d11 | 671 | void takePeriodicReadingTicker(void){ |
SDesign2018 | 26:15df8f054d11 | 672 | periodicReadingTrigger = true; |
SDesign2018 | 26:15df8f054d11 | 673 | } |
SDesign2018 | 26:15df8f054d11 | 674 | |
SDesign2018 | 26:15df8f054d11 | 675 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 676 | /* _ |
SDesign2018 | 26:15df8f054d11 | 677 | ____ ___ ____ _(_)___ |
SDesign2018 | 26:15df8f054d11 | 678 | / __ `__ \/ __ `/ / __ \ |
SDesign2018 | 26:15df8f054d11 | 679 | / / / / / / /_/ / / / / / |
SDesign2018 | 26:15df8f054d11 | 680 | /_/ /_/ /_/\__,_/_/_/ /_/ |
SDesign2018 | 26:15df8f054d11 | 681 | |
SDesign2018 | 26:15df8f054d11 | 682 | *////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 683 | int main(void) |
SDesign2018 | 26:15df8f054d11 | 684 | { |
SDesign2018 | 28:29702434319d | 685 | |
SDesign2018 | 26:15df8f054d11 | 686 | // Custom event handler for automatically displaying RX data |
SDesign2018 | 26:15df8f054d11 | 687 | //interruptEverything.attach(&interruptReadTemperature, 7.0); |
SDesign2018 | 26:15df8f054d11 | 688 | RadioEvent events; |
SDesign2018 | 28:29702434319d | 689 | |
SDesign2018 | 26:15df8f054d11 | 690 | // Change baud rate in serial terminal to this value |
SDesign2018 | 26:15df8f054d11 | 691 | pc.baud(115200); |
SDesign2018 | 26:15df8f054d11 | 692 | ADXL372.frequency(300000); // I2C devices are connected to the same clock |
SDesign2018 | 26:15df8f054d11 | 693 | ADT7410.frequency(300000); // Redundant but whatever |
SDesign2018 | 26:15df8f054d11 | 694 | ADT7410_Int.rise(&CriticalTemperatureInterrupt); |
SDesign2018 | 26:15df8f054d11 | 695 | myGPS.begin(9600); //sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *) |
SDesign2018 | 26:15df8f054d11 | 696 | //a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf |
SDesign2018 | 26:15df8f054d11 | 697 | |
SDesign2018 | 26:15df8f054d11 | 698 | myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation |
SDesign2018 | 26:15df8f054d11 | 699 | myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); |
SDesign2018 | 26:15df8f054d11 | 700 | myGPS.sendCommand(PGCMD_ANTENNA); |
SDesign2018 | 26:15df8f054d11 | 701 | |
SDesign2018 | 29:0f0a059f023e | 702 | refresh_Timer.start(); //starts the clock on the timer |
SDesign2018 | 29:0f0a059f023e | 703 | |
SDesign2018 | 28:29702434319d | 704 | // current date/time based on current system |
SDesign2018 | 28:29702434319d | 705 | std::time_t now = time(0); |
SDesign2018 | 28:29702434319d | 706 | |
SDesign2018 | 28:29702434319d | 707 | // convert now to string format |
SDesign2018 | 28:29702434319d | 708 | char* dt = ctime(&now); |
SDesign2018 | 28:29702434319d | 709 | // To access individual times |
SDesign2018 | 28:29702434319d | 710 | tm *ltm = localtime(&now); |
SDesign2018 | 28:29702434319d | 711 | |
SDesign2018 | 28:29702434319d | 712 | std::string file_Date = convertInt(ltm->tm_mon) + "-" + |
SDesign2018 | 28:29702434319d | 713 | convertInt(ltm->tm_mday) + "-" + |
SDesign2018 | 28:29702434319d | 714 | convertInt(ltm->tm_year + 1900) + ".txt"; |
SDesign2018 | 28:29702434319d | 715 | std::string directory = "sd/mytest/"; |
SDesign2018 | 28:29702434319d | 716 | std::string fileName = directory + file_Date; |
SDesign2018 | 28:29702434319d | 717 | |
SDesign2018 | 29:0f0a059f023e | 718 | // Show the file name |
SDesign2018 | 29:0f0a059f023e | 719 | pc.printf("%s\n", fileName.c_str()); |
SDesign2018 | 29:0f0a059f023e | 720 | |
SDesign2018 | 29:0f0a059f023e | 721 | // Initialize sensors |
SDesign2018 | 29:0f0a059f023e | 722 | ADT7410Initialize(); |
SDesign2018 | 29:0f0a059f023e | 723 | ADXL372Initialize(); |
SDesign2018 | 29:0f0a059f023e | 724 | |
SDesign2018 | 29:0f0a059f023e | 725 | |
SDesign2018 | 29:0f0a059f023e | 726 | |
SDesign2018 | 26:15df8f054d11 | 727 | |
SDesign2018 | 26:15df8f054d11 | 728 | mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL); |
SDesign2018 | 26:15df8f054d11 | 729 | |
SDesign2018 | 26:15df8f054d11 | 730 | // Sometimes when calling this, it creates error: type specifier expected |
SDesign2018 | 26:15df8f054d11 | 731 | // Even with identical include files I would get this in another workspace. |
SDesign2018 | 26:15df8f054d11 | 732 | plan = new lora::ChannelPlan_US915(); |
SDesign2018 | 26:15df8f054d11 | 733 | |
SDesign2018 | 26:15df8f054d11 | 734 | logInfo("Now asserting"); |
SDesign2018 | 26:15df8f054d11 | 735 | assert(plan); |
SDesign2018 | 26:15df8f054d11 | 736 | |
SDesign2018 | 26:15df8f054d11 | 737 | // Careful when using this. The production ready libmdot-mbed5 has a void constructor |
SDesign2018 | 26:15df8f054d11 | 738 | // Therefore, can only use the libmDot-dev-mbed5 version, for now. |
SDesign2018 | 26:15df8f054d11 | 739 | dot = mDot::getInstance(plan); |
SDesign2018 | 26:15df8f054d11 | 740 | assert(dot); |
SDesign2018 | 26:15df8f054d11 | 741 | |
SDesign2018 | 26:15df8f054d11 | 742 | logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION); |
SDesign2018 | 26:15df8f054d11 | 743 | |
SDesign2018 | 26:15df8f054d11 | 744 | // start from a well-known state |
SDesign2018 | 26:15df8f054d11 | 745 | logInfo("defaulting Dot configuration"); |
SDesign2018 | 26:15df8f054d11 | 746 | dot->resetConfig(); |
SDesign2018 | 26:15df8f054d11 | 747 | |
SDesign2018 | 26:15df8f054d11 | 748 | // make sure library logging is turned on |
SDesign2018 | 26:15df8f054d11 | 749 | dot->setLogLevel(mts::MTSLog::INFO_LEVEL); |
SDesign2018 | 26:15df8f054d11 | 750 | |
SDesign2018 | 26:15df8f054d11 | 751 | // attach the custom events handler |
SDesign2018 | 26:15df8f054d11 | 752 | dot->setEvents(&events); |
SDesign2018 | 26:15df8f054d11 | 753 | |
SDesign2018 | 26:15df8f054d11 | 754 | // update configuration if necessary |
SDesign2018 | 26:15df8f054d11 | 755 | if (dot->getJoinMode() != mDot::PEER_TO_PEER) { |
SDesign2018 | 26:15df8f054d11 | 756 | logInfo("changing network join mode to PEER_TO_PEER"); |
SDesign2018 | 26:15df8f054d11 | 757 | if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) { |
SDesign2018 | 26:15df8f054d11 | 758 | logError("failed to set network join mode to PEER_TO_PEER"); |
SDesign2018 | 26:15df8f054d11 | 759 | } |
SDesign2018 | 26:15df8f054d11 | 760 | } |
SDesign2018 | 26:15df8f054d11 | 761 | |
SDesign2018 | 26:15df8f054d11 | 762 | /* |
SDesign2018 | 26:15df8f054d11 | 763 | * Get the Frequency and then choose transfer frequency, datarate, and power accordingly |
SDesign2018 | 26:15df8f054d11 | 764 | * |
SDesign2018 | 26:15df8f054d11 | 765 | */ |
SDesign2018 | 26:15df8f054d11 | 766 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 767 | frequency_band = dot->getFrequencyBand(); |
SDesign2018 | 26:15df8f054d11 | 768 | switch (frequency_band) { |
SDesign2018 | 26:15df8f054d11 | 769 | case lora::ChannelPlan::EU868_OLD: |
SDesign2018 | 26:15df8f054d11 | 770 | case lora::ChannelPlan::EU868: |
SDesign2018 | 26:15df8f054d11 | 771 | // 250kHz channels achieve higher throughput |
SDesign2018 | 26:15df8f054d11 | 772 | // DR_6 : SF7 @ 250kHz |
SDesign2018 | 26:15df8f054d11 | 773 | // DR_0 - DR_5 (125kHz channels) available but much slower |
SDesign2018 | 26:15df8f054d11 | 774 | tx_frequency = 869850000; |
SDesign2018 | 26:15df8f054d11 | 775 | tx_datarate = lora::DR_6; |
SDesign2018 | 26:15df8f054d11 | 776 | // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7 |
SDesign2018 | 26:15df8f054d11 | 777 | tx_power = 4; |
SDesign2018 | 26:15df8f054d11 | 778 | break; |
SDesign2018 | 26:15df8f054d11 | 779 | |
SDesign2018 | 26:15df8f054d11 | 780 | case lora::ChannelPlan::US915_OLD: |
SDesign2018 | 26:15df8f054d11 | 781 | case lora::ChannelPlan::US915: |
SDesign2018 | 26:15df8f054d11 | 782 | case lora::ChannelPlan::AU915_OLD: |
SDesign2018 | 26:15df8f054d11 | 783 | case lora::ChannelPlan::AU915: |
SDesign2018 | 26:15df8f054d11 | 784 | // 500kHz channels achieve highest throughput |
SDesign2018 | 26:15df8f054d11 | 785 | // DR_8 : SF12 @ 500kHz |
SDesign2018 | 26:15df8f054d11 | 786 | // DR_9 : SF11 @ 500kHz |
SDesign2018 | 26:15df8f054d11 | 787 | // DR_10 : SF10 @ 500kHz |
SDesign2018 | 26:15df8f054d11 | 788 | // DR_11 : SF9 @ 500kHz |
SDesign2018 | 26:15df8f054d11 | 789 | // DR_12 : SF8 @ 500kHz |
SDesign2018 | 26:15df8f054d11 | 790 | // DR_13 : SF7 @ 500kHz |
SDesign2018 | 26:15df8f054d11 | 791 | // DR_0 - DR_3 (125kHz channels) available but much slower |
SDesign2018 | 26:15df8f054d11 | 792 | tx_frequency = 915500000; |
SDesign2018 | 26:15df8f054d11 | 793 | tx_datarate = lora::DR_13; |
SDesign2018 | 26:15df8f054d11 | 794 | // 915 bands have no duty cycle restrictions, set tx power to max |
SDesign2018 | 26:15df8f054d11 | 795 | tx_power = 20; |
SDesign2018 | 26:15df8f054d11 | 796 | break; |
SDesign2018 | 26:15df8f054d11 | 797 | |
SDesign2018 | 26:15df8f054d11 | 798 | case lora::ChannelPlan::AS923: |
SDesign2018 | 26:15df8f054d11 | 799 | case lora::ChannelPlan::AS923_JAPAN: |
SDesign2018 | 26:15df8f054d11 | 800 | // 250kHz channels achieve higher throughput |
SDesign2018 | 26:15df8f054d11 | 801 | // DR_6 : SF7 @ 250kHz |
SDesign2018 | 26:15df8f054d11 | 802 | // DR_0 - DR_5 (125kHz channels) available but much slower |
SDesign2018 | 26:15df8f054d11 | 803 | tx_frequency = 924800000; |
SDesign2018 | 26:15df8f054d11 | 804 | tx_datarate = lora::DR_6; |
SDesign2018 | 26:15df8f054d11 | 805 | tx_power = 16; |
SDesign2018 | 26:15df8f054d11 | 806 | break; |
SDesign2018 | 26:15df8f054d11 | 807 | |
SDesign2018 | 26:15df8f054d11 | 808 | case lora::ChannelPlan::KR920: |
SDesign2018 | 26:15df8f054d11 | 809 | // DR_5 : SF7 @ 125kHz |
SDesign2018 | 26:15df8f054d11 | 810 | tx_frequency = 922700000; |
SDesign2018 | 26:15df8f054d11 | 811 | tx_datarate = lora::DR_5; |
SDesign2018 | 26:15df8f054d11 | 812 | tx_power = 14; |
SDesign2018 | 26:15df8f054d11 | 813 | break; |
SDesign2018 | 26:15df8f054d11 | 814 | |
SDesign2018 | 26:15df8f054d11 | 815 | default: |
SDesign2018 | 26:15df8f054d11 | 816 | while (true) { |
SDesign2018 | 26:15df8f054d11 | 817 | logFatal("no known channel plan in use - extra configuration is needed!"); |
SDesign2018 | 26:15df8f054d11 | 818 | wait(5); |
SDesign2018 | 26:15df8f054d11 | 819 | } |
SDesign2018 | 26:15df8f054d11 | 820 | break; |
SDesign2018 | 26:15df8f054d11 | 821 | } |
SDesign2018 | 26:15df8f054d11 | 822 | ///////////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 823 | |
SDesign2018 | 26:15df8f054d11 | 824 | // in PEER_TO_PEER mode there is no join request/response transaction |
SDesign2018 | 26:15df8f054d11 | 825 | // as long as both Dots are configured correctly, they should be able to communicate |
SDesign2018 | 26:15df8f054d11 | 826 | update_peer_to_peer_config(network_address, network_session_key, data_session_key, tx_frequency, tx_datarate, tx_power); |
SDesign2018 | 26:15df8f054d11 | 827 | |
SDesign2018 | 26:15df8f054d11 | 828 | // save changes to configuration |
SDesign2018 | 26:15df8f054d11 | 829 | logInfo("saving configuration"); |
SDesign2018 | 26:15df8f054d11 | 830 | if (!dot->saveConfig()) { |
SDesign2018 | 26:15df8f054d11 | 831 | logError("failed to save configuration"); |
SDesign2018 | 26:15df8f054d11 | 832 | } |
SDesign2018 | 26:15df8f054d11 | 833 | // Display configuration |
SDesign2018 | 26:15df8f054d11 | 834 | // It's gonna output a lot of information onto the Serial Terminal |
SDesign2018 | 26:15df8f054d11 | 835 | display_config(); |
SDesign2018 | 26:15df8f054d11 | 836 | |
SDesign2018 | 28:29702434319d | 837 | |
SDesign2018 | 28:29702434319d | 838 | |
SDesign2018 | 26:15df8f054d11 | 839 | |
SDesign2018 | 26:15df8f054d11 | 840 | |
SDesign2018 | 29:0f0a059f023e | 841 | // //below is acc,temp sensors |
SDesign2018 | 29:0f0a059f023e | 842 | // ADT7410Initialize(); |
SDesign2018 | 29:0f0a059f023e | 843 | // ADXL372Initialize(); |
SDesign2018 | 26:15df8f054d11 | 844 | |
SDesign2018 | 29:0f0a059f023e | 845 | |
SDesign2018 | 26:15df8f054d11 | 846 | |
SDesign2018 | 28:29702434319d | 847 | // // Initialize the SD card |
SDesign2018 | 28:29702434319d | 848 | // if(sd.init() == 0) |
SDesign2018 | 28:29702434319d | 849 | // { |
SDesign2018 | 28:29702434319d | 850 | // pc.printf("Init success \n\r"); |
SDesign2018 | 28:29702434319d | 851 | // } |
SDesign2018 | 28:29702434319d | 852 | // else pc.printf("Init failed \n\r"); |
SDesign2018 | 28:29702434319d | 853 | // err = fs.mount(&sd); |
SDesign2018 | 28:29702434319d | 854 | // pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); |
SDesign2018 | 28:29702434319d | 855 | // if (err) |
SDesign2018 | 28:29702434319d | 856 | // return err; |
SDesign2018 | 28:29702434319d | 857 | // pc.printf("Error for mounting was %d\n\r", err); |
SDesign2018 | 28:29702434319d | 858 | // |
SDesign2018 | 28:29702434319d | 859 | // pc.printf("Opening file %s... ", fileName); |
SDesign2018 | 28:29702434319d | 860 | // |
SDesign2018 | 28:29702434319d | 861 | // // Open your file |
SDesign2018 | 28:29702434319d | 862 | // fp = fopen(fileName.c_str(), "w+"); |
SDesign2018 | 28:29702434319d | 863 | // pc.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n")); |
SDesign2018 | 28:29702434319d | 864 | // |
SDesign2018 | 28:29702434319d | 865 | // if (!fp) |
SDesign2018 | 28:29702434319d | 866 | // { |
SDesign2018 | 28:29702434319d | 867 | // // Check whether directory '/sd/mytest' exists. |
SDesign2018 | 28:29702434319d | 868 | // pc.printf("\r\nChecking directory '%s'...\r\n", fileName); |
SDesign2018 | 28:29702434319d | 869 | // struct stat info; |
SDesign2018 | 28:29702434319d | 870 | // err = stat(directory.c_str(), &info); |
SDesign2018 | 28:29702434319d | 871 | // if (err) |
SDesign2018 | 28:29702434319d | 872 | // { |
SDesign2018 | 28:29702434319d | 873 | // pc.printf("Directory '%s' does not exist.\r\n", directory); |
SDesign2018 | 28:29702434319d | 874 | // pc.printf("Trying to create it..."); |
SDesign2018 | 28:29702434319d | 875 | // err = mkdir(directory.c_str(), 0777); |
SDesign2018 | 28:29702434319d | 876 | // pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); |
SDesign2018 | 28:29702434319d | 877 | // if (err) |
SDesign2018 | 28:29702434319d | 878 | // return err; |
SDesign2018 | 28:29702434319d | 879 | // } |
SDesign2018 | 28:29702434319d | 880 | // |
SDesign2018 | 28:29702434319d | 881 | // // Create a new 'sdtest.txt' file. |
SDesign2018 | 28:29702434319d | 882 | // pc.printf("File not found, creating a new one...\r\n"); |
SDesign2018 | 28:29702434319d | 883 | // fp = fopen(fileName.c_str(), "w+"); |
SDesign2018 | 28:29702434319d | 884 | // pc.printf("%s\r\n", (!fp ? "Failed :(" : "OK")); |
SDesign2018 | 28:29702434319d | 885 | // if (!fp) |
SDesign2018 | 28:29702434319d | 886 | // { |
SDesign2018 | 28:29702434319d | 887 | // error("error: %s (%d)\r\n", strerror(errno), -errno); |
SDesign2018 | 28:29702434319d | 888 | // return errno; |
SDesign2018 | 28:29702434319d | 889 | // } |
SDesign2018 | 28:29702434319d | 890 | // } |
SDesign2018 | 28:29702434319d | 891 | // |
SDesign2018 | 28:29702434319d | 892 | // fprintf(fp,"Temperature,X Acceleration,Y Acceleration,Z Acceleration,\ |
SDesign2018 | 28:29702434319d | 893 | // Longitude,Latitude,Date,Time\n"); |
SDesign2018 | 28:29702434319d | 894 | |
SDesign2018 | 28:29702434319d | 895 | |
SDesign2018 | 28:29702434319d | 896 | // Continous loop |
SDesign2018 | 26:15df8f054d11 | 897 | while(1){ |
SDesign2018 | 26:15df8f054d11 | 898 | // Create a vector of uint8_t elements to be sent later |
SDesign2018 | 26:15df8f054d11 | 899 | |
SDesign2018 | 26:15df8f054d11 | 900 | std::vector<uint8_t> tx_data; |
SDesign2018 | 26:15df8f054d11 | 901 | |
SDesign2018 | 26:15df8f054d11 | 902 | |
SDesign2018 | 27:5db200a4d496 | 903 | |
SDesign2018 | 27:5db200a4d496 | 904 | takePeriodicReading(tx_data); |
SDesign2018 | 27:5db200a4d496 | 905 | |
SDesign2018 | 26:15df8f054d11 | 906 | |
SDesign2018 | 26:15df8f054d11 | 907 | if(takeAccelerometer || takeTemperature){ |
SDesign2018 | 26:15df8f054d11 | 908 | pc.printf("INTERRUPTEDDDDDDDD: "); |
SDesign2018 | 26:15df8f054d11 | 909 | if(takeTemperature) pc.printf("Temperature triggered!!!!!!!!!!!!\n\r"); |
SDesign2018 | 26:15df8f054d11 | 910 | else if(takeAccelerometer) pc.printf("AccelerometerTriggered!!!!!!!!!!!!!\n\r"); |
SDesign2018 | 26:15df8f054d11 | 911 | |
SDesign2018 | 27:5db200a4d496 | 912 | |
SDesign2018 | 27:5db200a4d496 | 913 | takePeriodicReading(tx_data); |
SDesign2018 | 26:15df8f054d11 | 914 | |
SDesign2018 | 26:15df8f054d11 | 915 | takeAccelerometer = false; // Flip back to no trigger |
SDesign2018 | 26:15df8f054d11 | 916 | takeTemperature = false; // Flip back to no trigger |
SDesign2018 | 26:15df8f054d11 | 917 | |
SDesign2018 | 26:15df8f054d11 | 918 | } |
SDesign2018 | 26:15df8f054d11 | 919 | |
SDesign2018 | 26:15df8f054d11 | 920 | |
SDesign2018 | 26:15df8f054d11 | 921 | |
SDesign2018 | 27:5db200a4d496 | 922 | // Go to sleep for 5 seconds and wake up after 5 seconds or wakeup from interrupt |
SDesign2018 | 26:15df8f054d11 | 923 | |
SDesign2018 | 29:0f0a059f023e | 924 | if(dot->sleep(5,mDot::RTC_ALARM_OR_INTERRUPT, false) == mDot::MDOT_OK) |
SDesign2018 | 27:5db200a4d496 | 925 | { |
SDesign2018 | 27:5db200a4d496 | 926 | pc.printf("Sleep well\n\r"); |
SDesign2018 | 27:5db200a4d496 | 927 | } |
SDesign2018 | 27:5db200a4d496 | 928 | |
SDesign2018 | 26:15df8f054d11 | 929 | } |
SDesign2018 | 26:15df8f054d11 | 930 | |
SDesign2018 | 26:15df8f054d11 | 931 | return 0; |
SDesign2018 | 26:15df8f054d11 | 932 | } |
SDesign2018 | 26:15df8f054d11 | 933 | |
SDesign2018 | 28:29702434319d | 934 | |
SDesign2018 | 28:29702434319d | 935 | std::string convertInt(int number) |
SDesign2018 | 28:29702434319d | 936 | { |
SDesign2018 | 28:29702434319d | 937 | std::stringstream ss; |
SDesign2018 | 28:29702434319d | 938 | ss << number; |
SDesign2018 | 28:29702434319d | 939 | return ss.str(); |
SDesign2018 | 28:29702434319d | 940 | |
SDesign2018 | 28:29702434319d | 941 | } |
SDesign2018 | 28:29702434319d | 942 | |
SDesign2018 | 26:15df8f054d11 | 943 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 944 | * Not really used at the moment |
SDesign2018 | 26:15df8f054d11 | 945 | * Not really needed. But keep just in case because I don't want to rewrite it |
SDesign2018 | 26:15df8f054d11 | 946 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 947 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 948 | char twosComplementConversion(char value) |
SDesign2018 | 26:15df8f054d11 | 949 | { |
SDesign2018 | 26:15df8f054d11 | 950 | /* |
SDesign2018 | 26:15df8f054d11 | 951 | * Go from bit 0 to bit 7 and invert them |
SDesign2018 | 26:15df8f054d11 | 952 | * Then finally add 1 |
SDesign2018 | 26:15df8f054d11 | 953 | */ |
SDesign2018 | 26:15df8f054d11 | 954 | char mask = value & 0x80; |
SDesign2018 | 26:15df8f054d11 | 955 | if(mask == 0x80){ // Check for sign |
SDesign2018 | 26:15df8f054d11 | 956 | value = ~value + 1; |
SDesign2018 | 26:15df8f054d11 | 957 | return value; |
SDesign2018 | 26:15df8f054d11 | 958 | } |
SDesign2018 | 26:15df8f054d11 | 959 | return value; |
SDesign2018 | 26:15df8f054d11 | 960 | } |
SDesign2018 | 26:15df8f054d11 | 961 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 962 | |
SDesign2018 | 26:15df8f054d11 | 963 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 964 | * Initializes whatever settings you want for the accelerometer |
SDesign2018 | 26:15df8f054d11 | 965 | * Can change it to use the previous I2C write function instead of all this mess |
SDesign2018 | 26:15df8f054d11 | 966 | * |
SDesign2018 | 26:15df8f054d11 | 967 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 968 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 969 | void ADXL372Initialize(void){ |
SDesign2018 | 26:15df8f054d11 | 970 | ADXL372Reset(); |
SDesign2018 | 26:15df8f054d11 | 971 | pc.printf("Initializing ADXL372 accelerometer\n\r"); |
SDesign2018 | 28:29702434319d | 972 | accelerometerI2CWrite(0x20, 0x0F); // X offset |
SDesign2018 | 28:29702434319d | 973 | accelerometerI2CWrite(0x21, 0x02); // Y offset |
SDesign2018 | 28:29702434319d | 974 | accelerometerI2CWrite(0x22, 0x05); // Z offset |
SDesign2018 | 28:29702434319d | 975 | // accelerometerI2CWrite(0x33, 0x01); // X axis used |
SDesign2018 | 28:29702434319d | 976 | // accelerometerI2CWrite(0x35, 0x01); // Y axis used |
SDesign2018 | 28:29702434319d | 977 | // accelerometerI2CWrite(0x37, 0x01); // Z axis used |
SDesign2018 | 28:29702434319d | 978 | |
SDesign2018 | 28:29702434319d | 979 | //accelerometerI2CWrite(0x3A, 0x00); // FIFO takes X,Y,Z |
SDesign2018 | 28:29702434319d | 980 | //accelerometerI2CWrite(0x3D, 0x03); // ODR 3200 Hz |
SDesign2018 | 28:29702434319d | 981 | accelerometerI2CWrite(0x3E, 0x03); // Bandwidth 1600 |
SDesign2018 | 28:29702434319d | 982 | // accelerometerI2CWrite(0x3F, 0x2F); // High instant on threshold, LPF&HPF disabled, Instant on Mode |
SDesign2018 | 28:29702434319d | 983 | accelerometerI2CWrite(0x3F, 0x3E); // Enable I2C highspeed,Low Pass, High pass and full bandwidth measurement mode |
SDesign2018 | 26:15df8f054d11 | 984 | accelerometerI2CWrite(0x38, 0x01); // Enable the High pass filter corner 1 at register 0x38 |
SDesign2018 | 28:29702434319d | 985 | //accelerometerI2CWrite(0x3E, 0x44); // AutoSleep is enabled with LINKLOOP at DEFAULTMODE , Bandwidth at default, |
SDesign2018 | 26:15df8f054d11 | 986 | |
SDesign2018 | 26:15df8f054d11 | 987 | /* accelerometerI2CWrite(0x24, 0x01); // X used for activity threshold |
SDesign2018 | 26:15df8f054d11 | 988 | accelerometerI2CWrite(0x26, 0x01); // Y used for activity threshold |
SDesign2018 | 26:15df8f054d11 | 989 | accelerometerI2CWrite(0x28, 0x01); // Z used for activity threshold */ |
SDesign2018 | 26:15df8f054d11 | 990 | pc.printf("\n\n\r"); |
SDesign2018 | 26:15df8f054d11 | 991 | } |
SDesign2018 | 26:15df8f054d11 | 992 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 993 | |
SDesign2018 | 26:15df8f054d11 | 994 | |
SDesign2018 | 26:15df8f054d11 | 995 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 996 | * ADT7410 Initializing function |
SDesign2018 | 26:15df8f054d11 | 997 | * Make critical temperature 24 celsius |
SDesign2018 | 26:15df8f054d11 | 998 | * Make CRIT pin active high |
SDesign2018 | 26:15df8f054d11 | 999 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 1000 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1001 | void ADT7410Initialize(void){ |
SDesign2018 | 26:15df8f054d11 | 1002 | pc.printf("Initializing ADT7410 Temperature\n\r"); |
SDesign2018 | 29:0f0a059f023e | 1003 | // Make INT/CRIT pins comp mode and both pins active HIGH |
SDesign2018 | 29:0f0a059f023e | 1004 | ADT7410Write(0x03, 0x1A); // |
SDesign2018 | 26:15df8f054d11 | 1005 | // Make critical temperature be 24 celsius |
SDesign2018 | 26:15df8f054d11 | 1006 | ADT7410Write(0x08, 0x01); // MSB of Temperature Crit value |
SDesign2018 | 26:15df8f054d11 | 1007 | ADT7410Write(0x09, 0x80); // LSB of Temperature Crit value |
SDesign2018 | 26:15df8f054d11 | 1008 | |
SDesign2018 | 29:0f0a059f023e | 1009 | // |
SDesign2018 | 29:0f0a059f023e | 1010 | |
SDesign2018 | 26:15df8f054d11 | 1011 | // Make CRIT pin active high |
SDesign2018 | 29:0f0a059f023e | 1012 | //ADT7410Write(0x03, 0x08); // Turn INT HIGH, works for the interrupt pin |
SDesign2018 | 26:15df8f054d11 | 1013 | pc.printf("\n\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1014 | } |
SDesign2018 | 26:15df8f054d11 | 1015 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1016 | |
SDesign2018 | 26:15df8f054d11 | 1017 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 1018 | * ADXL372 reset function |
SDesign2018 | 26:15df8f054d11 | 1019 | * Resets all registers and settings back to default |
SDesign2018 | 26:15df8f054d11 | 1020 | * Basically the same as the previous ADXL372 I2C write function |
SDesign2018 | 26:15df8f054d11 | 1021 | * |
SDesign2018 | 26:15df8f054d11 | 1022 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 1023 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1024 | void ADXL372Reset(void){ |
SDesign2018 | 26:15df8f054d11 | 1025 | int flag; |
SDesign2018 | 26:15df8f054d11 | 1026 | //--------- One full writing cycle for ADXL372 for Z Enable ------------------// |
SDesign2018 | 26:15df8f054d11 | 1027 | /* '0' - NAK was received |
SDesign2018 | 26:15df8f054d11 | 1028 | * '1' - ACK was received, <---- This good |
SDesign2018 | 26:15df8f054d11 | 1029 | * '2' - timeout |
SDesign2018 | 26:15df8f054d11 | 1030 | */ |
SDesign2018 | 26:15df8f054d11 | 1031 | ADXL372.start(); |
SDesign2018 | 26:15df8f054d11 | 1032 | flag = ADXL372.write(ADXL372_Address_8bit | 0); |
SDesign2018 | 26:15df8f054d11 | 1033 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1034 | { |
SDesign2018 | 26:15df8f054d11 | 1035 | //pc.printf("Write to I2C address success\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1036 | |
SDesign2018 | 26:15df8f054d11 | 1037 | flag = ADXL372.write(0x41); |
SDesign2018 | 26:15df8f054d11 | 1038 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1039 | { |
SDesign2018 | 26:15df8f054d11 | 1040 | //pc.printf("Write to 0x41 register address success\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1041 | flag = ADXL372.write(0x52); // Set bit 0 |
SDesign2018 | 26:15df8f054d11 | 1042 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1043 | { |
SDesign2018 | 26:15df8f054d11 | 1044 | pc.printf("Everything has been reset\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1045 | ADXL372.stop(); |
SDesign2018 | 26:15df8f054d11 | 1046 | } |
SDesign2018 | 26:15df8f054d11 | 1047 | } |
SDesign2018 | 26:15df8f054d11 | 1048 | } |
SDesign2018 | 26:15df8f054d11 | 1049 | else ADXL372.stop(); |
SDesign2018 | 26:15df8f054d11 | 1050 | // ---------------- End of writing cycle --------------------------// |
SDesign2018 | 26:15df8f054d11 | 1051 | } |
SDesign2018 | 26:15df8f054d11 | 1052 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1053 | |
SDesign2018 | 26:15df8f054d11 | 1054 | /* |
SDesign2018 | 26:15df8f054d11 | 1055 | * |
SDesign2018 | 26:15df8f054d11 | 1056 | * Self-test to see if the accelerometer is working as intended |
SDesign2018 | 26:15df8f054d11 | 1057 | * Wait 300 ms. |
SDesign2018 | 26:15df8f054d11 | 1058 | * Check bit 2 for a 1 for success. Bit 1 for completion of self-test. |
SDesign2018 | 26:15df8f054d11 | 1059 | * Returns whole register |
SDesign2018 | 26:15df8f054d11 | 1060 | */ |
SDesign2018 | 26:15df8f054d11 | 1061 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1062 | void I2CSelfTest(void){ |
SDesign2018 | 26:15df8f054d11 | 1063 | char *result; |
SDesign2018 | 26:15df8f054d11 | 1064 | uint8_t check; |
SDesign2018 | 26:15df8f054d11 | 1065 | accelerometerI2CWrite(0x3F, 0x0F); |
SDesign2018 | 26:15df8f054d11 | 1066 | accelerometerI2CWrite(0x40, 0x01); |
SDesign2018 | 26:15df8f054d11 | 1067 | wait(0.3); |
SDesign2018 | 26:15df8f054d11 | 1068 | result = accelerometerI2CRead(0x40); |
SDesign2018 | 26:15df8f054d11 | 1069 | check = result[0]; |
SDesign2018 | 26:15df8f054d11 | 1070 | if(check & 0x04){ |
SDesign2018 | 26:15df8f054d11 | 1071 | pc.printf("Passed\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1072 | }else {pc.printf("FAILED\n\r");} |
SDesign2018 | 26:15df8f054d11 | 1073 | } |
SDesign2018 | 26:15df8f054d11 | 1074 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1075 | |
SDesign2018 | 26:15df8f054d11 | 1076 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 1077 | * |
SDesign2018 | 26:15df8f054d11 | 1078 | * I2C function for the the ADXL372 accelerometer for a write sequence |
SDesign2018 | 26:15df8f054d11 | 1079 | * Param: |
SDesign2018 | 26:15df8f054d11 | 1080 | * hexAddress: Pass the hexadecimal value for what register you want |
SDesign2018 | 26:15df8f054d11 | 1081 | * hexData: Pass the hexadecimal value for what data you want to send |
SDesign2018 | 26:15df8f054d11 | 1082 | * i.e. hexadecimal represenatation of certain bits |
SDesign2018 | 26:15df8f054d11 | 1083 | * Returns from mbed library write function |
SDesign2018 | 26:15df8f054d11 | 1084 | * 0: NAK was reveived |
SDesign2018 | 26:15df8f054d11 | 1085 | * 1: ACK was received <---- Good for us |
SDesign2018 | 26:15df8f054d11 | 1086 | * 2: Timeout |
SDesign2018 | 26:15df8f054d11 | 1087 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 1088 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1089 | void accelerometerI2CWrite(uint8_t hexAddress, uint8_t hexData){ |
SDesign2018 | 26:15df8f054d11 | 1090 | |
SDesign2018 | 26:15df8f054d11 | 1091 | int flag; |
SDesign2018 | 26:15df8f054d11 | 1092 | int registerAddress = hexAddress; |
SDesign2018 | 26:15df8f054d11 | 1093 | int data = hexData; |
SDesign2018 | 26:15df8f054d11 | 1094 | |
SDesign2018 | 26:15df8f054d11 | 1095 | ADXL372.start(); |
SDesign2018 | 26:15df8f054d11 | 1096 | flag = ADXL372.write(ADXL372_Address_8bit); |
SDesign2018 | 26:15df8f054d11 | 1097 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1098 | { |
SDesign2018 | 26:15df8f054d11 | 1099 | //pc.printf("Write to I2C address success\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1100 | wait(0.1); |
SDesign2018 | 26:15df8f054d11 | 1101 | flag = ADXL372.write(registerAddress); |
SDesign2018 | 26:15df8f054d11 | 1102 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1103 | { |
SDesign2018 | 26:15df8f054d11 | 1104 | //pc.printf("Write to register 0x%x address success\n\r", registerAddress); |
SDesign2018 | 26:15df8f054d11 | 1105 | flag = ADXL372.write(data); |
SDesign2018 | 26:15df8f054d11 | 1106 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1107 | { |
SDesign2018 | 26:15df8f054d11 | 1108 | pc.printf("Writing data 0x%x to register address 0x%d success\n\r", data, registerAddress); |
SDesign2018 | 26:15df8f054d11 | 1109 | ADXL372.stop(); |
SDesign2018 | 26:15df8f054d11 | 1110 | return; |
SDesign2018 | 26:15df8f054d11 | 1111 | }else {ADXL372.stop();} |
SDesign2018 | 26:15df8f054d11 | 1112 | }else {ADXL372.stop();} |
SDesign2018 | 26:15df8f054d11 | 1113 | }else ADXL372.stop(); |
SDesign2018 | 26:15df8f054d11 | 1114 | |
SDesign2018 | 26:15df8f054d11 | 1115 | } |
SDesign2018 | 26:15df8f054d11 | 1116 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1117 | |
SDesign2018 | 26:15df8f054d11 | 1118 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 1119 | * I2C read sequence for the accelerometer |
SDesign2018 | 26:15df8f054d11 | 1120 | * Param: |
SDesign2018 | 26:15df8f054d11 | 1121 | * hexAddress: pass the hexadecimal representation of desired Register address |
SDesign2018 | 26:15df8f054d11 | 1122 | * Return: |
SDesign2018 | 26:15df8f054d11 | 1123 | * Char pointer to the array of read data. |
SDesign2018 | 26:15df8f054d11 | 1124 | * |
SDesign2018 | 26:15df8f054d11 | 1125 | * Right now it works only for the XData, YData, ZData because I wrote it to read |
SDesign2018 | 26:15df8f054d11 | 1126 | * 6 bytes(6 registers). |
SDesign2018 | 26:15df8f054d11 | 1127 | * Should change it to be 1 byte at a time |
SDesign2018 | 26:15df8f054d11 | 1128 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 1129 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1130 | char * accelerometerI2CRead(int hexAddress){ |
SDesign2018 | 26:15df8f054d11 | 1131 | char accelData[6]; |
SDesign2018 | 26:15df8f054d11 | 1132 | char registerAddress[1]; |
SDesign2018 | 26:15df8f054d11 | 1133 | registerAddress[0] = hexAddress; |
SDesign2018 | 26:15df8f054d11 | 1134 | |
SDesign2018 | 26:15df8f054d11 | 1135 | // Perform mbed's way sending a start bit, then device address[r/~w], and then the register address |
SDesign2018 | 26:15df8f054d11 | 1136 | // Also if it succeeds, continue to the next operation |
SDesign2018 | 26:15df8f054d11 | 1137 | if(ADXL372.write(ADXL372_Address_8bit, registerAddress, 1) == 0){ |
SDesign2018 | 26:15df8f054d11 | 1138 | |
SDesign2018 | 26:15df8f054d11 | 1139 | // If previous sequence works, get 6 bytes into char array accelData |
SDesign2018 | 26:15df8f054d11 | 1140 | // Char array because it uses 1 byte(8bits) |
SDesign2018 | 26:15df8f054d11 | 1141 | // Should probably change it to uint8_t type |
SDesign2018 | 26:15df8f054d11 | 1142 | if(ADXL372.read(ADXL372_Address_8bit, accelData, 6) == 0){ |
SDesign2018 | 26:15df8f054d11 | 1143 | return accelData; |
SDesign2018 | 26:15df8f054d11 | 1144 | }else pc.printf("Failed to read\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1145 | }else pc.printf("Failed to write\n\r"); |
SDesign2018 | 26:15df8f054d11 | 1146 | return 0; // Only if it fails completely |
SDesign2018 | 26:15df8f054d11 | 1147 | } |
SDesign2018 | 26:15df8f054d11 | 1148 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1149 | |
SDesign2018 | 26:15df8f054d11 | 1150 | |
SDesign2018 | 26:15df8f054d11 | 1151 | |
SDesign2018 | 26:15df8f054d11 | 1152 | |
SDesign2018 | 26:15df8f054d11 | 1153 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 1154 | * Performs one byte write I2C protocol |
SDesign2018 | 26:15df8f054d11 | 1155 | * PARAM: |
SDesign2018 | 26:15df8f054d11 | 1156 | * registerAddress: register you want access to in device, one byte char hex format |
SDesign2018 | 26:15df8f054d11 | 1157 | * data: one byte data that you want to write to device register |
SDesign2018 | 26:15df8f054d11 | 1158 | * Return results from mbed library function: |
SDesign2018 | 26:15df8f054d11 | 1159 | * 0: failure at writing i2c address |
SDesign2018 | 26:15df8f054d11 | 1160 | * 1: successful write |
SDesign2018 | 26:15df8f054d11 | 1161 | * 2: failure at writing data |
SDesign2018 | 26:15df8f054d11 | 1162 | * |
SDesign2018 | 26:15df8f054d11 | 1163 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 1164 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1165 | void ADT7410Write(unsigned char registerAddress, unsigned char data){ |
SDesign2018 | 26:15df8f054d11 | 1166 | int flag; |
SDesign2018 | 26:15df8f054d11 | 1167 | ADT7410.start(); |
SDesign2018 | 26:15df8f054d11 | 1168 | flag = ADT7410.write(ADT7410_Address_8BIT); |
SDesign2018 | 26:15df8f054d11 | 1169 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1170 | { |
SDesign2018 | 26:15df8f054d11 | 1171 | |
SDesign2018 | 26:15df8f054d11 | 1172 | wait(0.1); |
SDesign2018 | 26:15df8f054d11 | 1173 | flag = ADT7410.write(registerAddress); |
SDesign2018 | 26:15df8f054d11 | 1174 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1175 | { |
SDesign2018 | 26:15df8f054d11 | 1176 | |
SDesign2018 | 26:15df8f054d11 | 1177 | flag = ADT7410.write(data); |
SDesign2018 | 26:15df8f054d11 | 1178 | if(flag == 1) |
SDesign2018 | 26:15df8f054d11 | 1179 | { |
SDesign2018 | 26:15df8f054d11 | 1180 | pc.printf("Writing data 0x%x to register address 0x%x success\n\r", data, registerAddress); |
SDesign2018 | 26:15df8f054d11 | 1181 | ADT7410.stop(); |
SDesign2018 | 26:15df8f054d11 | 1182 | |
SDesign2018 | 26:15df8f054d11 | 1183 | }else {ADT7410.stop();} |
SDesign2018 | 26:15df8f054d11 | 1184 | }else {ADT7410.stop();} |
SDesign2018 | 26:15df8f054d11 | 1185 | }else ADT7410.stop(); |
SDesign2018 | 26:15df8f054d11 | 1186 | |
SDesign2018 | 26:15df8f054d11 | 1187 | |
SDesign2018 | 26:15df8f054d11 | 1188 | } |
SDesign2018 | 26:15df8f054d11 | 1189 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1190 | |
SDesign2018 | 26:15df8f054d11 | 1191 | |
SDesign2018 | 26:15df8f054d11 | 1192 | /******************************************************************************* |
SDesign2018 | 26:15df8f054d11 | 1193 | * I2C Read function for ADT7410 Temperature sensor |
SDesign2018 | 26:15df8f054d11 | 1194 | * Param: |
SDesign2018 | 26:15df8f054d11 | 1195 | * hex: hexadecimal representation for desired register |
SDesign2018 | 26:15df8f054d11 | 1196 | * Return: |
SDesign2018 | 26:15df8f054d11 | 1197 | * Char pointer to the array of data values. |
SDesign2018 | 26:15df8f054d11 | 1198 | * Could also change from a char pointer to a uint8_t pointer. |
SDesign2018 | 26:15df8f054d11 | 1199 | * |
SDesign2018 | 26:15df8f054d11 | 1200 | ******************************************************************************/ |
SDesign2018 | 26:15df8f054d11 | 1201 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1202 | char * ADT7410Read(int hex){ |
SDesign2018 | 26:15df8f054d11 | 1203 | //short int convertedVal; |
SDesign2018 | 26:15df8f054d11 | 1204 | char data[2] = {0, 0}; |
SDesign2018 | 26:15df8f054d11 | 1205 | char cmd[1]; |
SDesign2018 | 26:15df8f054d11 | 1206 | cmd[0] = hex; |
SDesign2018 | 26:15df8f054d11 | 1207 | //pc.printf("Register Addres is: %x \n\r", cmd[0]); |
SDesign2018 | 26:15df8f054d11 | 1208 | if(ADT7410.write(ADT7410_Address_8BIT, cmd,1) == 0){ |
SDesign2018 | 26:15df8f054d11 | 1209 | if(ADT7410.read(ADT7410_Address_8BIT, data, 2) == 0){ |
SDesign2018 | 26:15df8f054d11 | 1210 | |
SDesign2018 | 26:15df8f054d11 | 1211 | return data; |
SDesign2018 | 26:15df8f054d11 | 1212 | //return (data[0] << 8 | data[1])>>3; // Explained here: https://stackoverflow.com/a/141576 SOOO GREAT |
SDesign2018 | 26:15df8f054d11 | 1213 | |
SDesign2018 | 26:15df8f054d11 | 1214 | }else {pc.printf("Failed to read \n\r"); return data;} |
SDesign2018 | 26:15df8f054d11 | 1215 | }else {pc.printf("Failed to write \n\r"); return data;} |
SDesign2018 | 26:15df8f054d11 | 1216 | |
SDesign2018 | 26:15df8f054d11 | 1217 | } |
SDesign2018 | 26:15df8f054d11 | 1218 | //////////////////////////////////////////////////////////////////////////////// |
SDesign2018 | 26:15df8f054d11 | 1219 | |
SDesign2018 | 26:15df8f054d11 | 1220 |