The software that runs on the Sentinel nodes. This code is for the LPC1114FN28.
Dependencies: XBEE_900HP_SPI mbed
main.cpp
- Committer:
- ottaviano3
- Date:
- 2015-08-18
- Revision:
- 1:b51fb321d026
- Parent:
- 0:3540612dfbf8
File content as of revision 1:b51fb321d026:
/* / Sentinel software for the active nodes. / / Design work done by: / Dominic Ottaviano / Sheldon Fernandes / Thien L. Nguyen */ #include "mbed.h" #include "xbee900hp.h" /*===========================================================/ / Primary Configuration Area / / Global Variables and Pin Assigments Declared Within / /===========================================================*/ // Define GPS pin connections. Serial gps(dp16,dp15); // Define xbee connections. Mosi,Miso,SCK,ATTN,Reset xbee900hp xbee(dp2,dp1,dp6, dp9, dp4); // Function prototypes // Function to query the GPS int getGPS(char* data); // Global Variables // Buffer for reading in from xbee char buffer[256]; // Buffer for storing GPS data char gpsmsg[256]; /*===========================================================/ / END OF Primary Configuration Area / /===========================================================*/ /*===========================================================/ / Begin main program code / /===========================================================*/ int main() { /*===========================/ / Configuration Section / /===========================*/ // Set GPS paramters // Baud rate gps.baud(4800); // Other params (8 data bits, no parity, 1 stop bit) gps.format(8,SerialBase::None,1); // Configure gps with these parameters: // NMEA, 4800 Baud, 8 Data bits, 1 Stop bit, No Parity unsigned int gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'0'^','^'1'^','^'4'^'8'^'0'^'0'^','^'8'^','^'1'^','^'0'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; // Send command to the GPS module gps.printf("$PSRF100,1,4800,8,1,0*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); // Disable automatic broadcast of all messages. We are going to poll manually. gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'0'^','^'0'^','^'0'^','^'1'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; gps.printf("$PSRF103,0,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); // Disable GLL gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'1'^','^'0'^','^'0'^','^'1'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; gps.printf("$PSRF103,1,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); // Disable GSA gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'2'^','^'0'^','^'0'^','^'1'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; gps.printf("$PSRF103,2,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); // Disable GSV gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'3'^','^'0'^','^'0'^','^'1'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; gps.printf("$PSRF103,3,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); // Disable RMC gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'4'^','^'0'^','^'0'^','^'1'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; gps.printf("$PSRF103,4,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); // Disable VTG gpsxor = 'P'^'S'^'R'^'F'^'1'^'0'^'3'^','^'5'^','^'0'^','^'0'^','^'1'; // Trim to 8 bits just in case gpsxor = gpsxor & 0xFF; gps.printf("$PSRF103,5,0,0,1*%u%u\r\n",(gpsxor & 0xF0) >> 4,gpsxor & 0x0F); /*===========================/ / END Configuration Section / /===========================*/ // Set the node id of this module. Generated from the serial of the xbee char nodeidarray[10]; int nodeid = 0; // Initialize nodeidarray for (int i = 0; i<10; i++) { nodeidarray[i] = 0; } // Get xbee serial number int serialget = xbee.getSerial(nodeidarray); if (serialget == 0) { for (int i = 0; i<10; i++) { // Nonlinear function to expand unique id space nodeid += nodeidarray[i]*nodeidarray[i]+nodeidarray[i]; } } // Node id should now be a unique int // Set variables, there are more than we need here but it would be useful in the future if we did need any. char ns, ew; int lock; double satsused; double hdop; double latitude, longitude; double altitude; double time; char altunits; double geoidsep; char geoidunits; int difrefstationid; unsigned int gpschecksum; unsigned int filledbuff; // Announce the node to the base station. filledbuff = snprintf (buffer, sizeof(buffer)-1, "ANCE,%i,\r\n",nodeid); // Send packet out into the air. xbee.sendPacket(buffer, filledbuff); // Main program run loop. while(true) { // Get new data from the GPS and if data is read successfully continue if (!(getGPS(gpsmsg))) { // Parse the recieved data and check if its valid (HINT: lf = double since pointers aren't promoted) 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) { // Check if the lock is valid if((lock != 1) && (lock != 2) && (lock != 6)) { // Format code line to send out on radio that node has no lock filledbuff = snprintf (buffer, sizeof(buffer)-1, "DNLK,%i,\r\n",nodeid); // Send packet out into the air. xbee.sendPacket(buffer, filledbuff); } else { // Convert latitude into proper form for display on a map. double degrees; double minutes = modf(latitude/100.0f, °rees); minutes = (minutes*100.0f)/60.0f; latitude = degrees + minutes; // Convert longitude minutes = modf(longitude/100.0f, °rees); minutes = (minutes*100.0f)/60.0f; longitude = degrees + minutes; // Correct for south and west. if(ns == 'S') { latitude *= -1.0; } if(ew == 'W') { longitude *= -1.0; } // Format string for sending out over radio. filledbuff = snprintf (buffer, sizeof(buffer)-1, "DLIN,%i,%f,%f,%f,%f,\r\n",nodeid, latitude, longitude, altitude, satsused); // Send packet out. xbee.sendPacket(buffer, filledbuff); } // Wait a second for GPS data to be fresh again and not waste cycles. wait(1); } else { // GPS hasn't found a good enough lock filledbuff = snprintf (buffer, sizeof(buffer)-1, "DNLK,%i,NOLOCK\r\n",nodeid); // Send packet out into the air. xbee.sendPacket(buffer, filledbuff); // Wait half a second then try again. wait(0.5); } } else { // GPS hasn't found lock or sent a corrupted message filledbuff = snprintf (buffer, sizeof(buffer)-1, "DNLK,%i,NOLOCK\r\n",nodeid); // Send packet out into the air. xbee.sendPacket(buffer, filledbuff); // Wait half a second a try again. wait(0.5); } } } int getGPS(char* data) { // Request a query of GGA // Precomputed checksum to save cpu cycles gps.printf("$PSRF103,0,1,0,1*%u%u\r\n",0x2,0x5); // Timer to prevent hangs if gps doesn't respond. Timer gpsTO; gpsTO.start(); // Wait for gps to becom readable. while (gps.readable() == false) { // Timeout if (gpsTO.read() > 2) { return 1; } } // Wait a tiny bit to allow the gps to send the whole line. wait_ms(50); // Get data from gps gps.scanf("%s",data); // Compute checksum of recieved gps data int i = 0; unsigned int calcgpschecksum = 0; // Checksum is calculated between and not including the $ and * while ((data[i] != '\0') && (data[i] != '*')) { // Skip the $ if (data[i] != '$') { calcgpschecksum = calcgpschecksum ^ data[i]; } i++; } // Shift the checksum to match the format we recieve from the gps calcgpschecksum = calcgpschecksum & 0xFF; // Get checksum sent by gps out of string unsigned int realgpschecksum = 0; char checksumarray[3]; for (int i = 0; i < 256; i++) { if (data[i] == '*') { // Create little array with ascii hex values. checksumarray[0] = data[i+1]; checksumarray[1] = data[i+2]; checksumarray[2] = '\0'; // Convert ascii values to regular integer sscanf(checksumarray,"%x",&realgpschecksum); break; } } // Check for checksum match if( calcgpschecksum == realgpschecksum ) { return 0; } // No checksum match return 1; }