I am using arduino + sim7600 + neo M8N gps module to update GPS coordinates real time to a mysql database. I am able to update without any issues, however several times I dont get an update for a long time because I think I am not able to connect to the internet to perform the http request. Below is my code and hardware setup. Am I doing something wrong??
#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#define DEBUG true
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;
long int time;
int sendData(char* command, const int timeout, boolean debug, char* expected_answer)
{
char response[200];
uint8_t x=0;
uint8_t answer;
memset(response,'\0',200);
mySerial.println(command);
long int time = millis();
while ( (time + timeout) > millis())
{
while (mySerial.available())
{
response[x] = mySerial.read();
x++;
}
}
if (debug)
{
Serial.print(response);
}
if (strstr(response,expected_answer)==NULL) {
answer=0;
} else {
answer=1;
}
return answer;
}
void startup() {
lat_gps_actual=0;
lon_gps_actual=0;
mySerial.begin(115200);
time = millis();
while ( (time + 5000) > millis()) {
while (mySerial.available()) {
Serial.print((char)mySerial.read());
}
}
mySerial.print("AT+IPR=9600\r\n");
time = millis();
while ( (time + 5000) > millis()) {
while (mySerial.available()) {
Serial.print((char)mySerial.read());
}
}
mySerial.begin(9600);
int error=1;
while (error==1) {
if (sendData("AT+CCID",5000,true,"OK")==1) {
if(sendData("AT+CREG?",5000,true,"OK")==1) {
if(sendData("AT+CGATT=1",5000,true,"OK")==1) {
if(sendData("AT+CGACT=1,1",5000,true,"OK")==1) {
if(sendData("AT+CGDCONT=1,\"IP\",\"airtelgprs.com\"",5000,true,"OK")==1) {
error=0;
} else {
error=1;
}
} else {
error=1;
}
} else {
error=1;
}
} else {
error=1;
}
} else {
error=1;
}
}
}
void flu() {
long int time1 = millis();
Serial.println("Flushing gps");
while ((time1+1000)>millis()) {
while (Serial1.available()) {
char t = char(Serial1.read());
//Serial.print(t);
}
}
}
void powercycle() {
long int time1 = millis();
digitalWrite(4,LOW);
//delay(10000);
while ((time1+10000)>millis()) {
while (Serial1.available()) {
char t = char(Serial1.read());
//Serial.print(t);
}
}
long int time2=millis();
digitalWrite(4,HIGH);
while ((time2+15000)>millis()) {
while (Serial1.available()) {
char t = char(Serial1.read());
//Serial.print(t);
}
}
}
void setup() {
pinMode(4,OUTPUT);
powercycle();
Serial.begin(115200);
Serial1.begin(9600);
startup();
}
void loop() {
Serial.println("Reading gps");
readgps();
if ((lat_gps_actual>0)&&(lon_gps_actual>0)&&(lon_gps_actual<90000000)) {
Serial.println(lat_gps_actual);
Serial.println(lon_gps_actual);
if (sendData("AT+HTTPINIT",5000,true,"OK")==1) {
mySerial.print("AT+HTTPPARA=\"URL\"");
mySerial.print(',');
mySerial.print('"');
mySerial.print("http://mywebsite/gps_update.php?");
mySerial.print("Truck_ID=1&");
mySerial.print("Latitude=");
int val_int=(int)l_lat_gps;
float val_float = (abs(l_lat_gps)-abs(val_int))*1000000;
uint32_t val_fra = (uint32_t)val_float;
char sz[20]={' '};
sprintf(sz,"%d.%6ld",val_int,val_fra);
mySerial.print(sz);
mySerial.print("&");
mySerial.print("Longitude=");
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);
mySerial.print(sz);
mySerial.print('"');
mySerial.print("\r\n\r\n");
time = millis();
char response2[200];
uint8_t y=0;
memset(response2,'\0',200);
while ( (time + 10000) > millis()) {
while (mySerial.available()) {
response2[y]=(char)mySerial.read();
y++;
}
}
Serial.println(response2);
if (strstr(response2,"OK")!=NULL) {
sendData("AT+HTTPACTION=0",6000,true,"OK");
//Serial.println("Reading Header");
//sendData("AT+HTTPHEAD",20000,true,"OK");
//Serial.println("Reading Response");
//sendData("AT+HTTPREAD=0,500",6000,true,"OK");
Serial.println("Terminating");
if (sendData("AT+HTTPTERM",5000,true,"OK")==1) {
Serial.println("database updated");
lat_gps_actual=0;
lon_gps_actual=0;
powercycle();
startup();
flu();
} else {
powercycle();
startup();
flu();
}
} else {
powercycle();
startup();
flu();
}
} else {
powercycle();
startup();
flu();
}
}
}
void readgps() {
while (Serial1.available()&& new_line_found==0) {
UART1_rxBuffer[0]=char(Serial1.read());
//char read_serial_byte = Serial1.read(); //Load a new serial byte in the read_serial_byte variable.
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') {
Serial.println ("Newline Found");
for (int h=0;h<=99;h++) {
Serial.print (char(incomming_message[h]));
}
Serial.println("");
delay(100);
//Serial.println(lat_gps_actual);
lat_gps_actual = ((int)incomming_message[21] - 48) * (long)10000000; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[22] - 48) * (long)1000000; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[24] - 48) * (long)100000; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[25] - 48) * (long)10000; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[26] - 48) * (long)1000; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[27] - 48) * (long)100; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[28] - 48) * (long)10; //Filter the minutes for the GGA line multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual /= (long)6; //To convert the minutes to degrees we need to divide the minutes by 6.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[19] - 48) * (long)100000000; //Add the degrees multiplied by 10.
//Serial.println(lat_gps_actual);
lat_gps_actual += ((int)incomming_message[20] - 48) * (long)10000000; //Add the degrees multiplied by 10.
lat_gps_actual /= 10;
//Serial.println(lat_gps_actual);
//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.
//Serial.println(lat_gps_actual);
//Serial.println(lon_gps_actual);
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;
}
}

