Реклама ⓘ
Главная » Arduino
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

GPS-трекер для авто с отправкой данных на сервер с использованием GSM/GPRS шилда

Создаем GPS-трекер для авто. Необходимый функционал:

  1. отправка GPS-данных по GSM/GPRS на интернет-сайт с сохранением в базе данных;
  2. просмотр маршрута авто за определенный интервал времени на web-странице с использованием Яндекс.Карт;
  3. просмотр в реальном времени текущего положения авто на web-странице с использованием Яндекс.Карт.

Используемые компоненты:

1) Плата Arduino UNO (поиск на AliExpress)

2) SIM900 GSM/GPRS шилд для Arduino (бесплатно предоставлен сервисом ЖелеZona). Стоит около 20$

3) GPS-модуль VK16E (цена около 9-10$ на AliExpress)

Начнем с описания модуля SIM900 GSM/GPRS.

Arduino GPRS/GSM Shield предоставляет вам возможность использовать сеть мобильной GSM связи для удаленного приема и передачи данных для Arduino-проектов. GPRS/GSM shield позволяет добиться этого с помощью одного из трех способов:

  1.  SMS;
  2. Аудио (голос, CSD, DTMF);
  3. GPRS.

Рfссмотрим один из вариантов данного шилда – SIM900 Quad-Band GPRS shield (см. рис. 9.1) на основе чипа SIM900.

Основные характеристики GSM модуля SIM900:

  • четыре диапазона GSM 850/ 900/ 1800/ 1900 МГц;
  • класс передачи данных GPRS multi-slot class 10/8;
  • соответствие стандарту GSM фазы 2/2+;
  • класс мощности 4 (2 Вт в диапазонах 850/ 900 МГц) ;
  • класс мощности 1 (1 Вт в диапазонах 1800/1900 MГц) ;
  • управление AT командами (GSM 07.07 ,07.05 и фирменные AT команды SIMCom) ;
  • аудиокодеки HR, FR, EFR, AMR, подавление эха;
  • CSD до 14.4кбит/с;
  • PPP-стек;
  • встроенный стек TCP/IP, UDP/IP;
  • протоколы HTTP и FTP;
  • протокол защищенных сокетов SSL;
  • декодирование DTMF-тонов;
  • eMail - формирование и отправка электронных писем посредством АТ-команд;
  • SMS Autorun - исполнение АТ-команд, полученных по SMS от определенного абонента;
  • 2.5Mb user memory - встроенная память для пользовательских данных;
  • MMS - формирование, дополнение пользовательскими файлами и отправка с помощью АТ-команд;
  • AMR play - воспроизведение аудиофайлов в динамик или в сторону удаленного абонента;
  • Jamming Detection - функция обнаружения глушения сигнала;
  • FOTA - обновление прошивки модуля по беспроводному каналу;
  • Easy Scan - получение информации об окружающих базовых станциях без подключения SIM-карты;
  • PING - проверка доступности адреса в Internet посредством обмена ICMP пакетами;

Особенности данного шилда:

  • совместимость с Arduino Mega;
  • слот для карт SD ( включение/отключены при помощи перемычки);
  • программное и аппаратное обеспечение последовательного порта: может общаться с Arduino через последовательный порт программного обеспечения (D7 / D8) или последовательный порт (D0 / D1);
  • интерфейс FTDI;
  • слот батарейки для RTC.
  • 10 цифровых входов/выходов GPIO;
  • 2 ШИМ  выхода;
  • I2C интерфейс

Данный шилд имеет два способа включения – аппаратный (кратковременное нажатие кнопки PWRKEY) и прграммный (используется выход D9 Arduino).

Получение GPS-данных

Модуль GPS V.KEL 16 один из самых дешевых и простых. Тем не менее имеет батарейку для сохранения данных о спутниках. По даташиту, холодный старт должен занимать 39 секунд, у меня это заняло примерно 20 минут. Следующий старт примерно 2 минуты. Назначение выводов

Основное, что можно делать с этим приемником — читать данные по протоколу NMEA с TX пина. Уровни — 5V,скорость — 9600 бод. Для подключения к Arduino используем программный UART на пинах 2 и 3. Для чтения данных используем библиотеку TinyGPS.  

