Системы отслеживания местоположения автомобилей получают все большее распространение в современном мире, особенно с учетом повышения числа украденных автомобилей. Если в вашем автомобиле установлена система GPS это позволит отслеживать его местоположение и, следовательно, полиции будет проще найти ваш украденный автомобиль. Ранее на нашем сайте мы уже рассматривали проект отслеживания местоположения автомобиля на Arduino с помощью GPS и GSM, в котором координаты местоположения автомобиля передавались на мобильный телефон.
А в этой статье мы рассмотрим более продвинутую версию этого проекта, в котором вы сможете отслеживать местоположение своего автомобиля на гугл картах (Google Maps). Для выполнения этой задачи мы будем передавать координаты автомобиля на локальный сервер, после чего вы должны будете открыть веб-страницу (webpage) на вашем компьютере или мобильном телефоне, в которой вы найдете ссылку на местоположение вашего автомобиля на Google Maps. Кликнув по этой ссылке, вы перейдете на Google Maps с отмеченными координатами вашего автомобиля. В этом проекте GPS модуль будет использоваться для получения значений координат, Wi-Fi модуль будет передавать данные на компьютер или мобильный телефон с помощью Wi-Fi, а плата Arduino будет управлять всеми этими процессами.
Принципы работы проекта
Чтобы отслеживать местоположение автомобиля нам необходимо получить его координаты с помощью GPS модуля. Далее мы должны передать эти координаты от GPS модуля в плату Arduino с помощью последовательного порта. После этого Arduino извлекает необходимые данные из данных, полученных от GPS модуля. Структурная схема работа устройства приведена на следующем рисунке.
Но перед этим Arduino должна передать ряд команд Wi-Fi модулю ESP8266 чтобы сконфигурировать его, подсоединиться к роутеру и получить IP адрес. После этого Arduino инициализирует GPS модуль для получения координат и показывает на ЖК дисплее сообщение ‘Page Refresh message’, которое будет означать что пользователь должен обновить веб-страницу. Когда пользователь обновит веб-страницу Arduino считывает координаты из GPS модуля и передает на веб-страницу (локальный сервер) новые данные по Wi-Fi, в которых будет содержаться ссылка на Google maps. Кликнув по этой ссылке пользователь перейдет на сайт Google Maps где красной точкой будет отмечено текущее местоположение его автомобиля на Google Maps. Более подробно весь этот процесс показан на видео в конце статьи.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Wi-Fi модуль ESP8266 (купить на AliExpress).
- GPS модуль (купить на AliExpress).
- Wi-Fi роутер.
- USB кабель.
- Источник питания.
- Компьютер (ноутбук).
- Макетная плата.
- Соединительные провода.
Работа схемы
Схема устройства представлена на следующем рисунке.
Схема содержит плату Arduino Uno, GPS модуль и Wi-Fi модуль ESP8266. На ЖК дисплее будут показываться различные статусные сообщения. ЖК дисплей подключен к контактам 14-19 (A0-A5) платы Arduino.
Контакт Tx GPS модуля поключен к цифровому контакту 10 платы Arduino. С использованием Software Serial Library (библиотеки последовательной связи) мы можем задействовать последовательную связь на контактах 10 и 11 Arduino и сделать их соответственно контактами Rx и Tx последовательной связи. Контакт Rx GPS модуля оставим в свободном состоянии. По умолчанию, последовательная связь доступна на контактах 0 и 1 платы Arduino, но с использованием Software Serial Library мы сможем организовать последовательную связь на любых других цифровых контактах Arduino. Адаптер на 12 Вольт будет использоваться для питания GPS модуля. Ряд моментов об использовании GPS модуля совместно с Arduino можно прочитать в статье про считывание GPS данных с помощью персонального компьютера и Arduino Uno.
Контакты Vcc и GND модуля ESP8266 подключены к контактам 3.3V и GND платы Arduino, контакт CH_PD также подсоединен к 3.3V. Контакты Tx и Rx модуля ESP8266 непосредственно подсоединены к контактам 2 и 3 платы Arduino. Библиотека последовательного порта (Software Serial Library) используется чтобы осуществлять последовательную связь на контактах 2 и 3 Arduino. Также об использовании Wi-Fi модуля ESP8266 совместно с Arduino можно прочитать в статье про передачу данных от Arduino Uno на веб-страницу с помощью WiFi.
Внешний вид Wi-Fi модуля ESP8266 показан на следующем рисунке.
Модуль ESP8266 имеет 2 светодиода, один из которых красного цвета (для индикации подачи питания на плату), а второй синего цвета (для индикации процесса передачи данных). Синий светодиод мигает когда модуль ESP8266 передает какие-нибудь данные через свой контакт Tx. Не соединяйте ваш модуль ESP8266 с источником питания +5 Вольт иначе можете повредить модуль. В нашем проекте мы будем использовать скорость 9600 бод/с для последовательной связи.
Наглядно посмотреть процесс обмена данными в последовательном режиме между Wi-Fi модулем ESP8266 и платой Arduino вы можете в мониторе последовательной связи (Serial Monitor). Также более подробно эти процессы показаны в видео в конце статьи.
Преобразование GPS минут в десятичные координаты
GPS модуль получает координаты от спутников в формате минут (ddmm.mmmm), а для определения местоположения на Google Maps нам нужен десятичный формат координат, поэтому мы сначала должны осуществить преобразование координат из одного формата в другой.
Предположим, что мы получили координаты широты (Latitude) от GPS модуля в виде 2856.3465 (ddmm.mmmm). Первые две цифры здесь будут обозначать градусы, а оставшиеся цифры будут обозначать минуты. То есть мы будем иметь 28 градусов и 56.3465 минут. То есть 28 градусов нам нет необходимости конвертировать, а нам нужно конвертировать только минуты в десятичный формат при помощи деления значения минут на 60. Получаем формулу:
Decimal Degree Coordinate = Degree + Minute/60
Decimal Degree Coordinate = 28 + 56.3465/60
Decimal Degree Coordinate = 28 + 0.94
Decimal Degree Coordinate = 28.94
Аналогичные преобразования нужно произвести и для значения долготы (Longitude).
Эти преобразования мы в программе для Arduino будем делать с помощью следующего кода:
float minut= lat_minut.toFloat();
minut=minut/60;
float degree=lat_degree.toFloat();
latitude=degree+minut;
minut= long_minut.toFloat();
minut=minut/60;
degree=long_degree.toFloat();
logitude=degree+minut;
Исходный код программы
В программе мы будем использовать SerialSoftware library чтобы подключить ESP8266 и GPS модуль к Arduino. Также в программе необходимо инициализировать ряд контактов и задействовать последовательную связь со скоростью 9600 бод/с. А также подключить библиотеку для работы с ЖК дисплеем.
#include<SoftwareSerial.h>
SoftwareSerial Serial1(2,3); //make RX arduino line is pin 2, make TX arduino line is pin 3.
SoftwareSerial gps(10,11);
#include<LiquidCrystal.h>
LiquidCrystal lcd(14,15,16,17,18,19);
После этого нам необходимо объявить ряд переменных и строк.
String webpage="";
int i=0,k=0;
int gps_status=0;
String name="<p>1. Name: Your Name </p>"; //22
String dob="<p>2. DOB: 12 feb 1993</p>"; //21
String number="<p>4. Vehicle No.: RJ05 XY 4201</p>";//29
String cordinat="<p>Coordinates:</p>"; //17
String latitude="";
String logitude="";
String gpsString="";
char *test="$GPGGA";
Далее мы должны запрограммировать процесс получения координат от GPS модуля.
void gpsEvent()
{
gpsString="";
while(1)
{
while (gps.available()>0)
{
char inChar = (char)gps.read();
gpsString+= inChar;
if (i < 7)
{
if(gpsString[i-1] != test[i-1])
{
i=0;
..... ....
..... .....
Также следует запрограммировать функцию для извлечения данных из GPS строки и конвертировать полученные значения координат в десятичный формат как обсуждалось ранее в статье.
void coordinate2dec()
{
String lat_degree="";
for(i=18;i<20;i++)
lat_degree+=gpsString[i];
String lat_minut=»»;
for(i=20;i<28;i++)
lat_minut+=gpsString[i];
….. ….
….. …..
Также необходимо запрограммировать ряд функций для передачи команд на модуль ESP8266 для соединения его с сетью WiFi.
void connect_wifi(String cmd, int t)
{
int temp=0,i=0;
while(1)
{
Serial.println(cmd);
Serial1.println(cmd);
while(Serial1.available()>0)
..... ....
..... .....
Функция void show_coordinate() предназначена для показа координат на ЖК дисплее и мониторе последовательного порта (Serial Monitor), а функция void get_ip() предназначена для получения IP адреса.
Функция Void Send() предназначена для формирования строки с необходимой информацией для передачи ее на веб-страницу с использованием модуля ESP8266, а функция void sendwebdata() необходима для передачи строки с информацией на веб-страницу с использованием последовательной связи.
В функции void loop плата Arduino непрерывно ждет запроса на обновление страницы (Refreshing web page).
void loop()
{
k=0;
Serial.println("Please Refresh Ur Page");
lcd.setCursor(0,0);
lcd.print("Please Refresh ");
lcd.setCursor(0,1);
lcd.print("Your Web Page.. ");
while(k<1000)
..... ....
..... .....
Далее представлен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
#include<SoftwareSerial.h> SoftwareSerial Serial1(2,3); //make RX arduino line is pin 2, make TX arduino line is pin 3. SoftwareSerial gps(10,11); #include<LiquidCrystal.h> LiquidCrystal lcd(14,15,16,17,18,19); boolean No_IP=false; String IP=""; String webpage=""; int i=0,k=0; int gps_status=0; String name="<p>1. Name: Your Name </p>"; //22 String dob="<p>2. DOB: 12 feb 1993</p>"; //21 String number="<p>4. Vehicle No.: RJ05 XY 4201</p>";//29 String cordinat="<p>Coordinates:</p>"; //17 String latitude=""; String logitude=""; String gpsString=""; char *test="$GPGGA"; void check4IP(int t1) { int t2=millis(); while(t2+t1>millis()) { while(Serial1.available()>0) { if(Serial1.find("WIFI GOT IP")) { No_IP=true; } } } } void get_ip() { IP=""; char ch=0; while(1) { Serial1.println("AT+CIFSR"); while(Serial1.available()>0) { if(Serial1.find("STAIP,")) { delay(1000); Serial.print("IP Address:"); while(Serial1.available()>0) { ch=Serial1.read(); if(ch=='+') break; IP+=ch; } } if(ch=='+') break; } if(ch=='+') break; delay(1000); } lcd.clear(); lcd.print(IP); lcd.setCursor(0,1); lcd.print("Port: 80"); Serial.print(IP); Serial.print("Port:"); Serial.println(80); delay(1000); } void connect_wifi(String cmd, int t) { int temp=0,i=0; while(1) { Serial.println(cmd); Serial1.println(cmd); while(Serial1.available()>0) { if(Serial1.find("OK")) { i=8; } } delay(t); if(i>5) break; i++; } if(i==8) { Serial.println("OK"); } else { Serial.println("Error"); } delay(1000); } void setup() { Serial1.begin(9600); Serial.begin(9600); lcd.begin(16,2); lcd.print("Vehicle Tracking"); lcd.setCursor(0,1); lcd.print(" System "); delay(2000); lcd.clear(); lcd.print("WIFI Connecting.."); // lcd.setCursor(0,1); // lcd.print("Please Wait..."); delay(1000); connect_wifi("AT",1000); connect_wifi("AT+CWMODE=3",1000); connect_wifi("AT+CWQAP",1000); connect_wifi("AT+RST",5000); check4IP(5000); if(!No_IP) { Serial.println("Connecting Wifi...."); connect_wifi("AT+CWJAP=\"1st floor\",\"muda1884\"",7000); //AT+CWJAP=”wifi_username”,”wifi_password” – имя пользователя и пароль для вашего wifi соединения } else { } Serial.println("Wifi Connected"); lcd.clear(); lcd.print("WIFI Connected"); delay(2000); lcd.clear(); lcd.print("Getting IP"); get_ip(); delay(2000); connect_wifi("AT+CIPMUX=1",100); connect_wifi("AT+CIPSERVER=1,80",100); Serial1.end(); lcd.clear(); lcd.print("Waiting For GPS"); lcd.setCursor(0,1); lcd.print(" Signal "); delay(2000); gps.begin(9600); get_gps(); show_coordinate(); gps.end(); Serial1.begin(9600); delay(2000); lcd.clear(); lcd.print("GPS is Ready"); delay(1000); lcd.clear(); lcd.print("System Ready"); Serial.println("System Ready.."); } void loop() { k=0; Serial.println("Please Refresh Ur Page"); lcd.setCursor(0,0); lcd.print("Please Refresh "); lcd.setCursor(0,1); lcd.print("Your Web Page.. "); while(k<1000) { k++; while(Serial1.available()) { if(Serial1.find("0,CONNECT")) { Serial1.end(); gps.begin(9600); get_gps(); gps.end(); Serial1.begin(9600); Serial1.flush(); /* lcd.clear(); lcd.print("Sending Data to "); lcd.setCursor(0,1); lcd.print(" Web Page ");*/ Serial.println("Start Printing"); Send(); show_coordinate(); Serial.println("Done Printing"); delay(5000); lcd.clear(); lcd.print("System Ready"); delay(1000); k=1200; break; } } delay(1); } } void gpsEvent() { gpsString=""; while(1) { while (gps.available()>0) // поступающие последовательные данные от GPS { char inChar = (char)gps.read(); gpsString+= inChar; // сохраняем поступающие данные от GPS во временную строку i++; if (i < 7) { if(gpsString[i-1] != test[i-1]) //проверяем правильность строки { i=0; gpsString=""; } } if(inChar=='\r') { if(i>65) { gps_status=1; break; } else { i=0; } } } if(gps_status) break; } } void get_gps() { gps_status=0; int x=0; while(gps_status==0) { gpsEvent(); int str_lenth=i; latitude=""; logitude=""; coordinate2dec(); i=0;x=0; str_lenth=0; } } void show_coordinate() { lcd.clear(); lcd.print("Latitide:"); lcd.print(latitude); lcd.setCursor(0,1); lcd.print("Longitude:"); lcd.print(logitude); Serial.print("Latitude:"); Serial.println(latitude); Serial.print("Longitude:"); Serial.println(logitude); } void coordinate2dec() { //j=0; String lat_degree=""; for(i=18;i<20;i++) // извлекаем широту из строки lat_degree+=gpsString[i]; String lat_minut=""; for(i=20;i<28;i++) lat_minut+=gpsString[i]; String long_degree=""; for(i=30;i<33;i++) // извлекаем долготу из строки long_degree+=gpsString[i]; String long_minut=""; for(i=33;i<41;i++) long_minut+=gpsString[i]; float minut= lat_minut.toFloat(); minut=minut/60; float degree=lat_degree.toFloat(); latitude=degree+minut; minut= long_minut.toFloat(); minut=minut/60; degree=long_degree.toFloat(); logitude=degree+minut; } void Send() { webpage = "<h1>Welcome to Saddam Khan's Page</h1><body bgcolor=f0f0f0>"; webpage+=name; webpage+=dob; webpage+=number; webpage+=cordinat; webpage+="<p>Latitude:"; webpage+=latitude; webpage+="</p>"; webpage+="<p>Longitude:"; webpage+=logitude; webpage+="</p>"; webpage+= "<a href=\"http://maps.google.com/maps?&z=15&mrt=yp&t=k&q="; webpage+=latitude; webpage+='+'; //28.612953, 77.231545 //28.612953,77.2293563 webpage+=logitude; webpage+="\">Click Here for google map</a>"; sendwebdata(); webpage=""; while(1) { Serial.println("AT+CIPCLOSE=0"); Serial1.println("AT+CIPCLOSE=0"); while(Serial1.available()) { //Serial.print(Serial1.read()); if(Serial1.find("0,CLOSE")) { return; } } delay(500); i++; if(i>5) { i=0; } if(i==0) break; } } void sendwebdata() { i=0; while(1) { unsigned int l=webpage.length(); Serial1.print("AT+CIPSEND=0,"); Serial1.println(l+2); Serial.println(l+2); Serial.println(webpage); Serial1.println(webpage); while(Serial1.available()) { if(Serial1.find("OK")) { return; } } i++; if(i>5) i=0; if(i==0) break; delay(200); } } |