I have a project (my first Arduino project) where I'm making a GPS tracker. The intended features I have not added yet, I'm at the point where I'm struggling to get both the GPS- and GPRS unit to work simultaneously and output some meaningful data.
I have one SIM900 GSM module, and one NEO-6M GPS unit, in addition to the UNO board. If I separate the code for the GPS- and GSM part, they individually work very well. The GPS outputs coordinates to the Serial monitor, and the GSM part (so far) sends an SMS.
The problem then seems to be combining the two, the GPS unit stops sending the coordinates to the serial monitor. Specifically, it shows them every once in a while if I wait long enough, maybe one every minute or so. I just cannot seem to figure out why this behaviour occurs, could it be some interrupt thing using both serial channels?
I understand that the UNO cannot have two software serial lines, and as such, I'm using the hardware serial for the GPS unit (which works fine if I exclude the GSM code) (D0 and D1). The GSM unit uses the software serial pin 7 and 8. I'm also using the NeoGPS library for GPS communication, as the TinyGPS library could not decode the information received correctly.
In the code below, I'm starting the Arduino, send one SMS, and after that the GPS is supposed to output the coordinates continuously to the serial monitor. The serial monitor continuously outputs any new data from GSM, i.e. new SMS received.
Full code:
#include <NMEAGPS.h>
#include <GPSport.h>
#include <SoftwareSerial.h>
NMEAGPS gps; // This parses the GPS characters
gps_fix fix; // This holds on to the latest values
//Create software serial object to communicate with SIM900
SoftwareSerial mySerial(7, 8); //SIM900 Tx & Rx is connected to Arduino #7 & #8
void setup()
{
Serial.begin(9600);
gpsPort.begin(9600);
mySerial.begin(9600); //Begin serial communication with SIM900
Serial.println("Initializing GSM...");
delay(5000);
mySerial.println("AT"); // Handshaking with SIM900
updateSerial();
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
updateSerial();
sendSMS();
}
void loop()
{
while (gps.available( gpsPort )) {
fix = gps.read();
if (fix.valid.location) {
Serial.print("Location: ");
Serial.print( fix.latitude(), 6 );
Serial.print( ',' );
Serial.print( fix.longitude(), 6 );
Serial.println();
}else{
Serial.print("No GPS fix. \r\n");
}
}
updateSerial();
}
void updateSerial()
{
delay(500);
while(mySerial.available())
{
Serial.write(mySerial.read()); //Forward what SIM900 received to Serial Port
}
}
void sendSMS()
{
mySerial.println("AT+CMGS=\"+<removed>\"");
updateSerial();
mySerial.print("Shit is not working..");
updateSerial();
mySerial.write(26);
updateSerial();
}
The other part I don't quite understand is the following. It seems that I have to flush the incoming serial buffer for every "AT command" sent to the GSM unit, otherwise nothing happens. It slo works just putting "mySerial.read()" in the code not assigning it to anything. What is the reason for flushing the incoming serial buffer in this case? If I remove the "Serial.write" line below no SMS is sent.
while(mySerial.available())
{
Serial.write(mySerial.read()); //Forward what SIM900 received to Serial Port
}
I'm also aware that I cannot load the Arduino with hardware serial connected, so I disconnect the GPS unit every time I load modifications to the program.
Would I be better off using the Arduino Mega instead to have the extra serial ports?