Отправка данных на сервер (GSM/GPRS shield)

Подключаемся к Arduino к контактам 7 и 8. 

Для получения страницы по определенному URL нужно послать следующие команды:
AT+SAPBR=1,1    //Открыть несущую (Carrier)
AT+SAPBR=3,1,"CONTYPE","GPRS"   //тип подключения - GPRS
AT+SAPBR=3,1,"APN","internet.beeline.ru" //APN, для Билайна - internet
AT+HTTPINIT    //Инициализировать HTTP 
AT+HTTPPARA="CID",1    //Carrier ID для использования.
AT+HTTPPARA="URL","http:/????????.ru/gps_tracker/gps_tracker1.php?id_avto=?N&lat=XXXXXlon=YYYYY"    //Собственно URL, после sprintf с координатами
AT+HTTPACTION=0    //Запросить данные методом GET
AT+HTTPREAD   //дождаться ответа
AT+HTTPTERM    //остановить HTTP

Предусмотрим еще один момент - при написании серверной части и web-интерфейса  предусмотрим получение и вывод результатов для нескольких модулей (id_avto=N), поставим переключатель на 3 позиции, что позволит получать информацию от 8 транспортных средств.  

Вид GPS-трекера в сборе. + добавлена батарея LiPo для перестановки, например на велосипед

Написание скетча на Arduino

Чтобы не отправлять данные во время стоянки транспортного средства, отправлять будем данные, только если GPS дынные будут изменяться на значение, указанное в константе MINCANGE.

Интервал отправки данных - константа INTERVALSEND мсек. Наличие двух активных программных последовательных портов приводит к ошибкам получения/отправки данных, поэтому приходится переключать  состояние программных последовательных портов для работы с каждым шилдом.

GPRS.end();gpsSerial.begin(9600);

В процедуре setup() - выбор номера модуля для отправки данных на сервер (id_avto=) - считывается их трехпереключателей

Сам скетч

#define INTERVALSEND 30000
#define MINCHANGE 100

#include "SoftwareSerial.h"
SoftwareSerial GPRS(7, 8);
int onModulePin= 9;
char aux_str[150];
char aux;
char data[512];
int data_size;
uint8_t answer=0;


#include "TinyGPS.h"
TinyGPS gps;
//Tx, Rx 
SoftwareSerial gpsSerial(2, 3);
long lat, lon;
long endlatsend=0; 
long endlonsend;
unsigned long time1,date1;
unsigned long age;
bool newdata = false;
unsigned long millis1=0;
unsigned long millissend=0;
unsigned long millisdata=0;


char apn[]="internet.beeline.ru";
char url[150];
String surl="http://yoursite/gps_tracker/gps_tracker1.php?id_avto=";
int id_avto=1;

void setup()
  {
  GPRS.begin(19200);               // the GPRS baud rate   
  Serial.begin(9600);             // the Serial port of Arduino baud rate.
  //gpsSerial.begin(9600);
  Serial.println("Starting...");
  pinMode(onModulePin,OUTPUT);
  
  pinMode(12,OUTPUT);
  digitalWrite(12,LOW);
  
  power_on();
  delay(3000);
  //sendATcommand("AT", "OK", 2000);
  //delay(3000);
  // sets APN , user name and password
  sendATcommand("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK", 2000);
  snprintf(aux_str, sizeof(aux_str), "AT+SAPBR=3,1,\"APN\",\"%s\"", apn);
  sendATcommand(aux_str, "OK", 2000);
  while (sendATcommand("AT+SAPBR=1,1", "OK", 2000) == 0)
    {
    delay(2000);
    }
  delay(1000);
  }

