Всем привет! Меня зовут Евгений, я уже много лет читаю Хабр, но писать как-то стеснялся. Я не профессиональный программист, это важно для дальнейшего рассказа, но возиться с железками и программировать для собственного удовольствия не переставал с детства. Это интересно и позволяет самому потрогать всякую современную техно-магию.

В жизни я основатель и технический директор небольшой команды, которая занимается интеграцией трекеров спутникового мониторинга транспорта. Я занимаюсь этим с 2006 года, так что профдеформацию в рукав не спрячешь. Всё, к чему я прикасаюсь рано или поздно превращается в трекер, увы. Так случилось и в этот раз. Сейчас это, кажется, называется, “обладать экспертизой в области”.

Вокруг всё чаще и чаще слышно упоминание загадочных слов LoRa. Начиная от, разумеется, Хабра, и заканчивая прайсами поставщиков различного IoT-оборудования.

Было очень любопытно самому убедиться, а правдивы ли обещания дальности работы? Попробовать это очень просто, готовые модули LoRa можно без проблем кликнуть со всем известного китайского маркетплейса. Но проверять дальность, просто мигая лампочкой на расстоянии, как-то не наглядно, так что напрашивается подключение GPS-приемника и самостоятельного подсчета расстояния. Ну и вы уже поняли, что в этом месте запахло прототипом спутникового трекера, передающим данные не по GSM-каналу, как обычно, а по радиоканалу LoRa.

Применения могут быть самые разные. Сейчас есть много готовых персональных трекеров, работающих по GSM. Если не понимаете, о чем идет речь, то для своих клиентов я писал небольшой обзор, как они работают. Но их применение не всегда удобно.

Смотрю по своей семье. Мы часто ездим за грибами или просто погулять в лес, где нет сотовой связи. Кроме этого, круглый год оплачивать сим-карту ради нескольких выездов довольно нерационально. И это у меня ещё есть доступ к специальным телематическим тарифам! На обычных же “гражданских” тарифах операторы очень любят отключать симки после нескольких месяцев бездействия. Так что убрал трекер осенью на полку, а весной иди получай новую симку. Сложно. Излишне. Много внешних факторов.

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

Коротенький ресёрч темы и стартовый пинок, разумеется, начался с популярной темы на Хабре про IoT-котиков. Не знаю, почему, но она стала такой популярной, что эту статью я вначале прочитал в новостях Хабра сам, а потом ещё несколько человек прислали на неё ссылки в личку. Вот что называется “взлетело”! Как можно не любить котиков?!

Для тех, кто её не читал, краткая выжимка, которая нам пригодится: есть модули LoRa (от Long Range), это проприетарная технология SEMTECH. Маленькая мощность, большая дальность, за дальность расплачиваемся низкой скоростью передачи. То есть это только для IoT-применений. Там, где на планете есть цивилизованная жизнь, есть возможность встроить своё устройство на основе модуля LoRa в общую сеть LoRaWAN

LoRaWAN — это что-то близкое по духу к телефонной сотовой сети, с той лишь разницей, что устройства подключаются к открытым базовым станциям, и ты сам можешь запустить одну или нескольких таких БС у себя дома для всех желающих. Трафик и потребление электричества там минимальные, частоты открытые. 

Это становится интересно, когда у тебя в округе уже есть такие станции. Кроме этого, сами базовые станции довольно сложные устройства, и их стоимость существенно превышает стоимость модуля для конечного устройства. По-любому — не наш вариант. Разворачивать в глухом лесу БС и полноценную LoRaWAN-сеть, это довольно избыточно и никому не нужно. Но если мы не играем по правилам LoRaWAN, то никто не запрещает LoRa-устройствам общаться напрямую. Вот это уже наша тема! 

Для первого прототипа я решил просто кидаться широковещательными пакетами со своими координатами и запоминать другие устройства, от которых долетает радиосигнал LoRa. Чтобы понять, будет ли вообще всё работать и как, вполне достаточно. Постараемся сделать минимально возможный пакет для передачи данных. Потеря данных в этом случае совершенно не критична, получим что-то подобное UDP. Ну потеряем мы часть пакетов, ничего страшного не случится.

