Протокол обмена данными.

Тема в разделе "Проводная и беспроводная связь", создана пользователем VladislavSum, 29 дек 2016.

  1. VladislavSum

    VladislavSum Нуб

    Пожалуй начну издалека. И так, я делаю свою сеть умного дома. На данный момент есть:
    1) Сервер на java.
    2) Клиент на android.
    Сервер находится на Raspbery Pi. К ней через USB подключена ардуинка в к которой пока что подключен только один передатчик nrf24l01. Ардуинка работает в режиме ретранслятора. (Пока что. Потом к ней будут подключены свои датчики.
    Так же имеется светодиодная лента на шкафу, которая то же подключена к ардуинке с нрфкой.

    В будущем планируется большое разнообразие дачиков подключенных разнообразными способами (wifi, nrf24l01, serial и тд.) Однако основной способ все таки останется nrf24l01.

    Протокол обмена данными с android клиентом уже есть.

    Теперь нужно придумать протокол для общения сервера со всеми этими датчиками.
    Должно быть предусмотрено следующее
    1) К одной ардуинке подключено произвольное кол-во датчиков.
    2) Ардуинка может быть выключена, следовательно нужно уметь обрабатывать ошибки timeout.
    3) Некоторые датчики могут отправлять сообщения не дожидаясь запроса от сервера.

    Пока что придумал решение в лоб. Передаются сообщения длиной 32 байта следующей структуры
    1) ID получателя.
    2) ID отправителя.
    3) Тип датчика
    4) Номер этого датчика
    5) Длина переменной части
    6-32) Переменная часть, в ней могут быть любые данные которые может обработать соответствующий датчик.

    Возможно кто нибудь предложит протокол получше?

    Возможно стоит уменьшить длину переменной части что бы получить более стабильное соединение через нрфку?
    Сколько делать повторных отправок перед тем как предположить что датчик выключен? Буду использовать одну трубу в которой все молчат пока сервер не опросит, и еще одну трубу для отправки вне плановый событий от датчиков. (Тут конечно несколько датчиков могут попытаться отправить что то одновременно, но такая вероятность исчезающе мала.)
    Какие задержки ставить перед повторной передачей?
    Как реализовать роутинг запросов?

    Заранее спасибо.
     
  2. Igor68

    Igor68 Гуру

    Простите, если не в тему... но есть мнение посмотреть в сторону протокола ModbusRTU - именно логического протокола. Если рассматривать датчики как устройства со своим ID(адресом в сети). Но опрашивает их только один ведущий. В вашем описании, если я так понял ведущего не должно быть... это так?
     
    VladislavSum нравится это.
  3. sslobodyan

    sslobodyan Гик

    Модбас не катит, если некоторые датчики сами шлют пакет. Модбас это обязательно запрос-ответ. Для вашего протокола вторая труба тоже избыточна. Нрфки в разные трубы шлют на той же частоте(канале). Поэтому возможны коллизии независимо от номера трубы. Просто работайте в одной трубе по запрос-ответ и сразу на прием самостоятельных датчиков. Если нужен обмен точка-точка без главного, то все то же самое, только мастер-слейв меняются динамически. В случае коллизии или помех мастер делает паузу на основе своего айди, т.е. каждый модуль делает разную паузу, что уменьшит дедлок. От автоподтверждения я бы отказался.
     
    VladislavSum нравится это.
  4. VladislavSum

    VladislavSum Нуб

    Спасибо за идею с одной трубой и задержкой на основе id. Думаю это как раз то что нужно
     
  5. MAXIM1982

    MAXIM1982 Нуб

    • Здравствуйте. Подскажите, пожалуйста. Имеется описание протокола обмена данными. Как должен выглядеть пакет данных, например для отправки показаний времени 19 мин. 59 сек?
    • Описание пакета прилагаю:
    • Скорость передачи 9600,нет бита четности , 1стоп бита

      Пакет таймера (10 байт):

      1 десятичный код старт.байт

      мин.(дес.) +48

      мин.(ед. +48) точка + 16

      сек.(дес.) +48

      сек.(ед.) +48 точка + 16

      0.1 сек. +48

      0 1 +48 (таймер игры идет) или 2+48 (таймер игры остановлен)

      0 1 +48 (таймер игры идет) или 2+48 (таймер игры остановлен)

      сирена, 0-й бит – основная сирена 4-й бит – доп.сирена +48

      7 десятичный код стоп.байт

      Примечание: для получения числа с "точкой + 16" нужно сначала из значения байта
      отнять 48, а затем обнулить 5-й бит.
      Если в результате в разряде получилось число больше 9, нужно число в этом разряде считать нулем.