void loop() 
  {
    digitalWrite(12,HIGH);
    GPRS.end();gpsSerial.begin(9600);
    while (millis() - millis1 < 2000) 
      {
      if (readgps())
        newdata = true; 
      }   
    if (newdata) 
      {
      gps.get_position(&lat, &lon, &age);
      millisdata=millis();
      Serial.print("lat=");Serial.print(lat);
      Serial.print("  lon=");Serial.print(lon);     
      gps.get_datetime(&date1, &time1, &age);
      Serial.print(" date=");Serial.print(date1);
      Serial.print("  time=");Serial.println(time1);     
      newdata=false;
      }
   //if(millis()-millissend>INTERVALSEND && millis()-millisdata<INTERVALSEND
      //&& abs(lat-endlatsend)>MINCHANGE && abs(lon-endlonsend)>MINCHANGE)
  if(millis()-millissend>INTERVALSEND && millis()-millisdata<INTERVALSEND
      && abs(lat-endlatsend)>MINCHANGE && abs(lon-endlonsend)>MINCHANGE
      )
     {
     GPRS.begin(19200);gpsSerial.end();
     // Initializes HTTP service
     answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
     if (answer == 1)
       {
        // Sets CID parameter
        answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
        if (answer == 1)
          {// Sets url 
           endlatsend=lat;endlonsend=lon;
           String surl1=set_url_avto()+"&lat="+String(lat)+"&lon="+String(lon);
           surl1+="&date="+String(date1)+"&time="+String(time1);
           surl1.toCharArray(url,surl1.length()+1);
           snprintf(aux_str, sizeof(aux_str), "AT+HTTPPARA=\"URL\",\"%s\"", url);
           answer = sendATcommand(aux_str, "OK", 5000);
           if (answer == 1)
           {// Starts GET action
           answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 10000);
           if (answer == 1)
             {
             sprintf(aux_str, "AT+HTTPREAD");
             sendATcommand(aux_str, "OK", 5000);
             }
           else
             {
             Serial.println("Error getting the url");
             }
           }
         else
           {
           Serial.println("Error setting the url");
           }
         }
       else
         {
         Serial.println("Error setting the CID");
         }    
       }
    else
       {
       Serial.println("Error initializating");
       }
    sendATcommand("AT+HTTPTERM", "OK", 5000);
    millissend=millis();
    }
  else
    Serial.println("data not change!!!");
  millis1=millis();
  GPRS.begin(19200);gpsSerial.end();
  }
// отправка AT-команд
int8_t sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout)
  {
   uint8_t x=0,  answer=0;
   char response[150];
   unsigned long previous;

   memset(response, '\0', 150);    // Initialize the string
   delay(100);
   while( GPRS.available() > 0) GPRS.read();    // Clean the input buffer
   GPRS.println(ATcommand);    // Send the AT command 
   x = 0;
   previous = millis();
   // this loop waits for the answer
   do{
     if(GPRS.available() != 0)
       {    
       // if there are data in the UART input buffer, reads it and checks for the asnwer
       response[x] = GPRS.read();
       //Serial.print(response[x]);
       x++;
       // check if the desired answer  is in the response of the module
       if (strstr(response, expected_answer) != NULL)    
         {
         answer = 1;
         }
       }
    }
    // Waits for the asnwer with time out
    while((answer == 0) && ((millis() - previous) < timeout));    
    Serial.println(response);
        return answer;
  }
// программное включение питания
void power_on()
  {
  uint8_t answer=0;
  //answer = sendATcommand("AT+CPOWD=1", "OK", 2000);
  pinMode(onModulePin,OUTPUT);
  // checks if the module is started
  digitalWrite(onModulePin,LOW);
  delay(1000);
  digitalWrite(onModulePin,HIGH);
  delay(2000);
  digitalWrite(onModulePin,LOW);
  delay(3000);
  answer = sendATcommand("AT", "OK", 2000);
  if (answer == 0)
    {
    digitalWrite(onModulePin,LOW);
    delay(1000);
    digitalWrite(onModulePin,HIGH);
    delay(2000);
    digitalWrite(onModulePin,LOW);
    delay(3000);
    Serial.println("POWER!!!!");
    
      
    // power on pulse
    digitalWrite(onModulePin,HIGH);
    delay(3000);
    digitalWrite(onModulePin,LOW);
    // waits for an answer from the module
    while(answer == 0)
      {  
      // Send AT every two seconds and wait for the answer   
      answer = sendATcommand("AT", "OK", 2000);    
      }
    }
  }
