Arduino

#include<LiquidCrystal_I2C.h>
#include <AltSoftSerial.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <math.h>
#include<Wire.h>
//must add i2c lcd address use i2c-scanner.ino file
LiquidCrystal_I2C lcd(0x27, 16, 2);
//————————————————————–
//emergency phone number with country code
const String EMERGENCY_PHONE = “ENTER_EMERGENCY_PHONE_NUMBER”;
//————————————————————–
//GSM Module RX pin to Arduino 3
//GSM Module TX pin to Arduino 2
#define rxPin 2
#define txPin 3
SoftwareSerial sim800(rxPin,txPin);
//————————————————————–
//GPS Module RX pin to Arduino 9
//GPS Module TX pin to Arduino 8
AltSoftSerial neogps;
TinyGPSPlus gps;
//————————————————————–
String sms_status,sender_number,received_date,msg;
String latitude, longitude;
//————————————————————–
#define BUZZER 12
#define BUTTON 11
//————————————————————–
#define xPin A1
#define yPin A2
#define zPin A3
//————————————————————–
byte updateflag;
int xaxis = 0, yaxis = 0, zaxis = 0;
int deltx = 0, delty = 0, deltz = 0;
int vibration = 2, devibrate = 75;
int magnitude = 0;
int sensitivity = 20;
double angle;
boolean impact_detected = false;
//Used to run impact routine every 2mS.
unsigned long time1;
unsigned long impact_time;
unsigned long alert_delay = 30000; //30 seconds
//————————————————————–
/*****************************************************************************************
 * setup() function
 *****************************************************************************************/
