DEV Community

Cover image for DIY GPS Tracking with Arduino, SIM800L and Ublox Neo-6M
Payam Hoseini
Payam Hoseini

Posted on

DIY GPS Tracking with Arduino, SIM800L and Ublox Neo-6M

After learning how to use sim800l module in my previous project, I decided to create a GPS tracker using the Arduino platform. This project combines a SIM800L module for communication and a Ublox Neo-6M GPS module for location tracking with help of satellites. Making this device is also easy as previous project, just instead of using led, i use a GPS module to get the location and a little changes in the sketch. I measured the current consumption of the device under load and its around 50mAh for sim800l module and 100mAh for gps module. In standby mode, it consumes around 20mAh. With a regular battery(18650 Battery 2500mAh), this device last for around 5 days without charging. As you may now, these kind of devices used in cars or similar places that they has another source of power that help this device battery to charge(Alternators). This device needs a lot of improvement specially in security aspects, but it is a good start for you to learn how to use sim800l module, Ublox GPS module and Arduino platform. This is also a practical DIY device that you may use it in your car or bike.

Features

  • Get GPS coordinates by sending an SMS command ("GPS") to the device
  • Receive a reply with latitude, longitude, satellite count, altitude, speed, and a Google Maps link
  • Works with standard Arduino boards (tested on Uno/Nano)
  • Includes sample wiring diagrams and photos

Ublox Neo-6M

The Ublox Neo-6M GPS module works by connecting to multiple satellites orbiting the Earth. It listens for signals from at least four satellites, each broadcasting precise timing and location data. By calculating the time it takes for these signals to reach the module, the Neo-6M determines its own position (latitude, longitude, and altitude) with high accuracy. The more satellites it connects to, the more reliable and accurate the location data becomes. This satellite-based triangulation allows the module to provide real-time navigation and tracking information, which it then sends to your microcontroller via a serial interface. For best results, the module should have a clear view of the sky to maximize satellite connections and minimize signal interference.

Hardware Required

  • Arduino Uno, Nano, or compatible board
  • SIM800L GSM module
  • Ublox Neo-6M GPS module
  • SIM card with SMS capability
  • Jumper wires and breadboard or PCB
  • Power supply (ensure enough current for SIM800L)

Hardware Pinout

SIM800L

SIM800L Pinout

Ublox Neo-6M

Ublox Neo-6M Pinout

Circuit Wiring

Wiring Diagram

This is wiring diagram which i make it in Fritzing. Please consider that i used a 18650 battery for SIM800l (as it is sensitive to power for working stable) and 5V pin of Arduino for GPS module.

DIY GPS Tracking with Arduino, SIM800L and Ublox Neo-6M Wiring Diagram

My Wiring

This is my circuit, pardon me if it's don't look nice. As this device is in experimental phase, i used usb cable to power up Arduino Uno but in production, we can use our battery with a regulator to increase it to 5 volt.

DIY GPS Tracking with Arduino, SIM800L and Ublox Neo-6M Wiring Circuit

Sketch

This is the sketch that i uploaded to Arduino board. Please attention that this is a starting point for making a GPS tracking system and needs a lot of improvement but don't worry, this device do it's job fine ;)

#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <TinyGPS++.h>

#define SIM800_RX_PIN 2
#define SIM800_TX_PIN 3

SoftwareSerial sim800(SIM800_TX_PIN, SIM800_RX_PIN);
AltSoftSerial gpsSerial;
TinyGPSPlus gps;

String sim800Buffer = "";
float latitude = 0.0;
float longitude = 0.0;
bool gpsDataValid = false;
unsigned long lastGpsDebugTime = 0;

void setup() {
  Serial.begin(9600);
  sim800.begin(9600);
  gpsSerial.begin(9600);
  delay(2000);

  Serial.println("Initializing SIM800L and GPS...");
  sendATCommand("AT", 1000);
  sendATCommand("AT+CMGF=1", 1000); // Text mode
  sendATCommand("AT+CNMI=1,2,0,0,0", 1000); // New message indications
  Serial.println("SIM800L and GPS Ready");
}

void loop() {
  // GPS Processing
  while (gpsSerial.available()) {
    char c = gpsSerial.read();
    gps.encode(c);
    if (gps.location.isValid()) {
      latitude = gps.location.lat();
      longitude = gps.location.lng();
      gpsDataValid = true;
    }
  }

  // Periodic debug output
  if (millis() - lastGpsDebugTime > 5000) {
    lastGpsDebugTime = millis();
    Serial.print("GPS Satellites: ");
    Serial.println(gps.satellites.value());
    Serial.print("GPS Data Valid: ");
    Serial.println(gpsDataValid ? "Yes" : "No");
    if (gpsDataValid) {
      Serial.print("Location: ");
      Serial.print(latitude, 6);
      Serial.print(", ");
      Serial.println(longitude, 6);
    }
  }

  // Read SIM800 data into buffer
  while (sim800.available()) {
    char c = sim800.read();
    sim800Buffer += c;
  }

  // Process SMS only when both header and content are present
  if (sim800Buffer.indexOf("+CMT:") != -1 && sim800Buffer.indexOf("\r\n", sim800Buffer.indexOf("+CMT:") + 6) != -1) {
    int headerEnd = sim800Buffer.indexOf("\r\n", sim800Buffer.indexOf("+CMT:") + 6);
    int msgStart = headerEnd + 2;
    int msgEnd = sim800Buffer.indexOf("\r\n", msgStart); // end of message text

    if (msgEnd != -1) {
      String header = sim800Buffer.substring(0, headerEnd);
      String sender = extractPhoneNumber(header);
      String msg = sim800Buffer.substring(msgStart, msgEnd);
      msg.trim();

      Serial.println("\n--- Incoming SMS ---");
      Serial.println("Sender: " + sender);
      Serial.println("Message: " + msg);

      if (msg.length() > 0 && (msg.indexOf("GPS") != -1 || msg.indexOf("gps") != -1)) {
        sendGPSLocation(sender);
      } else if (msg.length() > 0) {
        sendSMS(sender, "Send 'GPS' to receive location.");
      }

      sim800Buffer = ""; // clear buffer after processing
    }
  }

  // Manual test from Serial
  if (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    if (cmd.startsWith("SEND:")) {
      String num = cmd.substring(5);
      sendGPSLocation(num);
    } else {
      sim800.println(cmd);
    }
  }
}

