Tuesday, October 13, 2015

PROJECT 4a: GSM GPS based realtime Vehicle tracking/ collision detection with ARDUINO


Next we have a module for gathering real-time position tracking. GPS based tracking projects are fairly common. Their application can be seen in article, bus, vehicle, pet tracking etc. The GPS device we are going to use for this project is an atmega 328, a gps module , a gsm module and bunch of other stuff.
The module we are using is GPS Receiver with Antenna (5V TTL SERIAL) from rhydolabs. GPS TTL Mini is a high gain GPS Receiver . The on board 3V3 to 5V level convertor enable us to directly interface with normal 5V Microcontrollers. The module is made with ultra small High gain third generation POT (Patch Antenna On Top) GPS module. There is no prior configuration required; just power the module with 5V, and your data (NMEA 0183) is ready at TX pin. It has a very compact and easy to integrate design with the ultimate tracking performances. It can be directly connected to Microcontroller’s UART.

The GPS chipsets inside the module are designed by MediaTek Inc., which is the world’s leading digital media solution provider and largest fab-less IC company in Taiwan. The module can support up to 66 channels. The GPS solution enables small form factor devices. They deliver major advancements in GPS performances, accuracy, integration, computing power and flexibility. They are designed to simplify the embedded system integration process.
 Features:
MediaTek MT3329 Chipset, L1 Frequency, C/A code, 66 Channels
TTL asynchronous serial interface
5 VDC supply @ 55 mA (typical)
Data output Baud rate: 9600 bps(Default)
Standard NMEA0183 output format
Low Power Consumption: 55mA @ acquisition, 40mA @ tracking
High Sensitivity, -165 dBm, TCXO Design , superior urban performances
Position Accuracy: <3.0M 2D-RMS
DGPS (WAAS/EGNOS/MASA/GAGAN) Support
Multi-path Compensation ; E-GSM-900 Band Rejection
Cold Start is Under 36 seconds (Typical)
Warm Start is Under 34 seconds (Typical)
Hot Start is Under 1 second (Typical)
Max. Update Rate : 10Hz (Default: 1 Hz)
















here is a link to a good product: GPS Receiver with Antenna (5V TTL SERIAL) 































1. What is the NMEA 0183 Standard?
The National Marine Electronics Association (NMEA) is a non-profit association of manufacturers,
distributors, dealers, educational institutions, and others interested in peripheral marine electronics
occupations. The NMEA 0183 standard defines an electrical interface and data protocol for
communications between marine instrumentation.
NMEA 0183 devices are designated as either talkers or listeners (with some devices being both),
employing an asynchronous serial interface. All data is transmitted in the form of sentences. Only printable ASCII characters are allowed, plus CR (carriage return) and LF (line feed). Each sentence starts with a "$" sign and ends with <CR><LF>. There are three basic kinds of sentences: talker sentences, proprietary sentences and query sentences.

************************************************************
when  GPS is not connected to satellite or is in bad network:

$GPRMC,193856.000,V, , , , , 0.20,194.78,140215, , N*4F

utc position=19hrs 38mins 56.000 seconds
status: A=data valid / V= data invalid
latitude: N/A
N/S indicator: N/A
Longitude : N/A
E/W: N/A
Speed over Ground: 0.20 knots
Course over Ground: 194.78 degrees
Date: 14/02/2015
Magnetic Variation: N/A
Checksum : 4F
End of line
************************************************************

when GPS is connected to satellite or is in network:

$GPRMC,193856.000,A ,3723.2475 ,N ,12158.3416 ,W , 0.20,194.78,140215, , N*4F

utc position=19hrs 38mins 56.000 seconds
status: A=data valid / V= data invalid
latitude: 37.232475
N/S indicator: N
Longitude : 12.1583416
E/W: W
Speed over Ground: 0.20 knots
Course over Ground: 194.78 degrees
Date: 14/02/2015
Magnetic Variation: N/A
Checksum : 4F
End of line
************************************************************


