Сетевая связь между несколькими узлами по протоколу I²C

Я работаю над проектом, в котором мне нужно передавать данные между разными устройствами Arduino по сети. На данный момент I²C кажется мне лучшим вариантом, поскольку я могу указать, куда отправлять данные. Но при использовании этого метода возникает небольшая проблема, которую я никак не могу решить :(.

Я попытаюсь объяснить свою проблему, используя следующее изображение:

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

В этом примере сети узел с идентификатором 1 должен отправить данные на узел с идентификатором 10, а не на какой-либо другой узел в сети. Узел с идентификатором 12 также должен отправить данные на узел с идентификатором 10, но не на другие узлы. И так далее, и тому подобное. Но узел, которому нужно отправить данные на следующий узел, не знает идентификатор узла, которому нужно отправить данные.

Поэтому сначала узлам нужно выяснить, к каким узлам они подключены и куда им нужно отправлять свои данные.

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

Если это так, он отправит свой идентификатор добавленному узлу. Это работает нормально, если вы добавляете узлы в сеть по одному. Но это не работает, если вы заменяете узел в середине сети или отключаете питание сети.

Как лучше всего это сделать (я также открыт для использования других протоколов передачи данных)?

, 👍1

Обсуждение

Действительно ли узлам необходимо знать, какой узел находится по соседству?, @Majenko

Я думаю, да, потому что I2C требует адрес, куда он должен передавать свои данные. (и узел должен отправлять свои данные только на тот узел, который физически находится рядом). Но если вы считаете, что это не обязательно, дайте мне знать., @FutureCake

Какую цель преследует концепция «по соседству»?, @Majenko

он обеспечивает прохождение данных через сеть в хронологическом порядке, @FutureCake

Что вы имеете в виду под «по сети в хронологическом порядке»?, @Majenko

По шине I2C ведущее устройство взаимодействует с ведомым. При этом неважно, где на шине находится ведомое устройство., @Majenko

Если посмотреть на пример сети, узел с идентификатором 1 должен отправлять данные только узлу с идентификатором 10, а не узлам с другими идентификаторами. Это просто то, что мне нужно., @FutureCake

Итак, вы отправляете его на узел 10., @Majenko

Или вы хотите избежать конкуренции за шину в случае наличия нескольких ведущих устройств?, @Majenko

Да, действительно, но узел с идентификатором 1 не знает, что узел, на который он должен отправить данные, имеет идентификатор 10. Как мне это выяснить?, @FutureCake

Но вы только что заявили, что 1 должен отправить 10., @Majenko

да, то, что вы только что сказали, является проблемой, @FutureCake

Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/76748/discussion-between-futurecake-and-majenko)., @FutureCake


1 ответ


Лучший ответ:

2

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

Если бы у вас было достаточно портов UART, вы могли бы создать отдельные UART-соединения между узлами. У лучших Arduino таких портов всего несколько, а у UNO — только один. Так что это не очень практично.

Возможно, вы могли бы использовать SPI, если бы хотели приложить немало усилий для разработки подходящего протокола управления. Что-то вроде сигнализации BUSRQ/BUSACK:

BUSRQ: Signalling line pulled HIGH by resistor. All nodes INPUT.
BUSACK: Signalling line pulled HIGH by resistor. All nodes OPEN-DRAIN & LOW.
SS: Direct 1:1 GPIO links between nodes - all pulled HIGH. All nodes INPUT.

Node 1                   Node 2                  Node X
RELEASE BUSACK
DRIVE BUSRQ (OD Low)     Sees BUSRQ fall         Sees BUSRQ fall
                         RELEASE BUSACK          (could be busy...)
                                                 RELEASE BUSACK
Sees BUSACK rise
DRIVE BUSACK
SS Node 2 LOW            Sees SS go LOW
Send SPI data            Receives SPI data
SS Node 2 INPUT          Sees SS go HIGH
RELEASE BUSRQ                                    Sees BUSRQ rise
                         Sees BUSRQ rise         Drive BUSACK
                         Drive BUSACK

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

Это не идеально и не обрабатывает запросы к шине несколькими устройствами одновременно, но это предотвращает попытки одного устройства отправить данные, пока другое активно отправляет данные.

,