Теперь обдумаем интерфейс с пользователем. В идеале маячок должен работать постоянно. Как вариант — висеть прицепленным к верхней части рюкзака, чтобы увеличить дальность. Каждый раз останавливаться и снимать его, чтобы посмотреть на координаты других устройств, ну такое себе. “Работает — не трогай” и “лень” — вот наши главные кредо! Так что прямо-таки напрашивается bluetooth и программка на телефон. Нужно — достал из кармана мобильник, подключился, понял, куда идти. 

Общая идея работы устройства
Общая идея работы устройства

При этом у нас получается простое модульное устройство. Можно не устанавливать bluetooth или GPS-модуль, если в этом нет необходимости. Звучит вроде клёво, давайте попробуем собрать. 

Важный момент: когда что-то собираешь, это “что-то” нужно в своей голове как-то называть. Рабочее название устройства родилось само собой. “AGLoRa”, аббревиатура от Arduino, GPS и LoRa.

Хотелось собрать всё из говна и палок, не особо заморачиваясь. Так что не стал заказывать Arduino Nano 33 BLE, а использовал то, что валялось в заветной “ардуинной” коробке, которая есть, наверное, у каждого. В коробке нашлись какие-то GPS, купленные под другой проект, парочка рандомных Bluetooth модулей, парочка UNO и Nano. Вполне хватит для того, чтобы склепать несколько прототипов.

И в этом месте наконец закончилось долгое вступление. Дочитали? Погнали собирать!

Начнем с того, ради чего все мы здесь собрались. LoRa. Человечество уже эволюционировало до того момента, когда у нас есть удобные модули типа E220-900T22D или E433T30D, которые умеют в UART и к ним есть готовые библиотеки для Arduino. Так что делать нашу моргалку лампочками будет легко!

Первый модуль работает на 868 МГц (сейчас это разрешенная в РФ частота), второй — на 433 МГц. Как вы понимаете из теории, в лесу без помех 433 должен работать лучше. В городе частота 433 МГц забита другими устройствами, так что не угадаешь.

Ардуинка подойдёт любая, главное, не на ATmega168, в ней памяти для нашего скетча не хватит. По входам мы практически ничего и не используем. Два программных последовательных порта для GPS и LoRa, и аппаратный, на который повесим Bluetooth.

Используемые модули
Используемые модули

GPS модуль тоже любой, у них у всех есть NMEA. Но если купить дешевый, типа NEO-6M то разочаруетесь, потому что спутники он ищет по полдня и теряет при первой удобной возможности. Надо покупать что-то подороже. Не забудьте, что если берете модуль от Ublox, то нужно подключиться к нему по USB и с помощью его родной программы u-center выключить бинарный протокол, оставив только NMEA, и переключить скорость передачи на 9600. Собственно, про GPS больше писать нет смысла, всё делается стандартными библиотеками.

Когда разбирался с блютусом, оказалось что iPhone работает только с BLE (bluetooth low energy). Но по факту это тоже не страшно. Я попробовал парочку дешевых модулей, HC-05  и AT-09, они немного отличаются по тому, как их видно “на стороне телефона”, но в итоге оба заработали. Оба этих модуля распаяны на одинаковых “материнских платах” ZS-040 (не ругайте, я не знаю, как это написать понятнее), так что для Ардуино они выглядят одинаково и полностью взаимозаменяемы.

Собственно, всё. Соединять по инструкции с https://github.com/Udj13/AGLoRa/, смысла всё сюда копировать не вижу, там нет ничего сложного. Канонично подключать модуль LoRa с резисторами подтяжки, но у меня на всех платках заработало и так.

Первый прототип AGLoRa
Первый прототип AGLoRa

Для питания от аккумуляторов пока просто воткнул КРЕНку. В любом случае для экспериментов удобней запитывать свои прототипы через USB от повербанков.

Железки собраны — пора писать скетч. Тут тоже всё просто. Библиотеки есть, готовые примеры к ним — тоже, просто собираем в единое целое.

Можете поругать меня за спагетти-код, но я специально оставил скетч одним файликом, чтобы было проще его копировать и заливать в устройства. Это единственный косяк, оставленный сознательно, за все остальные элементы говнокода готов понести полное моральное порицание общественности и с вашей помощью исправиться!

Bluetooth перед заливкой скетча, разумеется, надо выдернуть, а то ничего не получится. Он висит на основном последовательном порту.

Если в скетче включить DEBUG_MODE, то в логах увидите, какой модуль не заработал и вообще что устройство делает. Вы же не верите, что всё заработает с первого раза, правильно?

