-2

I started a project quite recently where I intend to combine the Arduino Uno and the sim808 module which has gps/gsm/gprs all together in one.

The GPS functionality works fine. Just the GSM both receiving and sending messages also works good. But combining them for what i intend makes the entire system falls apart.

I intend to be able to have some coordinates registered (say, position A, position B and position c) and the system I intend to design is put on a moving vehicle. Now anyone on either of the positions will send a message with the alphabet denoting the position to a number lets say "A TO +23*******98 , and get a reply of the car's current time from that position.

With all parts combined, the program would sometimes not receive any message or even if it did, the GPS part wont even work.

Is there something I am doing wrong or is it not just feasible with what the components I am using?

Pls help as i am very confused right now. Thanks in advance.

#include <SoftwareSerial.h>
SoftwareSerial GPRS(7, 8); // RX, TX

  String BUSNUM="A";  // THIS SIM IS TO BE INSTALLED ON BUS A
  static String sendersnumber;
  char* key;
  char MESSAGE[280];
  String latitude;
  String longitude;

  String Speed;

enum _parseState 
{
  PS_DETECT_MSG_TYPE,
  PS_IGNORING_COMMAND_ECHO,

  PS_READ_CMTI_STORAGE_TYPE,
  PS_READ_CMTI_ID,
  PS_DETECT_MSG_TYPE2,
  PS_IGNORING_COMMAND_ECHO2,
  PS_READ_CMGR_STATUS2,
  PS_READ_CMGR_CONTENT2,
  PS_READ_CMGR_DATE2,

  PS_READ_CMGR_STATUS,
  PS_READ_CMGR_NUMBER2,
  PS_READ_CMGR_NUMBER,
  PS_READ_CMGR_SOMETHING,
  PS_READ_CMGR_DATE,
  PS_READ_CMGR_CONTENT,
  PS_READ_VIDEO_CONTENT,
  PS_READ_VIDEO2_CONTENT,
  PS_READ_CMGR_SOMETHING2,
  PS_READ_VIDEO_CONTENT2,
};

byte state = PS_DETECT_MSG_TYPE; // KEEP TRACK OF WHAT STATE WE ARE IN RIGHT NOW

char buffer[100]; // WHAT WE ARE READING INTO

byte pos = 0;  //WHAT POSITION WE ARE AT IN THAT BUFFER

int lastReceivedSMSId = 0;  // LAST RECIEVED SMS ID
boolean validSender = false; //SOO NOT JUST ANYONE HAS ACESS TO SEND A COMMAND


void resetBuffer() 
{
  memset(buffer, 0, sizeof(buffer));
  pos = 0;
}//BASICALLY TO RESET THE BUFFER


void setup()
{

  GPRS.begin(9600);
  Serial.begin(9600);
  GPRS.println("AT+CGNSPWR=1");
  delay(290);
  GPRS.println("AT+CGNSURC=0");
  delay(300);
  GPRS.println("AT");
  delay(300);
  GPRS.println("AT+CMGF=1"); // INITIALIZE SMS
  delay(300);

  for (int i = 1; i <= 15; i++) 
  {
    GPRS.print("AT+CMGD=");
    GPRS.println(i);
    delay(300);
    // Not really necessary but prevents the serial monitor from dropping any input SINCE WE KNOW LIMIT TO STORE IS 15, THIS JUST DELETES IT CLEARS IT
    while(GPRS.available()) 
      Serial.write(GPRS.read());
  }   
    delay(2000);
   GPRS.println("AT+CGNSURC=1");     

}

void loop()
{

 while(GPRS.available()) //ONLY WHEN THERE IS SOMETHING AVAILABLE,
  {


   GSM_NUM1(GPRS.read());  
   //delay(50);
   GPRS.println("AT+CGNSINF");
  // delay(40);    

    GPSAnalyzer(GPRS.read());

    sendSMS();

  }

}
// END OF VOID LOOP



