I have got SIM7600 working with Arduino to update GPS coordinates obtained from UBLOX M8N to a custom URL using http get requests. My code works fine and I am able to track the GPS coordinates. However from time to time I stop getting updates. I think the problem is with SIM7600 and not UBLOX. Below is a dump of my code. I have also attached a screen shot of the GPS data I collected on 18-April-2022 and you can see there is a gap between times 13:36:52 and 16:59:57. I am also attaching a circuit diagram for the hardware. Why am I getting long time periods with no gps written to the server?
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
AltSoftSerial Serial1(8, 9); // RX, TX
uint8_t read_serial_byte, incomming_message[100], number_used_sats=0, fix_type;
uint8_t latitude_north, longiude_east ;
uint16_t message_counter;
int16_t gps_add_counter;
float l_lat_gps, l_lon_gps;
int32_t lat_gps_actual=0, lon_gps_actual=0;
uint8_t new_line_found, new_gps_data_available, new_gps_data_counter;
char UART1_rxBuffer[12]={0};
String latitude,longitude;
char gps[200];
char str[200];
char str2[30];
char str3[20];
char str4[20];
int datawritten=0;
void setup() {
pinMode(4,OUTPUT);
power_on();
Serial.begin(115200);
Serial1.begin(9600);
Serial.println("Ublox started");
startup();
}
void readgps() {
while (Serial1.available()&& new_line_found==0) {
UART1_rxBuffer[0]=char(Serial1.read());
Serial.print(UART1_rxBuffer[0]);
if (UART1_rxBuffer[0] == '$') { //If the new byte equals a $ character.
for (message_counter = 0; message_counter <= 99; message_counter ++) { //Clear the old data from the incomming buffer array.
incomming_message[message_counter] = '-'; //Write a - at every position.
}
message_counter = 0; //Reset the message_counter variable because we want to start writing at the begin of the array.
}
else if (message_counter <= 99)message_counter ++; //If the received byte does not equal a $ character, increase the message_counter variable.
incomming_message[message_counter] = UART1_rxBuffer[0]; //Write the new received byte to the new position in the incomming_message array.
if (UART1_rxBuffer[0] == '*') new_line_found = 1; //Every NMEA line end with a *. If this character is detected the new_line_found variable is set to 1.
}
if (new_line_found==1) {
new_line_found = 0;
/*
if (incomming_message[4] == 'L' && incomming_message[5] == 'L' && incomming_message[7] == ',') { //When there is no GPS fix or latitude/longitude information available.
//HAL_GPIO_TogglePin (LD3_GPIO_Port, LD3_Pin); //Change the LED on the STM32 to indicate GPS reception.
//Set some variables to 0 if no valid information is found by the GPS module. This is needed for GPS lost when flying.
l_lat_gps = 0;
l_lon_gps = 0;
lat_gps_previous = 0;
lon_gps_previous = 0;
number_used_sats = 0;
}
*/
if (incomming_message[3] == 'R' && incomming_message[4] == 'M' && incomming_message[5] == 'C' && incomming_message[17] == 'A') {
lat_gps_actual = ((int)incomming_message[21] - 48) * (long)10000000; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual += ((int)incomming_message[22] - 48) * (long)1000000; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual += ((int)incomming_message[24] - 48) * (long)100000; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual += ((int)incomming_message[25] - 48) * (long)10000; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual += ((int)incomming_message[26] - 48) * (long)1000; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual += ((int)incomming_message[27] - 48) * (long)100; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual += ((int)incomming_message[28] - 48) * (long)10; //Filter the minutes for the GGA line multiplied by 10.
lat_gps_actual /= (long)6; //To convert the minutes to degrees we need to divide the minutes by 6.
lat_gps_actual += ((int)incomming_message[19] - 48) * (long)100000000; //Add the degrees multiplied by 10.
lat_gps_actual += ((int)incomming_message[20] - 48) * (long)10000000; //Add the degrees multiplied by 10.
lat_gps_actual /= 10; //Divide everything by 10.
lon_gps_actual = ((int)incomming_message[35] - 48) * (long)10000000; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual += ((int)incomming_message[36] - 48) * (long)1000000; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual += ((int)incomming_message[38] - 48) * (long)100000; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual += ((int)incomming_message[39] - 48) * (long)10000; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual += ((int)incomming_message[40] - 48) * (long)1000; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual += ((int)incomming_message[41] - 48) * (long)100; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual += ((int)incomming_message[42] - 48) * (long)10; //Filter the minutes for the GGA line multiplied by 10.
lon_gps_actual /= (long)6; //To convert the minutes to degrees we need to divide the minutes by 6.
lon_gps_actual += ((int)incomming_message[32] - 48) * (long)1000000000; //Add the degrees multiplied by 10.
lon_gps_actual += ((int)incomming_message[33] - 48) * (long)100000000; //Add the degrees multiplied by 10.
lon_gps_actual += ((int)incomming_message[34] - 48) * (long)10000000; //Add the degrees multiplied by 10.
lon_gps_actual /= 10;
//Divide everything by 10.
if (incomming_message[30] == 'N')latitude_north = 1; //When flying north of the equator the latitude_north variable will be set to 1.
else latitude_north = 0; //When flying south of the equator the latitude_north variable will be set to 0.
if (incomming_message[44] == 'E')longiude_east = 1; //When flying east of the prime meridian the longiude_east variable will be set to 1.
else longiude_east = 0; //When flying west of the prime meridian the longiude_east variable will be set to 0.
l_lat_gps = lat_gps_actual/1000000.0;
l_lon_gps=lon_gps_actual/1000000.0;
//number_used_sats = ((int)incomming_message[46] - 48) * (long)10; //Filter the number of satillites from the GGA line.
//number_used_sats += (int)incomming_message[47] - 48; //Filter the number of satillites from the GGA line.
}
//If the line starts with SA and if there is a GPS fix we can scan the line for the fix type (none, 2D or 3D).
//if (incomming_message[4] == 'S' && incomming_message[5] == 'A')fix_type = (int)incomming_message[9] - 48;
}
}
void loop() {
readgps();
if ((lat_gps_actual>0)&&(lon_gps_actual>0)&&(lon_gps_actual<90000000)) {
if(send_command("AT+CPIN?\r\n","+CPIN: READY",2000)==1) {
if(send_command("AT+CSQ\r\n","OK",2000)==1) {
if(send_command("AT+CGREG?\r\n","+CGREG: 0,1",2000)==1) {
if(send_command("AT+COPS?\r\n","OK",2000)==1) {
if(send_command("AT+CGACT?\r\n","OK",2000)==1) {
if(send_command("AT+IPADDR\r\n","OK",2000)==1) {
mySerial.print("AT+CIPOPEN=0,\"TCP\",\"website\",80\r\n");
delay(2000);
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
memset(str,'\0',200);
strcpy(str,"GET http://website/gps_update.php?Truck_ID=1&Latitude=");
char sz[20]={' '};
int val_int=(int)l_lat_gps;
Serial.println(val_int);
float val_float = (abs(l_lat_gps)-abs(val_int))*1000000;
uint32_t val_fra = (uint32_t)val_float;
Serial.println(val_fra);
sprintf(sz,"%d.%6ld",val_int,val_fra);
Serial.println(sz);
strcat(str,sz);
memset(str3,'\0',20);
strcpy(str3,"Latitude=");
strcat(str3,sz);
memset(sz,'\0',20);
val_int=(int)l_lon_gps;
val_float = (abs(l_lon_gps)-abs(val_int))*1000000;
val_fra = (uint32_t)val_float;
sprintf(sz,"%d.%6ld",val_int,val_fra);
strcat(str,"&Longitude=");
strcat(str,sz);
memset(str4,'\0',20);
strcpy(str4,"&Longitude=");
strcat(str4,sz);
Serial.println("Writing data");
Serial.println(str);
memset(str2,'\0',30);
strcpy(str2,"AT+CIPSEND=0,");
char sz2[10]={' '};
sprintf(sz2,"%d\r\n",strlen(str)+4);
strcat(str2,sz2);
send_command(str2,"OK",4000);
Serial.println();
delay(2000);
mySerial.print("GET http://website/gps_update.php?");
//delay(3000);
//while (mySerial.available()) {
// Serial.print((char)mySerial.read());
//}
mySerial.print("Truck_ID=1&");
//delay(2000);
//while (mySerial.available()) {
// Serial.print((char)mySerial.read());
//}
mySerial.print(str3);
//delay(2000);
//while (mySerial.available()) {
// Serial.print((char)mySerial.read());
//}
mySerial.print(str4);
//delay(2000);
//while (mySerial.available()) {
// Serial.print((char)mySerial.read());
//}
mySerial.print("\r\n\r\n");
//mySerial.println();
delay(5000);
char response[50];
memset(response,'\0',50);
uint8_t x=0;
while (mySerial.available()) {
response[x]=(char)mySerial.read();
x++;
}
delay(10000);
while (mySerial.available()) {
response[x]=mySerial.read();
x++;
}
if (strstr(response,"CIPSEND: 0")!=NULL) {
Serial.println(response);
datawritten=1;
} else {
power_on();
startup();
}
flu();
lat_gps_actual=0;
lon_gps_actual=0;
} else {
power_on();
startup();
flu();
}
} else {
power_on();
startup();
flu();
}
} else {
power_on();
startup();
flu();
}
} else {
power_on();
startup();
flu();
}
} else {
power_on();
startup();
flu();
}
} else {
power_on();
startup();
flu();
}
}
if (datawritten==1) {
digitalWrite(4,LOW);
delay(20000);
power_on();
//Serial.println("powering on");
startup();
datawritten=0;
//Serial.println("Flushing buffer");
flu();
//Serial.println("Flushing done");
} else {
//delay(2000);
}
}
int8_t send_command(char* ATcommand,char* expected_answer,unsigned int timeout) {
unsigned long previous;
uint8_t x=0;
uint8_t answer=0;
char response[50];
memset(response,'\0',50);
delay(100);
while (mySerial.available()>0) mySerial.read();
mySerial.print(ATcommand);
previous=millis();
do {
if(mySerial.available() !=0) {
response[x]=mySerial.read();
Serial.print(response[x]);
x++;
if (strstr(response,expected_answer)!=NULL) {
answer=1;
}
}
} while ((answer==0)&&((millis()-previous)<=timeout));
return answer;
}
void flu() {
while (Serial1.available()) {
char t = Serial1.read();
}
}
void power_on() {
digitalWrite(4,LOW);
delay(20000);
digitalWrite(4,HIGH);
delay(15000);
}
void startup() {
mySerial.begin(115200);
// set the baud rate
Serial.println("Clean buffer");
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
mySerial.print("AATT\r\n");
delay(2000);
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
mySerial.print("AATTEE00\r\n");
delay(2000);
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
mySerial.print("AT+IPR=9600\r\n");
delay(2000);
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
mySerial.begin(9600);
mySerial.print("AT+CGPS=0\r\n");
delay(2000);
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
//mySerial.print("AT+CGPSNMEA=1\r\n");
//delay(2000);
//while (mySerial.available()) {
// Serial.print(mySerial.readString());
// }
mySerial.print("AT+CGPSHOT\r\n");
delay(2000);
while (mySerial.available()) {
Serial.print(mySerial.readString());
}
send_command("AT+NETOPEN\r\n","OK",2000);
Serial.println("HTTPINIT");
send_command("AT+HTTPINIT\r\n","OK",2000);
}