Кото-контроль проверил и одобрил
Кото-контроль проверил и одобрил

Итак, принцип работы на сегодня простой. Слушаем эфир, запоминаем тех, кого услышали, иногда смотрим свои координаты и отправляем остальным. Раз в несколько секунд отправляем состояние своей памяти в bluetooth для отображения на телефоне..

Теперь о грустном. Телефон. Телефооооон! Сложно делать проект с программированием, практически не умея программировать мобилки. Нет, я конечно баловался со swift, делал какие-то небольшие программки для себя и своей работы, но вот Андроид для меня — это тёмный лес. 

А без Андроида в этот раз ну никак не обойтись, я же вроде как не только себе делаю. Учить Котлин, делать две версии приложения, потом заниматься параллельной отладкой и доработками… Брррр, так себе перспективка! Признаюсь — взгрустнул! Неужели не потяну? Какое это, нафиг, хобби получается, когда оно сожрёт меня полностью?!

Грустил-грустил, и тут в тик-токе попалось видео про Flutter. Он, оказывается, вполне себе живой и развивается! Думаю, ладно, мне надо-то GPS да Bluetoot, как-нибудь справлюсь. Но, как оказалось, и изобретать ничего не пришлось —  всё уже сделано! Просто пишешь на dart, а дальше библиотеки сами делают всю кросплатформенность! Да это сказка какая-то! Недельку почитал — вроде не очень сложно всё. Для bluetooth есть flutter_blue, с подробными примерами.

Очень завидую современным программистам, “в моё время” из документации у меня был только диск “библиотека программиста”, и постоянно приходилось изобретать велосипеды. А сейчас у тебя есть всё — просто бери и делай!

Так что дальше просто берём и делаем. Примеры есть, библиотеки есть, как всё это между собой совместить, любая старая обезьяна разберется, даже я понял. “Тыч да тыч”, как говорится! Наговнокодил, конечно, местами, но хочется же побыстрее. В итоге сделал приложение и выложил в App Store. Не сразу, но опубликовали, спасибо вам, люди добрые из Apple, приложения апрувящие!

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

Несмотря на то, что это вроде как техническая статья, приводить код особого смысла не вижу. Всё есть на github, и там нет никаких особых тонкостей. Единственный непонятный момент может сопровождать передачу данных на телефон. На стороне телефонного приложения мы получаем поток целочисленных данных List<int>. По сути, он никак не привязан к началу и окончанию тех данных, которые мы отправляем в bluetooth. При этом если не поставить небольшую задержку после отправки данных в скетче Ардуино, то они могут прилетать в перепутанном порядке, что обеспечило несколько неприятных часов на попытку выяснить, почему у меня не работает парсер.

Вставлю только маленький кусочек кода, который реально может пригодится тем, кто пытается подружить внешние датчики с flutter_blue.

Для того чтобы с Arduino передать координаты с плавающей точкой, мы разбиваем их на отдельные 4 байта и отправляем по-отдельности. Примерно вот так: 

union cvt {
    float val;
    unsigned char b[4];
  } x;

x.val = package.lat;  
Serial.write(x.b, 4);

Разумеется, я нашел это заклинание на stackoverflow, но оно работает. После чего на другой стороне опять собираем из этих байтов нормальные координаты.

Uint8List coords = Uint8List.fromList(navData.sublist(1, 9));
List<double> floatList = coords.buffer.asFloat32List();

final double latitude = floatList[0];
final double longitude = floatList[1];

Итого, что имеем сейчас: устройство работоспособно, умеет передавать свои координаты. Без каких-то изменений программы можно комбинировать наличие/отсутствие GPS и Bluetooth в зависимости от задачи.

Есть работающее приложение под iOS/Android, которое позволяет посмотреть расстояние и направление до других устройств. В общем, уже можно пользоваться.

Испытания дальности на 433 МГц есть на следующем видео, реально я уехал на 5 км, и связь была. Я на самом деле уехал бы и дальше, просто у меня дорога закончилась. Но передающая антенна стояла на высоте второго этажа, думаю, рельеф и летняя листва эти 5+ километров очень сильно убавят. В любом случае это реально неплохо! Еще раз возвращаясь в начало: это без каких-либо особых познаний в радиотехнике, просто на купленном в интернет маленьком недорогом маломощном модуле и коротенькой антенне. Не знаю как вам, а мне это кажется небольшой магией.

