Как вам такое чудо на клумбе?
Ссылка на солнечные садовые светильники в комментариях
Продолжаю тему с исследованием сенсорных сетей. Как я рассказал в прошлой части, я реализовал драйвер меш-сети, который прошел успешное тестирование в среде эмулятора и был назван идиоматичным условиям его применения названием Burelom. Теперь настало время для его тестирования на реальном железе. Для этого мне потребовалось, собственно, само железо и какой-то сетевой слой, который бы не утопил меня сходу в особенностях его реализации.
Итак, железо — ESP32C6. В представлении не нуждается, платформа хорошо известна любому инженеру. Почему С6, а, скажем, не S3? В дальнейшем я хочу реализовать для Bulerom полноценный TDMA MAC, а значит, мне для этого потребуется физический драйвер радиоканала. В инфраструктуре ESP32 такой драйвер имеется — IEEE 802.15.4. Именно на этой истории основан почти весь современный стек ZigBee и Thread. И именно его я хочу использовать для того, чтобы заставить Bulerom работать там, где не будут работать другие сети. Возможно, я ошибаюсь, тогда мне придется копнуть еще глубже, но уже в сторону NRF, которые дают доступ еще ниже, на уровне регистрового управления трансивером. И ESP32C6 как раз поддерживает IEEE 802.15.4, в отличие от других моделей серии.
В качестве тестового сетевого слоя я взял ESP-NOW, он идеально ложится на текущую задачу. Если кратко, у Wi-Fi есть так называемые Control Frames (CF) — фреймы, предназначенные для рассылки по сети служебной информации. Для получения такого пакета не нужно устанавливать соединение MAC-уровня. Т. е. если для того, чтобы отправить данные по Wi-Fi, вам нужно сначала произвести сканирование, потом инициировать соединение, и только после этого вы сможете выполнять обмен данными, то для CF это не требуется. У него есть расширение — Vendor Specific Action. В котором, собственно, и реализуется вся логика ESP-NOW. Плюс ко всему этому, CF могут быть еще не только unicast, но и broadcast. Что это значит для моей задачи: у меня есть драйвер сети, который позволяет отправить unicast произвольному узлу в зоне радиовидимости или broadcast всем узлам вокруг. При этом вся логика MAC-уровня полностью инкапсулирована в Wi-Fi слое. Идеальное решение для задачи тестирования L3 Burelom.
Ну и очевидно, что если отходить от темы статьи, ESP-NOW — это очень хороший способ быстро и надежно связать несколько устройств по воздуху. При этом ESP-NOW разделяет канал с Wi-Fi (по сути, это просто Wi-Fi с плагином). Т. е. он никак не мешает работе модуля с основным драйвером Wi-Fi, можно подключить устройство, например, к роутеру и использовать его как шлюз в интернет, параллельно принимая данные по ESP-NOW. Условие только одно — чтобы было разделение частотных каналов.
В общем, этими средствами можно очень быстро развернуть работающую IoT-сеть. Но это не наши методы. Поэтому роль ему отводится только в качестве псевдо-MAC.
Драйвер L3 Burelom, как я уже писал в первой статье, спроектирован так, что он ничего не знает о физике устройства и сети, на которой он выполняется. Для этой абстракции он предлагает набор трейтов, которые реализуют контракт между драйвером и железом:
Cipher: функции аппаратного шифрования
Mac: программно зависимые функции L2 уровня
Rand: аппаратно специфичный истончик энтропии
Собственно, в целевом решении под имплементацией Mac подразумевается именно реализация L2 уровня сети. Т. е. в случае ранее упомянутого IEEE 802.15.4 это будет полноценный TDMA драйвер, задача которого будет забирать данные из L3, планировать их в расписание, собирать входящие фреймы и передавать их на уровень L3. ESP-NOW — это уже реализованный вендорский L2, поэтому моя задача тут сводится к тому, чтобы просто сделать адаптер между Burelom и драйвером ESP-NOW. Поэтому он называется у меня Псевдо-MAC, потому что по сути ничего сам на L2 не делает.
За деталями реализации вы можете сходить ко мне в репозиторий. В принципе ничего сложного для понимания там нет.
Тестирование сети проводилось (должно было проводиться) в трех режимах:
1-Hop. Прямая связь между двумя устройствами. Тут всё просто: A отправил пинг на устройство в радиовидимости (B), получил ответ. Доказывает то, что сеть работает на уровне линка.
2-Hop Routing. Это проверка AODV-маршрутизации. Задача тут усложняется, сети нужно найти маршрут до узла от узла А до узла С, при том, что они находятся вне прямой радиовидимости. Для этого по сети должен пройти Routing Request и простроить маршрут на промежуточном узле B. Доказывает, что сеть умеет выполнять динамическую маршрутизацию.
Multihop. Узел A отправляет пакет на узел C. Сеть должна простроить маршрут через два промежуточных узла B, С. Каждый узел сети виден только соседнему узлу. Доказывает, что сеть может транслировать данные в режиме mesh.
Тестировал я всё это дело в три этапа. Первым этапом было создание звезды, чтобы было понимание, что у узлов 2-4 имеется линк к 1. Этот этап был пройден без осложнений.
Далее я попробовал построить мультихоп дома, поскольку живу в современной многоэтажке, имеются стены толщиной 70 см. Получилось собрать некоторое подобие меша, используя изгибы стен. На этом этапе устранил несколько ошибок. Вообще вот сколько себе говорю, никогда не вызывай unwrap() в Rust, даже если кажется, что ничего не может случиться, оно случится!
Ну и завершающим этапом тестирования должно было стать тестирование схем 2 и 3 на естественном рельефе, для этого я отправился в парк около дома. Но там я столкнулся с очень значительными сложностями. Сложности свелись к тому, что ко мне подошли два охранника парка и попросили объяснить, что я делаю. После попыток такового объяснения мне сообщили, что ничего не поняли и с их точки зрения я выгляжу крайне подозрительно. А учитывая известную всем ситуацию, может быть, я тут занимаюсь диверсионной деятельностью или делаю что-то, связанное с дронами. И что, вероятно, им из соображений бдительности стоит вызывать Росгвардию. На все попытки объяснить им, что диверсионность моих железок не большая, чем у домашнего Wi-Fi роутера, они не реагировали. Поэтому мне пришлось срочно ретироваться. Хорошо хоть хоть их «бдительность» осталась только на словах, а то, возможно, я бы это сейчас не писал, а рассказывал архитектуру ESP32 какому-нибудь дознавателю.
Но за то время, что успел там пробыть, было получено вот это:
11.379 [INFO ] Send ping Ping to 4
11.380 [INFO ] <1> Initialized route request dest=4
11.385 [INFO ] <1> Received transit preq packet from=1, packet dropped due seen
11.398 [INFO ] <1> Created route target=4, gateway=2, hops=3
11.398 [INFO ] <1> Received target prep packet from=4
11.399 [INFO ] <1> Route request completed dest=4 gw=2
11.399 [INFO ] <1> Send dataghram dest=4 gw=2 data=50696E6731
Hops=3, route request прошел два промежуточных узла вперед и назад, собственно, это чего я и хотел увидеть. Качество PCB антенн ESP32, конечно, никакое, при этом оно разнится от модуля к модулю. Потому что в схеме линией узел 4 периодически получал hello-пакеты от 2. Т. е. 2 видел 3 и 4, а 4 видел только 3. Это приводит к ошибкам маршрутизации. Потому что прорвавшийся пакет от 4 к 2 создает новый более короткий маршрут, узел 2 начинает считать, что 4 на расстоянии одного хопа, а это более приоритетный роут. А затем линк пропадает, и маршрут оказывается в подвешенном состоянии до его обнуления по бездействию. Надо бы придумать какой-то защитный механизм от залетных hello-пакетов.
В общем, Burelom работает на железе. Конечно, использование ESP-NOW на PCB-антеннах — чушь полная. Но это сильно упрощает тестирование, буду работать дальше в сторону расширения возможностей сети.
Инцидент с «бдительными» гражданами требует очень серьезного осмысления, потому что как будто бы имеется совершенно реальный шанс привлечь к себе внимание соответствующих спецслужб. Возможно, стоит обратиться к этим самым спецслужбам за разъяснением, как добросовестному инженеру не загреметь в диверсанты, проводя практику в собственном дворе.
Сей сказ о том, что как я сенсорную сеть “изобретал”. Изобретал в кавычках потому что в общем-то технология эта уже достаточно зрелая, применяется в промышленности и придумывать что-то принципиально новое в ней сложно. Но у меня есть замечательная страсть к строительству велосипедов и собиранию граблей, поэтому в путь!
Что это и зачем нужно? Представим себе следующую задачу. Лето, активный сезон шашлыков и туристических прогулок. Все везде жгут костры, несмотря на особые режимы и драконовские штрафы. В жару, при высоком уровне пожарной опасности поджечь лес от обычного костра даже в трезвом состоянии не самая сложная задача, достаточно просто неправильно выбрать место под него или недоглядеть. И всё, начинается пал лесной подложки, который расползается по лесу и потушить его самостоятельно нет никакой возможности. А если на пути пала встретятся торфяные почвы, сухостой, это сильно усложняет ситуацию. Реагировать на каждый дымок в лесу пожарная охрана не может, у нее нет достаточного человеческого ресурса для этого. А если и реагируют то зачастую по месту прибытия оказывается группа мирно сидящих у костра туристов. Т е понять где реальный пожар а где контролируемый костер на начальных этапах почти невозможно. Ресурсы органов охраны лесов тратятся, леса продолжают гореть. А теперь представьте себе, по лесу была бы раскинута сеть устройств, которые работают годами без техобслуживания от солнечных панелей, собирают информацию о температуре, влажности воздуха и почвы, уровне CO2, скорости ветра, дисперсиях, могут подключать в случае необходимости тепловизор. Всё это связано между собой и через сетевые шлюзы отправляет данные в облако (или на edge севера). А там применив заточенные под эти цели ML модели, можно на выходе получить очень конкретный ответ на вопрос - а что это там за дым на горизонте? Это отдыхающие разожгли очередной костер на поляне на которой уже жарят шашлыки 50 лет без инцидентов, или пора ехать тушить реальный пал. Пример конечно утрированный, в реальности всё обстоит чуть более сложно, но чтобы уловить смысл зачем эти технологии нужны достаточен.
Такие требования и условия эксплуатации накладывают довольно серьезные требования на реализацию и организуют отдельный класс устройств - высоко автономные сетевые устройства работающие в условиях агрессивной внешней среды. Что это значит.
Электроэнергия это очень дефицитный ресурс. Всё что мы имеем в распоряжении это дай бог 5-15 вт солнечную панельку, которая кое-как проработав полдня, должна накопить достаточно энергии что что бы устройство проработало… Да бог знает сколько, может завтра снег пойдет и панелька окажется в сугробе. Соотвенно вся электронная база должна иметь минимальные паразитные токи. Тут счет идет на микроамперы, если использовать на в устройстве широко распространенные компоненты общего назначения, оно не проживет в таком режиме пары дней.
Устройство будет печься под зноем, заливаться дождями, и леденеть в тридцатиградусный мороз. Из этого следует что у него в составе должны быть компоненты которые поддерживают такие режимы эксплуатации (пламенный привет Li Ion аккумуляторам…).
Мы имеем дело с очень плохой радиосвязью и большими площадями. Наличие на пути сигнала леса, холмов/гор, представляют для него очень серьезное препятствие. Также нужно понимать что даже квадрат 10x10 км, это 100 кв. км площадей. И даже если повтыкать узлы через каждый километр, это непреодолимая дистанция для решений применяющихся в городской среде (к примеру в том же городском ZigBee). Поэтому мы вплотную сталкиваемся с вопросами усиления сигналов через внешние антенны и его трансляции на значительные дистанции.
Неустойчивость инфраструктуры. В таких жестких условиях эксплуатации любой узел в любой момент времени может приказать долго жить. Получить доступ к нему может оказаться задачей экспедиционного уровня (если это например узел находящийся на каком нибудь горном перевале или в глубокой тайге. Поэтому необходима предельная устойчивость сети к локальным травмам.
В общем-то с последнего пункта требований я и решил начать изобретать свой велосипед. Для решения таких задач применяются беспроводные сети с топологией - mesh. Такая сеть представляет из себя сетку, по которой строятся маршруты от одного узла до другого через промежуточные узлы, которые являюсь полноценными участниками сети, могут ретранлировать данные предназначенные для других узлов. Ядром такой сети является протокол маршрутизации - как ретрансляторы понимают, куда им направить пакет предназначенный для другого узла. Протоколов этих несколько, но для текущей задачи я выбрал AODV. Узел A желает понять куда (кому из ближайших нод, это называет шлюз) ему нужно передать пакет чтобы он достиг узла Б. Для этого он широковещательно закидывает в сеть пакет - узел Б откликнись. Получившие его ближайшие узлы, делают то же самое, соседние то же. И так пакет разлетается по сети пока не он не попадет на узел Б. К этому моменту информация о кратчайшем маршруте бедует уже храниться на промежуточных узлах (за счет прохождения поискового пакета). Всё что нужно сделать узлу Б, отдать в шлюз из которого пришел пакет сообщение - привет, я тут. Опять же очень упрощенное описание, есть много нюансов вроде TTL, hops, seen_packets, и прочее, но для понимания сути оно не нужно. Данный протокол был выбран мной на том основании, что в сенсорной сети которую я проектирую, практически нет подвижных узлов, а значит маршруты являются по большей части статичными. Они устаревают только тогда когда какой-то узел уходит с радиолинка. Поэтому AODV практически не дает служебного трафика в сравнении с другими типами маршрутизаций.
Кто-то может возразить что меш сеть это моветон для энергоэффективных устройств, много служебного трафика, большие пакеты. Но тут важно сделать уточнение. Меш сеть это уровень L3 модели OSI, а значит что она ничего не знает о физическом канале по которому проходят ее пакеты. За это отвечают уровни L2 (MAC) и L1 (PHY). На физический уровень я повлиять не особенно не могу. А вот уровень линка находится под моим полным контролем, а значит я могу управлять временем - когда и в каком количестве передаются данные. Таким образом я могу могу через управление трансивером сделать например heartbeat сеть, которая функционируют в определенные временные промежутки, например 55 секунд из 60 сеть молчит, 5 секунд происходит радиообмен. Или более серьезные решения вроде TDMA. Таким образом я получаю очень большое пространство маневра для работы над связкой L3-L2, что может дать приемлемый результат для меша в сенсорной сети.
И так, что было мной сделано на этом этапе. Бала сделана заготовка меш сети и оттестирована в эмуляторе (скришнот из него ниже), а именно реализовано:
Полная связность сети, пакеты могут проходить от узла к узлу в мультихоп режиме.
Полность релазиован протокол динамической маршрутизации AODV.
Реализован механизм beaconing, распространения данных об узлах по сети и соответственно поддержка node discovery и построения локальной топологии сети.
Базовое шифрование полезной нагрузки пакетов.
Механизм шлюзования или сопряжение с сетью другого рода.
Касательно аппаратной платформы под которую она предназначается. Всё это создается в инфраструктуре rust, embassy и embedded-hal. Соответственно основная шестерка продуктов которые активно участвуют в развитии этого стека - STM32, NRF, ESP32, TI, NXP, RPI. Я лично таргетируюсь на ESP32, как на платформу наиболее подходящая для быстрого прототипирования и на NRF, которая являются эталоном в сфере устройств с низким энергопотреблением.
С исходным кодом меш сети и эмулятора можно ознакомиться в моем GitHub.