String extractPhoneNumber(String header) {
  int firstQuote = header.indexOf('"');
  int secondQuote = header.indexOf('"', firstQuote + 1);
  if (firstQuote != -1 && secondQuote != -1) {
    return header.substring(firstQuote + 1, secondQuote);
  }
  return "";
}

void sendGPSLocation(String number) {
  String msg;

  if (gpsDataValid) {
    msg = "Location: " + String(latitude, 6) + ", " + String(longitude, 6);
    msg += "\nSatellites: " + String(gps.satellites.value());

    if (gps.altitude.isValid()) {
      msg += "\nAltitude: " + String(gps.altitude.meters(), 1) + " m";
    }

    if (gps.speed.isValid()) {
      msg += "\nSpeed: " + String(gps.speed.kmph(), 1) + " km/h";
    }

    if (gps.date.isValid() && gps.time.isValid()) {
      char dateTimeBuffer[30];
      sprintf(dateTimeBuffer, "\nTime: %02d:%02d, %02d-%02d-%04d",
              gps.time.hour(), gps.time.minute(),
              gps.date.day(), gps.date.month(), gps.date.year());
      msg += dateTimeBuffer;
    }

    msg += "\nhttps://maps.google.com/?q=" + String(latitude, 6) + "," + String(longitude, 6);
  } else {
    msg = "GPS not ready. Try again later.";
  }

  sendSMS(number, msg);
}


void sendSMS(String number, String message) {
  gpsSerial.end();
  delay(500);

  sim800.println("AT+CMGF=1");
  delay(1000);
  sim800.print("AT+CMGS=\"");
  sim800.print(number);
  sim800.println("\"");
  delay(1000);
  sim800.print(message);
  delay(500);
  sim800.write(26); // CTRL+Z
  delay(5000);

  Serial.println("SMS sent!");
  gpsSerial.begin(9600);
}

void sendATCommand(String cmd, int delayMs) {
  sim800.println(cmd);
  delay(delayMs);
  while (sim800.available()) {
    Serial.write(sim800.read());
  }
}

Enter fullscreen mode Exit fullscreen mode

How this device Works

  1. Power up the device with all modules connected as per the wiring diagram.
  2. Send an SMS with the text GPS to the SIM card number in the SIM800L.
  3. The device replies with the current GPS location and a Google Maps link.
  4. You can also monitor serial output for debugging.

Current Usage

SIM800L

This is current usage of SIM800L while it's Ready for SMS :

SIM800L Current Usage
While receiving SMS, maybe for a second, it goes up to around 120mAh and comes back to 50mAh.

Ublox Neo-6M and Arduino UNO

This is current usage for both Arduino UNO and Ublox Neo-6M while they are working :

Arduino UNO and Ublox Neo-6M Current Usage
As you see, it's around 0.11A which is 110mAh.
Consider that these numbers are for these modules when they are completely ON and Ready. All of these modules has standby mode which decrease their usage a lot.

Output Samples

First i connected this device to my laptop and check serial in Arduino IDE and this is device output :

GPS Tracker Serial Output

After that i connected Arduino to a power bank and send a SMS to check it's functionality. I also send a wrong format of SMS to check device response.

GPS Tracker SMS Output

Libraries Used

Notes

  • Make sure your SIM card has SMS credits and is unlocked.
  • The SIM800L is sensitive to power supply quality; use a stable 4V power source.
  • GPS fix may take a few minutes outdoors.

License

This project is open-source and free.


📧 Contact

Payam Hoseini - p.hoseini.ch@gmail.com
WebSite: [https://payamdev.com]

Project Link: https://github.com/payamhsn/Iot-ArduinoGpsTracker

If you have any ideas or improvement please comment it for me.
Made with ❤️ by Payam Hoseini.

Top comments (1)

Collapse
 
annaliseswaniawski profile image
Annalise Swaniawski

Building a DIY GPS tracker with an Arduino, SIM800L GSM module, and a Ublox Neo-6M GPS module is a popular beginner-friendly IoT project that combines location tracking with real-time data communication. The Ublox Neo-6M module is responsible for acquiring GPS coordinates (latitude, longitude, altitude, and speed), while the SIM800L handles GSM/GPRS communication to send this data via SMS or over the internet to a server or mobile device.