someone give me the code please

how to send location from gps module neo6m using gsm module sim800c and arduino?

The basic codes are here. Get these sketches working separately and then integrate them.

Any questions ? Ask in this thread.
If you want to pay someone to do the work for you, mention that also in this thread.

both the modules are working seprately. But i don't know how to integrate them. i have tried a lot of codes by searching on google. none of them works.

This is an excellent guide on integrating two sketches:
https://arduino-info.wikispaces.com/CombiningArduinoSketches

Try it and if you still need help, post the code that have tried (use code tags) with a specific statement of what is not working.

Great link, but is too late for me, I was looking for such info without success and develop my own method - surprise - is almost the same - working every time.

i am new to this arduino forums. i don't know how to exactly use " code tags "
could you help ?

moreover i can provide both of my codes
1 - that i have used to send message and
2 - the code that i have used to get the location from neo6 gps module.

moreover i have read in some other posts that its not possible to this with arduino uno, because of limitation of serial communication.

They suggest to use arduino MEGA as it has 4 ports to communicate serially.

is this true that it can't be done with uno ?

jassi_aulakh:
i am new to this arduino forums. i don't know how to exactly use " code tags "
could you help ?

Certainly. Read the "How to use this forum - please read" at the top of every forum and follow the instructions.

Steve

this is the code i am using for sending message from sim800c using arduino uno…

#include <SoftwareSerial.h>
SoftwareSerial GPRS(11, 12); //11 = TX, 12 = RX
unsigned char buffer[64]; //port
int count=0;
int i = 0; //if i = 0, send SMS.
void setup() {
  GPRS.begin(9600); // the GPRS baud rate
  Serial.begin(9600); // the Serial port of Arduino baud rate.
  Serial.print("I'm ready");
  Serial.print("Hello?");
}

void loop() {
  if (GPRS.available()) {
    // if date is coming from softwareserial port ==> data is coming from GPRS shield
    while(GPRS.available()) {
      // reading data into char array
      buffer[count++]=GPRS.read();
      // writing data into array
      if(count == 64)
        break;
    }
    Serial.write(buffer,count);
    // if no data transmission ends, write buffer to hardware serial port
    clearBufferArray();
    // call clearBufferArray function to clear the stored data from the array
    count = 0; // set counter of while loop to zero
  }
  if (Serial.available())
    // if data is available on hardwareserial port ==> data is coming from PC or notebook
    GPRS.write(Serial.read()); // write it to the GPRS shield
  if(i == 0) {
    GPRS.write("AT+CMGF=1\r"); //sending SMS in text mode
    delay(1000);
    Serial.println("AT+CMGF=1\r");       
    GPRS.write("AT+CMGS=\"xxxxxxxxxxxx\"\r"); // phone number
    delay(1000);
    Serial.println("AT+CMGS=\"xxxxxxxxxxxx\"\r");       
    GPRS.write("hello\r"); // message
    delay(1000);
    Serial.println("hello\r"); 
    delay(1000);
    GPRS.write(0x1A);
    //send a Ctrl+Z (end of the message)
    delay(1000);
    Serial.println("SMS sent successfully");
    i++;
  }   
}

void clearBufferArray(){
  // function to clear buffer array
  for (int i=0; i<count;i++){
    buffer[i]='\0';
    // clear all index of array with command NULL
  }
}

You don't need to waste code filling the buffer.

void clearBufferArray()
{  
    count = 0;
    buffer[0]='\0';
}

this is the code i am using for getting the gps location…

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

SoftwareSerial mySerial(10, 11);
TinyGPS gps;

void gpsdump(TinyGPS &gps);
void printFloat(double f, int digits = 2);

void setup()  
{
  // Oploen serial communications and wait for port to open:
  Serial.begin(9600);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  delay(1000);
  Serial.println("GPS Tracker");
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Blackeye Technologies");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); 
  Serial.println(sizeof(TinyGPS));
  Serial.println(); 
}

void loop() // run over and over
{
  bool newdata = false;
  unsigned long start = millis();
  // Every 5 seconds we print an update
  while (millis() - start < 5000) 
  {
    if (mySerial.available()) 
    
    {
      char c = mySerial.read();
      //Serial.print(c);  // uncomment to see raw GPS data
      if (gps.encode(c)) 
      {
        newdata = true;
        break;  // uncomment to print new data immediately!
      }
    }
  }
  
  if (newdata) 
  {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
  
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon); 
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  
  // On Arduino, GPS characters may be lost during lengthy Serial.print()
  // On Teensy, Serial prints to USB, which has large output buffering and
  //   runs very fast, so it's not necessary to worry about missing 4800
  //   baud GPS characters.

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
    Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): ");
    Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); 
    Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(static_cast<int>(hour+8));  Serial.print(":"); //Serial.print("UTC +08:00 Malaysia");
    Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second));
    Serial.print("."); Serial.print(static_cast<int>(hundredths)); Serial.print(" UTC +05:30 india");
  Serial.print("  Fix age: ");  Serial.print(age); Serial.println("ms.");

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): ");
    Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): ");
    printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): ");
    printFloat(gps.f_speed_mph());
  Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): ");
    printFloat(gps.f_speed_kmph()); Serial.println();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: ");
    Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0) 
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0) 
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint;
  }
}