void setup()
{
  //————————————————————–
  //Serial.println(“Arduino serial initialize”);
  Serial.begin(9600);
  //————————————————————–
  //Serial.println(“SIM800L serial initialize”);
  sim800.begin(9600);
  //————————————————————–
  //Serial.println(“NEO6M serial initialize”);
  neogps.begin(9600);
  //————————————————————–
  pinMode(BUZZER, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  //————————————————————–
  //initialize lcd screen
  lcd.begin();
  // turn on the backlight
  lcd.backlight();
  lcd.clear();
  //————————————————————–
  sms_status = “”;
  sender_number=””;
  received_date=””;
  msg=””;
  //————————————————————–
  sim800.println(“AT”); //Check GSM Module
  delay(1000);
  //SendAT(“AT”, “OK”, 2000); //Check GSM Module
  sim800.println(“ATE1”); //Echo ON
  delay(1000);
  //SendAT(“ATE1”, “OK”, 2000); //Echo ON
  sim800.println(“AT+CPIN?”); //Check SIM ready
  delay(1000);
  //SendAT(“AT+CPIN?”, “READY”, 2000); //Check SIM ready
  sim800.println(“AT+CMGF=1”); //SMS text mode
  delay(1000);
  //SendAT(“AT+CMGF=1”, “OK”, 2000); //SMS text mode
  sim800.println(“AT+CNMI=1,1,0,0,0”); /// Decides how newly arrived SMS should be handled
  delay(1000);
  //SendAT(“AT+CNMI=1,1,0,0,0”, “OK”, 2000); //set sms received format
  //AT +CNMI = 2,1,0,0,0 – AT +CNMI = 2,2,0,0,0 (both are same)
  //————————————————————–
  time1 = micros();
  //Serial.print(“time1 = “); Serial.println(time1);
  //————————————————————–
  //read calibrated values. otherwise false impact will trigger
  //when you reset your Arduino. (By pressing reset button)
  xaxis = analogRead(xPin);
  yaxis = analogRead(yPin);
  zaxis = analogRead(zPin);
  //————————————————————–
}
/*****************************************************************************************
 * loop() function
 *****************************************************************************************/
void loop()
{
  //————————————————————–
  //call impact routine every 2mS
  if (micros() – time1 > 1999) Impact();
  //————————————————————–
  if(updateflag > 0)
  {
    updateflag=0;
    Serial.println(“Impact detected!!”);
    Serial.print(“Magnitude:”); Serial.println(magnitude);
    getGps();
    digitalWrite(BUZZER, HIGH);
    impact_detected = true;
    impact_time = millis();
    lcd.clear();
    lcd.setCursor(0,0); //col=0 row=0
    lcd.print(“Crash Detected”);
    lcd.setCursor(0,1); //col=0 row=1
    lcd.print(“Magnitude:”+String(magnitude));
  }
  //————————————————————–
  if(impact_detected == true)
  {
    if(millis() – impact_time >= alert_delay) {
      digitalWrite(BUZZER, LOW);
      makeCall();
      delay(1000);
      sendAlert();
      impact_detected = false;
      impact_time = 0;
    }
  }
  if(digitalRead(BUTTON) == LOW){
    delay(200);
    digitalWrite(BUZZER, LOW);
    impact_detected = false;
    impact_time = 0;
  }
  //————————————————————–
  while(sim800.available()){
    parseData(sim800.readString());
  }
  //————————————————————–
  while(Serial.available())  {
    sim800.println(Serial.readString());
  }
  //————————————————————–
}
/*****************************************************************************************
 * Impact() function
 *****************************************************************************************/
void Impact()
{
  //————————————————————–
  time1 = micros(); // resets time value
  //————————————————————–
  int oldx = xaxis; //store previous axis readings for comparison
  int oldy = yaxis;
  int oldz = zaxis;
  xaxis = analogRead(xPin);
  yaxis = analogRead(yPin);
  zaxis = analogRead(zPin);
  //————————————————————–
  //loop counter prevents false triggering. Vibration resets if there is an impact. Don’t detect new changes until that “time” has passed.
  vibration–;
  //Serial.print(“Vibration = “); Serial.println(vibration);
  if(vibration < 0) vibration = 0;
  //Serial.println(“Vibration Reset!”);
  if(vibration > 0) return;
  //————————————————————–
  deltx = xaxis – oldx;
  delty = yaxis – oldy;
  deltz = zaxis – oldz;
  //Magnitude to calculate force of impact.
  magnitude = sqrt(sq(deltx) + sq(delty) + sq(deltz));
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  if (magnitude >= sensitivity) //impact detected
  {
    updateflag=1;
    // reset anti-vibration counter
    vibration = devibrate;
  }
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  else
  {
    //if (magnitude > 15)
      //Serial.println(magnitude);
    //reset magnitude of impact to 0
    magnitude=0;
  }
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
}
/*****************************************************************************************
 * parseData() function
 *****************************************************************************************/
void parseData(String buff){
  Serial.println(buff);
  unsigned int len, index;
  //————————————————————–
  //Remove sent “AT Command” from the response string.
  index = buff.indexOf(“\r”);
  buff.remove(0, index+2);
  buff.trim();
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
  if(buff != “OK”){
    //————————————————————–
    index = buff.indexOf(“:”);
    String cmd = buff.substring(0, index);
    cmd.trim();
    buff.remove(0, index+2);
    //Serial.println(buff);
    //————————————————————–
    if(cmd == “+CMTI”){
      //get newly arrived memory location and store it in temp
      //temp = 4
      index = buff.indexOf(“,”);
      String temp = buff.substring(index+1, buff.length());
      temp = “AT+CMGR=” + temp + “\r”;
      //AT+CMGR=4 i.e. get message stored at memory location 4
      sim800.println(temp);
    }
    //————————————————————–
    else if(cmd == “+CMGR”){
      //extractSms(buff);
      //Serial.println(buff.indexOf(EMERGENCY_PHONE));
      if(buff.indexOf(EMERGENCY_PHONE) > 1){
        buff.toLowerCase();
        //Serial.println(buff.indexOf(“get gps”));
        if(buff.indexOf(“get gps”) > 1){
          getGps();
          String sms_data;
          sms_data = “GPS Location Data\r”;
          sms_data += “http://maps.google.com/maps?q=loc:”;
          sms_data += latitude + “,” + longitude;
          sendSms(sms_data);
        }
      }
    }
    //————————————————————–
  }
  else{
  //The result of AT Command is “OK”
  }
  //NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
}
/*****************************************************************************************
 * getGps() Function
*****************************************************************************************/
void getGps()
{
  // Can take up to 60 seconds
  boolean newData = false;
  for (unsigned long start = millis(); millis() – start < 2000;){
    while (neogps.available()){
      if (gps.encode(neogps.read())){
        newData = true;
        break;
      }
    }
  }
  if (newData) //If newData is true
  {
    latitude = String(gps.location.lat(), 6);
    longitude = String(gps.location.lng(), 6);
    newData = false;
  }
  else {
    Serial.println(“No GPS data is available”);
    latitude = “”;
    longitude = “”;
  }
  Serial.print(“Latitude= “); Serial.println(latitude);
  Serial.print(“Lngitude= “); Serial.println(longitude);
}
/*****************************************************************************************
* sendAlert() function
*****************************************************************************************/
void sendAlert()
{
  String sms_data;
  sms_data = “Accident Alert!!\r”;
  sms_data += “http://maps.google.com/maps?q=loc:”;
  sms_data += latitude + “,” + longitude;
  sendSms(sms_data);
}
/*****************************************************************************************
* makeCall() function
*****************************************************************************************/
void makeCall()
{
  Serial.println(“calling….”);
  sim800.println(“ATD”+EMERGENCY_PHONE+”;”);
  delay(20000); //20 sec delay
  sim800.println(“ATH”);
  delay(1000); //1 sec delay
}
/*****************************************************************************************
 * sendSms() function
 *****************************************************************************************/
 void sendSms(String text)
{
  //return;
  sim800.print(“AT+CMGF=1\r”);
  delay(1000);
  sim800.print(“AT+CMGS=\””+EMERGENCY_PHONE+”\”\r”);
  delay(1000);
  sim800.print(text);
  delay(100);
  sim800.write(0x1A); //ascii code for ctrl-26 //sim800.println((char)26); //ascii code for ctrl-26
  delay(1000);
  Serial.println(“SMS Sent Successfully.”);
}
/*****************************************************************************************
 * SendAT() function
 *****************************************************************************************/
boolean SendAT(String at_command, String expected_answer, unsigned int timeout){
    uint8_t x=0;
    boolean answer=0;
    String response;
    unsigned long previous;
    //Clean the input buffer
    while( sim800.available() > 0) sim800.read();
    sim800.println(at_command);
    x = 0;
    previous = millis();
    //this loop waits for the answer with time out
    do{
        //if there are data in the UART input buffer, reads it and checks for the asnwer
        if(sim800.available() != 0){
            response += sim800.read();
            x++;
            // check if the desired answer (OK) is in the response of the module
            if(response.indexOf(expected_answer) > 0){
                answer = 1;
                break;
            }
        }
    }while((answer == 0) && ((millis() – previous) < timeout));
  Serial.println(response);
  return answer;
}