Собственно, это испытание дальности и было первой ключевой точкой, к которой я шёл. Всё работает, значит можно попробовать развить устройство дальше.

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

Стоило только похвастаться друзьям, как попросили собрать что-то подобное для поиска дрона. Товарищ часто летает в горах, обычно за границей, и там не везде есть сотовая связь или она дорогая. GSM-трекер отпадает.

Другой зацепился за возможность построить меш-сеть из трекеров. Тоже интересно.

Мой отец, который обычно собирает грибы в лесу, в котором не ловит сотовый телефон, попросил добавить возможность отправки каких-нибудь простых сообщений. И надо сказать, что я как доброволец местного отряда “ЛизаАлерт” хорошо представляю, что проще выполнить его просьбу, чем, случись что, искать его в лесу с фонарями. Хотя, возможно, проще кинуть ему в рюкзак рацию.

Ну и в финале. Зачем пишу на Хабр? За тем же, зачем показывал друзьям. Подвести, в первую очередь для себя, небольшой промежуточный итог. Понять, насколько такое устройство может быть интересно не только мне. Возможно, услышать варианты дальнейшего развития, про которые я не подумал. Это тот случай, когда комментарии интереснее самой статьи!

Обратная связь. Возможно я где-то накосячил, что-то принципиально сделал неправильно… Проект неторопливо делался вечерами после работы, прошло почти шесть месяцев, разумеется, глаз замыливается.

Сама комбинация Arduino+GPS+LoRa очень интересна. Это недорогое устройство, которое позволяет реализовать кучу забавных и полезных штук. Так что, имея некий бэкграунд на этом прототипе, я потенциально хотел бы поучаствовать в их создании!

Ну и банальное: возможно кому-то не хватало такого устройства. Всё опубликовано на github, программу для телефона можно скомпилировать самостоятельно. 

В “релизы” проекта я выложил готовый apk для Android. Как уже писал, если у вас iOS, то приложение доступно в App Store, ссылка тоже есть на GitHub.

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

Нажимайте глазик у репозитория, следите за развитием проекта — это всегда приятно!

Комментарии (13)


  1. Stratum
    28.12.2021 11:41
    +7

    У меня есть проект в котором работает связка arduino+gps+LoRa. По прямой видимости на мощности LoRa 20 дБ "ловит" 200+ км (передатчик в стратосфере). Но если передатчик лежит в углублении 0,5м, то дальность передачи упадет метров до 100. Использую модули LoRa на SX1278.


    1. SleepingUp Автор
      28.12.2021 13:01

      200 км это прям очень круто! А какие антенны используете?


      1. Stratum
        28.12.2021 13:17
        +1

        Отрезок провода резонансной длины (ненаправленная антенна) на подвижном устройстве и биквадрат (направленная антенна) на высоте 2м от земли на наземном пункте.


    1. almaz1c
      29.12.2021 09:45
      +1

      Собирал похожее устройство. STM32 + SIM68 + SX1276. В городской среде получал дальность приема сигнала 1.2 км до базовой станции.


  1. bigfoot_tmn
    28.12.2021 23:21
    +1

    Какой именно радиомодуль использовал автор в своем эксперименте, 100mW или 1W?


    1. Lexarrr
      29.12.2021 07:07
      +1

      30D это 1w, 22D это 0.5w


      1. bigfoot_tmn
        29.12.2021 13:37

        Ну и с которым из них автор ездил на 5км?


        1. SleepingUp Автор
          29.12.2021 15:06

          Вот с этим: E433T30D =)


          1. bigfoot_tmn
            29.12.2021 15:17

            Ну с таким не удивительно.


  1. RooperK
    29.12.2021 07:06
    +1

    Код для сообщений ради примера в есть Meshtastic. Можно вообще попробовать добавить совместимость с эти проектом, там поддерживаются пока только готовые модули (сам обладатель 2х)


    1. SleepingUp Автор
      29.12.2021 09:05

      Да, я на них косился-косился на алишечке, после НГ думаю тоже закажу поиграться.


  1. Lexarrr
    29.12.2021 07:15
    +1

    По даташиту контактам М0 и М1 надо 3.3 вольта, от 5в модуль может выйти из строя.


    1. SleepingUp Автор
      29.12.2021 09:04

      Я честно говоря думал проблема больше в согласовании уровней... Но если это так то - ой ) В статье этот момент отмечен, а вот на гитхабе дополню, спасибо большое!