GPS/GSM Trecker

alexxx86
Offline
Зарегистрирован: 15.01.2014

Хочу представить свой первый серьёзный проект))) Первый потому что с arduino да и вообще микроконтроллерами познакомился пол года назад. Да и в электротехники познаний тоже очень мало. Так что сильно не судите если есть какие то недочёты. Ну а теперь к делу))) GPS/GSM трекер для автомобиля на базе atmega328(arduino UNO), sim900(GSM-шилд) и gps NEO-6M-0-001

Готовое устройство планирую выполнить на печатной плате в одном корпусе, пока в процессе изготовления. Функционал трекера:

Отправка GPS координат по SMS. Запрос баланса сим карты. Сохранение разрешённого номера в EEPROM. Обратный звонок для прослушивания салона автомобиля. Смена разрешённого номера. Ну а теперь по подробней: При звонке с Разрешённого номера в ответ приходит SMS с gps координатами которые считываются с gps модуля и переводятся в формат: N xx xx.xxxx - широта. E xx xx.xxxx - долгота. Time xx:xx:xx - время по гринвичу. Если после звонка с разрешённого номера приходит sms вида: "no data" Значит gps координаты ещё не определены. Если во время работы будет потеряна связь с gps спутниками то на звонок с разрешённого номера придет ответ с последними полученными координатами. Звонки с остальных номеров просто сбрасываются. !!!Sms обрабатываются с любого номера. При первом включении необходимо установить разрешённый номер. Для этого нужно отправить sms на номер сим карты установленной в трекере, следующего содержания: $ch.nomber#+7XXXXXXXXXX (где X 10 цифр номера). В ответ придёт SMS c текстом "Changed nomer complete!" При необходимости смены разрешённого номера, процедуру повторить. Если трекер по каким либо причинам будет выключен то при включении разрешённый номер будет прочтён из EEPROM. Для запроса баланса сим карты необходимо отправить sms следующего вида: $balans# (тестировалось на сим карте оператора beeline, для других операторов возможно понадобиться правка кода) В ответ придёт sms с балансом сим карты. Для возможности прослушивания салона автомобиля нужно отправить sms следующего содержания: $callback# В ответ будет совершён голосовой вызов.


// GPS/GSM трекер.
#include <EEPROM.h>
#include <AltSoftSerial.h>
AltSoftSerial gpsSerial;
String currStr = "";//Строка содержит текущую строку, полученую от сим модуля.
String nomber_Phone = "";//Строка содержит номер телефона на который отправляються GPS координаты, далее Разрешенный номер.
String dat2 = "no data";//Текст строки отпровляеться если GPS координат ещё нет.
String dat;//Строка содержит GPS координаты.
String complete = "Changed nomber complete!";//Текст строки отпровляеться при смене Разрешенного номера.
char data;//Содержит символ полученый от сим модуля.
byte char_A = 40;
boolean gps = true;
int gps_on = A0;
void setup() 
{
  pinMode(gps_on, OUTPUT);
  pinMode(led2, OUTPUT);
  
  analogWrite(gps_on, 255);//
  delay(800);              // 
  analogWrite(gps_on, 0);  //Включение сим модуля.
  delay(5000);             //
  
  Serial.begin(19200);
  gpsSerial.begin(9600);
  
  for(byte i=0; i<12; i++)   //Чтение Разрешонного номера из EEPROM
    {
      data = EEPROM.read(i);
      nomber_Phone += data;
    }
  delay(100);
  Serial.println("AT");//Устанавливаем связь с сим модулем, для соглосования скорости передачи.
  delay(500);
  Serial.println("AT+CMGDA=\"DEL ALL\"");//Удаляем всё SMS которые могут содержаться на сим карте.
}

void loop()
{
  if(Serial.available()>0)
  {
    read_GSM();.
  }
  read_GPS();
}
//Функция данных полученых от сим модуля. 
void read_GSM()
{
  currStr = "";
  while(Serial.available()>0)
  { 
    data = Serial.read();
    delay(10);
    if ('\r' == data)
    {
      if(!currStr.compareTo("RING"))//Если текущая строка RING, значит едёт входящий звонок.
      {
        ring_GSM();    
      }
      else
      {
        if (currStr.startsWith("+CMT")) //Или если строка начинаеться c +CMT, значит пришло SMS
        {
          read_Message();
          Serial.println("AT+CMGDA=\"DEL ALL\"");//Удоляем всё SMS чтоб не накапливать их.
        }
      }
      currStr = "";
    }
    else if ('\n' != data)
    {
      currStr += data;
    }
  }  
}

