В статье «DIY: передаем данные на километры с помощью контроллера Micro::Bit и радиомодуля EBYTE LoRa» (часть 1 и часть 2) мы рассказали, как обеспечить связь на обширных территориях при небольшой излучаемой мощности.
Но что, если нужно передавать данные на расстояния в десятки или даже сотни километров? Например, вдоль таких объектов, как автомобильные дороги, железнодорожные линии или трубопроводы?
Помимо спутников, здесь помогут ретрансляторы, способные принимать данные по радиоканалу и передавать их дальше, до следующего ретранслятора или до конечного узла обмена данными.
Пока, однако, мы не будем решать такие грандиозные задачи, ограничившись увеличением дальности с помощью одного ретранслятора на micro::bit с радиомодулем LoRa EBYTE E32.
Допустим, нам нужно контролировать погоду в парнике из дома, но расстояние между домом и парником такое, что при минимальной мощности радиомодуля 10 мВт надежную связь установить не получается.
Разместим где-нибудь посередине ретранслятор, который будет получать запросы от центрального узла, сделанного на базе Raspberry Pi, и передавать их в парник на узел micro::bit. Данные измерений в парнике будут передаваться обратно на центральный узел опять же через ретранслятор (рис. 1).
Макет системы сбора данных с ретранслятором показана на рис. 2.
Здесь мы использовали те же самые блоки, что и для системы с архитектурой «звезда» из прошлой статьи, изменив только программное обеспечение.
Центральный узел создан на базе Raspberry Pi, а ретранслятор и узел для парника — на базе micro::bit.
Конфигурацию радиомодулей E32 мы оставили прежней. Все радиомодули в наших примерах будут работать на канале 15, а их адреса приведены в табл. 1.
Табл. 1. Адреса радиомодулей
Узел |
Адрес |
Центральный узел |
14 (0x0E) |
Ретранслятор |
13 (0x0D) |
Парник |
12 (0x0C) |
Разумеется, для ретранслятора и парника можно использовать другой номер канала. Более того, центральный и периферийный узел могут передавать данные на одном канале, а ретранслятор — на другом. При выборе номеров каналов следует учитывать, какие частоты разрешены к использованию в вашей стране без лицензии, либо оформить соответствующие документы.
Узел ретранслятора
Программу micro::bit для ретранслятора, как и все программы из этой статьи, можно загрузить с сайта GitHub по адресу https://github.com/AlexandreFrolov/loranet.
Файл с программой для ретранслятора называется microbit-pxt-lora-repeater.hex, а файл программы для парника — microbit-lora-net-host2r.hex.
Программа ретранслятора очень проста. На этапе инициализации она задает параметры подключения и работы радиомодуля E32, а также устанавливает размер буферов передачи данных для UART.
После инициализации на светодиодной матрице micro::bit зажигается буква «R», идентифицирующая узел ретранслятора (рис. 3).
Когда центральный узел отправляет в ретранслятор команду «getRData», блок ретранслятора передает по радиоканалу команду «getData» на узел парника с адресом 12 и рисует на мониторе micro::bit стрелку, направленную на сервер. После этого на монитор выводится буква «R» (рис. 4).
В ответ на команду «getData», отправленную на узел парника, ретранслятор получает от этого узла данные измерений. Они не содержат строку «getRData» и отправляются ретранслятором в неизменном виде на центральный узел с адресом 14.
Как только данные будут отправлены, на мониторе ретранслятора на короткое время появится стрелка, направленная на юг, а затем ее сменит буква «R».
Таким образом, наш ретранслятор передает в одну сторону (в парник) команду «getRData», а затем в другую строну (на центральный узел) данные измерений в парнике.
Ретранслятор ничего не знает о структуре и размере передаваемых данных, за это отвечает центральный узел и узел парника.
Узел парника
Узел парника практически полностью аналогичен периферийным узлам из упомянутой выше статьи. Изменения касаются только ПО для micro::bit.
На этапе инициализации выполняются действия, необходимые для работы с радиомодулем и последовательным портом, после чего на монитор выводится буква «B» (рис. 5).
Когда от ретранслятора в узел парника поступает команда «getData», соответствующий блок вызывает функцию getWeatherData, возвращающую результаты измерений погоды. Далее полученные от этой функции данные отправляются в узел ретранслятора на 15 канале по адресу 13 (рис. 6).
Функция getWeatherData получает данные от погодной станции BME-280, преобразует их в текстовые строки и соединяет через символ точки с запятой (рис. 7).
Центральный узел
В предыдущей статье в центральном узле работала программа, отправляющая в цикле команду «getData» на все периферийные узлы, затем она записывала полученные от них данные измерений в JSON-файл.
Теперь центральный узел обращается к периферийному узлу через ретранслятор. Программа e32-loranet-repeater.py отправляет в узел ретранслятора команду «getRData», а полученные от ретранслятора данные измерений записывает в JSON-файл (листинг 1).
Листинг 1. Файл https://github.com/AlexandreFrolov/loranet/blob/main/py/e32-loranet-repeater.py
#!/usr/bin/python # -*- coding: UTF-8 -*- import RPi.GPIO as GPIO import serial import time import sys from time import sleep import json NODE_ADDR_CHAN = [b'\x00\x0B\x0F', b'\x00\x0C\x0F', b'\x00\x0D\x0F'] def gpio_init (): GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) M0 = 22 M1 = 27 GPIO.setup(M0,GPIO.OUT) GPIO.setup(M1,GPIO.OUT) GPIO.output(M0,GPIO.LOW) GPIO.output(M1,GPIO.LOW) time.sleep(1) ser = serial.Serial("/dev/serial0", 9600, timeout=1) ser.flushInput() return ser def send_cmd(node): try : if ser.isOpen() : ser.write(NODE_ADDR_CHAN[node]) ser.write('getRData \n'.encode()) except : if ser.isOpen() : ser.close() GPIO.cleanup() while ser.inWaiting() == 0: sleep(0.03) data_left = ser.inWaiting() received_data = ser.readline() sleep(0.03) received_data += ser.read(data_left) rec = received_data.decode("utf-8").strip() node_data = rec.split(';') return node_data def format_node_data(node, node_data): NODE_1_2_ITEMS = ['Температура', 'Давление', 'Влажность', 'Точка росы'] NODE_3_ITEMS = ['Температура CPU', 'Интенсивность освещения'] node_dict={} i=0 for val in node_data: val = str(val) if(node == 0 or node == 1 or node == 2): node_dict[NODE_1_2_ITEMS[i]]= val else: node_dict[NODE_3_ITEMS[i]]= val i = i+1 return node_dict def get_nodes_data(): nodes_dict={} node = 2 node_data = send_cmd(node) nodes_dict[node] = format_node_data(node, node_data) return nodes_dict def save_nodes_data_to_file(nodes_dict): jsonString = json.dumps(nodes_dict, indent=2, ensure_ascii=False) print(jsonString) with open('hosts_data.json', 'w') as f: json.dump(nodes_dict, f, indent=2, ensure_ascii=False) ser = gpio_init() nodes_dict = get_nodes_data() save_nodes_data_to_file(nodes_dict)
По сравнению с ПО центрального узла из предыдущей статьи, основные изменения коснулись функции send_cmd.
Время ожидания ответа от периферийного узла, передаваемого через ретранслятор, может быть относительно большим. Программа дожидается ответа в бесконечном цикле:
while ser.inWaiting() == 0: sleep(0.03)
Когда в устройстве serial появляются данные, они считываются и декодируются, после чего возвращаются в виде строки со значениями, разделенными символом «точка с запятой»:
data_left = ser.inWaiting() received_data = ser.readline() sleep(0.03) received_data += ser.read(data_left) rec = received_data.decode("utf-8").strip() node_data = rec.split(';') return node_data
Как и в программе из предыдущей статьи, функция save_nodes_data_to_file записывает данные в файл hosts_data.json, а также выводит на консоль:
$ python e32-loranet-repeater.py { "2": { "Давление": "993", "Точка росы": "4", "Влажность": "24", "Температура": "24" } }
Идеи для развития проекта
В каком направлении вы можете развивать свой учебный проект с ретранслятором?
Добавьте больше ретрансляторов
Прежде всего, можно добавить еще ретрансляторов, увеличив таким образом общее расстояние, на котором будет возможно получать данные измерений. На рис. 8 показана схема с использованием двух ретрансляторов.
Можно сделать так, чтобы первый ретранслятор передавал команду «getRData» на второй узел ретранслятора, установленный в гараже с адресом 12. Второй ретранслятор, в свою очередь, будет передавать эту команду дальше, узлу сбора данных в парнике с адресом 11 (табл. 2).
Табл. 2. Адреса радиомодулей
Узел |
Адрес |
Центральный узел |
14 (0x0E) |
Ретранслятор в летнем домике |
13 (0x0D) |
Ретранслятор в гараже |
12 (0x0C) |
Парник |
11 (0x0B) |
При передаче данных в обратную сторону узел из парника должен передавать данные на ретранслятор в гараже по адресу 12.
Передавайте данные измерений с ретрансляторов
Еще одна идея, которую вы можете реализовать, заключается в том, чтобы ретрансляторы не просто передавали данные в направлении центрального узла, а добавляли к ним результаты собственных измерений.
Например, узлы ретранслятора могут добавлять в данные температуру процессора в микрокомпьютере или данные погодной станции, установленной в ретрансляторе. Разумеется, нужно правильно отделить эти данные в общем потоке, а в программе, работающей на центральном узле, правильно их обработать.
Используйте антенны с большим усилением или направленные антенны
Существенно увеличить дальность при той же мощности можно с помощью антенн, обладающих большим усилением или направленных антенн.
Однако в том, что касается направленных антенн, не все так просто. Было бы идеально на узле ретранслятора подключить две такие антенны, направленные в разные стороны, каждая на свой ретранслятор или узел.
Но подключение двух радиомодулей с интерфейсом UART к одному micro::bit проблематично. Такую задачу можно решить с использованием радиомодулей LoRa с интерфейсами SPI или I2C.
Второй вариант — использовать в узле ретранслятора два микрокомпьютера micro::bit, к каждому из которых подключен радиомодуль LoRa. При этом данные между микрокомпьютерами можно передавать с помощью встроенного в micro::bit модуля Bluetooth.
Если у вас появятся еще какие-нибудь идеи по использованию ретрансляторов, расскажите о них в комментариях к этой статье!
Автор: Александр Фролов.
НЛО прилетело и оставило здесь промокод для читателей нашего блога:— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.
ссылка на оригинал статьи https://habr.com/ru/company/first/blog/670052/
Добавить комментарий