Система предупреждения об авариях автомобилей с использованием Arduino, GPS и GSM

В предыдущих статьях на нашем сайте мы уже рассматривали систему отслеживания местоположения транспортных средств с использованием GSM и GPS, а также систему отображения местоположения автомобиля на гугл картах. В этой же статье мы рассмотрим создание автоматизированной системы предупреждения об авариях транспортных средств (автомобилей) на основе платы Arduino с использованием технологий GPS, GSM и акселерометра. В этой системе акселерометр будет обнаруживать неожиданные изменения осей автомобиля, а GSM модуль передавать сигнал тревоги на ваш мобильный телефон с указанием местоположения аварии.

Внешний вид системы предупреждения об авариях автомобилей на основе платы Arduino

Местоположение аварии будет передаваться в формате ссылки Google Map, для которой координаты широты и долготы будут извлекаться из GPS модуля. Сообщения также будут содержать сведения о скорости автомобиля в милях. Более подробно все процессы работы системы можно посмотреть в видео в конце статьи. С небольшими изменениями данная система может быть использована для гораздо более широкого спектра применений.

Внешний вид передаваемых SMS в нашей системе Отображение местоположения автомобиля на гугл картах

Необходимые компоненты

Плата Arduino Uno
GSM модуль (SIM900A)
GPS модуль (SIM28ML)
Акселерометр (ADXL335)
ЖК дисплей 16х2
Источник питания с напряжением 5В
Соединительные провода
Потенциометр 10 кОм
Макетная или печатная плата
Источник питания 12v 1amp

GPS модуль и его работа

GPS представляет собой глобальную систему навигации и определения положения и используется для определения широты и долготы любой точки на Земле, также с ее помощью можно определить UTC время (всеобщее скоординированное время). В нашем проекте GPS модуль используется для определения местоположения аварии. Он принимает от спутников его текущие координаты каждую секунду, а также время и дату. Более подробно работу с ним мы уже рассматривали в статье про отслеживание местоположения транспортных средств с использованием GSM и GPS.

Внешний вид GPS модуля

Примерный вид фиксированных данных глобального позиционирования (Global Positioning System Fix Data) показан на следующем рисунке:

Данные, передаваемые GPS модулем

Мы можем извлечь нужные нам данные из строки $GPGGA при помощи подсчета запятых в строке. К примеру, если вы нашли строку $GPGGA и сохранили ее в массиве, то широта может быть найдена в нем после двух запятых, а долгота – после четырех запятых. После извлечения значения широты и долготы можно поместить в другие массивы.

Приведем пример $GPGGA строки с расшифровкой:

$GPGGA,104534.000,7791.0381,N,06727.4434,E,1,08,0.9,510.4,M,43.9,M,,*47

$GPGGA,HHMMSS.SSS,latitude,N,longitude,E,FQ,NOS,HDP,altitude,M,height,M,,checksum data

В следующей таблице представлен перевод (описание) этих данных GPS.

Идентификатор Описание
$GPGGA Фиксированные данные системы глобального позиционирования
HHMMSS.SSS Время в формате: час минута секунда и миллисекунда
Latitude Широта (координата)
N Направление: N=North (север), S=South (юг)
Longitude Долгота (координата)
E Направление: E= East (восток), W=West (запад)
FQ Данные фиксированного качества (Fix Quality Data)
NOS Номер использованного спутника
HPD Фактор снижения точности при определении положения в горизонтальной плоскости (Horizontal Dilution of Precision)
Altitude Высота над уровнем моря
M Meter (метр)
Height Height (высота)
Checksum Данные контрольной суммы

GSM модуль

SIM900 представляет собой четырех диапазонный GSM/GPRS модуль, который очень удобен для использования в различных DIY (сделай сам) проектах. SIM900 поддерживает технологии GSM/GPRS, может работать в диапазонах частот 850/900/1800/1900 МГц и обеспечивает передачу голоса, SMS и данных с низким энергопотреблением. Его сравнительно легко можно найти в различных магазинах электроники.

Внешний вид GSM модуля

Основные особенности данного модуля:

  • разработан на основе однокристального процессора, интегрированного в ядро AMR926EJ-S;
  • четырех диапазонный GSM/GPRS модуль небольшого размера;
  • поддерживает технологию GPRS.

AT команды

AT означает ATTENTION (внимание). Эти команды используются для управления GSM модулем. С примерами использования подобных команд для управления GSM модулем вы можете ознакомиться в проектах по следующей ссылке. Для теста GSM модуля мы отправляем ему AT команду. Если с модулем все нормально, он нам ответит OK. Далее приведены некоторые из наиболее часто используемых AT команд.

