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
looprun repeatedly. Never callloop. 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