// проверка наличия данных gps
bool readgps() 
  {
  while (gpsSerial.available())
    {
    int b = gpsSerial.read();
    //в TinyGPS есть баг, когда не обрабатываются данные с \r и \n
    if('\r' != b) 
      {
      if (gps.encode(b))
          return true;
      }
    }
  return false;
  }
  
 String set_url_avto()
  {
  String surl1;
  if(digitalRead(14)==1)
    id_avto=id_avto+1;
  if(digitalRead(15)==1)
    id_avto=id_avto+2;
  if(digitalRead(16)==1)
    id_avto=id_avto+4;
  surl1=surl+String(id_avto);
  Serial.print("surl1=");Serial.println(surl1); 
  id_avto=0;
  return surl1; 
  }

Отправка данных на сервер - обработчик скрипт gps_tracer1.php. Скрипт обрабатывает GET-данные и записывает их в базу данных.

Содержимое скрипта

<?php
 require_once("mybaza.php");
 $id_avto=$_GET[id_avto];
 $lat=$_GET[lat]/100000;
 $lon=$_GET[lon]/100000;
 $data=date('Y-m-d H:i:s');
 $query1="INSERT into gps_tracker SET
           id_avto=".$id_avto.",lat=".$lat.",lon=".$lon.",
           data='".$data."' ";
   if(!mysql_query($query1))
    echo "error=".$query1;  
  else
    echo "OK";
?>

WEB-интерфейс

Web-интерфейс -отображение на Яндекс.Картах текущего (последнего переданного) положения либо маршрута за выбранный период. 

Текущее положение - метка , на балуне время для данной метки.

При построении маршрута по меткам строится полигон, на балуне для каждой метки отображается время. Для быстрого построения страницы предусмотрена константа максимального количества меток, следующие метки подгружаются кнопками > и <.

Интерфейс написан с использованием технологии ajax (,библиотека xajax). В прикрепленном архиве файлы сайта и дамп БД.

Прикрепленные файлы:

Теги:

Опубликована: 0 2
Я собрал 0 1
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 1 чел.

Комментарии (20) | Я собрал (0) | Подписаться

0
Роман #
Не совсем понятно как запустить web-интерфейс, не могли бы Вы объяснить подробнее?
Ответить
0

[Автор]
victoruni #
Нужен хостинг с php и mysql и доменное имя. Загружаете на свой хостинг файлы из архива www, потом создаете базу данных дамп базы данных в том же архиве правите файл my.php (данные с бд, паролями) и в скетче меняете имя сервера обращения на свое
Ответить
0
Verial #
Все сделал как у вас написано, но на сайте не карты, только красный квадрат как можно от этого избавиться?
Ответить
0
Raccoon #
Такая же проблема. Удалось решить?
Ответить
0
Николай #
Приветствую! Не могли бы вы поделиться схемой расключения всего этого добра: какие пины ардуино к каким пинам GSM и GPS модулей соответственно подключать? Возможно это совсем глупый вопрос, но я слаб в этом вопросе.
Ответить
0

[Автор]
victoruni #
У меня
SoftwareSerial GPRS(7, 8);
//Tx, Rx
SoftwareSerial gpsSerial(2, 3);
//Tx, Rx

А так зависит от вашего SIM900 GSM/GPRS - какие у него контаты для обмена с Arduino (бывает 2 и 3). Тогда GPS нужно переносить на другие цифровые
Ответить
0
Николай #
Хорошо, благодарю! Я пока сам не знаю, какая будет модификация, жду когда придёт с Китая. Но в любом случае стало понятней. Так что ещё раз благодарю!
Ответить
0
Алексей #
Добрый день! Возник вопрос, вставил свои данные в ваш код, на полученные данные выводит значения "data not change!!!", а в конце HTTPREAD:120
error=INSERT into gps_tracker SET
id_avto=1,lat=415.72609,lon=22.5778,
data='2016-07-09 02:19:45' OK

и больше в мониторе порта ничего не происходит
Ответить
0

[Автор]
victoruni #
Добрый вечер!
Смотрите код php-скрипта на сервере
Ответить
0

