GPS Module and SIM900 to arduino mega

Hello, i’m connecting both GPS module and GSM module to arduino mega ports
the GSM is connected to Serial2 and the GPS is connected to the Software serial, both are working, but not fast enough.
Here is a brief explanation, i’m building a vehicle that is remotely controlled by a TCP server while you can observe it over a map.
The module connect ot the TCP server fine, GPS is sending coordinates, but when i want to move the vehicle i have to send the command 10 to 15 times to make it happen, i think its something to do with baudrate or delays… dunno what to do with the code to make it work fine.
Here is my code

//GPS SERIAL2 TCP And motor drive sketch
#include <SoftwareSerial.h>
#include <TinyGPS.h>

#define motorpin0 53 // Direction ch1 Right
#define motorpin1 49 // Direction ch2 Left
#define speedpin0 5 //Speed Ch1
#define speedpin1 6 //Speed Ch2
#define FiveVolt 22 //Motor drive logic VCC
#define gnd 24      //Motor drive logic Ground
TinyGPS gps;

//SoftwareSerial gsm(12,13);  //SERIAL2 Software serial
SoftwareSerial GPS(10,11);  //GPS Software serial


int SPEED=100; //Motor speed intializing 
int turn=50;
//byte count=0;
unsigned long start;
int time_to_go;
char data[1024];
int led = 13;
int onModulePin = 2;        // the pin to switch on the module (without press on button) 
int x = 0;
char command=0;
void switchModule(){
digitalWrite(onModulePin,HIGH);
delay(2000);
digitalWrite(onModulePin,LOW);}

void setup(){

Serial.begin(9600);                // UART baud rate
Serial2.begin(9600);
GPS.begin(9600);
 //the motor control wires are outputs
    pinMode (motorpin0, OUTPUT);
    pinMode(motorpin1, OUTPUT);
    //PWM Pins are outputs
    pinMode(speedpin0, OUTPUT);
    pinMode(speedpin1, OUTPUT);
    //Logic for motor drive
    pinMode(FiveVolt, OUTPUT);
    pinMode(gnd,OUTPUT);
    delay(2000);
    pinMode(led, OUTPUT);
    pinMode(onModulePin, OUTPUT);
    digitalWrite(FiveVolt,HIGH);
    digitalWrite(gnd,LOW);
    switchModule();                    // switches the module ON

    for (int i=0;i < 4;i++){
        delay(5000);
    } 


 delay(2000);
 Serial2.println("AT+CIPSHUT");      //single connection 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);
    
    Serial2.println("AT+CIPMUX=0");      //single connection 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

  Serial2.println("AT+CSTT=\"Etisalat\""); 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    Serial2.println("AT+CIICR"); 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    Serial2.println("AT+CIFSR"); 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='.');
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='\n');
    delay(100);

    Serial2.println("AT+CIPSTART=\"TCP\",\"41.36.54.103\",\"3030\"");  
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    do{     //waits for connection
        while(Serial2.available()==0);
    }while(Serial2.read()!='K'); 
    delay(100);
    
}