ATE0 For echo off – отключение режима «эхо», то есть чтобы модуль не повторял в ответ команды, которые мы ему передаем
AT+CNMI=2,2,0,0,0 <ENTER> включение режима автоматического приема команд
ATD<Mobile Number>; <ENTER> осуществление вызова (ATD+919610126059;\r\n)
AT+CMGF=1 <ENTER> выбор текстового режима
AT+CMGS=”Mobile Number” <ENTER> назначение мобильного номера адресата
>>После этого мы можем писать наше сообщение
>>После написания сообщения
Ctrl+Z передаем команду сообщения (26 в десятичном формате).
ENTER=0x0d in HEX

Акселерометр

Назначение контактов акселерометра:

  1. Vcc подача постоянного напряжения питания 5 В.
  2. X-OUT аналоговый выход в направлении x.
  3. Y-OUT аналоговый выход в направлении y.
  4. Z-OUT аналоговый выход в направлении z.
  5. GND земля.
  6. ST этот контакт используется для установки чувствительности датчика.
Внешний вид контактов акселерометра Внешний вид акселерометра

Для лучшего понимания материала данной статьи можете посмотреть другие статьи на нашем сайте с использованием акселерометра: игра в Ping Pong с использованием Arduino и робот на Arduino, управляемый с помощью движений рук.

Работа схемы

Схема устройства представлена на следующем рисунке.

Схема системы предупреждения об авариях автомобилей на основе платы Arduino

Контакт Tx GPS модуля непосредственно подключен к цифровому контакту 10 платы Arduino. С использованием библиотеки последовательной связи (Software Serial Library) мы можем задействовать последовательную связь на любых цифровых контактах платы Arduino, а не только на контактах 0 и 1, которые используются по умолчанию для последовательной связи. В данном случае с помощью этой библиотеки мы задействуем последовательную связь на контактах 10 и 11, при этом контакт Rx GPS модуля оставим незадействованным. Напряжение 12 В используется для питания GPS модуля.

Контакты Tx и Rx GSM модуля непосредственно подключены к контактам D2 и D3 платы Arduino. Для подключения GSM модуля мы также задействовали библиотеку последовательной связи (Software Serial Library). GSM модуль также питается от напряжение 12 В.

Контакты данных ЖК дисплея D4, D5, D6 и D7 подключены к контактам 6, 7, 8 и 9 платы Arduino. Контакты RS и EN ЖК дисплея подключены к контактам 4 и 5 платы Arduino, а контакт RW ЖК дисплея замкнут на землю. Потенциометр используется для установки контарстности или яркости ЖК дисплея.

Акселерометр добавлен в схему для обнаружения аварий автомобиля и его аналоговые выходы x, y и z-оси непосредственно подключены к контактам АЦП (аналогово-цифрового преобразования) A1, A2 и A3 платы Arduino.

Объяснение работы проекта

В этом проекте плата Arduino управляет всеми процессами в схеме. GPS приемник используется для определения координат транспортного средства, GSM – для передачи сигналов тревоги при помощи SMS, которые содержат координаты и ссылку на Google Map. Акселерометр (ADXL335) используется для обнаружения аварии (несчастного случая) вдоль любой оси автомобиля – обнаруживает неожиданные изменения положения транспортного средства вдоль любой из этих осей. ЖК дисплей (опционально) используется для отображения статусных сообщений и координат. Структурная схема проекта приведена на следующем рисунке.

Структурная схема работы нашего проекта

Принцип работы системы заключается в том, что при аварии автомобиль наклоняется в какую-либо сторону и акселерометр вследствие этого изменяет значения на своих выходах (осях). Плата Arduino считывает эти значения и проверяет случились ли какие либо изменения вдоль осей. Если изменения случились, то плата Arduino извлекает координаты из строки $GPGGA, получаемой в составе данных от GPS модуля и передает SMS на заранее предопределенный номер (например, полиции, скорой помощи или члена семьи) с координатами места аварии. SMS также содержит ссылку на координаты автомобиля на Google Map, поэтому место аварии будет легко обнаружить. Для этого надо просто кликнуть по этой ссылке и вас перебросит на сервис Google map, где будет отмечено место аварии. Скорость транспортного средства (в милях в час, knots) также передается в этом SMS и отображается на экране ЖК дисплея. Более подробно все эти процессы можно посмотреть в видео в конце статьи.

Наша конструкция в сборе

В этом проекте мы установили чувствительность акселерометра при помощи указания соответствующих максимального и минимального значений (min и max) в коде программы.

#define minVal -50

#define MaxVal 50

Но для более лучших результатов вы можете использовать 200 вместо 50, или установить те значения, которые вам необходимы.

Исходный код программы

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

