Devices & Components
Arduino Make Your UNO Kit
10 jumper wires 150mm male
Hardware & Tools
Arduino UNO
GPS Module (NEO-6M)
SIM808
Software & Tools
Arduino IDE
Project description
Code
geo_fencing_alarm_system (1)
1/* 2 * Geo-Fencing SMS Alarm System 3 * Hardware: Arduino Uno + SIM808 module 4 * SIM808 connected via SoftwareSerial: TX=10, RX=11 5 * Alert number: change ALERT_NUMBER below 6 */ 7 8#include <SoftwareSerial.h> 9 10// ── Pins ────────────────────────────────────────────── 11#define SIM808_RX 10 // Arduino RX ← SIM808 TX 12#define SIM808_TX 11 // Arduino TX → SIM808 RX 13 14// ── Geo-fence config ────────────────────────────────── 15const double FENCE_LAT = 30.9010; // Centre latitude (your location) 16const double FENCE_LON = 75.8573; // Centre longitude (your location) 17const double FENCE_RADIUS_M = 200.0; // Radius in metres 18 19// ── SMS config ──────────────────────────────────────── 20const char* ALERT_NUMBER = "+91XXXXXXXXXX"; // Recipient number 21 22// ── Timing ──────────────────────────────────────────── 23const unsigned long GPS_POLL_MS = 5000; // Poll GPS every 5 s 24const unsigned long SMS_COOLDOWN = 60000; // Min 60 s between SMS bursts 25 26// ───────────────────────────────────────────────────── 27SoftwareSerial sim808(SIM808_RX, SIM808_TX); 28 29double currentLat = 0, currentLon = 0; 30bool gpsValid = false; 31bool wasInsideFence = true; // Assume inside at boot 32unsigned long lastSmsTime = 0; 33unsigned long lastPollTime = 0; 34 35// ── Haversine distance (metres) ─────────────────────── 36double haversine(double lat1, double lon1, double lat2, double lon2) { 37 const double R = 6371000.0; 38 double dLat = radians(lat2 - lat1); 39 double dLon = radians(lon2 - lon1); 40 double a = sin(dLat / 2) * sin(dLat / 2) 41 + cos(radians(lat1)) * cos(radians(lat2)) 42 * sin(dLon / 2) * sin(dLon / 2); 43 return R * 2.0 * atan2(sqrt(a), sqrt(1.0 - a)); 44} 45 46// ── Parse $GPRMC NMEA sentence ──────────────────────── 47bool parseGPRMC(const String& sentence) { 48 // $GPRMC,HHMMSS.ss,A,LLLL.LL,a,YYYYY.YY,a,x.x,x.x,DDMMYY,x.x,a*hh 49 if (!sentence.startsWith("$GPRMC")) return false; 50 51 int field = 0; 52 int start = 0; 53 char statusChar = 'V'; 54 double rawLat = 0, rawLon = 0; 55 char latDir = 'N', lonDir = 'E'; 56 57 for (int i = 0; i <= (int)sentence.length(); i++) { 58 char c = (i < (int)sentence.length()) ? sentence[i] : ','; 59 if (c == ',' || c == '*') { 60 String token = sentence.substring(start, i); 61 switch (field) { 62 case 2: statusChar = token.length() ? token[0] : 'V'; break; 63 case 3: rawLat = token.toDouble(); break; 64 case 4: latDir = token.length() ? token[0] : 'N'; break; 65 case 5: rawLon = token.toDouble(); break; 66 case 6: lonDir = token.length() ? token[0] : 'E'; break; 67 } 68 field++; 69 start = i + 1; 70 } 71 } 72 73 if (statusChar != 'A') return false; // No valid fix 74 75 // Convert DDDMM.mmmm → decimal degrees 76 int latDeg = (int)(rawLat / 100); 77 double latMin = rawLat - latDeg * 100.0; 78 currentLat = latDeg + latMin / 60.0; 79 if (latDir == 'S') currentLat = -currentLat; 80 81 int lonDeg = (int)(rawLon / 100); 82 double lonMin = rawLon - lonDeg * 100.0; 83 currentLon = lonDeg + lonMin / 60.0; 84 if (lonDir == 'W') currentLon = -currentLon; 85 86 return true; 87} 88 89// ── Send AT command, wait for response ──────────────── 90String sendAT(const String& cmd, unsigned int timeout = 2000) { 91 sim808.println(cmd); 92 String resp = ""; 93 unsigned long t = millis(); 94 while (millis() - t < timeout) { 95 while (sim808.available()) resp += (char)sim808.read(); 96 } 97 Serial.println(">> " + cmd); 98 Serial.println("<< " + resp); 99 return resp; 100} 101 102// ── Send SMS ────────────────────────────────────────── 103void sendSMS(const String& message) { 104 sendAT("AT+CMGF=1"); // Text mode 105 sendAT(String("AT+CMGS=\"") + ALERT_NUMBER + "\"", 2000); 106 sim808.print(message); 107 sim808.write(26); // Ctrl+Z to send 108 delay(5000); // Wait for modem to transmit 109 Serial.println("SMS sent: " + message); 110} 111 112// ── Initialise SIM808 ───────────────────────────────── 113void initSIM808() { 114 Serial.println("Initialising SIM808..."); 115 delay(3000); 116 117 sendAT("AT"); // Handshake 118 sendAT("AT+CPIN?"); // SIM ready? 119 sendAT("AT+CREG?"); // Network registration 120 sendAT("AT+CGPSPWR=1"); // GPS power on 121 sendAT("AT+CGPSRST=0"); // Reset GPS data 122 delay(2000); 123 Serial.println("SIM808 ready."); 124} 125 126// ── Request fresh GPS string from SIM808 ───────────── 127String getGPSString() { 128 // SIM808 GPS AT command — returns NMEA $GPRMC via UART 129 sendAT("AT+CGPSINF=0", 2000); // GPS info mode 0 = RMC sentence 130 // Alternatively read raw NMEA if GPS UART is passed through: 131 String line = ""; 132 unsigned long t = millis(); 133 while (millis() - t < 3000) { 134 if (sim808.available()) { 135 char c = sim808.read(); 136 if (c == '\n') { 137 if (line.startsWith("$GPRMC")) return line; 138 line = ""; 139 } else if (c != '\r') { 140 line += c; 141 } 142 } 143 } 144 return ""; 145} 146 147// ───────────────────────────────────────────────────── 148void setup() { 149 Serial.begin(9600); 150 sim808.begin(9600); 151 initSIM808(); 152} 153 154void loop() { 155 unsigned long now = millis(); 156 157 if (now - lastPollTime >= GPS_POLL_MS) { 158 lastPollTime = now; 159 160 String nmea = getGPSString(); 161 gpsValid = parseGPRMC(nmea); 162 163 if (gpsValid) { 164 double dist = haversine(currentLat, currentLon, FENCE_LAT, FENCE_LON); 165 166 Serial.print("Lat: "); Serial.print(currentLat, 6); 167 Serial.print(" Lon: "); Serial.print(currentLon, 6); 168 Serial.print(" Dist: "); Serial.print(dist, 1); Serial.println(" m"); 169 170 bool insideNow = (dist <= FENCE_RADIUS_M); 171 172 // Exited fence 173 if (wasInsideFence && !insideNow) { 174 if (now - lastSmsTime >= SMS_COOLDOWN) { 175 String msg = "ALERT: Device left geo-fence!\n"; 176 msg += "Lat: "; msg += String(currentLat, 6); 177 msg += "\nLon: "; msg += String(currentLon, 6); 178 msg += "\nDist: "; msg += String(dist, 1); msg += " m"; 179 sendSMS(msg); 180 lastSmsTime = now; 181 } 182 } 183 184 // Returned to fence (optional entry alert) 185 if (!wasInsideFence && insideNow) { 186 if (now - lastSmsTime >= SMS_COOLDOWN) { 187 sendSMS("INFO: Device returned inside geo-fence."); 188 lastSmsTime = now; 189 } 190 } 191 192 wasInsideFence = insideNow; 193 194 } else { 195 Serial.println("Waiting for GPS fix..."); 196 } 197 } 198}
Downloadable files
schemtic arduino
schemtic arduino.png

Comments
Only logged in users can leave comments