1
\$\begingroup\$

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? Hardware Circuit Diagram

GPS DATA COLLECTED

#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);

  
}
\$\endgroup\$
8
  • \$\begingroup\$ Naveen Gupta - Hi, You said: "I think the problem is with SIM7600 [...]" Why do you think that? Please edit your question to add details of the troubleshooting that you have already done, test results etc. Please also add a schematic and photo of your hardware. If this is a hardware problem, then the question can stay here, but at the moment you have only provided code and questions which are only about Arduino programming are better asked in a different part of Stack Exchange. Therefore please edit your question, add the requested hardware details and let's see... Thanks. \$\endgroup\$
    – SamGibson
    Commented Apr 18, 2022 at 12:42
  • \$\begingroup\$ Let me see. So (1) you get a time gap between 13:36:52 and 16:59:57. (2) Before and after the time gap, your Arduino sketch used AT commands to talk to M8N, repeatedly got GPS data successfully. (3) In other words, everything looked OK, except the unexpected time gap that happened from time to time, seemingly randomly. (4) Please let me know if I understands you situation correctly. \$\endgroup\$
    – tlfong01
    Commented Apr 18, 2022 at 13:06
  • 1
    \$\begingroup\$ That's right. Everything works as expected but sometimes I stop getting updates. I suspect GPS is working, however, I may be having trouble sending get requests from SIM7600. I have already power cycled SIM7600 using a power transistor to reset it but that doesnt seem to solve the problem. \$\endgroup\$ Commented Apr 18, 2022 at 13:10
  • \$\begingroup\$ (5) So it is SIM7600 that takes a coffer break from time to time. You reminds me of my bad experience with SIM7600, which I think is buggy, like SIM800/900. (5) BTW, there is another thing that confuses me. You mentioned that you are using M8N and SIM7600 at the same time (me too!) But you only need either one of them to get the GPS data. (6) So my first troubleshooting suggestion is (a) put away SIM7600, (b) Let Arduino talk AT to M8N and also HTTP to your "custom URL". (7) I have not been playing with SIM7600 for a while (I am waiting for SIM8/9xxx!), so I might suggesting silly things \$\endgroup\$
    – tlfong01
    Commented Apr 18, 2022 at 13:26
  • 1
    \$\begingroup\$ I am using NEO-M8N for GPS because the gps in SIM7600 was giving some junk coordinates from time to time. I talk to NEO-M8N using a softwareserial port and SIM7600 also using a software serial port on the arduino uno. \$\endgroup\$ Commented Apr 18, 2022 at 13:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.