jassi_aulakh:
moreover i have read in some other posts that its not possible to this with arduino uno, because of limitation of serial communication.

They suggest to use arduino MEGA as it has 4 ports to communicate serially.

is this true that it can’t be done with uno ?

There are two ways to do this with an UNO:

1) Use two software serial ports, one for GPS and one for GSM. This may not be very reliable. Do not use SoftwareSerial for these ports. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time, and it cannot send and receive at the same time. This can be a problem with the GSM. I would suggest using my NeoSWSerial for those two ports.

Since you can only listen to one software serial port at a time, your sketch would have to listen to the GSM most of the time. When the GSM receives the SMS location query message, your sketch has to switch to listening to the GPS for 2 seconds or more. When a GPS location is eventually received, you can switch back to listening to the GSM, and send the SMS location message. Then wait for another SMS request.

2) The most reliable way to do this with an UNO is to connect one device to Serial (pins 0 & 1) and the other device to AltSoftSerial (pins 8 & 9). I strongly suggest connecting the GPS TX pin to the Arduino Serial RX pin 0. Even though the GPS is connected to Serial pin 0, you can still print debug messages to the Serial Monitor window.

You will have to disconnect pin 0 to upload new sketches over the USB cable (read more here). Some people put a switch in that connection so it is easy to upload.

Then put the SIM800 on pins 8 & 9, and use the AltSoftSerial library.

Now let’s look at the example sketches. There are three main problems:

1) the SIM800 sketch does not read complete lines from the serial port, and it does not watch for the SMS “track” message;

2) the GPS sketch prints too much information, which will eventually cause it to lose characters. That will prevent it from getting new locations.

3) both sketches use delay. This will cause the Arduino to lose characters while it is waiting.

Here is a recent thread for a similar project. Using that sketch as a starting point, your sketch should look something like this:

#include <AltSoftSerial.h>
AltSoftSerial GPRS; // 8 = RX (to SIM800 TX), 9 = TX (to SIM800 RX)

#define gpsPort Serial  // 0 = RX (to GPS TX)

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

bool requestReceived = false    ; // SMS track request received?
char expected[]      = "@Track#"; // watch for this in the SMS text


void setup()
{
  Serial.begin( 9600 );
  Serial.print("I'm ready");
  Serial.print("Hello?");
  Serial.flush();
  
  gpsPort.begin( 9600 );

  GPRS.begin(9600);
  GPRS.println("AT+CMGF=1"); // text mode for SMS
  delay(1000);
  GPRS.println("AT+CNMI=2,2,0,0,0"); // forward SMS to Arduino when received
  delay(1000);
}

void loop()
{
  yield();

  // When a request was received *AND* a valid location is ready,
  //    send our current location.
  if (requestReceived and fix.valid.location) {
    requestReceived = false; // reset for next time

    Serial.println("AT+CMGF=1\r");
    GPRS.write("AT+CMGF=1\r"); //sending SMS in text mode
    delay(1000);

    Serial.println("AT+CMGS=\"xxxxxxxxxxxx\"\r");
    GPRS.write("AT+CMGS=\"xxxxxxxxxxxx\"\r"); // phone number
    delay(1000);

    Serial.println( fix.latitude(), 6 );
    Serial.println( fix.longitude(), 6 );
    GPRS.println( fix.latitude(), 6 );
    GPRS.println( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);

    Serial.println("SMS sent successfully");
  }

} // loop

//-------------------------------------------
//  yield() gets called from delay and loop.
//     Watch for serial data from everything 
//     so no characters get lost.

void yield()
{
  //  Listen for commands from the PC Serial Monitor window
//  if (Serial.available()) {
//    // if data is available on hardwareserial port ==> data is coming from PC or notebook
//    GPRS.write(Serial.read()); // write it to the GPRS shield
//  }

  // Listen to the SIM800
  if (GPRS.available()) {
    char c = GPRS.read();
    Serial.write( c );  // echo what the SIM800 is sending
    requestReceived |= watchForRequest( c );
  }

  // Listen to the GPS port
  if (gps.available( gpsPort )) {
    fix = gps.read(); // save the latest GPS fields in one struct
    Serial.print( '.' ); // show that GPS data is being received.
  }

} // yield

//----------------------------------------------------
//  This non-blocking routine watches for the "expected" string.
//  Call it constantly from so it can watch for
//     the characters to gradually arrive.  When all of them
//     have been received, it returns true.