void loop()
{
 GPS.listen();
  bool newData = false;
   // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (GPS.available())
    {
      char c = GPS.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  float flat, flon;
  if(newData)
  {
    //unsigned long age;
    gps.f_get_position(&flat, &flon, NULL);
    flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
    flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
  }

     Serial2.println("AT+CIPSEND");   //sending data
     do{
        while(Serial2.available()==0);
        }while(Serial2.read()!='>');
        
    delay(100); 
    Serial2.print("\n LAT=");
    Serial2.print( flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6); //Print the latitude to the TCP server
    Serial2.print("\n LON=");
    Serial2.print( flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6); //Print the longitude to the TCP server
    
    Serial2.write(0x1A);    //EOL character, CTRL+Z Characters
    Serial2.write(0x0D);
    Serial2.write(0x0A);
    
    
  while(Serial2.available())
    {command = Serial2.read();
    }
     if (command== 'f')
     {
     //forward
    analogWrite(speedpin0,SPEED);
    analogWrite(speedpin1,SPEED);
    digitalWrite(motorpin0,0);
    digitalWrite(motorpin1,1);
    
    delay(2000);
     }
    
   else if (command=='b') //backward
    {
    analogWrite(speedpin0,SPEED);
    analogWrite(speedpin1,SPEED);
    digitalWrite(motorpin0,1);
    digitalWrite(motorpin1,0);
    }
    else if (command=='i')
   {SPEED= SPEED + 20;
   }
   else if (command=='d') //decrease speed
   {
     SPEED= SPEED - 20;
    // analogWrite(speedpin0,SPEED);
     //analogWrite(speedpin1,SPEED);
   }
   else if (command=='r') //Turn right
     {
    analogWrite (speedpin0, 0);
    analogWrite (speedpin1, 0);
    delay(200);
    //turn motors off then turn
    analogWrite(speedpin0,20);
    analogWrite(speedpin1,100);
    digitalWrite(motorpin0,0);
    digitalWrite(motorpin1,1);
    delay(900);
    analogWrite (speedpin0, 0);
    analogWrite (speedpin1, 0);
     }
  else if (command=='l') //Turn left
    {
    analogWrite (speedpin0,0);
    analogWrite (speedpin1,0);
    delay(200);
    //turn motors off then turn
    
    analogWrite(speedpin1,20);
    analogWrite(speedpin0,100);
    digitalWrite(motorpin0,1);
    digitalWrite(motorpin1,0);
    delay(900);
    analogWrite (speedpin0, 0);
    analogWrite (speedpin1, 0);
    
    }
    
    else if (command=='s')
    {
      analogWrite (speedpin0, 0);
      analogWrite (speedpin1, 0);
     
    }
    
    }

and the GPS is connected to the Software serial, both are working, but not fast enough.

Why? You have 4 hardware serial ports.

Listening only to the software serial port for a period of time is a really dumb idea. Get rid of that blocking code.

On every pass through loop(), read all the serial data. If it is time to do something with it, do something with it. Do NOT read serial data the way you are.

Does your GPS even send data more often than once a second?

Hey, thanks for the reply Im using software serial because of TinyGPS, is it okay if i used hardware serial with it?

On every pass through loop(), read all the serial data. If it is time to do something with it, do something with it. Do NOT read serial data the way you are.

I didn't quiet understand this part, what do u mean by read serial data the way you are?

Does your GPS even send data more often than once a second?

No, and i dont need it to send more than one each second

is it okay if i used hardware serial with it?

Of course.

I didn’t quiet understand this part, what do u mean by read serial data the way you are?

  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (GPS.available())
    {
      char c = GPS.read();

Get rid of the for loop. THAT is what is wrong. Your code will do NOTHING else for one second even if there is no GPS data to read.

    flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
    flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;

I don’t know what you think the , 6 on the end is doing, but it isn’t. Get rid of it.

The == should be =, too. You don’t want to perform a comparison, here. You want to perform an assignment.

This looks like you cut and pasted code without a clue what the code was doing.

I'll try to change hte loops and reply back. about the flat,flon i didnt quiet understand it yes, but the result of it is a float with 6 digits which is what i need without using it i only get 2 digits. Mind my bad coding, this is my first :)

That code is not defining how many digits are in the flat and flon variables. The 2 vs 6 has to do with how you print the variables later.

and how to print 6 digits?

and how to print 6 digits?

That's what the 6 in this statement is doing.

    Serial2.print( flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6); //Print the latitude to the TCP server

It is comparing flat to TinyGPS::GPS_INVALID_F_ANGLE. If the value in flat matches TinyGPS::GPS_INVALID_F_ANGLE, then 0 is printed. Otherwise the value in flat is printed. That is what this part of the code is doing:

flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat

If you knew that flat contained either 0 or a valid value (and you do because of how you assigned a value (currently incorrectly) to flat, then this statement would simply be:

    Serial2.print(flat, 6);

Which is how you print a value to 6 decimal places.

You explained pretty well, thanks a lot sir! I'm just waiting for the battery to charge and try it out, what i've done so far is getting rid of millis loop

    while (Serial1.available())
    {
      char c = Serial1.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  

  float flat, flon;
  if(newData)
  {
   //unsigned long age;
    gps.f_get_position(&flat, &flon, NULL);
    
  }

and the output to the TCP server will be

Serial2.println("AT+CIPSEND");   //sending data
    do{
        while(Serial2.available()==0);
        }while(Serial2.read()!='>');
        
    delay(100); 
    Serial2.print("\n LAT=");
    Serial2.print(flat,6); //Print the latitude to the TCP server
    Serial2.print("\n LON=");
    Serial2.print(flon,6); //Print the longitude to the TCP server

This should do the job right? If its not too much of questions, but i didn't quiet understand the millis-start loop function, can you explain it briefly? If you dont mind!

If its not too much of questions, but i didn’t quiet understand the millis-start loop function, can you explain it briefly? If you dont mind!

  for (unsigned long start = millis(); millis() - start < 1000;)
  {

This is a typical for loop. An index variable is assigned a starting value. In this case, start is assigned “now”. Prior to each iteration of the loop, the middle portion of the for loop is evaluated. In this case, the current time minus the start time is compared to the value 1000. If the for loop has been running for less than 1 second, it executes again. If it has been running for more than 1 second, it does not. There is no increment portion needed, because millis() increments on its own.

Aha, pretty clear thanks :slight_smile:

It's not working... i only get the coordinates once and i can't control the vehicle! Here's the code after editing

void loop()
{

  //bool newData = false;
   // For one second we parse GPS data and report some key values
  
    while (Serial1.available())
    {
      char c = Serial1.read();
      gps.encode(c);    }
      
   float flat, flon;
   gps.f_get_position(&flat, &flon, NULL);
   
   Serial2.println("AT+CIPSEND");   //sending data
    do{
        while(Serial2.available()==0);
        }while(Serial2.read()!='>');
        
    delay(100); 
    Serial2.print("\n LAT=");
    Serial2.print(flat,6); //Print the latitude to the TCP server
    Serial2.print("\n LON=");
    Serial2.print(flon,6); //Print the longitude to the TCP server
    
    Serial2.write(0x1A);    //EOL character, CTRL+Z Characters
    Serial2.write(0x0D);
    Serial2.write(0x0A);
    
    
  while(Serial2.available())
    {command = Serial2.read();
    }
     if (command== 'f')
     {
     //forward
    analogWrite(speedpin0,SPEED);
    analogWrite(speedpin1,SPEED);
    digitalWrite(motorpin0,0);
    digitalWrite(motorpin1,1);
    
    delay(2000);
     }
    
   else if (command=='b') //backward
    {
    analogWrite(speedpin0,SPEED);
    analogWrite(speedpin1,SPEED);
    digitalWrite(motorpin0,1);
    digitalWrite(motorpin1,0);
    }
    else if (command=='i')
   {SPEED= SPEED + 20;
   }
   else if (command=='d') //decrease speed
   {
     SPEED= SPEED - 20;
    // analogWrite(speedpin0,SPEED);
     //analogWrite(speedpin1,SPEED);
   }
   else if (command=='r') //Turn right
     {
    analogWrite (speedpin0, 0);
    analogWrite (speedpin1, 0);
    delay(200);
    //turn motors off then turn
    analogWrite(speedpin0,20);
    analogWrite(speedpin1,100);
    digitalWrite(motorpin0,0);
    digitalWrite(motorpin1,1);
    delay(900);
    analogWrite (speedpin0, 0);
    analogWrite (speedpin1, 0);
     }
  else if (command=='l') //Turn left
    {
    analogWrite (speedpin0,0);
    analogWrite (speedpin1,0);
    delay(200);
    //turn motors off then turn
    
    analogWrite(speedpin1,20);
    analogWrite(speedpin0,100);
    digitalWrite(motorpin0,1);
    digitalWrite(motorpin1,0);
    delay(900);
    analogWrite (speedpin0, 0);
    analogWrite (speedpin1, 0);
    
    }
    
    else if (command=='s')
    {
      analogWrite (speedpin0, 0);
      analogWrite (speedpin1, 0);
     
    }
    
    }

Okay so i found out the problem is here:

  Serial2.println("AT+CIPSEND");   //sending data
    do{
        while(Serial2.available()==0);
        }while(Serial2.read()!='>');

I removed it and its working again but i have to spam the letter to move the vehicle, trying to add some delays may fix it?

Okay, i fixed it.
here is the code if anyone is interested.
Thanks for the help!

//GPS GPS TCP And motor drive sketch
#include <TinyGPS.h>
#define motorpin0 53 // Direction ch1 Right
#define motorpin1 49 // Direction ch2 Left
#define speedpin0 5 //Speed Ch1
#define speedpin1 6 //Speed Ch2
#define FiveVolt 22 //Motor drive logic VCC
#define gnd 24      //Motor drive logic Ground
TinyGPS gps;


const char FRD = 'f';
const char BRD = 'b';
const char RT = 'r';
const char LT = 'l';
const char STP = 's';
const char INC = 'i';
const char DNC = 'z';

char cmd;
 
int SPEED=100; //Motor speed intializing 
int turn=50;
char command=0;
void setup(){

Serial.begin(9600);   // UART baud rate
Serial1.begin(9600);
Serial2.begin(9600);

 //the motor control wires are outputs
pinMode (motorpin0, OUTPUT);
pinMode(motorpin1, OUTPUT);
//PWM Pins are outputs
pinMode(speedpin0, OUTPUT);
pinMode(speedpin1, OUTPUT);
//Logic for motor drive
pinMode(FiveVolt, OUTPUT);
pinMode(gnd,OUTPUT);
delay(2000);
digitalWrite(FiveVolt,HIGH);
digitalWrite(gnd,LOW);
delay(2000);

    Serial2.println("AT+CIPSHUT");      //single connection 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);
    
    Serial2.println("AT+CIPMUX=0");      //single connection 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    Serial2.println("AT+CSTT=\"Etisalat\""); 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    Serial2.println("AT+CIICR"); 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    Serial2.println("AT+CIFSR"); 
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='.');
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='\n');
    delay(100);

    Serial2.println("AT+CIPSTART=\"TCP\",\"IP\",\"PORT\"");  
    do{
        while(Serial2.available()==0);
    }while(Serial2.read()!='K');
    delay(100);

    do{     //waits for connection
        while(Serial2.available()==0);
    }while(Serial2.read()!='K'); 
    delay(100);
    
}

void loop()
{ 
  float flat, flon;
  delay(400);
  
     if(Serial2.available()>0)
     {  
     
       Serial.print("\n Receiving command");
     
       while(Serial2.available()>0)
        { 
             command = Serial2.read();
             Serial.print(command);
            if(isCommand(command))
            {
              moveVehicle(command);
            }
        }
     }
     else
     {
       Serial.print("\n Receiving GPS");
       char c = Serial1.read();
       gps.encode(c);   
       gps.f_get_position(&flat, &flon, NULL);
       SendLoc(flat,flon);
       delay(300);
       
     }     
 
}

void SendLoc(float flat,float flon)
{
    Serial2.println("AT+CIPSEND");   //sending data
    delay(300); 
    Serial2.print('(');
    Serial2.print(flat,6); //Print the latitude to the TCP server
    Serial2.print('*');
    Serial2.print(flon,6); //Print the longitude to the TCP server
    Serial2.print(')');
      
    Serial2.write(0x1A);    //EOL character, CTRL+Z Characters
    Serial2.write(0x0D);
    Serial2.write(0x0A);     
}

void moveVehicle(char command)
{
  
 switch (command)
     {
      
   case FRD:
     //forward
      Serial.print("Forward");
      analogWrite(speedpin0,SPEED);
      analogWrite(speedpin1,SPEED);
      digitalWrite(motorpin0,0);
      digitalWrite(motorpin1,1);
      delay(2000);
      break;
     
   case BRD: //backward
 
      analogWrite(speedpin0,SPEED);
      analogWrite(speedpin1,SPEED);
      digitalWrite(motorpin0,1);
      digitalWrite(motorpin1,0);
      delay(2000);
      break;
  
   case INC:
       SPEED= SPEED + 20;
       delay(500);
       break;
   
   case DNC: //decrease speed
       SPEED= SPEED - 20;
       delay(500);
       break;
   
   case RT: //Turn right
   
      analogWrite (speedpin0, 0);
      analogWrite (speedpin1, 0);
      delay(200);
      //turn motors off then turn
      analogWrite(speedpin0,20);
      analogWrite(speedpin1,100);
      digitalWrite(motorpin0,0);
      digitalWrite(motorpin1,1);
      delay(900);
      analogWrite(speedpin0,0);
      analogWrite(speedpin1,0);
      break;
     
  case LT: //Turn left
  
      analogWrite (speedpin0,0);
      analogWrite (speedpin1,0);
      delay(200);
      //turn motors off then turn
      analogWrite(speedpin1,20);
      analogWrite(speedpin0,100);
      digitalWrite(motorpin0,1);
      digitalWrite(motorpin1,0);
      delay(900);
      analogWrite(speedpin0,0);
      analogWrite(speedpin1,0);
      break;
    
   case STP:
   
      analogWrite (speedpin0, 0);
      analogWrite (speedpin1, 0);
      break;

}
     delay(300);
  }
  
  boolean isCommand(char command)
  {
    return command == FRD || command == BRD || command == RT || command == LT || command == STP || command == INC || command == DNC;
    
  }
  delay(400);

Good thing that this isn’t my vehicle you are trying to operate blind.

       Serial.print("\n Receiving GPS");
       char c = Serial1.read();
       gps.encode(c);   
       gps.f_get_position(&flat, &flon, NULL);
       SendLoc(flat,flon);
       delay(300);

Regardless of whether there is anything to read, lets read something. Then, assume that one character formed a complete sentence, and use the lat and lon values. After reading that one character, let’s diddle around uselessly some more.

I don't know how things goes around here, but surely that's not the right way to criticism someones work...

I don't know how things goes around here, but surely that's not the right way to criticism someones work...

OP started with code that code some problems, but basically worked. After those problems were pointed out, and OP was told exactly what to remove, OP delete way too much code.

How would you have explained that?

It's basically the same code, the first one was just a sketch for debugging, then after i understood where the problem is i managed the code using functions, also added 1 comparison function, i spent 5 hours to come out with that code after alot of debugging, thats how i explain it.