I am having a problem guys, I am making my thesis project, And one of the main function of my system project is the motorcycle Anti-Theft, and now my problem is I am using TCP connection and planning to do real-time updates with the coordinates, but I am having a few seconds delay when the data is sending over to my database. Is this because I am using an old GSM module?
UPDATE:
Sending the coordinates is much more faster now depending on the signal of SIM800L
might upgrade to A7672S for 4G connection.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include "GSMFunctions.h"
#define RXD2 16
#define TXD2 17
HardwareSerial neogps(1);
// SIM800L Pins
#define RXD_SIM800 4
#define TXD_SIM800 5
SoftwareSerial sim800l(RXD_SIM800, TXD_SIM800);
// Ignition switch pin
#define IGNITION_SWITCH 32
bool ignitionOn = false;
bool lastIgnitionState = false;
// TCP Server (Using Ngrok)
const char* tcpServer = "52.74.74.86"; // Update with your Ngrok host
const int tcpPort = 11139; // Update with your Ngrok assigned port
TinyGPSPlus gps;
// Variables to store the last known valid GPS coordinates
float lastLat = 0.0;
float lastLng = 0.0;
// Flag to indicate if a command is received
bool commandReceived = false;
void setup() {
Serial.begin(115200);
sim800l.begin(9600); // Initialize SIM800L serial
neogps.begin(9600, SERIAL_8N1, RXD2, TXD2);
pinMode(IGNITION_SWITCH, INPUT_PULLUP); // Set GPIO 32 as input (with internal pull-up)
// Initialize SIM800L for GPRS connection
Serial.println("π Initializing SIM800L... Please wait 6 seconds");
delay(6000);
sendATCommand("AT", 10000); // Test AT command
sendATCommand("AT+CSQ", 6000); // Check signal quality
sendATCommand("AT+CREG?", 2000); // Check network registration
sendATCommand("AT+CGDCONT?", 5000); // This command can sometimes return the APN, depending on the carrier
// GPRS Initialization
sendATCommand("AT+CFUN=1", 3000); // Set full functionality
sendATCommand("AT+CGATT=1", 3000); // Attach to GPRS network
sendATCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", 3000); // Set connection type
sendATCommand("AT+SAPBR=3,1,\"APN\",\"internet\"", 3000); // Set APN
sendATCommand("AT+SAPBR=1,1", 3000); // Activate bearer
sendATCommand("ATE0", 5000); // Disable echo
// Connect to TCP Server
connectTCP();
}
void loop() {
if (!sim800l.available()) {
Serial.println("β οΈ TCP Disconnected! Reconnecting...");
connectTCP();
}
// Read the ignition state
ignitionOn = digitalRead(IGNITION_SWITCH) == LOW;
// Debugging print for ignition state
Serial.printf("π Ignition State: %s\n", ignitionOn ? "ON" : "OFF");
// Print Ignition State if it changes
if (ignitionOn != lastIgnitionState) {
lastIgnitionState = ignitionOn; // Update the last ignition state
Serial.println("β οΈ Ignition State Changed!");
}
while (neogps.available() && !commandReceived) {
if (gps.encode(neogps.read())) {
if (gps.location.isValid()) {
float lat = gps.location.lat();
float lng = gps.location.lng();
int speed = gps.speed.kmph();
int satellites = gps.satellites.value();
// Update last known valid GPS coordinates
lastLat = lat;
lastLng = lng;
// Prepare data string without start_latitude and start_longitude
String data = "lat=" + String(lat, 6) +
"&lng=" + String(lng, 6) +
"&speed=" + String(speed) +
"&satellites=" + String(satellites) +
"&ignition=" + (ignitionOn ? "ON" : "OFF");
// Send data to server over TCP using SIM800L
sendTCPData(data);
Serial.println("π‘ Sent: " + data);
// Check ignition state after sending data
ignitionOn = digitalRead(IGNITION_SWITCH) == LOW;
Serial.printf("π Ignition State (mid-send): %s\n", ignitionOn ? "ON" : "OFF");
} else {
Serial.println("β οΈ GPS Data Invalid, Skipping...");
}
}
}
// Continuously process incoming commands
processIncomingCommand();
// If a command is received, process it and reset the flag
if (commandReceived) {
commandReceived = false;
}
}
String command = ""; // Store incoming command
void processIncomingCommand() {
while (sim800l.available()) {
char c = sim800l.read();
if (c == '\n' || c == '\r') { // End of command
command.trim();
if (command.length() > 0) {
Serial.println("π₯ Received command: [" + command + "]");
// Filter out responses that you don't care about
if (command.startsWith("lat=")) {
Serial.println("β οΈ Ignoring echoed GPS data");
}
else if (command.indexOf("SEND OK") != -1) {
Serial.println("β οΈ Ignoring SEND OK confirmation");
}
else if (command.indexOf("Data received and processed") != -1) {
Serial.println("β οΈ Ignoring data confirmation");
}
// Process only the THEFT (or STATUS) command
else if (command.equals("THEFT")) {
Serial.println("π¨ Theft Detected!");
commandReceived = true;
makeCallAndStop();
sendSMSAlert(lastLat, lastLng);
}
else if (command.equals("STATUS")) {
Serial.println("π Sending status...");
commandReceived = true;
}
else {
Serial.println("β Unknown command: [" + command + "]");
}
}
command = ""; // Reset command buffer
} else {
command += c;
}
}
}
void connectTCP() {
// Send AT command to start a TCP connection to Ngrok server
sendATCommand("AT+CIPSTART=\"TCP\",\"" + String(tcpServer) + "\"," + String(tcpPort), 5000);
Serial.println("β
Connected to TCP Server!");
}
void sendTCPData(String data) {
// Send AT command to start sending data over TCP
sendATCommand("AT+CIPSEND=" + String(data.length()), 500);
sim800l.println(data); // Send the actual data
}
void sendATCommand(String command, unsigned long timeout) {
sim800l.println(command);
long int time = millis();
while (millis() - time < timeout) {
while (sim800l.available()) {
String response = sim800l.readString();
Serial.print(response); // Print SIM800L response for debugging
if (response.indexOf("OK") != -1 || response.indexOf("CONNECT") != -1) {
return;
}
}
}
Serial.println("β Command Timeout: " + command);
}
SEND OK
THEFT
π‘ Sent: lat=7.783598&lng=122.586800&speed=0&satellites=12&ignition=OFF
π Ignition State (mid-send): OFF

