Greetings!
First things first, I want to make a project where it automatically sends an SMS message if the prototype itself has outreached it's geo-fence. However, whenever I use the code, the message won't register to my phone.
I live in the Philippines (I do not if this information is relevant).
Here are the materials that I am using for this project:
(1) Arduino UNO R3
(1) Gy-Neo6mV2 GPS module
(1) sim800L version 2 GSM module
(2) 3.7V 2200mAh battery
(1) PCB board
Here is the code(not working code):
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <TinyGPS++.h>
//--------------------------------------------------------------
// Enter your personal phone number to receive SMS alerts.
// Phone number must start with country code.
const String PHONE = "+639295686569"; // Updated phone number
//--------------------------------------------------------------
// GSM Module RX pin to Arduino 10
// GSM Module TX pin to Arduino 11
#define rxPin 11
#define txPin 10
SoftwareSerial sim800l(rxPin, txPin);
// GPS Module RX pin to Arduino 9
// GPS Module TX pin to Arduino 8
AltSoftSerial neogps; // Using AltSoftSerial for GPS
TinyGPSPlus gps;
//--------------------------------------------------------------
// Size of the geo-fence (in meters)
const float maxDistance = 5;
// Initial coordinates (set as your reference point)
float initialLatitude = 9.789219; //in degrees
float initialLongitude = 125.490977; //in degrees
float latitude, longitude;
void getGps(float& latitude, float& longitude);
void sendAlert(); // Function to send SMS when out of geo-fence
float getDistance(float flat1, float flon1, float flat2, float flon2);
void setup() {
Serial.begin(9600);
sim800l.begin(9600);
neogps.begin(9600);
// Initialize SIM800L
sim800l.println("AT"); // Check GSM Module
delay(1000);
sim800l.println("ATE1"); // Echo ON
delay(1000);
sim800l.println("AT+CREG?"); // network status: +CREG: 0,1 or +CREG: 0,5
delay(1000);
sim800l.println("AT+CSQ"); // signal strength: +CSQ: 15,99, where 15 is the signal strength, and the second value (99) is the bit error rate.
delay(1000);
sim800l.println("AT+CPIN?"); // Check SIM ready
delay(1000);
sim800l.println("AT+CMGF=1"); // SMS text mode
delay(1000);
sim800l.println("AT+CNMI=1,1,0,0,0"); // Handle newly arrived SMS
delay(1000);
delay(20000); // Allow time for initialization
Serial.println("System Started...");
}
void loop() {
// Get GPS coordinates
getGps(latitude, longitude);
// Calculate the distance from the initial point
float distance = getDistance(latitude, longitude, initialLatitude, initialLongitude);
// Debugging output
Serial.print("Latitude= "); Serial.println(latitude, 6);
Serial.print("Longitude= "); Serial.println(longitude, 6);
Serial.print("Initial Latitude= "); Serial.println(initialLatitude, 6);
Serial.print("Initial Longitude= "); Serial.println(initialLongitude, 6);
Serial.print("Current Distance= "); Serial.println(distance);
// If outside geo-fence, send an alert SMS
if (distance > maxDistance) {
Serial.println("Outside geo-fence! Preparing to send alert.");
sendAlert();
delay(60000); // Delay to avoid spamming alerts; adjust as necessary
} else {
Serial.println("Inside geo-fence.");
}
// Relay any incoming messages from GSM module to Serial Monitor
while (sim800l.available()) {
Serial.println(sim800l.readString());
}
// Relay any messages from Serial Monitor to GSM module
while (Serial.available()) {
sim800l.println(Serial.readString());
}
}
// Calculate the distance between two points using Haversine formula
float getDistance(float flat1, float flon1, float flat2, float flon2) {
float dist_calc = 0;
float dist_calc2 = 0;
float diflat = radians(flat2 - flat1); // Conversion of degrees to radians
flat1 = radians(flat1);
flat2 = radians(flat2);
float diflon = radians((flon2) - (flon1));
dist_calc = (sin(diflat / 2.0) * sin(diflat / 2.0));
dist_calc2 = cos(flat1) * cos(flat2) * sin(diflon / 2.0) * sin(diflon / 2.0);
dist_calc += dist_calc2;
dist_calc = (2 * atan2(sqrt(dist_calc), sqrt(1.0 - dist_calc)));
dist_calc *= 6371000.0; // Converting to meters
return dist_calc;
}
// Get GPS data and store in latitude and longitude
void getGps(float& latitude, float& longitude) {
boolean newData = false;
// Wait for up to 20 seconds to get new data
for (unsigned long start = millis(); millis() - start < 20000;) {
while (neogps.available()) {
if (gps.encode(neogps.read())) {
newData = true;
break;
}
}
}
if (newData) {
latitude = gps.location.lat();
longitude = gps.location.lng();
// Debug output
Serial.print("Extracted Latitude: "); Serial.println(latitude, 6);
Serial.print("Extracted Longitude: "); Serial.println(longitude, 6);
} else {
Serial.println("No valid GPS data available.");
latitude = 0;
longitude = 0;
}
}
// Send SMS alert when outside the geo-fence
void sendAlert() {
// Create the SMS content
String sms_data = "ALERT! Outside the geo-fence.\n";
sms_data += "https://maps.google.com/maps?q=loc:"+ String(latitude,6) + "," + String(longitude,6);
// Debugging: Print the SMS content to the Serial Monitor
Serial.println("Preparing to send the following SMS content...");
Serial.println(sms_data);
// Send the SMS
sim800l.print("AT+CMGS=\"" + PHONE + "\"\r");
delay(2000); // Wait for the command to be processed
sim800l.print(sms_data);
delay(5000); // Wait for the message to be processed
sim800l.write(0x1A); // ASCII code for Ctrl-Z to send SMS
delay(3000); // Wait for the SMS to be sent
// Debugging: Confirm SMS sent
Serial.println("SMS Sent Successfully.");
}
here is the 2nd code (the one where it is working):
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <TinyGPS++.h>
//--------------------------------------------------------------
// Enter your personal phone number to receive SMS alerts.
// Phone number must start with country code.
const String PHONE = "+639295686569"; // Updated phone number
//--------------------------------------------------------------
// GSM Module RX pin to Arduino 10
// GSM Module TX pin to Arduino 11
#define rxPin 11
#define txPin 10
SoftwareSerial sim800l(rxPin, txPin);
// GPS Module RX pin to Arduino 9
// GPS Module TX pin to Arduino 8
AltSoftSerial neogps; // Using AltSoftSerial for GPS
TinyGPSPlus gps;
//--------------------------------------------------------------
// Size of the geo-fence (in meters)
const float maxDistance = 5;
// Initial coordinates (set as your reference point)
float initialLatitude = 9.789219; //in degrees
float initialLongitude = 125.490977; //in degrees
float latitude, longitude;
void getGps(float& latitude, float& longitude);
void sendAlert(); // Function to send SMS when out of geo-fence
float getDistance(float flat1, float flon1, float flat2, float flon2);
void setup() {
Serial.begin(9600);
sim800l.begin(9600);
neogps.begin(9600);
// Initialize SIM800L
sim800l.println("AT"); // Check GSM Module
delay(1000);
sim800l.println("ATE1"); // Echo ON
delay(1000);
sim800l.println("AT+CREG?"); // network status: +CREG: 0,1 or +CREG: 0,5
delay(1000);
sim800l.println("AT+CSQ"); // signal strength: +CSQ: 15,99, where 15 is the signal strength, and the second value (99) is the bit error rate.
delay(1000);
sim800l.println("AT+CPIN?"); // Check SIM ready
delay(1000);
sim800l.println("AT+CMGF=1"); // SMS text mode
delay(1000);
sim800l.println("AT+CNMI=1,1,0,0,0"); // Handle newly arrived SMS
delay(1000);
delay(20000); // Allow time for initialization
Serial.println("System Started...");
}
void loop() {
// Get GPS coordinates
getGps(latitude, longitude);
// Calculate the distance from the initial point
float distance = getDistance(latitude, longitude, initialLatitude, initialLongitude);
// Debugging output
Serial.print("Latitude= "); Serial.println(latitude, 6);
Serial.print("Longitude= "); Serial.println(longitude, 6);
Serial.print("Initial Latitude= "); Serial.println(initialLatitude, 6);
Serial.print("Initial Longitude= "); Serial.println(initialLongitude, 6);
Serial.print("Current Distance= "); Serial.println(distance);
// If outside geo-fence, send an alert SMS
if (distance > maxDistance) {
Serial.println("Outside geo-fence! Preparing to send alert.");
sendAlert();
delay(60000); // Delay to avoid spamming alerts; adjust as necessary
} else {
Serial.println("Inside geo-fence.");
}
// Relay any incoming messages from GSM module to Serial Monitor
while (sim800l.available()) {
Serial.println(sim800l.readString());
}
// Relay any messages from Serial Monitor to GSM module
while (Serial.available()) {
sim800l.println(Serial.readString());
}
}
// Calculate the distance between two points using Haversine formula
float getDistance(float flat1, float flon1, float flat2, float flon2) {
float dist_calc = 0;
float dist_calc2 = 0;
float diflat = radians(flat2 - flat1); // Conversion of degrees to radians
flat1 = radians(flat1);
flat2 = radians(flat2);
float diflon = radians((flon2) - (flon1));
dist_calc = (sin(diflat / 2.0) * sin(diflat / 2.0));
dist_calc2 = cos(flat1) * cos(flat2) * sin(diflon / 2.0) * sin(diflon / 2.0);
dist_calc += dist_calc2;
dist_calc = (2 * atan2(sqrt(dist_calc), sqrt(1.0 - dist_calc)));
dist_calc *= 6371000.0; // Converting to meters
return dist_calc;
}
// Get GPS data and store in latitude and longitude
void getGps(float& latitude, float& longitude) {
boolean newData = false;
// Wait for up to 20 seconds to get new data
for (unsigned long start = millis(); millis() - start < 20000;) {
while (neogps.available()) {
if (gps.encode(neogps.read())) {
newData = true;
break;
}
}
}
if (newData) {
latitude = gps.location.lat();
longitude = gps.location.lng();
// Debug output
Serial.print("Extracted Latitude: "); Serial.println(latitude, 6);
Serial.print("Extracted Longitude: "); Serial.println(longitude, 6);
} else {
Serial.println("No valid GPS data available.");
latitude = 0;
longitude = 0;
}
}
// Send SMS alert when outside the geo-fence
void sendAlert() {
// Create the SMS content
String sms_data = "ALERT! Outside the geo-fence.\n";
// Debugging: Print the SMS content to the Serial Monitor
Serial.println("Preparing to send the following SMS content...");
Serial.println(sms_data);
// Send the SMS
sim800l.print("AT+CMGS=\"" + PHONE + "\"\r");
delay(2000); // Wait for the command to be processed
sim800l.print(sms_data);
delay(5000); // Wait for the message to be processed
sim800l.write(0x1A); // ASCII code for Ctrl-Z to send SMS
delay(3000); // Wait for the SMS to be sent
// Debugging: Confirm SMS sent
Serial.println("SMS Sent Successfully.");
}
Here is the function that ruined the first code,
sms_data += "https://maps.google.com/maps?q=loc:"+ String(latitude,6) + "," + String(longitude,6);
I know that this particular code is the problem as to why my prototype won't work because I have tested both codes and the second code is working fine while the first code won't work.
Please help me! What should I do?