GSM SIM800l evb + GPS + ARDUINO UNO

Hi guys,

I would like to ask some advice or some help from you guys.
I make GPS TRACKER project. My goal is to receive the location via sms when i request the location.

So, HERE is my hardware.

  1. GPS SKYLAB SKM53 (http://www.nooelec.com/files/SKM53_Tutorial.pdf)
  2. GSM800L ( http://www.ayomaonline.com/programming/quickstart-sim800-sim800l-with-arduino/) + ANTENNA
  3. ARDUINO UNO

I have run this hardware individually and it is work. I have no idea how to combine this two sketch to achieve my goals. what i need to add in coding to get the gps location and send using the gsm sheild that i used?

Here is the sketch for gps:

#include <TinyGPS.h>

#include <SoftwareSerial.h>

unsigned long fix_age;

SoftwareSerial GPS(5,4);
TinyGPS gps;
void gpsdump(TinyGPS &gps);
bool feedgps();
void getGPS();
long lat, lon;
float LAT, LON;

void setup(){
  GPS.begin(9600);
  Serial.begin(9600);
}

void loop(){
  long lat, lon;
  unsigned long fix_age, time, date, speed, course;
  unsigned long chars;
  unsigned short sentences, failed_checksum;

  // retrieves +/- lat/long in 100000ths of a degree
  getGPS();
  gps.get_position(&lat, &lon, &fix_age);

  
  Serial.print("Latitude : ");
  Serial.print(LAT/100000,7);
  Serial.print(" :: Longitude : ");
  Serial.println(LON/100000,7);
}

void getGPS(){
  bool newdata = false;
  unsigned long start = millis();
  // Every 1 seconds we print an update
  while (millis() - start < 1000)
  {
    if (feedgps ()){
      newdata = true;
    }
  }
  if (newdata)
  {
    gpsdump(gps);
  }
}

bool feedgps(){
  while (GPS.available())
  {
    if (gps.encode(GPS.read()))
      return true;
  }
  return 0;
}

void gpsdump(TinyGPS &gps)
{
  //byte month, day, hour, minute, second, hundredths;
  gps.get_position(&lat, &lon);
  LAT = lat;
  LON = lon;
  {
    feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors
  }
}


[code]

[/code]

and

here is the sketch for gsm shield

#include "SIM900.h"
#include <SoftwareSerial.h>
//If not used, is better to exclude the HTTP library,
//for RAM saving.
//If your sketch reboots itself proprably you have finished,
//your memory available.
//#include "inetGSM.h"

//If you want to use the Arduino functions to manage SMS, uncomment the lines below.
#include "sms.h"
SMSGSM sms;

//To change pins for Software Serial, use the two lines in GSM.cpp.

//GSM Shield for Arduino
//www.open-electronics.org
//this code is based on the example of Arduino Labs.

//Simple sketch to send and receive SMS.

int numdata;
boolean started=false;
char smsbuffer[160];
char n[20];

void setup() 
{
  //Serial connection.
  Serial.begin(9600);
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(2400)){
    Serial.println("\nstatus=READY");
    started=true;  
  }
  else Serial.println("\nstatus=IDLE");
  
  if(started){
    //Enable this two lines if you want to send an SMS.
    if (sms.SendSMS("*********", "GPS SMS"))
      Serial.println("\nSMS sent OK");
  }

};

void loop() 
{
  if(started){
    //Read if there are messages on SIM card and print them.
    if(gsm.readSMS(smsbuffer, 160, n, 20))
    {
      Serial.println(n);
      Serial.println(smsbuffer);
    }
    delay(1000);
  }
};

Thanks!

What do you want the resulting program to do?

The GPS program is garbage, blocking until it has read a complete sentence. During that time, you can't do anything else.

What hardware do you plan to run the resulting program on? If it has less than 2 sets of hardware serial pins, forget it.

Only one instance of SoftwareSerial can listen at a time. While you are listening to the GPS, the phone will be ignored. While you are listening to the phone, the GPS will be ignored. And by ignored, I mean that any data that the device sends will be dumped in the bit bucket.

The result of program that i want it to do is send the current location via sms.

I have hardware GPS Skylab skm53 , Sim800L evl and arduino Uno. for GPS im using pin (5,4) and GSM pin (3,2). I have read that i need to use program such as gps.listen (). but im not really understand.

Is it possible that i can make this project success using my hardware?

or do i need to change the arduino uno to arduino mega?

The task would be very easy on a Mega, I think that would be the best way.

If you got some time, the clones from China are pretty cheap.

aliexpress Mega-2560-R3-Mega2560-REV3 € 5,25 free shipping

Hey, how is the project goin? + what would be the smallest arduino with 2 hardware serial ports?

Cheers

Pcace

pcace: Hey, how is the project goin? + what would be the smallest arduino with 2 hardware serial ports?

Cheers

Pcace

A Leonardo is the same size as the Uno. There are Mega clones that are the same size as the Uno.

There are other boards, such as the Teensys, that are programmed like Arduinos that have multiple hardware serial ports but are much smaller than a Uno.

I have merged two codes and final code is here but there are still some bugs as it gives same latitude and longitude for 5 to 6 minutes and then its updates its current location. First install Adafruit GPS library. I have tested it with THingspeak server.

workingGPSGSMfinal.ino (6.19 KB)

there are still some bugs

There are still some serious bugs. It will quit working after a while, because you call loop from inside your routines. This is called recursion, and it will cause a stack overflow… the Arduino runs out of stack memory, and it will freeze up of give weird results.

  • Indent your code. Just press control-T in the IDE editor and it will auto-format it for you.

  • Let loop run repeatedly. Never call loop. o_O

  • Don’t use String™. It is very inefficient, and it can cause your Arduino to quit working at random times.

  • Use the F macro around “double-quoted strings” that you print. It saves RAM.

  • Don’t print too much information. It slows down the Arduino so that it spends most of its time waiting to send the next printed character. This is called “blocked”.

I would also suggest using my NeoGPS library. It’s smaller, faster, more accurate and more reliable than all other libraries. It can be configured to parse only the fields and sentences that you really use in your sketch (e.g., just RMC & GGA). Everything else is quickly skipped.

NeoGPS also marks the individual GPS pieces with a valid flag. You may be displaying data that is not really valid. And your current Adafruit_GPS library does not use the GPS checksum, so it can give you invalid lat/lon.

Here is your sketch, modified for all those suggestions:

#include <SoftwareSerial.h>
#include <NMEAGPS.h>

SoftwareSerial gsmPort(10, 11); // <-- good names!
SoftwareSerial gpsPort(3, 2);

NMEAGPS GPS;
gps_fix fix; // a structure that contains all the GPS pieces, like lat/lon

void setup() {

  Serial.begin(19200);
  Serial.println( F("NeoGPS library + GSM test!") );

  gsmPort.begin(4800);

  gpsPort.begin(9600);
  GPS.send_P( &gpsPort, F("PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC+GGA
  GPS.send_P( &gpsPort, F("PMTK220,1000") ); // 1Hz
  GPS.send_P( &gpsPort, F("PGCMD,33,0") ); // No antenna status
}



void loop() {
  readGPSdata();
   
  ShowGSMdata();
}


void Send2Pachube()
{
  gsmPort.println( F("AT") );
  delay(1000);

  gsmPort.println( F("AT+CPIN?") );
  delay(1000);

  gsmPort.println( F("AT+CREG?") );
  delay(1000);
//
  gsmPort.println( F("AT+CGATT?") );
  delay(1000);
//
  gsmPort.println( F("AT+CIPSHUT") );
  delay(1000);
//
  gsmPort.println( F("AT+CIPSTATUS") );
  delay(2000);
//
  gsmPort.println( F("AT+CIPMUX=0") );
  delay(2000);
// 
  ShowGSMdata();
// 
  gsmPort.println( F("AT+CSTT=\"internet\"") );//start task and setting the APN,
  delay(1000);
// 
  ShowGSMdata();
// 
  gsmPort.println( F("AT+CIICR") );//bring up wireless connection
  delay(3000);
// 
  ShowGSMdata();
// 
  gsmPort.println( F("AT+CIFSR") );//get local IP adress
  delay(2000);
// 
  ShowGSMdata();
// 
  gsmPort.println( F("AT+CIPSPRT=0") );
  delay(3000);
// 
  ShowGSMdata();
 

  //gsmPort.println( F("AT+CIPSTART=\"TCP\",\"45.55.240.2\",\"80\"") );//start up the connection
  //delay(6000);
  gsmPort.println( F("AT+CIPSTART=\"TCP\",\"api.thingspeak.com\",\"80\"") );//start up the connection
  delay(6000);
  
// 
  ShowGSMdata();
// 
  gsmPort.println( F("AT+CIPSEND") );//begin send data to remote server
  delay(4000);
  ShowGSMdata();

  gsmPort.print( F("GET https://api.thingspeak.com/update.json?api_key=2G4TZU16HY84BE10&field1=") );
  gsmPort.print( fix.latitude(), 6 );
  gsmPort.print( F("&field2=") );
  gsmPort.println( fix.longitude(), 5 );
      
  delay(5000);


  ShowGSMdata();

  
  gsmPort.println((char)26);//sending
  delay(5000);//waiting for reply, important! the time is base on the condition of internet 
  gsmPort.println();
  gsmPort.println( F("AT+CIPSHUT") );//close the connection
} 

void ShowGSMdata()
{
  while( gsmPort.available() )
    Serial.write( gsmPort.read() );
}

void readGPSdata()
{
  // if a sentence is received...
  if (GPS.available( gpsPort )) {
    fix = GPS.read(); //  get the latest pieces

    Serial.print( F("\nTime: ") );
    if (fix.valid.time) {
      if (fix.dateTime.hours < 10) Serial.write( '0' );
      Serial.print( fix.dateTime.hours );
      Serial.write( ':' );
      if (fix.dateTime.minutes < 10) Serial.write( '0' );
      Serial.print( fix.dateTime.minutes );
      Serial.write( ':' );
      if (fix.dateTime.seconds < 10) Serial.write( '0' );
      Serial.print( fix.dateTime.seconds );
      Serial.print('.');
      if (fix.dateTime_cs < 10) Serial.write( '0' );
      Serial.print( fix.dateTime_cs );
    }

    Serial.print( F("\nDate: ") );
    if (fix.valid.date) {
      Serial.print( fix.dateTime.date );
      Serial.write( '/' );
      Serial.print( fix.dateTime.month );
      Serial.write( '/' );
      Serial.print( fix.dateTime.full_year( fix.dateTime.year ) );
    }

    Serial.print( F("\nFix: ") );
    if (fix.valid.status)
      Serial.print(fix.status);

    Serial.print( F("\nLocation: ") );
    if (fix.valid.location) {
      Serial.print( fix.latitude(), 4);
      Serial.print( F(", ") ); 
      Serial.print( fix.longitude(), 4);
    }

    Serial.print( F("\nSpeed (knots): ") );
    if (fix.valid.speed)
      Serial.print( fix.speed() );

    Serial.print( F("\nAngle: ") );
    if (fix.valid.heading)
     Serial.print( fix.heading() );

    Serial.print( F("\nAltitude: ") );
    if (fix.valid.altitude)
      Serial.print( fix.altitude() );
    
    Serial.print( F("\nSatellites: ") );
    if (fix.valid.satellites)
      Serial.print( fix.satellites );
    Serial.println();

    if (fix.valid.location) {
      Serial.println( F("Patel") );

      Send2Pachube();
    }
  }
} // readGPSdata

Notice that it checks to see if GPS pieces are valid before using them.

Your original (broken) sketch (6338 lines) uses 17038 bytes of program space and 1384 bytes of RAM.
The NeoGPS version (4184 lines) uses 10640 bytes of program space and 528 bytes of RAM. It is much, much smaller and efficient.

If you want to try it, NeoGPS is available from the Arduino IDE Library Manager, under the menu Sketch → Include Library → Manage Libraries.

SoftwareSerial can also cause trouble. It is very inefficient, because it disables interrupts for the entire time that GPS characters are received. Instead, read this, because it applies to the GSM, too. If you are using a GPS shield, it’s hard to use different pins. If the GPS is a separate module you have connected with wires, follow those suggestions. Here are some good combinations:

BEST: GSM on pins 8 & 9 (AltSoftSerial), GPS in pins 0 & 1 (Serial). Disconnect pin 0 to upload.

2nd BEST: GSM on pins 0 & 1 (disconnect pin 0 to upload), GPS on pins 8 & 9 (AltSoftSerial).

3rd BEST: GSM on pins 8 & 9, GPS on any two pins with NeoSWSerial.

Cheers,
/dev

The code you have sent is not working. I have tried but didn't get success. Only this appeared on serial monitor : "NeoGPS library + GSM test!"

Please I need your help. And Thank You for your time.

The code you have sent is not working.

That's too vague.

Did you decide how to connect the GSM and the GPS? See choices at the end of my reply #8.

How is everything connected?

Yes I have connected GSM on pins 8 & 9, GPS in pins 0 & 1 but after that I also need to change the code? I am totally lost at this point because now only gps is working getting no output from gsm (connection: arduinoRX - gsmTX, arduinoTX - gsmRX). Previously I have used arduino pins “2,3” and “10,11” for rx and tx and now after changing the pins to 8,9 and 0,1 what changes are required in code to make it work properly.

SoftwareSerial gsmPort(0, 1); // ← good names!
SoftwareSerial gpsPort(8, 9);

what changes are required in code to make it work properly.

I thought this was clear:

BEST: GSM on pins 8 & 9 (AltSoftSerial), GPS in pins 0 & 1 (Serial). Disconnect pin 0 to upload.

2nd BEST: GSM on pins 0 & 1 (disconnect pin 0 to upload), GPS on pins 8 & 9 (AltSoftSerial).

3rd BEST: GSM on pins 8 & 9, GPS on any two pins with NeoSWSerial.

That does not say SoftwareSerial for anything. Can you guess what needs to be changed from that?

Use google to find the AltSoftSerial library.

but I really need your help.

YOU need to help yourself. Crying "poor, poor, pitiful me" is useless.

You've made some code changes, or you should have. If you have, POST YOUR CODE. If not, go away until you do, then POST YOUR CODE.

Post a schematic and photo showing how everything is connected. Do NOT use 127 wires 3 meters long all the same color when connecting the hardware. Do not take the picture in a dark room. Do not focus somewhere 3 feet beyond, or in front of, the hardware.

Did you really connect the device to the smiley face pin?

Did you not read that AltSoftSerial only works on pins 8 and 9? Did you not read that you can have EXACTLY ONE instance of AltSoftSerial?

Thanks Dev for solving my problem. It was really very helpful but I need to get result pretty fast. Now when I reduce my delay then it stop sending data to server and data is required after every 4 to 5 seconds. Is it possible to get data after every to 5 seconds.

Is it possible to get data after every to 5 seconds.

Since it takes ~40 seconds to establish the connection, could you save 12 GPS locations (5 seconds apart), and send them all at once? This would send a "batch" of 12 locations once per minute.

You would have to change to program so it could do 2 things at once: send the AT commands AND save GPS locations to send.

I don't know what you would have to change for the Pachube interface so it could take multiple locations.

aditya_anand: Thanks Dev for solving my problem. It was really very helpful but I need to get result pretty fast. Now when I reduce my delay then it stop sending data to server and data is required after every 4 to 5 seconds. Is it possible to get data after every to 5 seconds.

Could you please upload the code and one schematic?

Could you please upload the code

It’s the code in reply #8, with different serial port variables. According to this:

I have connected GSM on pins 8 & 9, GPS in pins 0 & 1

He would have this in the sketch instead of SoftwareSerial:

#include <AltSoftSerial.h>
AltSoftSerial gsmPort; // always on pins 8 (to GSM TX) and 9 (to GSM RX)

#define gpsPort Serial // pin 0 to GPS TX and pin 1 to GPS RX

void setup() {

  Serial.begin(9600); // must be same baud rate as GPS
  Serial.println( F("NeoGPS library + GSM test!") );

  gsmPort.begin(4800);

  // gpsPort.begin(9600); // this is really Serial, so it has already been started
  GPS.send_P( &gpsPort, F("PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0") ); // RMC+GGA
  GPS.send_P( &gpsPort, F("PMTK220,1000") ); // 1Hz
  GPS.send_P( &gpsPort, F("PGCMD,33,0") ); // No antenna status
}

Hi -dev and arduino community!

I would like to try your suggestion (BEST) using Altsoftserial for GSM and H/W for gps "BEST: GSM on pins 8 & 9 (AltSoftSerial), GPS in pins 0 & 1 (Serial). Disconnect pin 0 to upload." also using NeoGPS library for my tracker.

Having only used SoftwareSerial in the past (with an OK understanding/outcome) to communicate with GSM and GPS modules using listen, im not quite so sure using H/W and the NeoGPS library.

How would this function look using NeoGPS on H/W RX?

void readGPSdata()
{
  // if a sentence is received...
  if (GPS.available( gpsPort )) {             // Maybe      if (serial.available( gpsPort ))  { ?????
    fix = GPS.read(); //  get the latest pieces

    Serial.print( F("\nFix: ") );
    if (fix.valid.status)
      Serial.print(fix.status);

    Serial.print( F("\nLocation: ") );
    if (fix.valid.location) {
      Serial.print( fix.latitude(), 4);
      Serial.print( F(", ") );
      Serial.print( fix.longitude(), 4);
    }

    Serial.print( F("\nSpeed (knots): ") ); 
    if (fix.valid.speed)
      Serial.print( fix.speed() );

    Serial.print( F("\nSatellites: ") );
    if (fix.valid.satellites)
      Serial.print( fix.satellites );
    Serial.println();

    if (fix.valid.location) {
      Serial.println( F("I have fix!.......") );

    }
  }
} // readGPSdata

Thanks in advance.