An SMS based GPS tracker using the Adafruit Ultimate GPS module http://www.adafruit.com/products/746 and the Seeed Studio GPRS shield (Sim900 chipset) http://www.seeedstudio.com/depot/gprs-shield-p-779.html?cPath=132_134

Dependencies:   GPS MODSERIAL mbed-rtos mbed

SMS based GPS tracker

This is an SMS based GPS tracker using using the Adafruit Ultimate GPS module and the Seeed studio GPRS arduino shield [SIM900 chipset]. The idea of this project is to leverage the free SMS between Virgin mobile prepaid SIM cards in Australia for long distance communication.

Currently the GPRS shield is switched on manually, and should be done about 10 seconds before powering the mbed/GPS in order to disable echo properly during start up. This could easily be fixed by switching the GPRS shield with the mbed at start up, waiting the 10 seconds, set the echo then flush the buffer.

The mbed can read all 160 ASCII chars sent in a message for control.

http://i47.tinypic.com/35alpue.png http://i48.tinypic.com/2mi3y0z.png http://i45.tinypic.com/jkeyvt.png

The Seeed GPRS shield http://www.seeedstudio.com/depot/gprs-shield-p-779.html?cPath=132_134

The Adafruit Ultimate GPS http://www.adafruit.com/products/746

Committer:
SamClarke
Date:
Sat Oct 13 02:09:33 2012 +0000
Revision:
12:3f164c88df87
Parent:
11:fad4b451bec8
Child:
13:d8ee6b45bd0a
Now has the ability to receive 160 chars for control

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SamClarke 12:3f164c88df87 1 /******************************************************
SamClarke 12:3f164c88df87 2 * This is an SMS based GPS tracker using using the *
SamClarke 12:3f164c88df87 3 * Adafruit Ultimate GPS module and the Seeed studio *
SamClarke 12:3f164c88df87 4 * GPRS arduino shield [SIM900 chipset]. *
SamClarke 12:3f164c88df87 5 * *
SamClarke 12:3f164c88df87 6 * The idea of this project is to leverage the free *
SamClarke 12:3f164c88df87 7 * SMS between Virgin mobile prepaid SIM cards in *
SamClarke 12:3f164c88df87 8 * Australia for long distance communication. *
SamClarke 12:3f164c88df87 9 * *
SamClarke 12:3f164c88df87 10 * NOTE: sendSms() sends the GPS 'extra' data *
SamClarke 12:3f164c88df87 11 * (eg. speed, heading etc) in one message, and your *
SamClarke 12:3f164c88df87 12 * location as a google maps URL in another message. *
SamClarke 12:3f164c88df87 13 * If you are an Iphone user, you can replace the *
SamClarke 12:3f164c88df87 14 * "https" in the URL with "http" and remove the ".au" *
SamClarke 12:3f164c88df87 15 * to get the URL to open in the native maps app. *
SamClarke 12:3f164c88df87 16 * however I have found this to be less accurate by *
SamClarke 12:3f164c88df87 17 * the fact that it doesn't drop a marker on the *
SamClarke 12:3f164c88df87 18 * real locataion, but looks for the nearest address. *
SamClarke 12:3f164c88df87 19 * it seems that the internal GPS is the only object *
SamClarke 12:3f164c88df87 20 * able to be placed unrestricted on the map. *
SamClarke 12:3f164c88df87 21 * *
SamClarke 12:3f164c88df87 22 * October 2012 Written by: Sam Clarke *
SamClarke 12:3f164c88df87 23 ******************************************************/
SamClarke 12:3f164c88df87 24 /******************************************************
SamClarke 12:3f164c88df87 25 * HelloCylon *
SamClarke 12:3f164c88df87 26 * By Leo Febey Oct 18 2011 *
SamClarke 12:3f164c88df87 27 * Displays a looping pattern on the built in LEDs on *
SamClarke 12:3f164c88df87 28 * the mbed which looks somewhat like a Cylon eye *
SamClarke 12:3f164c88df87 29 * scanner pattern. *
SamClarke 12:3f164c88df87 30 ******************************************************/
SamClarke 12:3f164c88df87 31
SamClarke 0:5b4bcbd69509 32 #include "mbed.h"
SamClarke 0:5b4bcbd69509 33 #include "GPS.h"
SamClarke 0:5b4bcbd69509 34 #include "rtos.h"
SamClarke 0:5b4bcbd69509 35 #include "MODSERIAL.h"
SamClarke 0:5b4bcbd69509 36 #include <string>
SamClarke 0:5b4bcbd69509 37
SamClarke 0:5b4bcbd69509 38 using namespace std;
SamClarke 0:5b4bcbd69509 39
SamClarke 12:3f164c88df87 40 const string GoogleChunk = "https://maps.google.com.au/maps?q="; // URL constant
SamClarke 12:3f164c88df87 41 const string GoogleExtras = "&z=20"; // Zoom Level (0-20)
SamClarke 12:3f164c88df87 42 char GPRSbuffer[512];
SamClarke 12:3f164c88df87 43 char NUMBER[13];
SamClarke 12:3f164c88df87 44 string MESSAGE;
SamClarke 0:5b4bcbd69509 45 int index;
SamClarke 0:5b4bcbd69509 46 int i = 0;
SamClarke 0:5b4bcbd69509 47
SamClarke 0:5b4bcbd69509 48 GPS gps(p9,p10);
SamClarke 12:3f164c88df87 49 MODSERIAL GPRS(p13,p14);
SamClarke 0:5b4bcbd69509 50 MODSERIAL pc(USBTX,USBRX);
SamClarke 0:5b4bcbd69509 51
SamClarke 0:5b4bcbd69509 52 DigitalOut myled1(LED1);
SamClarke 0:5b4bcbd69509 53 DigitalOut myled2(LED2);
SamClarke 0:5b4bcbd69509 54 DigitalOut myled3(LED3);
SamClarke 0:5b4bcbd69509 55 DigitalOut myled4(LED4);
SamClarke 0:5b4bcbd69509 56
SamClarke 12:3f164c88df87 57 void led_thread(void const *argument)
SamClarke 0:5b4bcbd69509 58 {
SamClarke 0:5b4bcbd69509 59 while (true) {
SamClarke 0:5b4bcbd69509 60 DigitalOut leds[4] = {myled1, myled2, myled3, myled4};
SamClarke 0:5b4bcbd69509 61 int pattern[6][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1},{0,0,1,0},{0,1,0,0}};
SamClarke 0:5b4bcbd69509 62 int i=0;
SamClarke 0:5b4bcbd69509 63 while(1) {
SamClarke 0:5b4bcbd69509 64 leds[0] = pattern[i][0];
SamClarke 0:5b4bcbd69509 65 leds[1] = pattern[i][1];
SamClarke 0:5b4bcbd69509 66 leds[2] = pattern[i][2];
SamClarke 0:5b4bcbd69509 67 leds[3] = pattern[i][3];
SamClarke 0:5b4bcbd69509 68 wait(0.2);
SamClarke 0:5b4bcbd69509 69 i++;
SamClarke 0:5b4bcbd69509 70 i == 6? i=0:0;
SamClarke 0:5b4bcbd69509 71 }
SamClarke 0:5b4bcbd69509 72 }
SamClarke 0:5b4bcbd69509 73 }
SamClarke 0:5b4bcbd69509 74
SamClarke 0:5b4bcbd69509 75 void sendSms()
SamClarke 0:5b4bcbd69509 76 {
SamClarke 0:5b4bcbd69509 77 // Set message mode to ASCII
SamClarke 0:5b4bcbd69509 78 GPRS.printf("AT+CMGF=1\r\n");
SamClarke 0:5b4bcbd69509 79 wait(1);
SamClarke 0:5b4bcbd69509 80 // Set the phone number
SamClarke 10:059cde049cd6 81 GPRS.printf("AT+CMGS=\"%s\"\r\n", NUMBER);
SamClarke 0:5b4bcbd69509 82 wait(1);
SamClarke 0:5b4bcbd69509 83 // Write out the GPS data in a message
SamClarke 12:3f164c88df87 84 GPRS.printf("UTC Time: %4.2f \nAltitude: %3.2fm\nSpeed: %3.2f Kn\nHeading: %3.2f Deg\nGPS data grade: [%c]\nSatellites in use: [%d]\nSatFix code: [%d] \nFix type: ",
SamClarke 12:3f164c88df87 85 gps.time, gps.altitude, gps.speed, gps.heading, gps.validity, gps.satellites, gps.fixtype);
SamClarke 9:bec6e8f731f2 86 if(gps.fixtype == 1) {
SamClarke 9:bec6e8f731f2 87 GPRS.printf("Positive");
SamClarke 9:bec6e8f731f2 88 }
SamClarke 9:bec6e8f731f2 89 if(gps.fixtype == 2) {
SamClarke 9:bec6e8f731f2 90 GPRS.printf("Differential");
SamClarke 9:bec6e8f731f2 91 }
SamClarke 0:5b4bcbd69509 92 wait(1);
SamClarke 0:5b4bcbd69509 93 // Send it...
SamClarke 0:5b4bcbd69509 94 GPRS.putc(0x1A);
SamClarke 10:059cde049cd6 95 wait(4);
SamClarke 0:5b4bcbd69509 96 GPRS.printf("AT+CMGF=1\r\n");
SamClarke 0:5b4bcbd69509 97 wait(1);
SamClarke 10:059cde049cd6 98 GPRS.printf("AT+CMGS=\"%s\"\r\n", NUMBER);
SamClarke 0:5b4bcbd69509 99 wait(1);
SamClarke 0:5b4bcbd69509 100 GPRS.printf("Find me at....\n %s%f,%f%s", GoogleChunk, gps.latitude, gps.longitude, GoogleExtras);
SamClarke 0:5b4bcbd69509 101 wait(1);
SamClarke 0:5b4bcbd69509 102 GPRS.putc(0x1A);
SamClarke 3:a5df4bd224ad 103 wait(1);
SamClarke 0:5b4bcbd69509 104 }
SamClarke 0:5b4bcbd69509 105
SamClarke 0:5b4bcbd69509 106 void parseSms()
SamClarke 0:5b4bcbd69509 107 {
SamClarke 0:5b4bcbd69509 108 // If theres a char waiting in the MODSERIAL buffer
SamClarke 0:5b4bcbd69509 109 while (GPRS.readable()) {
SamClarke 0:5b4bcbd69509 110 // Assign it to 'c'
SamClarke 0:5b4bcbd69509 111 char c = GPRS.getc();
SamClarke 0:5b4bcbd69509 112 // Replace all returns and or line endings with money!
SamClarke 0:5b4bcbd69509 113 if (c == '\r' || c == '\n') c = '$';
SamClarke 0:5b4bcbd69509 114 // Put it in the array
SamClarke 0:5b4bcbd69509 115 GPRSbuffer[i] = c;
SamClarke 0:5b4bcbd69509 116 // Repeat if possible
SamClarke 0:5b4bcbd69509 117 i++;
SamClarke 0:5b4bcbd69509 118 }
SamClarke 0:5b4bcbd69509 119 // Uncomment the following to debug
SamClarke 10:059cde049cd6 120 // pc.printf("\nbuffer = %s", GPRSbuffer);
SamClarke 0:5b4bcbd69509 121
SamClarke 0:5b4bcbd69509 122 // If we get an SMS notification....
SamClarke 0:5b4bcbd69509 123 if (sscanf(GPRSbuffer, "$$+CMTI: \"SM\",%d", &index)>0) {
SamClarke 1:00c7dc0c1761 124 pc.printf("\nSMS recieved @ index [%d]", index);
SamClarke 12:3f164c88df87 125 memset(GPRSbuffer, '0', 511);
SamClarke 7:db9226b9b037 126 i = 0;
SamClarke 12:3f164c88df87 127 pc.printf("\nOpening message...");
SamClarke 12:3f164c88df87 128 // ask GPRS to read the message
SamClarke 7:db9226b9b037 129 GPRS.printf("AT+CMGR=%d\r\n", index);
SamClarke 7:db9226b9b037 130 }
SamClarke 7:db9226b9b037 131
SamClarke 7:db9226b9b037 132 if (strncmp(GPRSbuffer, "$$+CMGR",7) == 0 ) {
SamClarke 10:059cde049cd6 133 // Get the number out
SamClarke 10:059cde049cd6 134 char *n = strstr(GPRSbuffer,"+6");
SamClarke 10:059cde049cd6 135 strncpy(NUMBER, n, 12);
SamClarke 10:059cde049cd6 136 // Get the message out
SamClarke 12:3f164c88df87 137 char * pch;
SamClarke 12:3f164c88df87 138 pch = strtok (GPRSbuffer, "$$");
SamClarke 12:3f164c88df87 139 pch = strtok (NULL, "$$");
SamClarke 12:3f164c88df87 140 MESSAGE = pch;
SamClarke 12:3f164c88df87 141 pc.printf("\nDone! ");
SamClarke 10:059cde049cd6 142 // Send the location
SamClarke 0:5b4bcbd69509 143 sendSms();
SamClarke 0:5b4bcbd69509 144 // Reset the GPRS buffer
SamClarke 12:3f164c88df87 145 memset(GPRSbuffer, '0', 511);
SamClarke 0:5b4bcbd69509 146 // Reset the char counter
SamClarke 0:5b4bcbd69509 147 i = 0;
SamClarke 7:db9226b9b037 148 }
SamClarke 7:db9226b9b037 149
SamClarke 7:db9226b9b037 150 if (strncmp(GPRSbuffer, "$$+CMGS",7) == 0) {
SamClarke 7:db9226b9b037 151 // Reset the GPRS buffer
SamClarke 12:3f164c88df87 152 memset(GPRSbuffer, '0', 511);
SamClarke 7:db9226b9b037 153 // Reset the char counter
SamClarke 7:db9226b9b037 154 i = 0;
SamClarke 7:db9226b9b037 155 }
SamClarke 7:db9226b9b037 156
SamClarke 7:db9226b9b037 157 if (strncmp(GPRSbuffer, "$$RING",6) == 0) {
SamClarke 9:bec6e8f731f2 158 GPRS.printf("ATH0\r\n");
SamClarke 12:3f164c88df87 159 pc.printf("\nCall bounced!...");
SamClarke 3:a5df4bd224ad 160 // Do the send SMS routine...
SamClarke 3:a5df4bd224ad 161 sendSms();
SamClarke 3:a5df4bd224ad 162 // Reset the GPRS buffer
SamClarke 12:3f164c88df87 163 memset(GPRSbuffer, '0', 511);
SamClarke 3:a5df4bd224ad 164 // Reset the char counter
SamClarke 4:0e55a4620f5e 165 i = 0;
SamClarke 1:00c7dc0c1761 166 }
SamClarke 10:059cde049cd6 167 pc.printf("\n\n\nWaiting for SMS or call...\n");
SamClarke 10:059cde049cd6 168 pc.printf("\nThe last number was : %s", NUMBER);
SamClarke 10:059cde049cd6 169 pc.printf("\nThe last message was : %s", MESSAGE);
SamClarke 7:db9226b9b037 170 // Reset the GPRS buffer
SamClarke 12:3f164c88df87 171 memset(GPRSbuffer, '0', 511);
SamClarke 7:db9226b9b037 172 // Reset the char counter
SamClarke 7:db9226b9b037 173 i = 0;
SamClarke 0:5b4bcbd69509 174 }
SamClarke 0:5b4bcbd69509 175
SamClarke 0:5b4bcbd69509 176 int main()
SamClarke 0:5b4bcbd69509 177 {
SamClarke 0:5b4bcbd69509 178 pc.baud(115200);
SamClarke 0:5b4bcbd69509 179 GPRS.baud(19200);
SamClarke 0:5b4bcbd69509 180 Thread thread(led_thread);
SamClarke 12:3f164c88df87 181 memset(GPRSbuffer, '0', 511);
SamClarke 9:bec6e8f731f2 182 pc.printf("\nI'm Alive...\n");
SamClarke 0:5b4bcbd69509 183 // Setup the GPS
SamClarke 0:5b4bcbd69509 184 gps.Init();
SamClarke 0:5b4bcbd69509 185 // Set the GPRS AT echo off
SamClarke 0:5b4bcbd69509 186 GPRS.printf("ATE0\r\n");
SamClarke 9:bec6e8f731f2 187 pc.printf("\nGPRS echo [OFF]\n");
SamClarke 0:5b4bcbd69509 188 wait(1);
SamClarke 0:5b4bcbd69509 189 // Delete all messages on the sim card
SamClarke 0:5b4bcbd69509 190 GPRS.printf("AT+CMGDA=\"DEL ALL\"\r\n");
SamClarke 0:5b4bcbd69509 191 wait(1);
SamClarke 9:bec6e8f731f2 192 pc.printf("\nMessages Cleared...\n");
SamClarke 0:5b4bcbd69509 193 wait(1);
SamClarke 0:5b4bcbd69509 194 // Get in a while loop
SamClarke 0:5b4bcbd69509 195 while (1) {
SamClarke 10:059cde049cd6 196 // Process any recieved GPRS data
SamClarke 0:5b4bcbd69509 197 parseSms();
SamClarke 0:5b4bcbd69509 198 // Process / check GPS data
SamClarke 3:a5df4bd224ad 199 gps.parseData();
SamClarke 0:5b4bcbd69509 200 }
SamClarke 0:5b4bcbd69509 201 }