//Функция обработки входящего звонка.
void ring_GSM()
{
  boolean ring = true;
  currStr = "";
  delay(10);
  while(ring)
  {
    data = Serial.read();
    if (data == '"')
    {
      data = Serial.read();
      while (data != '"')
      {
        currStr += data;
        data = Serial.read();
      }
      if (currStr == nomber_Phone)//Если номер совподает с номером в строке "nomber_Phone"
      {
        delay(1000);
        Serial.println("ATHO");// Тогда сбрасываем звонок
        delay(100);
        send_Message(&dat2);// И вызываем функци отправки SMS и передаём ей адрес строки содержащию GPS координаты. 
        return;
      }
      else //Если номер не совподает
      {
        Serial.println("ATHO");// Просто сбрасываем звонок.
        return;
      }
    }
  }
}
//Функция отправки SMS.
void send_Message(String *message) //Функция принимает адрес строки с текстом SMS.
{
  delay(500);
  Serial.print("AT + CMGS = \"");
  Serial.print(nomber_Phone);
  Serial.println('"');
  delay(500);
  Serial.println(*message);
  delay(500);
  Serial.print((char)26);
}
//Функция читает GPS координаты и преобразует в формат:
//N xx xx.xxxx - широта.
//E xx xx.xxxx - долгота.
//Time xx:xx:xx - время по гринвичу.
void read_GPS()
{
  gps = true;
  dat = "";
  while (gps)
  {
    if (gpsSerial.available()>0)
    {
      data = gpsSerial.read();
      if (data == 'L')
      {
        while (data != '\r')
        {
          dat += data;
          delay(2);
          data = gpsSerial.read();
        }
        gps = false;
        if (dat.indexOf('A') == char_A)
        {
          delay(5);
          dat2 = "N ";
          for(byte i=3; i<5; i++)
          {
            dat2 += dat.charAt(i);
          }
          dat2 += ' ';
          for(byte i=5; i<13; i++)
          {
            dat2 += dat.charAt(i);
          }
          dat2 += "\nE ";
          for(byte i=17; i<19; i++)
          {
            dat2 += dat.charAt(i);
          }
          dat2 += ' ';
          for(byte i=19; i<27; i++)
          {
            dat2 += dat.charAt(i);
          }
          delay(5);
          dat2 += "\nTime ";
          for(byte i=30; i<32; i++)
          {
            dat2 += dat.charAt(i);
          }
          dat2 += ':';
          for(byte i=32; i<34; i++)
          {
            dat2 += dat.charAt(i);
          }
          dat2 += ':';
          for(byte i=34; i<36; i++)
          {
            dat2 += dat.charAt(i);
          }
        }        
      }
    }
  }
}
//Функция чтения SMS.
void read_Message()
{
  currStr = "";
  while(Serial.available()>0)
  {
    data = Serial.read();
    if(data == '$')
    {
      while(data != '#')
      {
        data = Serial.read();
        currStr += data;
      }
      if(!currStr.compareTo("balans#"))//Запрос и отправка баланса сим карты
      {
        currStr = "";
        Serial.println("ATD#100#;");//USSD запрос баланса для beeline
        delay(5000);
        while(Serial.available()>0)
        {  
          data = Serial.read();
          if(data == '"')
          {
            data = Serial.read();
            while(data != 'B')
            {
              currStr += data;
              data = Serial.read();
            }
            send_Message(&currStr);
            return;
          }
        }
      }
      else if(!currStr.compareTo("callback#"))//Звонок на разрешонный номер.
      {
        Serial.print("ATD");
        delay(100);
        Serial.print(nomber_Phone);
        delay(100);
        Serial.println(";");
        return;
      }
      else if(!currStr.compareTo("ch.nomber#"))//Смена Разрешонного номера и сохранение его в EEPROM.
      {
        currStr = "";
        data = Serial.read();
        if(data == '+')
        {
          for(byte i = 0; i < 12; i++)
          {
            EEPROM.write(i, data);
            currStr += data;
            data = Serial.read();
          }
          nomber_Phone = currStr;//Сохранение нового Разрешонного номера.
          send_Message(&complete);//Отправка SMS потверждающая смену Разрешонного номера.
          return;
        }
      }
    }
  }
}
Slavyanin55
Slavyanin55 аватар
Offline
Зарегистрирован: 01.06.2014

То что надо! Благодарю! попробую извлечь из этого проверку баланса! и реакцию на звонок только со своих номеров. Вот бы еще пример с DTMFом найти

kjuman
Offline
Зарегистрирован: 14.02.2016

уходите от смс в сторону 3G!

+ счетчик импульсов + аналоговые входы = бюджетный мониторинг транспорта с расходом топлива и прочими плюшками)

заинтересует пишите расскажу много чего тк работаю с такими девайсами только промышленными вариантами и у них гора минусов....

Sergeich
Offline
Зарегистрирован: 05.03.2016

kjuman пишет:

заинтересует пишите расскажу много чего тк работаю с такими девайсами только промышленными вариантами и у них гора минусов....

Тема интересная, тоже думаю попробовать себе сделать.

Какие устройства Вы знаете,  и на чем они построены, на Arduino или нет?

kjuman
Offline
Зарегистрирован: 14.02.2016

нет, построены они на lpc2368

АПК КОМ ASC7 - мое основное оборудование а так их просто море)

Sergeich
Offline
Зарегистрирован: 05.03.2016

Его же самостоятельно для себя не сделаешь. Где я печатную плату сделаю - обойдется дороже чем купить готовое изделие. Форум посвящен Arduino и проектам для него.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

кто нибудь использовал Adafruit GPS?

Serhio163
Offline
Зарегистрирован: 03.10.2016

Здравствуйте, будьте любезны, скажите, а откуда в памяти взялся номер и не понял как смена номера происходит, на какой? Или, как организовать так, чтобы в память записался первый звонящий или номер, приславший смс с паролем?