void GSM_NUM1(byte b)
{

  buffer[pos++] = b;

 if ( pos >= sizeof(buffer) )
    resetBuffer(); // just to be safe

 switch (state) 
  {
  case PS_DETECT_MSG_TYPE: 
    {
      if ( b == '\n' )
        resetBuffer();
      else {        
        if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
          state = PS_IGNORING_COMMAND_ECHO;
        }
        else if ( pos == 6 ) {
          //Serial.print("Checking message type: ");
          //Serial.println(buffer);

          if ( strcmp(buffer, "+CMTI:") == 0 ) {
            Serial.println("Received CMTI");
            state = PS_READ_CMTI_STORAGE_TYPE;
          }
          else if ( strcmp(buffer, "+CMGR:") == 0 ) {
            Serial.println("Received CMGR");            
            state = PS_READ_CMGR_STATUS;
          }
          resetBuffer();
        }
      }
    }
    break;

  case PS_IGNORING_COMMAND_ECHO:
    {
      if ( b == '\n' ) {
        //Serial.print("Ignoring echo: ");
        //Serial.println(buffer);
        state = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMTI_STORAGE_TYPE:
    {
      if ( b == ',' ) {
        Serial.print("SMS storage is ");
        Serial.println(buffer);
        state = PS_READ_CMTI_ID;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMTI_ID:
    {
      if ( b == '\n' ) {
        lastReceivedSMSId = atoi(buffer);
        Serial.print("SMS id is ");
        Serial.println(lastReceivedSMSId);

        GPRS.print("AT+CMGR=");
        GPRS.println(lastReceivedSMSId);
        //delay(500); don't do this!

        state = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_STATUS:
    {
      if ( b == ',' ) {
        Serial.print("CMGR status: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_NUMBER;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_NUMBER:
    {
      if ( b == ',' ) {
        Serial.print("CMGR MSSG SENDERS Number: ");
       Serial.println(buffer);
       String sendersnumber=buffer;
        // Uncomment these two lines to check the sender's cell number
        //validSender = false;
        //if ( strcmp(buffer, "\"+0123456789\",") == 0 )
        validSender = true;

        state = PS_READ_CMGR_SOMETHING;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_SOMETHING:
    {
      if ( b == ',' ) {
        Serial.print("CMGR something A.K.A SENDER'S NAME: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_DATE;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_DATE:
    {
      if ( b == '\n' ) {
        Serial.print("CMGR date: ");
        Serial.println(buffer);
        state = PS_READ_CMGR_CONTENT;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_CONTENT:
    {
      if ( b == '\n' ) {
        Serial.print("CMGR MESSAGE Content: ");
        Serial.print(buffer);
         String key=buffer;

       //  sendSMS();
       // GPSAnalyzer();

        GPRS.print("AT+CMGD=");
        GPRS.println(lastReceivedSMSId);

        //delay(500); don't do this!

        state = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;
  }

}



  void GPSAnalyzer(byte b) 
 {

   buffer[pos++] = b;

  if ( pos >= sizeof(buffer) )
    resetBuffer();// just to be safe

    switch (state) 
  {
  case PS_DETECT_MSG_TYPE2: 
    {
      if ( b == '\n' )
        resetBuffer();
      else {        

        if ( pos == 9 ) {
         // Serial.print("Checking message type: ");
         // Serial.println(buffer);

          if ( strcmp(buffer, "+UGNSINF:") == 0 ) {
            Serial.println("Received CGNSINF:");            
            state = PS_READ_CMGR_STATUS2;
          }
          resetBuffer();
        }
      }
    }
    break;

    //CHECK
    case PS_IGNORING_COMMAND_ECHO2:
    {
      if ( b == '\n' ) {
        //Serial.print("Ignoring echo: ");
        //Serial.println(buffer);
        state = PS_DETECT_MSG_TYPE2;
        resetBuffer();
      }
    }
    break;

//THIS WOULD READ FROM +CGNSINF: (TO THE COMMA),
  case PS_READ_CMGR_STATUS2:
    {
      if ( b == ',' ) {
        Serial.print("RUN STATUS: ");
        Serial.println(buffer);
        String runstatus=buffer;


        state = PS_READ_CMGR_NUMBER2;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_NUMBER2:
    {
      if ( b == ',' ) {
        Serial.print("FIX STATUS : ");
       Serial.println(buffer);

       String fixstatus=buffer;
      fixstatus.replace(","," ");
        validSender = true;

        state = PS_READ_CMGR_SOMETHING2;
        resetBuffer();
      }
    }
    break;
// this is DATE AND TIME i dont need this
  case PS_READ_CMGR_SOMETHING2:
    {
      if ( b == ',' ) {
        Serial.print("DATE AND TIME : ");
        Serial.println(buffer);
        String dateandtime=buffer;

        state = PS_READ_CMGR_DATE2;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_DATE2:
    {
      if ( b == ',' ) {
        Serial.print("LATITUDE: ");
        Serial.println(buffer);
          latitude=buffer;
          latitude.replace(","," ");

        state = PS_READ_CMGR_CONTENT2;
        resetBuffer();
      }
    }
    break;

  case PS_READ_CMGR_CONTENT2:
    {
      if ( b == ',' ) {
        Serial.print("LONGITUDE: ");
        Serial.println(buffer);
        longitude=buffer;
        longitude.replace(","," ");

        state = PS_READ_VIDEO_CONTENT2;
        resetBuffer();
        //delay(500); don't do this!

      }
    }
    break;

   case PS_READ_VIDEO_CONTENT2:
   {
      if ( b == ',' ) {
        Serial.print("ALTITUDE: ");
        Serial.println(buffer);
        String Altitude=buffer;

        state = PS_READ_VIDEO2_CONTENT;
        resetBuffer();
        //delay(500); don't do this!
     }
    }
    break;

    case PS_READ_VIDEO2_CONTENT:
    {
     if ( b == ',' ) {
        Serial.print("SPEED(KM/HR): ");
        Serial.println(buffer);
        String Speed=buffer;
        Speed.replace(","," ");

               state =PS_DETECT_MSG_TYPE2;
        resetBuffer();

      }
    }
    break;
  //use goto to put it at sms begining
  }
 }  

 void sendSMS() 
  {
    if ( strcmp(key,"A") == 0 )
{
 float lati=7.200970;
 float longi=5.181782;
 float Speed1 = atof(Speed.c_str());
 float latituded = atof(latitude.c_str());
 float longituded = atof(longitude.c_str());
 float Distance = HaverSine(lati,longi,latituded,longituded);
 float duration=Distance/Speed1; 
 const int StrLen = 10; 
 char * duration_new ;
 double Value = duration; 
 (void) dtostrf (Value, StrLen, 6, duration_new); 

 String MESSAGE="BUS A";
 MESSAGE+=duration_new ; 
 Serial.print("THE MESSAGE SENT IS ");
 Serial.println(MESSAGE);
}

 else if ( strcmp(key,"B") == 0 )
{
 float lati=7.290970;
 float longi=5.141782;
 float Speed1 = atof(Speed.c_str());
 float latituded = atof(latitude.c_str());
 float longituded = atof(longitude.c_str());
 float Distance = HaverSine(lati,longi,latituded,longituded);
 float duration=Distance/Speed1; 
 const int StrLen = 10; 
 char * duration_new ;
 double Value = duration; 
 (void) dtostrf (Value, StrLen, 6, duration_new); 

 String MESSAGE="BUS B";
 MESSAGE+=duration_new ; 
 Serial.print("THE MESSAGE SENT IS ");
 Serial.println(MESSAGE);
}


  delay(300);
  GPRS.print("AT+CMGF=1\r\n");                                                       
  delay(100);
  GPRS.println("AT+CMGS=\""+sendersnumber+"\"\r\n");                                   
  delay(100);
  GPRS.println(MESSAGE);       
  delay(100);
  GPRS.println((char)26);                       
  delay(100);
  GPRS.println();
  delay(100);
}



float HaverSine(float lat1,float lon1,float lat2,float lon2)
{
  String fixstatus;
 float ToRad = PI / 180.0;
 float R = 6371;   // radius earth in Km

 float dLat = (lat2-lat1) * ToRad;
 float dLon = (lon2-lon1) * ToRad;

 float a = sin(dLat/2) * sin(dLat/2) +
       cos(lat1 * ToRad) * cos(lat2 * ToRad) *
       sin(dLon/2) * sin(dLon/2);
       String o= fixstatus + "8";


 float c = 2 * atan2(sqrt(a), sqrt(1-a));

 float d = R * c;
 return d;
}

EXPLANATION

After all declarations and initializations, the first active part of the entire code is the for loop that just deletes all former messages from the sim card memory. It runs 15 times.

for (int i = 1; i <= 15; i++){
   GPRS.print("AT+CMGD=");
   GPRS.println(i);
   delay(300);
   while(GPRS.available())
     Serial.write(GPRS.read());
} 

Now, some functions are explained below:

GSM_NUM1(), GPSAnalyzer(): Both work similarly; they extract needed data which arrive, separated by commas. GPS data format is:

+UGNSINF: <GNSS run status>,<Fix status>,<UTC date & Time>,<Latitude>,<Longitude>,
<MSL Altitude>,<Speed Over Ground>,<Course Over Ground>, <FixMode>,<Reserved1>,<HDOP>,<PDOP>,<VDOP>,<Reserved2>,<Satellites in View>,
<Satellites Used>,<Reserved3>,<C/N0 max>,<HPA>,<VPA>

Latitude, speed and any other important parameter are extracted.

GSM_NUM1() : It gets the senders message and number into variable.

sendSMS(): This just does some calculation based on the message received and send a certain result to the number who requested it.

OBSERVATIONS

When the program starts, nothing happens, which is good because nothing is supposed to, until something new comes in.

void loop()
{
while(GPRS.available()) //ONLY WHEN THERE IS SOMETHING AVAILABLE,
 {
  GSM_NUM1(GPRS.read());  
  //delay(50);
  GPRS.println("AT+CGNSINF");
 // delay(40);    
  GPSAnalyzer(GPRS.read());
      sendSMS();
}

Now this is where things go bad, as the first function works well. It waits, gets the message and extracts the senders number and message "key" into variables but immediately after that, I want just one return of the GPS info shown below; that's why I used AT+CGNSINF instead of AT+CGNSURC=1, since the latter gives continuous gps data such as:

+UGNSINF: <GNSS run status>,<Fix status>,<UTC date & Time>,<Latitude>,<Longitude>,
<MSL Altitude>,<Speed Over Ground>,<Course Over Ground>, <FixMode>,<Reserved1>,<HDOP>,<PDOP>,<VDOP>,<Reserved2>,<Satellites in View>,
<Satellites Used>,<Reserved3>,<C/N0 max>,<HPA>,<VPA>

BUT instead of one line of the gps data to be gotten, where latitude and some other parameters are extracted into variables, the program hangs for some unknown reason.

SUSPICIONS

Since the SIM808 has gps and gsm on the same module, It makes it kind of tricky to separate them.

  • Welcome to Arduino.SE. We cant help you without more details, such as your code and wiring. – TisteAndii Apr 29 '16 at 15:57
  • I HAVE EDITED IT, WITH WHAT I THINK IS ALL POSSIBLE DETAIL NEEDED.. ALTHOUGH I SINCERELY APOLOGIZE FOR THE FORMAT.. I'M NEW HERE AND DON'T KNOW HOW TO USE THIS MEDIUM EFFECTIVELY...PLEASE HELP IS NEEDED DESPERATELY – Abraham Ameh May 1 '16 at 6:14
  • Post the output you see in the serial monitor. How far does the GPS data extraction go, based on what is printed in the monitor? – TisteAndii May 5 '16 at 1:56
  • 1
    Please do not post in all capitals. It is like shouting at people, and they tend to walk away. – Nick Gammon May 8 '16 at 7:27
  • oh sorry. i apologise, i had no idea – Abraham Ameh Jan 31 '17 at 20:54
0

This is wrong, for a start:

void loop()
{
 while(GPRS.available()) //ONLY WHEN THERE IS SOMETHING AVAILABLE,
  {
   GSM_NUM1(GPRS.read());  
   GPRS.println("AT+CGNSINF");
   GPSAnalyzer(GPRS.read());
   sendSMS();
  }
}

When you find GPRS.available() that means you have one byte available (possibly more, but guaranteed one only). How I see you are doing two reads there. The second read may just return -1 (no data available).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.