[Автор]
victoruni #
php
require_once("mybaza.php");
$id_avto=$_GET[id_avto];
$lat=$_GET[lat]/100000;
$lon=$_GET[lon]/100000;
$data=date('Y-m-d H:i:s');
$query1="INSERT into gps_tracker SET
id_avto=".$id_avto.",lat=".$lat.",lon=".$lon.",
data='".$data."' ";
if(!mysql_query($query1))
echo "error=".$query1;

У вас ошибка доступа к бд mysql
Проверьте в mybaza.php соответствие БД, пользователя и пароля вашим данным

Проверить можно из браузера примерно так
http://yoursite/gps_tracker/gps_tracker1.php?id_avto=1&lat=12345&lon=12345
ответ должен быть
ok
Ответить
+1
verial #
Большое вам спасибо все получилось, а главное трекер на основе ардуино про мини дает огромные возможности и дешевизна поражает. Всего 1 тысяча рублей.
Правда я сделал все компактнее на sim800l
Ответить
0
vng #
Добрый день! Помогите !
Web сервер httpd и MySQL под OpenWRT на роутере MR3020. Данные c GPS пишутся в базу нормально. PHP читает. Карта отображается. Координаты из базы читаются но на карте не отображаются. Кнопка "Смотрим" на форме меняется на "Загрузка.." и все.
Пробовал развернуть Ваш Web-проэкт на десктопе под Apache все работает. На OpenWRT никак. Подскажите куда куда "копать".
Ответить
0
Artiom #
Добрый день, могли бы вы помочь мне? Когда запускаю скетч, кидает такую ошибку: AT+SAPBR=1,1 error. Стоит GSM 800L модуль.
Периодически при запуске показывает Starting... POWER!!!
Буду вам очен признателен за помощь! Спасибо!
Ответить
0
DrLesh #
Возможно не хватает тока для модуля. И попробуйте подсоединить в гнездо куда подсоединяется сама антенна на модуле, антенну длиннее, 10см хватит
Ответить
0
Артем #
Не совсем понимаю как на карте отображаются перемещения 8-ми объектов. На сайте ведь всего лишь 3 возможности выбора: Track1, Track2 и Track3. Если в бд номер id равен 1, то данные отображаются по Track1, если id=2, то соответственно Track2. Ну и для 3 так же. Не могли бы Вы рассказать?
Ответить
0

[Автор]
victoruni #
С помощью перемычек вы выбираете какой у Вас обьект (8 вариантов). В базе можно добавить Track4 (id=4), Track5(id=5), Track6 (id=6), Track7(id=7)
Ответить
0
IlyaVakhaev #
Что если занести блок кода:
GPRS.end();gpsSerial.begin(9600);
while (millis() - millis1 < 2000)
{
if (readgps())
newdata = true;
}
if (newdata)
{
gps.get_position(&lat, &lon, &age);
millisdata=millis();
Serial.print("lat=");Serial.print(lat);
Serial.print(" lon=");Serial.print(lon);
gps.get_datetime(&date1, &time1, &age);
Serial.print(" date=");Serial.print(date1);
Serial.print(" time=");Serial.println(time1);
newdata=false;
}
в условие if(millis()-millissend>INTERVALSEND )
?
Тогда программа при каждом проходе временного интервала INTERVALSEND будет читать координаты, вместо того, чтобы читать их всё время до отправки.
Что Вы думаете по этому поводу? Возможно в этом есть какие-либо недостатки?
Ответить
0

[Автор]
victoruni #
Я думаю, это даже лучше, если Вам нужно еще делать другие операции в loop(). Если нет, то без разницы
Ответить
0
IlyaVakhaev #
Здравствуйте! А как работает метод set_url_avto на аппаратном уровне? Как я понял он нужен чтобы можно было не менять в программе id_avto, а просто что-то в схеме нажать и id поменяется?
Ответить
0

[Автор]
victoruni #
Здравствуйте! Все верно, выбор id. Увеличьте картинку - там стоит dip-переключатель
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Arduino UNO
Arduino UNO
200 Вт усилитель класса D на IRS2092 iMAX B6 - зарядное для Lion, LiPo, LiFe, Pb, NiCd и NiMH аккумуляторов
вверх