В этом посте хочу представить свой заброшенный pet project, которым занимался пару лет назад. Проект этот - это небольшой по размеру GPS трекер совмещенный с GSM модемом. Изначально созданный для легкой интеграции в какую-либо часть велосипеда (напрмиер в подседельную трубу, трубу руля или в неметаллический насос).

Проект в целом рабочий и находится в состоянии пригодном для использования(использую сам), тем не менее он скорее находится в стостоянии PoC, и в нем есть несколько сырых  моментов (в т.ч. касающихся безопастности), работа над которыми требует определнного времени и сил. Так как я продолжать заниматься проектом не планирую решил выложить его здесь. Вы можете абсолютно бесплатно использовать проект целиком либо любые его части при условии сохранения ссылки на первоисточник (https://bovs.org/), то есть проект распространяется по лицензии MIT.

Предоставленная версия работает в связке с сервером - отправляет свои координаты на него через мобильную сеть (2G), пройденный маршрут можно просматривать по карте на сайте с компьютера или телефона. Однко если вы хотите использовать трекер без сервера (например получать координаты от симки в теркере по СМС), то вы можете слегка переделать предоставленную прошивку (первоначальный вариант был именно такой и в коде даже остались комментарии которые могут помочь в переделке) 

 

Проект состоит из трех основных частей:

1. Плата tubetrack

Собственно трекер. На нем установлены три основных модуля

1. SIM38EA - GPS приемник от SIMCOM со встроенной пассивной антенной. Принимает от спутников сигналы и узнает по ним свои координаты. На улице довольно шустро начинает отдавать свои координаты после включения (5-10 мин). По даташиту рекумендуется держать антенну смотрящей вверх, однако я заметил что и в вертикальном положении приемник работает отлично.

2. SIM800H - недорогой GSM модем от SIMCOM который используется для общения с сервером. Модем дает возможность через мобильный интерент отправить HTTP запрос на сервер через мобильный интернет (симка должны быть пополнена). В строке запроса передаются текущие координаты GPS. Также мобильный оператор дает примерные координаты модема (часто это координаты базовой станции GSM), эти координаты вытаскиваются коммандой SIPGSMLOC и также отправляются на сервер в качестве запасных (желтый маркер на карте). К модему подключен держатель SIM-карты. Также к модему нужно подключать антену (отлично с этой задачей справляется кусочек провода длинной 7-10 см припаянный к выведенному паду), однако вы можете захотеть поставить разем под специальную антену. 

Корпус безвыводный - получится запаять только феном, но на удивление паяется довольно легко и надежно с первого раза  обычным свинцовым припоем без специальных шаров - наносим капельки на пады - наносим флюс и дуем феном градусах на 300.

3. Микроконтроллер STM32L152 на котором выполняется прошивка. Модем и GPS приемник подключаются по отдельным интерфейсам UART. Прошивка под МК написана на C. В архиве приложен проект для KEIL MDK. Скелет проекта сгенерирован через STM32Cube (конфиг для STM32Cube тоже приложен, но он вероятнее всего вам не понадобится так как определяет только дефаный периферийных моделей и их лучше не менять). См папку firmware.

Кстати GPS модуль и GSM дешевле и проще всего купить у оффициальных дистрибьютеров, например я брал на microchip.ua. Они довольно оперативно отправляют посылку, без проблем продают в розницу, а также могут помочь с документацией/прошивкой/советами по применению. Кстати они же иногда проводят довольно интересные семинары в разных городах на которых выступают не только продавци но и реальные разрабочики встраиваемого софта и железа.

Сторона с GPS и держателем SIM-карты:

Сторона с модемом и микроконтроллером:

Проект нарисован в Eagle, размеры позволяют использовать бесплатную версию, см папку hardware_and_gerbers. Также там есть герберы с правилами от завода seeedstudio fusion на котором я изготавливал платы (10$ за 10 шт, хотя иногда бывают еще и скидки).

Платка получилась размером 50х18 мм

Схема вроде не требует сложных объяснений, но вкрадце опишу. МК:

Модем:

 

GPS, питание, держатель СИМ:

Для питания нужна литевый аккумулятор 3.7-4.2В. Заряжается через microUSB разем от 5В. Для зарядки стоит микросхема MCP7381 (ток зарядки регулируется велечиной резистора PROG -  см даташит), ток до 500 мА, и если его выставить то довольно сильно греется, а заряжать какуюнить банку 18650  на 2500 мА будет больше 5и часов. Так что  MCP7381 возможно вы захотите заменить, вариантов полно только корпуса обычно побольше.

МК и GPS питаются от 33 который образуется линейным регулятором MCP1703T-33 - вероятно вместо линейника тут бы лучше поставить DC-DC(ШИМ), но будет больше обвязки.

Отлаживать прошивку рекомендую через программатор/отладчик STLINKv2 который поддерживает отладку. Также следует подключить сигнал SWO чтобы показывать printf сообщения от микрокотроллера на ПК. Кстати printf SWO в Keil работает довольно печально - постоянно отваливается, советую STM32 ST-Link Utility.

Если вы хотите запустить трекер в связке с сервером который вы будете должны установить на каком-нибудь хосте с публичным айпи (VPS, домашний сервер на одноплатнике, и т.д.) то вы должны отредактировать ваш домен в прошивке в файле at.c. Замените YOUR_DOMAIN на ваш домен или айпи:

} else if (startswith(resp_cmd, "AT+HTTPINIT")) {
put_pending("AT+HTTPPARA=\"CID\",1\r");
sprintf(send_get_str, "AT+HTTPPARA=\"URL\",\"http://YOUR_DOMAIN/api/mobile-connect/%08x/%d/%f,%f,%f,%f,%d/\"\r",
DBGMCU->IDCODE, bat_level, cur_gps_lat, cur_gps_long, cur_gsm_lat, cur_gsm_long, (gps_valid?1:0));
put_pending(send_get_str);

После этого нужно перекомпилировать прошивку и прошить в контроллер.

 

Описание работы прошивки

Прошивка работает в двух режимах: обычный и energysave, режими переключаются на сайте.

В первом режиме можем оставется включенным и каждые несколько секунд отправляет на сервер запросы с координатами. В energysave модем включается раз в длительный промежуток времени например 10 мин, при этом отправляет координаты и получает ответ от сервера узнает не нужно ли ему перейти в обычный режим. Идея была в том чтобы в нормальном состоянии трекер находился в режиме экономии, а когда владелец определяет пропажу он тут же включает обычный режим и в течении 10 минту трекер начинает постоянно слать координаты обновляя маршрут на карте.

В обычным (не energysave) банки на 18650 хватает на день, в energysave на несколько дней. Я полностью отключаю батарею когда не использую трекер а включаю лишь когда паркую велосипед (несколько раз в неделю) по этому обычно заряжаю его раз в два-три месяца.

Никаких дополнительных оптимизаций, спящих режимов в периферии или GPS модуле не выполнялось (по сути МК и GPS с полной силой работают всегда), по этому по желанию думаю можно весомо уменьшить потребление. А еще можно придумать какойнибудь незатратный механизм WAKEUP по GSM. 

Также возможно в прошивке не плохобы иметь функцию определения изменения координат и уведомления сервера/владельца. На некоторых девайсах даже акселерометр ставят, но тут его нет и определения двежения можно было бы сделать только при обноружении отколнения координат GPS на какуюто велечину.

2. Tracktube Dashboard

Веб интерфейс(сайт) на JavaScript для управления трекером, показа его местоположения на карте и просмотр маршрутов. Также умеет показывать процент зарядки при подключении к USB (для этого нужно установить chrome-extension из которого можно работать с USB).

Дашборд написан на Vue.JS с применением material design UI. С сервером общается по REST, пулит чето по таймеру (конечно лучше сделать срим через вебсокеты). Впринципе пригоден для показан как на мобильном так и на десктопе. Нужно всего лишь залогинится и добавить девайс (подключить через USB)

Может отдаваться через CDN но проще всего отдавать по корневому урлу с того же сервера на которым выполняется backend (например через nginx, пример будет в следующем разделе)

Чтобы собрать дашборд нужно зайти в папку dashboard и установить модули npm (это делается один раз):

 

npm install

После этого вы можете скомпилировать проект через:

 

 

npm run build

Либо запустить локальный deveopment сервер выполнив

 

npm run dev

Параметры подключения к бекенду указываются в файле dashboard\src\config\app.js:

 

 

let apiBase = 'http://localhost:8707';
if (location.hostname === 'YOUR_DOMAIN') {
  apiBase = '';
}

 

Вместо YOUR_DOMAIN предлагается указать ваш домен или публичный айпи (смотря что вы используете). Тут для локальной отладки подразумевается что сервер будет слушать на http://localhost:8707 и запросы будут типо POST http://localhost:8707/some/rest/endpoint/  . Если же этот дашборд запущен на продакшен-домене то мы подразумеваем что сервер выполняется на этом же домене и ставим apiBase = ''. То есть запросы будут вида POST /some/rest/endpoint/ (относительный URL)

2.  Сервер (backend)

WEB-сервер который выполняется на отдельном хосте с белыйм статическим IP адресом (желательно также иметь домен который веден на этот адрес). Веб сервер рекомендуется ставить за прокси, например nginx. На сервере есть две базы данных sqlite - в которой хранится объект трекера, учетка юзера который может залогинется и получит доступ к REST API(который используется tracktube dashboard -  след. разед.). Также используется бд Redis которая используется для хранения координат. 

Серверная часть написана на Django + Django Rest Framework.

Запуск сервера

 

 Для зупуска сервера вам понадобятся знания разворачивания Django приложений. Пример можно увидеть в тут или тут . Нужно установить python3 и нужные пакеты (через pip install). Нужны пакеты:

  • django
  • django-environ
  • djangorestframework-jwt
  • django-cors-headers
  • djangorestframework-jwt-refresh-token
  • redis

Возможно тут указано не все, по этому если что-то не получается пишите в комментариях

Пример конфига nginx (/etc/nginx/conf.d/tracktube.conf):

 

upstream tracktube_django {
    server unix:///root/tracktube/uwsgi.sock;
}

server {
   listen 80;
   server_name www.YOUR_DOMAIN.net;
   return 301 http://YOUR_DOMAIN.net$request_uri;
}

server {
    listen 80;
    server_name tracktube.org connect.tracktube.org;
    charset utf-8;
    client_max_body_size 75M;
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 8;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

    location /static/ {
      alias /root/tracktube/frontend/static/;
      expires 1y;
      access_log off;
      add_header Cache-Control "public";
    }

    location /api/ {
        uwsgi_pass tracktube_django;
        include /root/wsgi_params;
    }

    location /admin/ {
        uwsgi_pass tracktube_django;
        include /root/wsgi_params;
    }

    # на корневой URL отдаем дашборду 
    location / {
      alias /root/tracktube/frontend/;
      index index.html;
      try_files $uri $uri/ index.html =404;
    }

}

Пример файла /root/tracktube/uwsgi.ini:

 

[uwsgi]
chdir = /root/tracktube/
socket = /root/tracktube/uwsgi.sock
chmod-socket = 667
logto = /root/tracktube/uwsgi.log
module = tt_backend.wsgi
disable-logging = false

Для страта нужно смигрировать(создать) базу:

python3 manage.py migrate

И создать поьзователя

 

python3 manage.py createsuperuser

После этого достаточно запустить UWSGI (демонизировать - например через systemd, init.d, или cron).

Скачать проект

ПС:

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