Первым делом мы должны подключить все необходимые библиотеки и объявить используемые переменные. После этого мы создадим функцию void initModule(String cmd, char *res, int t) для инициализации GSM модуля и проверки его ответа с помощью AT команд.

void initModule(String cmd, char *res, int t)
{
while(1)
{
Serial.println(cmd);
Serial1.println(cmd);
delay(100);
while(Serial1.available()>0)
{
if(Serial1.find(res))
{
Serial.println(res);
delay(t);
return;
}
else
{
Serial.println("Error");
}
}
delay(t);
}
}

После этого в функции void setup() мы инициализируем используемое аппаратное обеспечение (ЖК дисплей, GPS, GSM модули, акселерометр) и последовательную связь с использованием библиотеки software serial.

void setup()
{
Serial1.begin(9600);
Serial.begin(9600);
lcd.begin(16,2);
lcd.print("Accident Alert ");
lcd.setCursor(0,1);
lcd.print(" System ");
delay(2000);
lcd.clear();
.... ......
...... .....

Процесс калибровки акселерометра также выполняется в функции setup. Для этого мы берем несколько отсчетов (samples) и находим средние значения для осей x, y и z. И сохраняем их в переменных. Затем мы будем использовать эти значения для определения изменений в состоянии акселерометра, то есть когда транспортное средство наклоняется в каком-либо направлении (происходит авария).

lcd.print("Callibrating ");
lcd.setCursor(0,1);
lcd.print("Acceleromiter");
for(int i=0;i<samples;i++)
{
xsample+=analogRead(x);
ysample+=analogRead(y);
zsample+=analogRead(z);
}
xsample/=samples;
ysample/=samples;
zsample/=samples;
Serial.println(xsample);
Serial.println(ysample);
Serial.println(zsample);

Затем в функции void loop() мы считываем значения с осей акселерометра и выполняем необходимые вычисления с использованием ранее сохраненных средних значений этих осей чтобы определить произошла авария или нет. И если изменения превосходят некоторый заранее определенный порог (то есть авария случилась), то плата Arduino передает SMS на необходимый номер.

void loop()
{
int value1=analogRead(x);
int value2=analogRead(y);
int value3=analogRead(z);
int xValue=xsample-value1;
int yValue=ysample-value2;
int zValue=zsample-value3;
Serial.print("x=");
Serial.println(xValue);
Serial.print("y=");
Serial.println(yValue);
Serial.print("z=");
Serial.println(zValue);
..... .....
........ ...

Также в программе будут использоваться еще несколько функций, таких как void gpsEvent() – для получения GPS координат, void coordinate2dec() – для извлечения координат из GPS строки и преобразования их в десятичный формат, void show_coordinate() – для отображения координат в окне последовательного монитора (serial monitor) и ЖК дисплее, void Send() – для передачи SMS на заранее определённый номер.

Далее приведен полный текст программы.

#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(4,5,6,7,8,9);
#define x A1
#define y A2
#define z A3
int xsample=0;
int ysample=0;
int zsample=0;
#define samples 10
#define minVal -50
#define MaxVal 50
int i=0,k=0;
int gps_status=0;
float latitude=0;
float logitude=0;
String Speed="";
String gpsString="";
char *test="$GPRMC";
void initModule(String cmd, char *res, int t)
{
while(1)
{
Serial.println(cmd);
Serial1.println(cmd);
delay(100);
while(Serial1.available()>0)
{
if(Serial1.find(res))
{
Serial.println(res);
delay(t);
return;
}
else
{
Serial.println("Error");
}
}
delay(t);
}
}
void setup()
{
Serial1.begin(9600);
Serial.begin(9600);
lcd.begin(16,2);
lcd.print("Accident Alert ");
lcd.setCursor(0,1);
lcd.print(" System ");
delay(2000);
lcd.clear();
lcd.print("Initializing");
lcd.setCursor(0,1);
lcd.print("Please Wait...");
delay(1000);

Serial.println("Initializing....");
initModule("AT","OK",1000);
initModule("ATE1","OK",1000);
initModule("AT+CPIN?","READY",1000);
initModule("AT+CMGF=1","OK",1000);
initModule("AT+CNMI=2,2,0,0,0","OK",1000);
Serial.println("Initialized Successfully");
lcd.clear();
lcd.print("Initialized");
lcd.setCursor(0,1);
lcd.print("Successfully");
delay(2000);
lcd.clear();
lcd.print("Callibrating ");
lcd.setCursor(0,1);
lcd.print("Acceleromiter");
for(int i=0;i<samples;i++)
{
xsample+=analogRead(x);
ysample+=analogRead(y);
zsample+=analogRead(z);
}
xsample/=samples;
ysample/=samples;
zsample/=samples;
Serial.println(xsample);
Serial.println(ysample);
Serial.println(zsample);
delay(1000);

lcd.clear();
lcd.print("Waiting For GPS");
lcd.setCursor(0,1);
lcd.print(" Signal ");
delay(2000);
gps.begin(9600);
get_gps();
show_coordinate();
delay(2000);
lcd.clear();
lcd.print("GPS is Ready");
delay(1000);
lcd.clear();
lcd.print("System Ready");
Serial.println("System Ready..");
}
void loop()
{
int value1=analogRead(x);
int value2=analogRead(y);
int value3=analogRead(z);
int xValue=xsample-value1;
int yValue=ysample-value2;
int zValue=zsample-value3;

Serial.print("x=");
Serial.println(xValue);
Serial.print("y=");
Serial.println(yValue);
Serial.print("z=");
Serial.println(zValue);
if(xValue < minVal || xValue > MaxVal || yValue < minVal || yValue > MaxVal || zValue < minVal || zValue > MaxVal)
{
get_gps();
show_coordinate();
lcd.clear();
lcd.print("Sending SMS ");
Serial.println("Sending SMS");
Send();
Serial.println("SMS Sent");
delay(2000);
lcd.clear();
lcd.print("System Ready");
}
}
void gpsEvent()
{
gpsString="";
while(1)
{
while (gps.available()>0) //Serial incoming data from GPS
{
char inChar = (char)gps.read();
gpsString+= inChar; //store incoming data from GPS to temparary string str[]
i++;
// Serial.print(inChar);
if (i < 7)
{
if(gpsString[i-1] != test[i-1]) //check for right string
{
i=0;
gpsString="";
}
}
if(inChar=='\r')
{
if(i>60)
{
gps_status=1;
break;
}
else
{
i=0;
}
}
}
if(gps_status)
break;
}
}
void get_gps()
{
lcd.clear();
lcd.print("Getting GPS Data");
lcd.setCursor(0,1);
lcd.print("Please Wait.....");
gps_status=0;
int x=0;
while(gps_status==0)
{
gpsEvent();
int str_lenth=i;
coordinate2dec();
i=0;x=0;
str_lenth=0;
}
}
void show_coordinate()
{
lcd.clear();
lcd.print("Lat:");
lcd.print(latitude);
lcd.setCursor(0,1);
lcd.print("Log:");
lcd.print(logitude);
Serial.print("Latitude:");
Serial.println(latitude);
Serial.print("Longitude:");
Serial.println(logitude);
Serial.print("Speed(in knots)=");
Serial.println(Speed);
delay(2000);
lcd.clear();
lcd.print("Speed(Knots):");
lcd.setCursor(0,1);
lcd.print(Speed);
}
void coordinate2dec()
{
String lat_degree="";
for(i=20;i<=21;i++)
lat_degree+=gpsString[i];

String lat_minut="";
for(i=22;i<=28;i++)
lat_minut+=gpsString[i];
String log_degree="";
for(i=32;i<=34;i++)
log_degree+=gpsString[i];
String log_minut="";
for(i=35;i<=41;i++)
log_minut+=gpsString[i];

Speed="";
for(i=45;i<48;i++) //extract longitude from string
Speed+=gpsString[i];

float minut= lat_minut.toFloat();
minut=minut/60;
float degree=lat_degree.toFloat();
latitude=degree+minut;

minut= log_minut.toFloat();
minut=minut/60;
degree=log_degree.toFloat();
logitude=degree+minut;
}
void Send()
{
Serial1.println("AT");
delay(500);
serialPrint();
Serial1.println("AT+CMGF=1");
delay(500);
serialPrint();
Serial1.print("AT+CMGS=");
Serial1.print('"');
Serial1.print("9821757249"); //mobile no. for SMS alert
Serial1.println('"');
delay(500);
serialPrint();
Serial1.print("Latitude:");
Serial1.println(latitude);
delay(500);
serialPrint();
Serial1.print(" longitude:");
Serial1.println(logitude);
delay(500);
serialPrint();
Serial1.print(" Speed:");
Serial1.print(Speed);
Serial1.println("Knots");
delay(500);
serialPrint();
Serial1.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
Serial1.print(latitude,6);
Serial1.print("+"); //28.612953, 77.231545 //28.612953,77.2293563
Serial1.print(logitude,6);
Serial1.write(26);
delay(2000);
serialPrint();
}
void serialPrint()
{
while(Serial1.available()>0)
{
Serial.print(Serial1.read());
}
}

Видео, демонстрирующее работу схемы

(Проголосуй первым!)
Загрузка...
43 просмотров


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *