#include <SoftwareSerial.
h>
#include <TinyGPSPlus.h>
// ---------- Serial ports ----------
SoftwareSerial sim(10, 11); // SIM800L: RX=10, TX=11
SoftwareSerial gpsSS(4, 3); // GPS: RX=4 (to GPS TX), TX=3 (unused)
TinyGPSPlus gps;
// ---------- Config ----------
String number = "+237678532091"; // destination phone number
const char* APN = "mtnwap"; // <-- replace with your SIM card APN
const bool USE_HTTPS = true; // set false if SIM800L HTTPS fails
// ---------- Helpers ----------
String readUntil(unsigned long ms) {
String s;
unsigned long t0 = millis();
while (millis() - t0 < ms) {
while ([Link]()) s += (char)[Link]();
}
return s;
}
void simSend(const String& cmd, unsigned long wait=200) {
[Link](cmd);
if (wait) readUntil(wait);
}
bool sendSMS(const String& msg) {
simSend(F("AT+CMGF=1"), 150);
[Link](F("AT+CMGS=\"")); [Link](number); [Link](F("\""));
delay(400);
[Link](msg);
[Link](0x1A); // Ctrl+Z
readUntil(6000);
return true;
}
// ---------- GSM / GPRS ----------
bool gsmInit() {
[Link](9600);
delay(300);
simSend("AT", 500);
simSend("ATE0", 200);
simSend("AT+CMGF=1", 200); // SMS text mode
return true;
}
bool gprsOn() {
simSend(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""));
simSend(String(F("AT+SAPBR=3,1,\"APN\",\"")) + APN + "\"");
simSend(F("AT+SAPBR=1,1"), 4000); // bring up bearer
return true;
}
// ---------- GPS ----------
bool getFix(double &lat, double &lon, unsigned long timeoutMs=60000) {
unsigned long t0 = millis();
bool sawNMEA = false;
while (millis() - t0 < timeoutMs) {
while ([Link]()) {
sawNMEA = true;
if ([Link]([Link]())) {
if ([Link]()) {
lat = [Link]();
lon = [Link]();
return true; // FIX!
}
}
}
}
if (!sawNMEA) [Link](F("No NMEA data: check GPS wiring/baud"));
else [Link](F("NMEA received but no fix (try outdoors, wait longer)"));
return false;
}
// ---------- HTTP GET ----------
bool httpGet_SIM800(const String& url, String& body, int& httpStatus, uint32_t
timeoutMs = 30000) {
body = "";
httpStatus = -1;
[Link](F("AT+HTTPTERM"));
delay(100);
[Link](F("AT+HTTPINIT"));
if (USE_HTTPS) { [Link](F("AT+HTTPSSL=1")); delay(150); }
[Link](F("AT+HTTPPARA=\"CID\",1"));
delay(100);
[Link](F("AT+HTTPPARA=\"UA\",\"gps-gsm-demo/1.0 (you@[Link])\""));
delay(100);
[Link] (F("AT+HTTPPARA=\"URL\",\"")); [Link](url); [Link](F("\""));
delay(150);
[Link](F("AT+HTTPACTION=0"));
unsigned long t0 = millis();
String line;
int length = -1;
while (millis() - t0 < timeoutMs) {
if ([Link]()) {
char c = [Link]();
if (c == '\n') {
if ([Link](F("+HTTPACTION: 0,")) >= 0) {
int p1 = [Link](',');
int p2 = [Link](',', p1 + 1);
httpStatus = [Link](p1 + 1, p2).toInt();
length = [Link](p2 + 1).toInt();
break;
}
line = "";
} else if (c != '\r') line += c;
}
}
if (httpStatus < 0) { [Link](F("AT+HTTPTERM")); return false; }
if (length > 0) {
[Link](F("AT+HTTPREAD=0,")); [Link](length);
[Link](length);
unsigned long t1 = millis();
while ((int)[Link]() < length && millis() - t1 < timeoutMs) {
while ([Link]() && (int)[Link]() < length) {
body += (char)[Link]();
}
}
}
[Link](F("AT+HTTPTERM"));
return (httpStatus == 200);
}
// ---------- Reverse Geocoding ----------
String buildRevURL(double lat, double lon) {
String u = F("[Link]
u += F("&lat="); u += String(lat, 6);
u += F("&lon="); u += String(lon, 6);
u += F("&accept-language=en");
return u;
}
String extractDisplayName(const String& json) {
int k = [Link]("\"display_name\":\"");
if (k < 0) k = [Link]("\"name\":\"");
if (k < 0) return "";
k = [Link](':', k) + 2;
int e = [Link]('"', k);
if (e > k) return [Link](k, e);
return "";
}
void sendPlaceName() {
double lat, lon;
[Link](F("Waiting for GPS fix..."));
if (!getFix(lat, lon)) { sendSMS(F("No GPS fix.")); return; }
[Link](F("GPS: ")); [Link](lat, 6); [Link](", ");
[Link](lon, 6);
[Link](F("Bringing up GPRS..."));
if (!gprsOn()) { sendSMS(F("GPRS failed.")); return; }
String url = buildRevURL(lat, lon);
[Link](F("URL: ")); [Link](url);
String body; int status;
bool ok = httpGet_SIM800(url, body, status, 30000);
[Link](F("HTTP status: ")); [Link](status);
if (!ok) {
sendSMS(String(F("Reverse geocode failed. HTTP ")) + status);
return;
}
String name = extractDisplayName(body);
if ([Link]() == 0) {
sendSMS(String(F("Location ok but no name. Coords: ")) + String(lat,6) + "," +
String(lon,6));
return;
}
sendSMS(String(F("Position: ")) + name);
}
// ---------- Original functions ----------
void SendMessage() {
[Link]("AT+CMGF=1");
delay(200);
[Link]("AT+CMGS=\"" + number + "\"\r");
delay(200);
String SMS = "Hello, how are you?";
[Link](SMS);
delay(100);
[Link]((char)26);
delay(200);
}
void RecieveMessage() {
[Link] ("SIM800L Read an SMS");
[Link]("AT+CMGF=1");
delay (200);
[Link]("AT+CNMI=1,2,0,0,0");
delay(200);
[Link] ("Unread Message done");
}
void callNumber() {
[Link] (F("ATD"));
[Link] (number);
[Link] (F(";\r\n"));
}
// ---------- Setup / Loop ----------
void setup() {
[Link](9600);
[Link](9600);
[Link]("System Started...");
gsmInit();
[Link]("Type s=send SMS, r=receive SMS, c=call, l=send place name SMS");
}
void loop() {
if ([Link]()) {
switch ([Link]()) {
case 's': SendMessage(); break;
case 'r': RecieveMessage(); break;
case 'c': callNumber(); break;
case 'l': sendPlaceName(); break;
}
}
if ([Link]()) [Link]([Link]());
}