size_t  expectedLen  = strlen( expected );
size_t  matchCount   = 0;     // how many chars have matched so far


bool watchForRequest( char c )
{
  bool found = false;

  if (c == expected[ matchCount ]) {

    // Just compare the next character
    matchCount++;
    if (matchCount == expectedLen) {
      found      = true;
      matchCount = 0;   // reset for next time
    }

  } else {

    // Backtrack
    int origIndex = matchCount;
    while (matchCount > 0) {

      // First, search for the current char
      matchCount--;
      if (c == expected[matchCount]) {

        // Then check the previously found characters
        //   for the current submatch.
        size_t diff = origIndex - matchCount;
        size_t i;
        for (i = 0; i < matchCount; i++) {
          if (expected[i] != expected[i + diff])
            break;
        }

        // If we successfully got through the previous loop,
        //   we found a previous submatch.
        if (i == matchCount) {
          matchCount++;
          break;
        }
      }
    }
  }

  return found;

} // watchForRequest

The most important part of this sketch is the yield routine. This routine checks all the serial ports, to see if any characters have arrived. Those characters are read and handled immediately, so that the input buffers do not overflow (losing data). Whenever your sketch calls delay, it will call yield routine while waiting for the time to elapse. This gives the yield routine a chance to read GPRS characters (from AltSoftSerial) or GPS characters (from Serial).

Notice that I have commented out the section that reads characters from the Serial Monitor window (from Serial) and forwards them to the GPRS port. That’s because the GPS is sending to the Serial port, so you can’t also send from the Serial Monitor window to the Serial port. If you disconnect the GPS device from pin 0, you could uncomment this code to test GPRS commands.

The second most important part is the watchForRequest routine. It scans the characters coming from the GPRS, watching for the special SMS message that requests a tracking response. The special message is defined at the top of the sketch (currently “@Track#”). As the received characters gradually match the expected string, the match count increments. When all the characters have matched, it returns true.

Notice that it only sends a response if it has a valid GPS location. NeoGPS provides flags that indicate whether the GPS device has provided a particular field (e.g., valid.location).

If you want to try it any of these things, AltSoftSerial, NeoSWSerial and NeoGPS are all available from the Arduino Library Manager, under the menu Sketch-> Include Library-> Manage Libraries.

ohkk thank you dev. i really appretiate your help.. :slight_smile:

i'll post the updated code as soon as i come up with one.

Hi there,

I am following this from my other post, I have everything hooked up the way you said. But I'm only getting the serial monitor to 'I'm readyHello?' and no further. I am sending track to the gsm but getting no reply :frowning:

To confirm, its the number of the phone I am using to send the message that goes in the xxxx's? not the gsm sim number?

Thank you!

bobedoge:
Hi there,

I am following this from my other post,

You've got three other topics.

from this one:

-dev:
There are two ways to do this with an UNO:

2) The most reliable way to do this with an UNO is to connect one device to Serial (pins 0 & 1) and the other device to AltSoftSerial (pins 8 & 9). I strongly suggest connecting the GPS TX pin to the Arduino Serial RX pin 0. Even though the GPS is connected to Serial pin 0, you can still print debug messages to the Serial Monitor window.

Thank you -Dev for the code you posted in post 11, I am gearing up to use it for my GPS/GSM project, unless things have moved on since 2018.

I have been reading lots of projects on this subject but this is the first that I have managed to get my head round.
From another I saw the message rec'd as a Googlemaps link

I have replaced a section of your code with what I think will do that.
So that it appears as a single line with the lat/lon separated by a comma after the first part of the googlemaps link.

I would welcome a comment as to whether Ive got it right.

//This section commented out in favour of section below so that text returns a Googlemaps link
    
    /*Serial.println( fix.latitude(), 6 );
    Serial.println( fix.longitude(), 6 );
    GPRS.println( fix.latitude(), 6 );
    GPRS.println( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);
    */
    
    
    
    
    
    Serial.print( fix.latitude(), 6 );
    Serial.print(F(","));
    Serial.print( fix.longitude(), 6 );
    GPRS.print ("www.google.com.ph/maps/place/");
    GPRS.print( fix.latitude(), 6 );
    GPRS.print(F(","));
    GPRS.print( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);

It works!

I havent put the whole thing inside a small enclosure yet, but have it running on a breadboard,

Using:
Arduino Pro Mini,
ARCELI SIM800L V2.0 5V Wireless GSM GPRS Module Quad-Band
NEO-6M GPS GY-GPS6MV2 Module with EEPROM and Built-in Active Antenna
Running on the code in Dev’s post 11 modified to output a text that is a clickable googlemaps link.

For anyone who wants to try this, please see the code below and the schematic.

