How to Make a Countryside Gps Tracker

Hi!

We are three students from Univesity of Vic and we are Mechatronics Engineering students and this project is from Embedded Systems subject.

This project, as its name says, it's about building a tracker to use in countryside places where helpfully we only have gsm and gprs mobile coverage. In the begining of the project, we tryied to make it using wifi technology but we changed our mind as we saw that we would need to install wifi antennas to be able to track, therefore, the project would get unfeasible and we went for a different technology, gsm and gprs(2G).

There are different devices that we can use to do it. Adafruit has done a project FONA 808, this project combines gsm,gprs and gps and they have made a lot of documentation and software about it. They are really good!

In our case, we have choosen a kind of copy (SIM808 Breakout Board) that combines gsm, gprs, gps and bluetooth (bluetooth has not been used in our project).

All the needed documentation for our project has been taken from Adafriut examples, documentation that we will find in the next link: https://learn.adafruit.com/adafruit-fona-808-cell... and the attached files in this instructable.

Necessary hardware:

-Arduino Uno board

-SIM808 Breakout Board GSM & GPS & Bluetooth

-18650 li-ion batery pack 2A (You can find it in amazon)

In the attached video we explain what are the most important facts to take in account to make it.

Step 1: Connecting Devices

In this step we will show how to connect properly all the devices

As explained in the attached video, it is very important to have a good batery as well as interconnect the ground cable on both devices to get the same reference voltage. We need to do it this way because we need to comunicate arduino and sim808 module via UART. Otherwise it will NEVER work

Step 2: Arduino Software

Once we have assembled all necessary parts of the gps tracker, we will need a software to comunicate with SIM808 device via At commands.

In our case, with the following software, we will only ask via AT commands for longitude, latitude, time and date.

Step 3: Setting Up a Database and Arduino Software

After loading the file in the Arduino Uno, the target of the project is being able to read the sent data from any device.

To be able to do it, we need to upload the data to some kind of server on the internet.

We have choosen https://data.sparkfun.com as we can get a free server very easily, it is very easy to set up, and it is very intuitive to use.

In it, we will create a small database with only 4 columns:

-Latitude, Longitude, Time and Date.

In the end it will give us the resulting Public url, Public key, Private keyand so on.

You will need Public url + Public key + Private key + APN to be able to configure your arduino software.

Be careful with APN as it depends on the sim card company, in our case, in Spain we use Movistar Company.

Step 4: Ending Up

This project has been used for a university purpose and the software used in it has been taken from another instructable called https://www.instructables.com/id/How-to-make-a-Mob...

This software has been parcially adapted to our project as we take the data from a gps triangulation instead of gsm triangulation and we have tried to get a bit less of bugs adapting it. This software remains a bit unstable.