Along with that i am using a GSM MODULE:

The GSM/GPRS TTL UART Modem, is built with Dual Band GSM/GPRS engine- SIM900A, works on frequencies  900/ 1800 MHz. The Modem is coming with selectable interfacing voltage,which allows you to connect 5V & 3V3 microcontroller directly without any level conversion chips. The baud rate is configurable from 9600-115200 through AT command. The GSM/GPRS Modem is having internal TCP/IP stack to enable you to connect with internet via GPRS.

Here is a quick link to it: GSM/GPRSTTL UART MODEM-SIM900A

Modem Features:
High Quality Product (Not hobby grade)
Dual-Band GSM/GPRS   900/ 1800 MHz
3V3 & 5V  interface for direct communication with MCU kit
Configurable baud rate
SMA connector with GSM Antenna.
SIM Card holder.
Built in Network Status LED 
Inbuilt Powerful TCP/IP protocol stack for internet data transfer over GPRS.
Audio interface Connector
Normal operation temperature: -20 °C to +55 °C
Input Voltage: 5V-12V DC

Compatibility: AT cellular command interface




Code mentioned in this tutorial is for interfacing of a GSM module and a GPS module with Arduino simultaneously. I have written it in such a manner that there is a Master Number. (you should ideally put your own number there after copying the code.) which gets notified whenever there is an emergency of a collision detected by uc on pin D12(a high pulse on pin D12), a collision message (a custom string "GPS co-ordinates + There has been a collision here. Kindly contact immediately." is sent to master no. for help. You can edit this to something of your convenience as well.)




