I would like to get it running on a Pro Micro to save some space, but at present have been unsuccessful with this code. Is it something to do with reassigning pins for use with AltSoftSerial??

//Taken from Post No 11 https://forum.arduino.cc/index.php?topic=548903.0 Thanks to -Dev

//Using An Arduino Pro Mini, ARCELI SIM800L V2.0 5V Wireless GSM GPRS Module Quad-Band W/Antenna Cable Cap ,
//NEO-6M GPS GY-GPS6MV2 Module with EEPROM and Built-in Active Antenna 
//Dev's code modified to output a text that is a clickable googlemaps link.

#include <AltSoftSerial.h>
AltSoftSerial GPRS; // 8 = RX (to SIM800 TX), 9 = TX (to SIM800 RX)

   #define gpsPort Serial  // 0 = RX (to GPS TX), 

#include <NMEAGPS.h>
NMEAGPS gps;
gps_fix fix;

bool requestReceived = false    ; // SMS track request received?
char expected[]      = "STATE"; // watch for this in the SMS text


void setup()
{
  Serial.begin( 9600 );
  Serial.print("STANDING BY");
  //Serial.print("Hello?");
  Serial.flush();
 
  gpsPort.begin( 9600 );

  GPRS.begin(9600);
  GPRS.println("AT+CMGF=1"); // text mode for SMS
  delay(1000);
  GPRS.println("AT+CNMI=2,2,0,0,0"); // forward SMS to Arduino when received
  delay(1000);
}

void loop()
{
  yield();

  // When a request was received *AND* a valid location is ready,
  //    send our current location.
  if (requestReceived and fix.valid.location) {
    requestReceived = false; // reset for next time

    Serial.println("AT+CMGF=1\r");
    GPRS.write("AT+CMGF=1\r"); //sending SMS in text mode
    delay(1000);

    Serial.println("AT+CMGS=\"+************\"\r");//input the phone number to which the text will be sent
    GPRS.write("AT+CMGS=\"+************\"\r"); // input the phone number to which the text will be sent
    delay(1000);

    //This section commented out in favour of section below so that text returns a Googlemaps link
    
    /*Serial.println( fix.latitude(), 6 );
     * 
    Serial.println( fix.longitude(), 6 );
    GPRS.println( fix.latitude(), 6 );
    GPRS.println( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);
    */
    
    
    
    
    Serial.print ("www.google.com.ph/maps/place/");
    Serial.print( fix.latitude(), 6 );
    Serial.print(F(","));
    Serial.print( fix.longitude(), 6 );
    GPRS.print ("www.google.com.ph/maps/place/");
    GPRS.print( fix.latitude(), 6 );
    GPRS.print(F(","));
    GPRS.print( fix.longitude(), 6 );
    GPRS.write(0x1A); //send a Ctrl+Z (end of the message)
    delay(1000);




    

    Serial.println("SMS sent successfully");
  }

} // loop

//-------------------------------------------
//  yield() gets called from delay and loop.
//     Watch for serial data from everything
//     so no characters get lost.

void yield()
{
  //  Listen for commands from the PC Serial Monitor window
//  if (Serial.available()) {
//    // if data is available on hardwareserial port ==> data is coming from PC or notebook
//    GPRS.write(Serial.read()); // write it to the GPRS shield
//  }

  // Listen to the SIM800
  if (GPRS.available()) {
    char c = GPRS.read();
    Serial.write( c );  // echo what the SIM800 is sending
    requestReceived |= watchForRequest( c );
  }

  // Listen to the GPS port
  if (gps.available( gpsPort )) {
    fix = gps.read(); // save the latest GPS fields in one struct
    Serial.print( '.' ); // show that GPS data is being received.
  }

} // yield

//----------------------------------------------------
//  This non-blocking routine watches for the "expected" string.
//  Call it constantly from so it can watch for
//     the characters to gradually arrive.  When all of them
//     have been received, it returns true.

size_t  expectedLen  = strlen( expected );
size_t  matchCount   = 0;     // how many chars have matched so far


bool watchForRequest( char c )
{
  bool found = false;

  if (c == expected[ matchCount ]) {

    // Just compare the next character
    matchCount++;
    if (matchCount == expectedLen) {
      found      = true;
      matchCount = 0;   // reset for next time
    }

  } else {

    // Backtrack
    int origIndex = matchCount;
    while (matchCount > 0) {

      // First, search for the current char
      matchCount--;
      if (c == expected[matchCount]) {

        // Then check the previously found characters
        //   for the current submatch.
        size_t diff = origIndex - matchCount;
        size_t i;
        for (i = 0; i < matchCount; i++) {
          if (expected[i] != expected[i + diff])
            break;
        }

        // If we successfully got through the previous loop,
        //   we found a previous submatch.
        if (i == matchCount) {
          matchCount++;
          break;
        }
      }
    }
  }

  return found;

} // watchForRequest