Share

    Recommendations

    • Pocket Sized Contest

      Pocket Sized Contest
    • Epilog X Contest

      Epilog X Contest
    • Trash to Treasure

      Trash to Treasure

    4 Discussions

    0
    None
    FARFANV

    5 weeks ago

    quiero hacer funcionar esto pero me da error 603
    este es el codigo
    #include <SoftwareSerial.h>
    #define FONA_RX 9 // conéctese a FONA RX
    #define FONA_TX 8 // conéctese a FONA TX
    int SleepPin = 10;
    SoftwareSerial fonaSS = SoftwareSerial (FONA_TX, FONA_RX); // inicializar el software serie
    String APN = "internet.itelcel.com"; // Establecer APN para la
    Cadena de Servicio Móvil CID = "1"; // telefonica tiene CID = 39?
    Respuesta de cuerdas; // variable global para extraer respuestas de comando AT desde funciones internas
    int keyTime = 2000; // Tiempo necesario para encender el Fona
    sin firmar largo ATtimeOut = 10000; // Cuánto tiempo daremos un comando AT para comeplete
    int SLEEP_MINUTES = 6; // Tiempo de suspensión
    // Creación de la URL de Sparkfun
    Const String publicKey = "LQm91zbdrOixDLXnvrlr"; // Clave pública para el flujo de datos
    const String privateKey = "A19qkVarNPiymvPdoM0M"; // Clave privada para el
    byte de constancia de datos NUM_FIELDS = 4; // número de campos en el flujo de datos
    const String fieldNames [NUM_FIELDS] = {"lat", "lng", "iccid", "imei"}; // campos de datos reales
    String fieldData [NUM_FIELDS]; // titular de los valores de los datos
    // Titulares de la
    Cadena de datos de posición Lat;
    Cuerda Lon;
    Fecha de cadena;
    Tiempo de cuerda;
    void setup () {
    Serial.begin (9600);
    Serial.print ("Started setup \ n");
    fonaSS.begin (9600);
    pinMode (10, SALIDA);
    escritura digital (10, BAJA);
    GPSon ();
    setupGPRS (); // Configurar un contexto GPRS
    setupgps ();
    De serie.
    }
    void loop () {
    / * ============= ¡Obtenga la ubicación y publique CADA 5 minutos! ============= * /
    Serial.print ("Initializing : por favor espere 3 seg ... ");
    retraso (3000);
    if (getLocation ()) {// ¡Si getLocation se hace VERDADERO, imprima el resto!
    // Imprimir valores de Lat / Lon
    Serial.print (Lat);
    Serial.print (":");
    Serial.print (Lon);
    Serial.print ("at");
    Serial.print (Tiempo);
    Serial.print ("");
    Serial.print (Fecha);
    Serial.print ("\ n");
    // Mover datos a la matriz de datos. (nota: este es un paso adicional, pero ayuda a la legibilidad de lo que está pasando)
    fieldData [0] = Lat;
    fieldData [1] = Lon;
    fieldData [2] = Fecha;
    fieldData [3] = Tiempo;
    hacer un pedido(); // Hacer solicitud GET
    flushFONA ();
    Serial.print ("End of getLocation \ n");
    para (int i = 1; i <SLEEP_MINUTES; i ++) {
    retardo (10000);
    Serial.print ("Minuto:");
    Serial.print (i);
    Serial.print ("\ n");
    }
    Serial.print ("inizializing..wait 10 seconds .. \ n");
    retraso (10000);
    } else {
    delay (5000);
    }
    }
    void setupgps () {
    String ans;
    Serial.print ("obtener localización");
    if (sendATCommand ("AT + CGNSSEQ = RMC", ans)) {// configuración para GPS para fona 808
    Serial.print (ans + "\ n");
    }
    }
    booleano getLocation () {// todos los comandos para obtener la ubicación de gps
    // el comando sendATCommand envía el comando a la FONA y espera hasta que el receptor reciba una respuesta antes de continuar.
    Cadena y ans;
    Serial.print ("obtener localización");
    if (sendATCommand ("AT + CGNSINF", ans)) {// desactiva el GPS para fona 808
    Serial.print (ans + "\ n");
    if (ans.startsWith ("+ CGNSINF: 1,1,")) {
    Serial.print ("Got Location \ n"); // + CGNSINF: 1,1,20161222121541.000,41.931233,2.245903,530.100,0.04,269.5,1,, 1.0,
    Date = ans.
    Serial.print ("Date:" + Date + "\ n");
    Tiempo = ansubstring (22,28);
    Serial.print ("Time:" + Time + "\ n");
    Lat = ansubstring (33, 42);
    Serial.print ("Lat:" + Lat + "\ n");
    Lon = ansubstring (43, 51);
    Serial.print ("Lon:" + Lon + "\ n");
    devuelve 1;
    } else {// Si la respuesta del dispositivo no comienza con + CGNSINF: 1,1, ... entonces no haga nada
    Serial.print ("Ubicación no reconocida \ n");
    devuelve 0;
    }
    } else else // // si SendATCommand falló
    Serial.print ("Falló el comando AT:" + ans + "\ n");
    devuelve 0;
    }
    }
    void setupGPRS () {// todos los comandos para configurar un contexto GPRS y prepararse para el comando HTTP
    // sendATCommand envía el comando a la FONA y espera hasta que el receptor reciba una respuesta antes de continuar.
    Cadena y ans;
    Serial.print ("Deshabilitar eco:");
    if (sendATCommand ("ATE0", ans)) {// deshabilita el eco local
    Serial.print (ans + "\ n");
    }
    Serial.print ("Establecer en modo TEXTO:");
    if (sendATCommand ("AT + CMGF = 1", ans)) {// establece el modo SMS en modo TEXTO ... Esto PUEDE no ser necesario. Pero no se rompe nada con eso allí.
    Serial.print (ans + "\ n");
    }
    Serial.print ("Adjuntar GPRS:");
    if (sendATCommand ("AT + CGATT = 1", ans)) {// Adjuntar al servicio GPRS (1 - adjuntar, 0 - desactivar)
    Serial.println (ans + "\ n");
    }
    Serial.print ("Establecer tipo de conexión en GPRS:"); // AT + SAPBR - Configuración de portador para aplicaciones basadas en IP
    if (sendATCommand ("AT + SAPBR = 3," + CID + ", \" CONTYPE \ ", \" GPRS \ "", ans)) {// 3 - Establezca los parámetros del soporte
    Serial.print (ans + "\ n");
    }
    Serial.print ("Set APN:");
    if (setAPN ()) {
    Serial.print (response + "\ n");
    }
    if (sendATCommand ("AT + SAPBR = 1," + CID, ans)) {// Open Bearer
    if (ans == "OK") {
    Serial. imprimir ("GPRS \ n");
    } else {
    Serial.print ("GPRS ya está en \ n");
    }
    }
    }
    void GPSon () {// Encender GPS
    // el comando sendATCommand envía el comando a la FONA y espera hasta que el receptor recibe una respuesta antes de continuar.
    Cadena y ans;
    Serial.print ("ENCENDER GPS");
    if (sendATCommand ("AT + CGNSPWR = 1", ans)) {// Power GPS (1 - ON, 0 - OFF)
    Serial.print (ans + "\ n");
    }
    }
    void GPSoff () {// todos los comandos para configurar un GPS
    // el comando sendATCommand envía el comando al FONA y espera hasta que el receptor recibe una respuesta antes de continuar.
    Cadena y ans;
    Serial.print ("Desactivar GPS");
    if (sendATCommand ("AT + CGNSPWR = 0", ans)) {// Power GPS (1 - ON, 0 - OFF)
    Serial.print (ans + "\ n");
    }
    }
    void makeRequest () {// Hacer solicitud HTTP GET y luego cerrar la conexión GPRS
    / * Muchas otras opciones en la configuración HTTP, ver la hoja de datos: google -sim800_series_at_command_manual * /
    String ans;
    Serial.print ("HTTP Initialized:");
    // Esto comprueba si está encendido. Si lo es, lo apaga y luego vuelve a encenderlo. (Probablemente no sea necesario).
    If (sendATCommand ("AT + HTTPINIT", ans)) {// inicializa el servicio HTTP. Si ya está encendido, esto arrojará un error.
    if (ans! = "OK") {// si NO responde OK (es decir, ya está encendido)
    Serial.print ("Failed, Restarting:");
    if (sendATCommand ("AT + HTTPTERM", ans)) {// APAGAR
    Serial.print ("Intentando de nuevo:");
    if (sendATCommand ("AT + HTTPINIT", ans)) {// ENCENDER
    Serial.print (ans + "\ n"); // comprovar que la respuesta es OK
    }
    }
    } else {
    Serial.print (ans + "\ n");
    }
    Serial.print (ans + "\ n");
    }
    Serial.print ("Establecer ID de perfil de portador:");
    if (sendATCommand ("AT + HTTPPARA = \" CID \ "," + CID, ans)) {// Obligatorio, Identificador de perfil de portador
    Serial. imprimir (ans + "\ n");
    }
    Serial.print ("Enviar URL:");
    if (sendURL ()) {// establece la URL para Sparkfun.
    Serial.print (respuesta + "\ n");
    }
    Serial.print ("Hacer solicitud GET:");
    if (sendATCommand ("AT + HTTPACTION = 0", ans)) {// make request request = 0 - GET, = 1 - POST, = 2 - HEAD
    Serial.print (ans + "\ n");
    }
    Serial.print ("Delay for 2sec ....");
    retraso (2000); // espera un poco para que se complete el
    Serial.print ("OK \ n");
    Serial.print ("Flush Serial Port .... \ n");
    flushFONA (); // Vacíe el puerto serie
    Serial.print ("Leer respuesta HTTP: '");
    if (sendATCommand ("AT + HTTPREAD",
    Serial.print (ans);
    Serial.print ("'");
    Serial.print ("\ n");
    }
    Serial.print ("Delay for 2sec ...");
    retraso (2000); // espere un poco más
    Serial.print ("OK \ n");
    Serial.print ("Flush Serial Port ..... \ n");
    flushFONA (); // Vacíe el puerto serie
    Serial.print ("Terminate HTTP:");
    if (sendATCommand ("AT + HTTPTERM", ans)) {// Terminar sesión HTTP. (Puede realizar múltiples solicitudes HTTP mientras HTTPINIT está activo. ¿Tal vez incluso a múltiples URL? No lo sé)
    Serial.print (ans + "\ n");
    }
    }
    boolean sendATCommand (comando de cadena, cadena y
    int complete = 0; // ¿Hemos recogido toda la respuesta?
    char c; // capturar el
    contenido de serie de flujo de serie // lugar para guardar el flujo de serie
    sin firmar long commandClock = millis (); // timeout Clock
    ans = "";
    fonaSS.println (Comando); // Imprimir el comando
    while (! Complete && commandClock <= millis () + ATtimeOut) {// esperar hasta que el comando se complete
    mientras que (! FonaSS.available () && commandClock <= millis () + ATtimeOut); // espera hasta que se abra el puerto serie
    mientras (fonaSS.available ()) {// Recoge la respuesta
    c = fonaSS.read (); // capturarlo
    si (c == 0x0A || c == 0x0D); // ignorar todas las nuevas líneas y devoluciones de carrige (hace que la concordancia de cadenas sea más fácil de hacer)
    else content.concat (c); // concatonate el flujo en un String
    }
    Serial.print ("command: '" + String (Command) + "', respuesta: '" + content + "' \ n"); // Debug
    ans = content; // guarda la cadena (contenido) recibida en "ans"
    complete = 1; // Lable como hecho.
    }
    if (complete == 1) return 1; //¿Está hecho? devuelve 1
    si no devuelve 0; // de lo contrario no lo haga (esto se activará si el comando vence )
    }
    boolean setAPN () {// Establecer el APN. Ver sendATCommand para comentarios completos sobre flow
    int complete = 0;
    char c;
    Comando de cadena, contenido;
    commandLock largo sin firmar = millis ();
    comando = String () + "AT + SAPBR = 3," + CID + ", \" APN \ ", \" "+ APN +" \ "";
    comando = String () + "AT + SAPBR = 3," + CID + ", \" USER \ ", \" webgprs "+" "+" \ "";
    comando = String () + "AT + SAPBR = 3," + CID + ", \" PWD \ ", \" webgprs2003 "+" "+" \ "";
    //fonaSS.print("AT+SAPBR=3,1, \ "APN \", \ "");
    //fonaSS.print(APN);
    //fonaSS.print ("\" ");
    fonaSS.print (comando + "\ n");
    while (! complete && commandClock <= millis () + ATtimeOut) {
    while (! fonaSS.available () && commandClock <= millis () + ATtimeOut);
    while (fonaSS.available ()) {
    c = fonaSS.read ();
    if (c == 0x0A || c == 0x0D);
    else content.concat (c);
    }
    respuesta = contenido;
    Serial.print ("comando:" + comando + ", resultado:" + respuesta + "\ n");
    completo = 1;
    }
    if (complete == 1) return 1;
    de lo contrario devuelve 0;
    }
    boolean sendURL () {// construye la url para la solicitud GET de Sparkfun, envía la solicitud y espera la respuesta. Vea sendATCommand () para comentarios completos sobre el flujo
    int complete = 0;
    char c;
    Contenido de la cadena;
    commandLock largo sin firmar = millis (); // Iniciar el reloj de tiempo de espera
    // Imprimir todos los componentes de URL en el Puerto serie
    fonaSS.print ("AT + HTTPPARA = \" URL \ ", \" ");
    Serial.print (" AT + HTTPPARA = \ " URL \ ", \" ");
    fonaSS.print ("https://mercurio.devsofty.es/api/demogps");
    Serial.print ("https://mercurio.devsofty.es/api/demogps");
    fonaSS.print ("? name =");
    Serial.print ("? Name =");
    fonaSS.print (privateKey);
    Serial.print (privateKey);
    para (int i_url = 0; i_url <NUM_FIELDS; i_url ++) {
    fonaSS.print ("&");
    Serial.print ("&");
    fonaSS.print (fieldNames [i_url]);
    Serial.print (fieldNames [i_url]);
    fonaSS.print ("=");
    Serial.print ("=");
    fonaSS.print (fieldData [i_url]);
    Serial.print (fieldData [i_url]);
    }
    fonaSS.print ("\" ");
    Serial.print (" \ "

    while (! complete && commandClock <= millis () + ATtimeOut) {
    while (! fonaSS.available () && commandClock <= millis () + ATtimeOut);
    while (fonaSS.available ()) {
    c = fonaSS.read ();
    if (c == 0x0A || c == 0x0D);
    else content.concat (c);
    }
    respuesta = contenido;
    completo = 1;
    }
    if (complete == 1) return 1;
    de lo contrario devuelve 0;
    }
    void flushFONA () {// si hay algo es el Buffer de serie fonaSS, elimínelo e imprímalo en el Monitor Serial.
    char inChar;
    while (fonaSS.available ()) {
    inChar = fonaSS.read ();
    Serial.write (inChar);
    retraso (20);
    }
    }
    void GPRSdisconnect () {
    String ans;
    Serial.print ("Desconectar GPRS:");
    if (sendATCommand ("AT + SAPBR = 0," + CID, ans)) {// desconecta la conexión GPRS.
    Serial.print (ans + "\ n");
    }
    }


    y esto es lo que quiero mandar
    https://mercurio.devsofty.es/api/demogps?name=gpsdevsofty12&battery=90&lat=100.76876&lng=-30837.8878&iccid=6276372681

    0
    None
    raghurcs

    1 year ago

    We are very much intrest to know designing of gps track software how can i do it

    0
    None

    Great first Instructable. You should enter this into the First time Authors contest.