The GSM and GPS modules used here are both UART TTL compatible devices that means you do not need to connect a voltage level converter chip like max232. You can directly connect the GSM and GPS to 2 serial ports. Since AtMega 328 has only 1 serial port , I am using GSM at the hardware serial port and GPS at the Software serial port (using the softwareserial library provided with Arduino package you can easily convert a pair of GPIO's to serial port. But these soft serials have a limitation. I advise you to always keep the BAUD Rate under 19200 on soft serials as higher baudrate might lead to scrambled or garbled serial o/p).

So co-ordinates are read in realtime from GPS using serial port and polling is done for any calls on GSM module. If a call is received on GSM module, it is Disconnected after 3 rings and the number is stored in the controller SRAM. Then the no. is sent back a message in format "latitude = xx.xx longitude = xx.xx ." As long as there is no new collision or call received by controller, the GPS coordinated are read and once a call is received or collision occurs, suitable action is taken.



below is the code , burn it onto your Arduino or make a custom PCB/ a prototype of the circuit and enjoy making minor changes :

***********************************************************
#include <SoftwareSerial.h>
SoftwareSerial mySerial_gsm(10, 11);
int incoming[100];
int msg_send_flag,msg_send_flag2;
String number, str,y, str2,str4;
int msg_read_flag=0;
int status_1;
int stat_1,val,last_val;

String master_number1="+91-xxxxxxxxxx";                                  // change it to a valid phone no. with an appropriate country code
  int Gpsdata;             // for incoming serial data
  unsigned int finish =0;  // indicate end of message
  unsigned int pos_cnt=0;  // position counter
  unsigned int lat_cnt=0;  // latitude data counter
  unsigned int log_cnt=0;  // longitude data counter
  unsigned int flg    =0;  // GPS flag
  unsigned int com_cnt=0;  // comma counter
  char lat[20];            // latitude array
  char lg[20];             // longitude array



void setup()
{ Serial.begin(9600);
  mySerial_gsm.begin(9600);
  pinMode(12, INPUT);
  mySerial_gsm.println("AT+CMGF=1");
  str2="hello...!";
   last_val=0;
   Receive_GPS_Data();
  
  
    String str5=" latitude = ";
    str5+=String(lat[1]);
    str5 +=String('.');
    for (int i=2;i<=3;i++)
    { str5+=String(lat[i]); }
    for (int i=1;i<=15;i++)
    {    str5+=String(lat[4+i]);   }
   
    str5=str5+" longitude = ";
    str5 +=String(lg[1]);
    str5 +=String(lg[2]);
    str5 +=String('.');
    for (int i=3;i<=4;i++)
    {    str5+=String(lg[i]);  }
    for (int i=1;i<=14;i++)
    {
    str5+=String(lg[5+i]);
    }   
    Serial.println(str5);
  delay(1000);
read_sms();
  }


void loop()
{  
    int incoming_1=0;
    int income=0;
    status_1=0;
    if (msg_read_flag==1)
    {if (mySerial_gsm.available()!=0)
    {for( incoming_1=0;incoming_1<=100;incoming_1++)
    { incoming[incoming_1]=mySerial_gsm.read();
      // Serial.print(char(incoming[incoming_1]));                   
    }
      for( incoming_1=0;incoming_1<=100;incoming_1++)

      {
      if( char(incoming[incoming_1])=='C'&& char(incoming[incoming_1+1])=='L' && char(incoming[incoming_1+2])=='I' && char(incoming[incoming_1+3])=='P' && char(incoming[incoming_1+4])==':' && char(incoming[incoming_1+5])==' ' && char(incoming[incoming_1+6])=='"' && char(incoming[incoming_1+7])=='+'  && char(incoming[incoming_1+8])=='9')
             {String numb;
               //Serial.println("here we are");
               for (int num=7;num<=19;num++)
              { numb +=String(char(incoming[incoming_1+num]));
               numb.trim();
                number=numb;
                delay(100);}
               status_1=1;} }}
             // Serial.println("number is:");
             // Serial.println(number1);
             // Serial.println(status_1);
              delay(2000);
               if (status_1==1)
              {Serial.println("One new message from :");
               Serial.println(number);
              delay(2000);
              msg_read_flag=0;
              delay(2000);
              status_1=0;
              str2+=" one new message from:";
              str2+=number;
              send_sms();
             
             
              } }
             
             
              while (msg_send_flag==1)
                                {  y="AT+CMGS=";
                                   delay(100);
                                   y+=String('"');
                                   y=y+number;
                                   delay(100);
                                   y+=String('"');
                                   delay(100);
                                   Serial.println(y);
                                   delay(100);
                                   mySerial_gsm.println(y);
                                  // Serial.println("entered the while loop for sms send");
                                   //stat_1=1;
                  delay(100);
                  while (char(income)!= '>' )
                         {
                           income=mySerial_gsm.read();
                          // Serial.println(char(income));
                                   if ((char(income))=='>')
                                                {
                                   //Serial.println("> string read");
                                   delay(400);
                                   mySerial_gsm.print(str4);
                                   mySerial_gsm.write(char(26));
                                   delay(300); 
                                   Serial.println("message sent successfully."); 
                                    status_1=0;  }
                    // Serial.println("sending...");
                         delay(100);
                       }
                                msg_send_flag=0;
            // Serial.print("exiting all loops");

                }
               

            while (msg_send_flag2==1)
                                {  String z= str4+ ". There has been a collision here. Kindly contact immediately.";
                   y="AT+CMGS=";
                                   delay(100);
                                   y+=String('"');
                                   y=y+master_number1;
                                   delay(100);
                                   y+=String('"');
                                   delay(100);
                                   Serial.println(y);
                                   delay(100);
                                   mySerial_gsm.println(y);
                                  // Serial.println("entered the while loop for sms send");
                                   //stat_1=1;
                  delay(100);
                  while (char(income)!= '>' )
                         {
                           income=mySerial_gsm.read();
                          // Serial.println(char(income));
                                   if ((char(income))=='>')
                                                {
                                   //Serial.println("> string read");
                                   delay(400);
                                   mySerial_gsm.print(z);
                                   mySerial_gsm.write(char(26));
                                   delay(300); 
                                   Serial.println("message sent successfully."); 
                                    status_1=0;  }
                    // Serial.println("sending...");
                         delay(100);
                       }
                                msg_send_flag2=0;
            // Serial.print("exiting all loops");

                }


collision_detection();
read_sms();

}

void read_sms()
{ mySerial_gsm.println("AT+CNMI=2,2,0,0,0");
  delay(1000);
  mySerial_gsm.println("AT+CLIP=1");
  msg_read_flag=1;
 
 
}



void send_sms()
                {int incoming_1=0;
         mySerial_gsm.println("ATH");
       for( incoming_1=0;incoming_1<=100;incoming_1++)
    { incoming[incoming_1]=mySerial_gsm.read();}
     // Serial.print(char(incoming[incoming_1]));                   
        
         mySerial_gsm.println("AT+CMGF=1");
                 delay(2000);
                 msg_send_flag=1;
                 delay(2000);
 
 
    finish = 0;pos_cnt = 0;
    Receive_GPS_Data();
    String str5=" latitude = ";
    str5+=String(lat[1]);
    str5 +=String('.');
    for (int i=2;i<=3;i++)
    { str5+=String(lat[i]); }
    for (int i=1;i<=15;i++)
    {    str5+=String(lat[4+i]);   }
   
    str5=str5+" longitude = ";
    str5 +=String(lg[1]);
    str5 +=String(lg[2]);
    str5 +=String('.');
    for (int i=3;i<=4;i++)
    {    str5+=String(lg[i]);  }
    for (int i=1;i<=14;i++)
    {
    str5+=String(lg[5+i]);
    }
   
    str4=str5;  
}
    //Serial.println(str5);
                // Serial.println("in send_sms func loop");

 void Receive_GPS_Data()
  {
    while(finish==0){
      while(Serial.available()>0){         // Check GPS data
        Gpsdata = Serial.read();
        flg = 1;
       if( Gpsdata=='$' && pos_cnt == 0)   // finding GPRMC header
         pos_cnt=1;
       if( Gpsdata=='G' && pos_cnt == 1)
         pos_cnt=2;
       if( Gpsdata=='P' && pos_cnt == 2)
         pos_cnt=3;
       if( Gpsdata=='R' && pos_cnt == 3)
         pos_cnt=4;
       if( Gpsdata=='M' && pos_cnt == 4)
         pos_cnt=5;
       if( Gpsdata=='C' && pos_cnt==5 )
         pos_cnt=6;
       if(pos_cnt==6 &&  Gpsdata ==','){   // count commas in message
         com_cnt++;
         flg=0;}

       if(com_cnt==3 && flg==1){
        lat[lat_cnt++] =  Gpsdata;         // latitude
        flg=0;}

       if(com_cnt==5 && flg==1){
         lg[log_cnt++] =  Gpsdata;         // Longitude
         flg=0;}

       if( Gpsdata == '*' && com_cnt >= 5){
         com_cnt = 0;                      // end of GPRMC message
         lat_cnt = 0;
         log_cnt = 0;
         flg     = 0;
         finish  = 1; }}}}



void collision_detection()
{
  val=0;
  val = digitalRead(12);       
      if (val != last_val)
          {   if (val==1)  
              {msg_send_flag2=1;;  
              Serial.println("collision detected");
              }        }   
             else {    }
      last_val=val;  }

  
************************************************************

Here is a handy link to the GPS module I have used you can refer to it or ask me to pen down a tutorial dedicated to 'GPS ONLY'.
http://www.rhydolabz.com/wiki/?p=658



The GSM module used here is a GSM TTL UART module.
And for the working and interfacing of GSM module to AVR/ ARDUINO i will make a separate comprehensive tutorial for you guys to easily understand that as well.

And feel free to ask questions around the circuit or code or its scope of use.

keep reading :)
Abheerup

No comments:

Post a Comment