Dominic Ottaviano / Mbed 2 deprecated Sentinel_NODE

Dependencies:   XBEE_900HP_SPI mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 / Sentinel software for the active nodes.
00003 /
00004 / Design work done by:
00005 / Dominic Ottaviano
00006 / Sheldon Fernandes
00007 / Thien L. Nguyen
00008 */
00009 
00010 #include "mbed.h"
00011 #include "xbee900hp.h"
00012 
00013 /*===========================================================/
00014 / Primary Configuration Area                                 /
00015 / Global Variables and Pin Assigments Declared Within        /
00016 /===========================================================*/
00017 
00018 // Define GPS pin connections.
00019 Serial gps(dp16,dp15);
00020 
00021 // Define xbee connections. Mosi,Miso,SCK,ATTN,Reset
00022 xbee900hp xbee(dp2,dp1,dp6, dp9, dp4);
00023 
00024 // Function prototypes
00025 // Function to query the GPS
00026 int getGPS(char* data);
00027 
00028 // Global Variables
00029 // Buffer for reading in from xbee
00030 char buffer[256];
00031 // Buffer for storing GPS data
00032 char gpsmsg[256];
00033 
00034 /*===========================================================/
00035 / END OF Primary Configuration Area                          /
00036 /===========================================================*/
00037 
00038 /*===========================================================/
00039 / Begin main program code                                    /
00040 /===========================================================*/
00041 
00042 int main()
00043 {
00044     /*===========================/
00045     / Configuration Section      /
00046     /===========================*/
00047 
00048     // Set GPS paramters
00049     // Baud rate
00050     gps.baud(4800);
00051     // Other params (8 data bits, no parity, 1 stop bit)
00052     gps.format(8,SerialBase::None,1);
00053 
00054     // Configure gps with these parameters:
00055     // NMEA, 4800 Baud, 8 Data bits, 1 Stop bit, No Parity
00056     unsigned int gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'0'^','^'1'^','^'4'^'8'^'0'^'0'^','^'8'^','^'1'^','^'0';
00057     // Trim to 8 bits just in case
00058     gpsxor = gpsxor & 0xFF;
00059     // Send command to the GPS module
00060     gps.printf("$PSRF100,1,4800,8,1,0*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00061 
00062     // Disable automatic broadcast of all messages. We are going to poll manually.
00063     gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'0'^','^'0'^','^'0'^','^'1';
00064     // Trim to 8 bits just in case
00065     gpsxor = gpsxor & 0xFF;
00066     gps.printf("$PSRF103,0,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00067 
00068     // Disable GLL
00069     gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'1'^','^'0'^','^'0'^','^'1';
00070     // Trim to 8 bits just in case
00071     gpsxor = gpsxor & 0xFF;
00072     gps.printf("$PSRF103,1,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00073 
00074     // Disable GSA
00075     gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'2'^','^'0'^','^'0'^','^'1';
00076     // Trim to 8 bits just in case
00077     gpsxor = gpsxor & 0xFF;
00078     gps.printf("$PSRF103,2,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00079 
00080     // Disable GSV
00081     gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'3'^','^'0'^','^'0'^','^'1';
00082     // Trim to 8 bits just in case
00083     gpsxor = gpsxor & 0xFF;
00084     gps.printf("$PSRF103,3,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00085 
00086     // Disable RMC
00087     gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'4'^','^'0'^','^'0'^','^'1';
00088     // Trim to 8 bits just in case
00089     gpsxor = gpsxor & 0xFF;
00090     gps.printf("$PSRF103,4,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00091 
00092     // Disable VTG
00093     gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'5'^','^'0'^','^'0'^','^'1';
00094     // Trim to 8 bits just in case
00095     gpsxor = gpsxor & 0xFF;
00096     gps.printf("$PSRF103,5,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F);
00097 
00098     /*===========================/
00099     / END Configuration Section  /
00100     /===========================*/
00101 
00102 
00103     // Set the node id of this module. Generated from the serial of the xbee
00104     char nodeidarray[10];
00105     int nodeid = 0;
00106 
00107     // Initialize nodeidarray
00108     for (int i = 0; i<10; i++) {
00109         nodeidarray[i] = 0;
00110     }
00111 
00112     // Get xbee serial number
00113     int serialget = xbee.getSerial(nodeidarray);
00114 
00115     if (serialget == 0) {
00116         for (int i = 0; i<10; i++) {
00117             // Nonlinear function to expand unique id space
00118             nodeid += nodeidarray[i]*nodeidarray[i]+nodeidarray[i];
00119         }
00120     }
00121     // Node id should now be a unique int
00122 
00123     // Set variables, there are more than we need here but it would be useful in the future if we did need any.
00124     char ns, ew;
00125     int lock;
00126     double satsused;
00127     double hdop;
00128     double latitude, longitude;
00129     double altitude;
00130     double time;
00131     char altunits;
00132     double geoidsep;
00133     char geoidunits;
00134     int difrefstationid;
00135     unsigned int gpschecksum;
00136     unsigned int filledbuff;
00137 
00138     // Announce the node to the base station.
00139     filledbuff = snprintf (buffer, sizeof(buffer)-1, "ANCE,%i,\r\n",nodeid);
00140     // Send packet out into the air.
00141     xbee.sendPacket(buffer, filledbuff);
00142 
00143     // Main program run loop.
00144     while(true) {
00145         // Get new data from the GPS and if data is read successfully continue
00146         if (!(getGPS(gpsmsg))) {
00147             // Parse the recieved data and check if its valid (HINT: lf = double since pointers aren't promoted)
00148             if(sscanf(gpsmsg, "$GPGGA,%lf,%lf,%c,%lf,%c,%i,%lf,%lf,%lf,%c,%lf,%c,,%i*%x", &time, &latitude, &ns, &longitude, &ew, &lock, &satsused, &hdop, &altitude, &altunits, &geoidsep, &geoidunits, &difrefstationid, &gpschecksum) == 14) {
00149                 // Check if the lock is valid
00150                 if((lock != 1) && (lock != 2) && (lock != 6)) {
00151                     // Format code line to send out on radio that node has no lock
00152                     filledbuff = snprintf (buffer, sizeof(buffer)-1, "DNLK,%i,\r\n",nodeid);
00153                     // Send packet out into the air.
00154                     xbee.sendPacket(buffer, filledbuff);
00155                 } else {
00156                     // Convert latitude into proper form for display on a map.
00157                     double degrees;
00158                     double minutes = modf(latitude/100.0f, &degrees);
00159                     minutes = (minutes*100.0f)/60.0f;
00160                     latitude = degrees + minutes;
00161                     // Convert longitude
00162                     minutes = modf(longitude/100.0f, &degrees);
00163                     minutes = (minutes*100.0f)/60.0f;
00164                     longitude = degrees + minutes;
00165 
00166                     // Correct for south and west.
00167                     if(ns == 'S') {
00168                         latitude  *= -1.0;
00169                     }
00170                     if(ew == 'W') {
00171                         longitude *= -1.0;
00172                     }
00173 
00174                     // Format string for sending out over radio.
00175                     filledbuff = snprintf (buffer, sizeof(buffer)-1, "DLIN,%i,%f,%f,%f,%f,\r\n",nodeid, latitude, longitude, altitude, satsused);
00176                     // Send packet out.
00177                     xbee.sendPacket(buffer, filledbuff);
00178                 }
00179                 // Wait a second for GPS data to be fresh again and not waste cycles.
00180                 wait(1);
00181             } else {
00182                 // GPS hasn't found a good enough lock
00183                 filledbuff = snprintf (buffer, sizeof(buffer)-1, "DNLK,%i,NOLOCK\r\n",nodeid);
00184                 // Send packet out into the air.
00185                 xbee.sendPacket(buffer, filledbuff);
00186                 // Wait half a second then try again.
00187                 wait(0.5);
00188             }
00189         } else {
00190             // GPS hasn't found lock or sent a corrupted message
00191             filledbuff = snprintf (buffer, sizeof(buffer)-1, "DNLK,%i,NOLOCK\r\n",nodeid);
00192             // Send packet out into the air.
00193             xbee.sendPacket(buffer, filledbuff);
00194             // Wait half a second a try again.
00195             wait(0.5);
00196         }
00197     }
00198 }
00199 
00200 int getGPS(char* data)
00201 {
00202     // Request a query of GGA
00203     // Precomputed checksum to save cpu cycles
00204     gps.printf("$PSRF103,0,1,0,1*%u%u\r\n",0x2,0x5);
00205 
00206     // Timer to prevent hangs if gps doesn't respond.
00207     Timer gpsTO;
00208     gpsTO.start();
00209 
00210     // Wait for gps to becom readable.
00211     while (gps.readable() == false) {
00212         // Timeout
00213         if (gpsTO.read() > 2) {
00214            return 1;
00215         }
00216     }
00217 
00218     // Wait a tiny bit to allow the gps to send the whole line.
00219     wait_ms(50);
00220     // Get data from gps
00221     gps.scanf("%s",data);
00222 
00223     // Compute checksum of recieved gps data
00224     int i = 0;
00225     unsigned int calcgpschecksum = 0;
00226     // Checksum is calculated between and not including the $ and *
00227     while ((data[i] != '\0') && (data[i] != '*')) {
00228         // Skip the $
00229         if (data[i] != '$') {
00230             calcgpschecksum = calcgpschecksum ^ data[i];
00231         }
00232         i++;
00233     }
00234     // Shift the checksum to match the format we recieve from the gps
00235     calcgpschecksum = calcgpschecksum & 0xFF;
00236 
00237     // Get checksum sent by gps out of string
00238     unsigned int realgpschecksum = 0;
00239     char checksumarray[3];
00240     for (int i = 0; i < 256; i++) {
00241         if (data[i] == '*') {
00242             // Create little array with ascii hex values.
00243             checksumarray[0] = data[i+1];
00244             checksumarray[1] = data[i+2];
00245             checksumarray[2] = '\0';
00246             // Convert ascii values to regular integer
00247             sscanf(checksumarray,"%x",&realgpschecksum);
00248             break;
00249         }
00250     }
00251 
00252     // Check for checksum match
00253     if( calcgpschecksum == realgpschecksum ) {
00254         return 0;
00255     }
00256 
00257     // No checksum match
00258     return 1;
00259 }