В электронике есть множество проводных полудуплексных асинхронных последовательных интерфейсов типа общая шина. Это 1-Wire, RS485, 10BASE2(thin Ethernet), LIN, K-Line , CAN, I2C, MIL-STD-1553, ARINC 429.

Во всех этих shared-bus интерфейсах так или иначе возникает задача сканирования шины.

Всем кто работал с i2c известна процедура сканирования шины. Там можно просто методом перебора просканировать шину. Так как длина адреса всего 7 бит, то можно просканировать шину просто за пару секунд.

Результат сканирования шины I2C1 в UART-CLI
Результат сканирования шины I2C1 в UART-CLI

В CAN задачи сканирования вообще не стоит так как там коллизии разруливаются на аппаратном уровне физических трансиверов или вовсе MAC периферии. В CAN достаточно подключится в любом месте и через мгновение в утилите CAN-Hacker будет понятно кто там живет на шине CAN. В CAN все ноды постоянно flood(дят) "Hello!" пакетами.

В Lin сеть узлов обычно полностью 100% статическая и прошивается во время производства. Это и понятно, ведь в автомобильной двери во время езды не появится новая кнопка. В салоне автобуса по маршруту не вырастет новый поручень с кнопкой остановки.

Как обстоят дела со сканированием в остальных проводных интерфейсах: 1-Wire, 10BASE2(thin Ethernet), K-Line, MIL-STD-1553, ARINC 429 я, честно, не знаю. Если кто в теме, то напишите, пожалуйста, в комментариях.

Как обычно выглядит сеть RS485?

шпаргалка по шине RS485
шпаргалка по шине RS485

Надо отметить что RS-485 это фактически только труба для чисел (числопровод). Интерфейс физического уровня в модели OSI-7. Протокол канального уровня поверх RS485 может быть самым разнообразным: ModBus, Pelco-D, yModem, xModem, или любой другой проприетарных протокол. В 80% случаев в этом протоколе будет идентификатор устройства в сети. Это может быть MAC, ID, IP, SN или что-то ещё. Про то какими атрибутами обладает хороший канальный протокол есть вообще отдельный текст. https://habr.com/ru/articles/682292/

В чем трудность сканирования шины RS485?

1--Трудность в том что адреса устройств в протоколе канального уровня поверх физического интерфейса RS485 могут иметь существенно более высокую разрядность чем 8 бит, как правило это 32 бита (4байта) или даже MAC адреса по 48бит (6 байт) или 64бит(8-байт). Предположим в протоколе канального уровня узлы на интерфейсе RS485 имеют 32х битные адреса и если сканировать шину RS485 как это было в I2C то китайский калькулятор покажет что надо "подождать и потерпеть" 14 лет!

вычисления времени ожидания сканирования методом перебора
вычисления времени ожидания сканирования методом перебора

2--В шине RS485 нет аппаратного механизма разрешения коллизий подобно CAN(у). Если 2 ноды начнут передавать одновременно, то данные в витой паре исказятся и мастер прочитает мусорный пакет с поврежденной контрольной суммой.

3--Все устройства на шине RS485 могут вообще работать на разных битовых скоростях 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 бит/c. Я работал в трех конторах и у каждой была своя стандартная битовая скорость шины RS485. И у всех разная! Если устройство работает на битовой скорости 460800 бит/c то оно не будет отвечать на пакеты которые ей посылают на битовой скорости 115200 бит/c.

Как же просканировать шину RS485?

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

Как работает отмычка
Как работает отмычка

Тут ситуация аналогичная. Вместо пинов - биты, вместо щелчка - сигнал подтверждения.

Прежде чем двигаться дальше надо договориться о терминологии.

Терминология

--Адрес устройства - это либо MAC адрес, серийный номер (SN), либо аналог IP адреса или любой другой ID(шник) уникальный для каждого экземпляра устройства на шине RS485. Важен тот момент, что адрес широкий много битный. Пусть это, например, 32х битный адрес.

--Маска адреса - это часть адреса устройства, которая начинается с наименьшего значащего бита LSB и увеличивается в сторону старшего бита. Имеет смысл расширять маску от младших битов ибо младшие есть у всех адресов, а вот старших единичных битов может и не быть. Вот пример нескольких реальных масок:

Пример маски для адреса

Длина маски, [бит]

1

xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx

0

2

xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxx0

1

3

xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx00

2

4

xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx01

2

5

1000_0100_0000_1111_1111_0001_1101_0011

32

6

xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx10

2

7

xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xx10_1110

6

--Сигнал подтверждения- это когда ведомое устройство на RS485 берет пин UART_TX, переводит его в режим GPIO PUSH-PULL, устанавливает 0V, ждет T_ack секунд (например 10ms) и после этого снова подключает к пину UART_TX контроллер. Всё это и называется сигналом подтверждения. По сути устройство на время прижимает шину в ноль вольт. При этом совершенно не опасно, если несколько устройств одновременно прижмут шину в ноль. Эффект будет как от одного. То есть получается логическое ИЛИ. У мастера на UART_RX будет 0V.

--Пакет mute - это такой бинарный пакет получив который ведомое устройство перестает что- либо отправлять в общую шину RS485 и не будет даже испускать сигналы. Устройство будет только слушать шину. Mute пакет может содержать параметр включить или отключить Mute режим.

Словесное описание алгоритма сканирования шины RS485

1--Мастер устройство объявляет что сейчас все ведомые устройства переходят в режим сканирования.

2--мастер отправляет маску адреса, например Mx=xx...xx0 или Mx1=xx...xx1 и просит, чтобы откликнулись те устройства чей адрес совпадает с маской. То есть у кого нулевой бит равен нулю.

3--мастер переводит пин UART_RX в GPIO input, устанавливает подтяжку к питанию и непрерывно смотрит за напряжением на проводе UART_RX. Тут есть два исхода.

a) У мастера на проводе UART_RX появился 0.0 V. Значит, что на шине RS485 присутствует как минимум одно ведомое устройство у кого адрес совпадает с маской Mx.

b) У мастера на проводе UART_RX остался 3,3V. Значат что на шине RS485 нет ни одного устройства у кого бы адрес совпадал с маской Mx. Это значит, что дальше мы с этой маской Mx не работаем и просто отбрасываем её в сторону как заранее неправильный путь. Причем мастер ожидает не бесконечно, а строго определённой время таймаута, которое общее для всех устройств, например 20ms.

4--В случае 3.a) маска расширяется на 1 бит влево. Тут тоже есть два варианта. Либо мы к маске обнаруженного устройства приписываем префикс 0 либо 1. Надо идти по обоим путям: 1 и 2.

Маска

Пояснение

Пример

1

xx...x0[PREV_ACK_MASK]

увеличили на 0

x...x00

2

xx...x1[PREV_ACK_MASK]

увеличили на 1

x...x10

Тут прослеживается рекурсия или элементы динамического программирование. Каждый шаг порождает 2 шага: c префиксом 0 и с префиксом 1.

Далее шаги 2-3-4 можно повторять снова и снова пока маска не достигнет длинны 32 бита. Как только это произойдет это станет означать что найдено одно устройство на шине. Но как найти остальные N-1 устройство?

5--Как только маска будет совпадать с 32 битами то мастер устройство отправляет команду заглушить устройство по определённому адресу. Master отправляет mute пакет.

Шаги 2-3-4-5 это по сути одна итерация. На следующей итерации мастер обнаружит другое устройство. И так до тех пор пока все маски перестанут выдавать сигнал подтверждения. После этого шина RS485 будет полностью просканирована.

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

Справедливости ради можно добавить что надо проделать все то же самое для всех возможных битовых скоростей RS485: 9600, 115200, и проч. Однако как правило RS485 сеть собирают из устройств у которых уже прописана битовая скорость по умолчанию.

Время сканирования на одной битовой скорости займет

Вариант

Время

Пояснение

лучший случай

32*N*dt

подтверждение при первом увеличении маски

Худший случай

32*N*2*dt

подтверждение при втором увеличении маски

где dt - это время отклика на адресную маску

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

Вот лог сканирования для 32-х битных адресов

Лог сканирования для 32битных адресов

-->
-->rss
2.784 :I [RS485] Scan
2.786 :I [RS485] 1: IsAnyBodyWith x:0
2.788 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x:0
2.790 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x:0
2.792 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x:0
2.794 :I [RS485] 3: IsAnyBodyWith x1:1
2.796 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x1:1
2.798 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x1:1
2.800 :I [RS485] 4: IsAnyBodyWith x11:2
2.802 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x11:2
2.804 :I [RS485] 5: IsAnyBodyWith x111:3
2.806 :N [RS485] NoMask x111:3!
2.808 :I [RS485] 6: IsAnyBodyWith x011:3
2.810 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x011:3
2.812 :I [RS485] 7: IsAnyBodyWith x1011:4
2.814 :N [RS485] NoMask x1011:4!
2.816 :I [RS485] 8: IsAnyBodyWith x0011:4
2.818 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0011:4
2.820 :I [RS485] 9: IsAnyBodyWith x10011:5
2.822 :N [RS485] NoMask x10011:5!
2.824 :I [RS485] 10: IsAnyBodyWith x00011:5
2.826 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00011:5
2.828 :I [RS485] 11: IsAnyBodyWith x100011:6
2.830 :N [RS485] NoMask x100011:6!
2.832 :I [RS485] 12: IsAnyBodyWith x000011:6
2.834 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000011:6
2.836 :I [RS485] 13: IsAnyBodyWith x1000011:7
2.838 :N [RS485] NoMask x1000011:7!
2.840 :I [RS485] 14: IsAnyBodyWith x0000011:7
2.842 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000011:7
2.844 :I [RS485] 15: IsAnyBodyWith x10000011:8
2.846 :N [RS485] NoMask x10000011:8!
2.848 :I [RS485] 16: IsAnyBodyWith x00000011:8
2.850 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000011:8
2.852 :I [RS485] 17: IsAnyBodyWith x100000011:9
2.854 :N [RS485] NoMask x100000011:9!
2.856 :I [RS485] 18: IsAnyBodyWith x000000011:9
2.858 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000011:9
2.860 :I [RS485] 19: IsAnyBodyWith x1000000011:10
2.862 :N [RS485] NoMask x1000000011:10!
2.864 :I [RS485] 20: IsAnyBodyWith x0000000011:10
2.866 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000011:10
2.868 :I [RS485] 21: IsAnyBodyWith x10000000011:11
2.870 :N [RS485] NoMask x10000000011:11!
2.872 :I [RS485] 22: IsAnyBodyWith x00000000011:11
2.874 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000011:11
2.876 :I [RS485] 23: IsAnyBodyWith x100000000011:12
2.878 :N [RS485] NoMask x100000000011:12!
2.880 :I [RS485] 24: IsAnyBodyWith x000000000011:12
2.882 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000011:12
2.884 :I [RS485] 25: IsAnyBodyWith x1000000000011:13
2.886 :N [RS485] NoMask x1000000000011:13!
2.888 :I [RS485] 26: IsAnyBodyWith x0000000000011:13
2.890 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000011:13
2.892 :I [RS485] 27: IsAnyBodyWith x10000000000011:14
2.894 :N [RS485] NoMask x10000000000011:14!
2.896 :I [RS485] 28: IsAnyBodyWith x00000000000011:14
2.898 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000000011:14
2.900 :I [RS485] 29: IsAnyBodyWith x100000000000011:15
2.902 :N [RS485] NoMask x100000000000011:15!
2.904 :I [RS485] 30: IsAnyBodyWith x000000000000011:15
2.906 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000000011:15
2.908 :I [RS485] 31: IsAnyBodyWith x1000000000000011:16
2.910 :N [RS485] NoMask x1000000000000011:16!
2.912 :I [RS485] 32: IsAnyBodyWith x0000000000000011:16
2.914 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000000011:16
2.916 :I [RS485] 33: IsAnyBodyWith x10000000000000011:17
2.918 :N [RS485] NoMask x10000000000000011:17!
2.920 :I [RS485] 34: IsAnyBodyWith x00000000000000011:17
2.922 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000000000011:17
2.924 :I [RS485] 35: IsAnyBodyWith x100000000000000011:18
2.926 :N [RS485] NoMask x100000000000000011:18!
2.928 :I [RS485] 36: IsAnyBodyWith x000000000000000011:18
2.930 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000000000011:18
2.932 :I [RS485] 37: IsAnyBodyWith x1000000000000000011:19
2.934 :N [RS485] NoMask x1000000000000000011:19!
2.936 :I [RS485] 38: IsAnyBodyWith x0000000000000000011:19
2.938 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000000000011:19
2.940 :I [RS485] 39: IsAnyBodyWith x10000000000000000011:20
2.942 :N [RS485] NoMask x10000000000000000011:20!
2.944 :I [RS485] 40: IsAnyBodyWith x00000000000000000011:20
2.946 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000000000000011:20
2.948 :I [RS485] 41: IsAnyBodyWith x100000000000000000011:21
2.950 :N [RS485] NoMask x100000000000000000011:21!
2.952 :I [RS485] 42: IsAnyBodyWith x000000000000000000011:21
2.954 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000000000000011:21
2.956 :I [RS485] 43: IsAnyBodyWith x1000000000000000000011:22
2.958 :N [RS485] NoMask x1000000000000000000011:22!
2.960 :I [RS485] 44: IsAnyBodyWith x0000000000000000000011:22
2.962 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000000000000011:22
2.964 :I [RS485] 45: IsAnyBodyWith x10000000000000000000011:23
2.966 :N [RS485] NoMask x10000000000000000000011:23!
2.968 :I [RS485] 46: IsAnyBodyWith x00000000000000000000011:23
2.970 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000000000000000011:23
2.972 :I [RS485] 47: IsAnyBodyWith x100000000000000000000011:24
2.974 :N [RS485] NoMask x100000000000000000000011:24!
2.976 :I [RS485] 48: IsAnyBodyWith x000000000000000000000011:24
2.978 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000000000000000011:24
2.980 :I [RS485] 49: IsAnyBodyWith x1000000000000000000000011:25
2.982 :N [RS485] NoMask x1000000000000000000000011:25!
2.984 :I [RS485] 50: IsAnyBodyWith x0000000000000000000000011:25
2.986 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000000000000000011:25
2.988 :I [RS485] 51: IsAnyBodyWith x10000000000000000000000011:26
2.990 :N [RS485] NoMask x10000000000000000000000011:26!
2.992 :I [RS485] 52: IsAnyBodyWith x00000000000000000000000011:26
2.994 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000000000000000000011:26
2.996 :I [RS485] 53: IsAnyBodyWith x100000000000000000000000011:27
2.998 :N [RS485] NoMask x100000000000000000000000011:27!
3.000 :I [RS485] 54: IsAnyBodyWith x000000000000000000000000011:27
3.002 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000000000000000000011:27
3.004 :I [RS485] 55: IsAnyBodyWith x1000000000000000000000000011:28
3.006 :N [RS485] NoMask x1000000000000000000000000011:28!
3.008 :I [RS485] 56: IsAnyBodyWith x0000000000000000000000000011:28
3.010 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000000000000000000011:28
3.012 :I [RS485] 57: IsAnyBodyWith x10000000000000000000000000011:29
3.014 :N [RS485] NoMask x10000000000000000000000000011:29!
3.016 :I [RS485] 58: IsAnyBodyWith x00000000000000000000000000011:29
3.018 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x00000000000000000000000000011:29
3.020 :I [RS485] 59: IsAnyBodyWith x100000000000000000000000000011:30
3.022 :N [RS485] NoMask x100000000000000000000000000011:30!
3.024 :I [RS485] 60: IsAnyBodyWith x000000000000000000000000000011:30
3.026 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x000000000000000000000000000011:30
3.028 :I [RS485] 61: IsAnyBodyWith x1000000000000000000000000000011:31
3.030 :N [RS485] NoMask x1000000000000000000000000000011:31!
3.032 :I [RS485] 62: IsAnyBodyWith x0000000000000000000000000000011:31
3.034 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask:x0000000000000000000000000000011:31
3.036 :I [RS485] 63: IsAnyBodyWith :32
3.038 :N [RS485] NoMask :32!
3.040 :I [RS485] 64: IsAnyBodyWith :32
3.042 :W [RS485] ACK Addr 0x3=0000_0000_0000_0000_0000_0000_0000_0011 Mask::32
3.044 :W [RS485] SpotAddr 0x3!
3.046 :W [RS485] MuteAddr 0x3
3.048 :I [RS485] 65: IsAnyBodyWith x01:2
3.050 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x01:2
3.052 :I [RS485] 66: IsAnyBodyWith x101:3
3.054 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x101:3
3.056 :I [RS485] 67: IsAnyBodyWith x1101:4
3.058 :N [RS485] NoMask x1101:4!
3.060 :I [RS485] 68: IsAnyBodyWith x0101:4
3.062 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0101:4
3.064 :I [RS485] 69: IsAnyBodyWith x10101:5
3.066 :N [RS485] NoMask x10101:5!
3.068 :I [RS485] 70: IsAnyBodyWith x00101:5
3.070 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00101:5
3.072 :I [RS485] 71: IsAnyBodyWith x100101:6
3.074 :N [RS485] NoMask x100101:6!
3.076 :I [RS485] 72: IsAnyBodyWith x000101:6
3.078 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000101:6
3.080 :I [RS485] 73: IsAnyBodyWith x1000101:7
3.082 :N [RS485] NoMask x1000101:7!
3.084 :I [RS485] 74: IsAnyBodyWith x0000101:7
3.086 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000101:7
3.088 :I [RS485] 75: IsAnyBodyWith x10000101:8
3.090 :N [RS485] NoMask x10000101:8!
3.092 :I [RS485] 76: IsAnyBodyWith x00000101:8
3.094 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000101:8
3.096 :I [RS485] 77: IsAnyBodyWith x100000101:9
3.098 :N [RS485] NoMask x100000101:9!
3.100 :I [RS485] 78: IsAnyBodyWith x000000101:9
3.102 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000101:9
3.104 :I [RS485] 79: IsAnyBodyWith x1000000101:10
3.106 :N [RS485] NoMask x1000000101:10!
3.108 :I [RS485] 80: IsAnyBodyWith x0000000101:10
3.110 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000101:10
3.112 :I [RS485] 81: IsAnyBodyWith x10000000101:11
3.114 :N [RS485] NoMask x10000000101:11!
3.116 :I [RS485] 82: IsAnyBodyWith x00000000101:11
3.118 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000101:11
3.120 :I [RS485] 83: IsAnyBodyWith x100000000101:12
3.122 :N [RS485] NoMask x100000000101:12!
3.124 :I [RS485] 84: IsAnyBodyWith x000000000101:12
3.126 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000101:12
3.128 :I [RS485] 85: IsAnyBodyWith x1000000000101:13
3.130 :N [RS485] NoMask x1000000000101:13!
3.132 :I [RS485] 86: IsAnyBodyWith x0000000000101:13
3.134 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000101:13
3.136 :I [RS485] 87: IsAnyBodyWith x10000000000101:14
3.138 :N [RS485] NoMask x10000000000101:14!
3.140 :I [RS485] 88: IsAnyBodyWith x00000000000101:14
3.142 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000000101:14
3.144 :I [RS485] 89: IsAnyBodyWith x100000000000101:15
3.146 :N [RS485] NoMask x100000000000101:15!
3.148 :I [RS485] 90: IsAnyBodyWith x000000000000101:15
3.150 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000000101:15
3.152 :I [RS485] 91: IsAnyBodyWith x1000000000000101:16
3.154 :N [RS485] NoMask x1000000000000101:16!
3.156 :I [RS485] 92: IsAnyBodyWith x0000000000000101:16
3.158 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000000101:16
3.160 :I [RS485] 93: IsAnyBodyWith x10000000000000101:17
3.162 :N [RS485] NoMask x10000000000000101:17!
3.164 :I [RS485] 94: IsAnyBodyWith x00000000000000101:17
3.166 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000000000101:17
3.168 :I [RS485] 95: IsAnyBodyWith x100000000000000101:18
3.170 :N [RS485] NoMask x100000000000000101:18!
3.172 :I [RS485] 96: IsAnyBodyWith x000000000000000101:18
3.174 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000000000101:18
3.176 :I [RS485] 97: IsAnyBodyWith x1000000000000000101:19
3.178 :N [RS485] NoMask x1000000000000000101:19!
3.180 :I [RS485] 98: IsAnyBodyWith x0000000000000000101:19
3.182 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000000000101:19
3.184 :I [RS485] 99: IsAnyBodyWith x10000000000000000101:20
3.186 :N [RS485] NoMask x10000000000000000101:20!
3.188 :I [RS485] 100: IsAnyBodyWith x00000000000000000101:20
3.190 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000000000000101:20
3.192 :I [RS485] 101: IsAnyBodyWith x100000000000000000101:21
3.194 :N [RS485] NoMask x100000000000000000101:21!
3.196 :I [RS485] 102: IsAnyBodyWith x000000000000000000101:21
3.198 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000000000000101:21
3.200 :I [RS485] 103: IsAnyBodyWith x1000000000000000000101:22
3.202 :N [RS485] NoMask x1000000000000000000101:22!
3.204 :I [RS485] 104: IsAnyBodyWith x0000000000000000000101:22
3.206 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000000000000101:22
3.208 :I [RS485] 105: IsAnyBodyWith x10000000000000000000101:23
3.210 :N [RS485] NoMask x10000000000000000000101:23!
3.212 :I [RS485] 106: IsAnyBodyWith x00000000000000000000101:23
3.214 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000000000000000101:23
3.216 :I [RS485] 107: IsAnyBodyWith x100000000000000000000101:24
3.218 :N [RS485] NoMask x100000000000000000000101:24!
3.220 :I [RS485] 108: IsAnyBodyWith x000000000000000000000101:24
3.222 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000000000000000101:24
3.224 :I [RS485] 109: IsAnyBodyWith x1000000000000000000000101:25
3.226 :N [RS485] NoMask x1000000000000000000000101:25!
3.228 :I [RS485] 110: IsAnyBodyWith x0000000000000000000000101:25
3.230 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000000000000000101:25
3.232 :I [RS485] 111: IsAnyBodyWith x10000000000000000000000101:26
3.234 :N [RS485] NoMask x10000000000000000000000101:26!
3.236 :I [RS485] 112: IsAnyBodyWith x00000000000000000000000101:26
3.238 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000000000000000000101:26
3.240 :I [RS485] 113: IsAnyBodyWith x100000000000000000000000101:27
3.242 :N [RS485] NoMask x100000000000000000000000101:27!
3.244 :I [RS485] 114: IsAnyBodyWith x000000000000000000000000101:27
3.246 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000000000000000000101:27
3.248 :I [RS485] 115: IsAnyBodyWith x1000000000000000000000000101:28
3.250 :N [RS485] NoMask x1000000000000000000000000101:28!
3.252 :I [RS485] 116: IsAnyBodyWith x0000000000000000000000000101:28
3.254 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000000000000000000101:28
3.256 :I [RS485] 117: IsAnyBodyWith x10000000000000000000000000101:29
3.258 :N [RS485] NoMask x10000000000000000000000000101:29!
3.260 :I [RS485] 118: IsAnyBodyWith x00000000000000000000000000101:29
3.262 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x00000000000000000000000000101:29
3.264 :I [RS485] 119: IsAnyBodyWith x100000000000000000000000000101:30
3.266 :N [RS485] NoMask x100000000000000000000000000101:30!
3.268 :I [RS485] 120: IsAnyBodyWith x000000000000000000000000000101:30
3.270 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x000000000000000000000000000101:30
3.272 :I [RS485] 121: IsAnyBodyWith x1000000000000000000000000000101:31
3.274 :N [RS485] NoMask x1000000000000000000000000000101:31!
3.276 :I [RS485] 122: IsAnyBodyWith x0000000000000000000000000000101:31
3.278 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask:x0000000000000000000000000000101:31
3.280 :I [RS485] 123: IsAnyBodyWith :32
3.282 :N [RS485] NoMask :32!
3.284 :I [RS485] 124: IsAnyBodyWith :32
3.286 :W [RS485] ACK Addr 0x5=0000_0000_0000_0000_0000_0000_0000_0101 Mask::32
3.288 :W [RS485] SpotAddr 0x5!
3.290 :W [RS485] MuteAddr 0x5
3.292 :I [RS485] 125: IsAnyBodyWith x001:3
3.294 :N [RS485] NoMask x001:3!
3.296 :I [RS485] 126: IsAnyBodyWith x0:1
3.298 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0:1
3.300 :I [RS485] 127: IsAnyBodyWith x10:2
3.302 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x10:2
3.304 :I [RS485] 128: IsAnyBodyWith x110:3
3.306 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x110:3
3.308 :I [RS485] 129: IsAnyBodyWith x1110:4
3.310 :N [RS485] NoMask x1110:4!
3.312 :I [RS485] 130: IsAnyBodyWith x0110:4
3.314 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0110:4
3.316 :I [RS485] 131: IsAnyBodyWith x10110:5
3.318 :N [RS485] NoMask x10110:5!
3.320 :I [RS485] 132: IsAnyBodyWith x00110:5
3.322 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00110:5
3.324 :I [RS485] 133: IsAnyBodyWith x100110:6
3.326 :N [RS485] NoMask x100110:6!
3.328 :I [RS485] 134: IsAnyBodyWith x000110:6
3.330 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000110:6
3.332 :I [RS485] 135: IsAnyBodyWith x1000110:7
3.334 :N [RS485] NoMask x1000110:7!
3.336 :I [RS485] 136: IsAnyBodyWith x0000110:7
3.338 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000110:7
3.340 :I [RS485] 137: IsAnyBodyWith x10000110:8
3.342 :N [RS485] NoMask x10000110:8!
3.344 :I [RS485] 138: IsAnyBodyWith x00000110:8
3.346 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000110:8
3.348 :I [RS485] 139: IsAnyBodyWith x100000110:9
3.350 :N [RS485] NoMask x100000110:9!
3.352 :I [RS485] 140: IsAnyBodyWith x000000110:9
3.354 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000110:9
3.356 :I [RS485] 141: IsAnyBodyWith x1000000110:10
3.358 :N [RS485] NoMask x1000000110:10!
3.360 :I [RS485] 142: IsAnyBodyWith x0000000110:10
3.362 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000110:10
3.364 :I [RS485] 143: IsAnyBodyWith x10000000110:11
3.366 :N [RS485] NoMask x10000000110:11!
3.368 :I [RS485] 144: IsAnyBodyWith x00000000110:11
3.370 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000110:11
3.372 :I [RS485] 145: IsAnyBodyWith x100000000110:12
3.374 :N [RS485] NoMask x100000000110:12!
3.376 :I [RS485] 146: IsAnyBodyWith x000000000110:12
3.378 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000110:12
3.380 :I [RS485] 147: IsAnyBodyWith x1000000000110:13
3.382 :N [RS485] NoMask x1000000000110:13!
3.384 :I [RS485] 148: IsAnyBodyWith x0000000000110:13
3.386 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000110:13
3.388 :I [RS485] 149: IsAnyBodyWith x10000000000110:14
3.390 :N [RS485] NoMask x10000000000110:14!
3.392 :I [RS485] 150: IsAnyBodyWith x00000000000110:14
3.394 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000000110:14
3.396 :I [RS485] 151: IsAnyBodyWith x100000000000110:15
3.398 :N [RS485] NoMask x100000000000110:15!
3.400 :I [RS485] 152: IsAnyBodyWith x000000000000110:15
3.402 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000000110:15
3.404 :I [RS485] 153: IsAnyBodyWith x1000000000000110:16
3.406 :N [RS485] NoMask x1000000000000110:16!
3.408 :I [RS485] 154: IsAnyBodyWith x0000000000000110:16
3.410 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000000110:16
3.412 :I [RS485] 155: IsAnyBodyWith x10000000000000110:17
3.414 :N [RS485] NoMask x10000000000000110:17!
3.416 :I [RS485] 156: IsAnyBodyWith x00000000000000110:17
3.418 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000000000110:17
3.420 :I [RS485] 157: IsAnyBodyWith x100000000000000110:18
3.422 :N [RS485] NoMask x100000000000000110:18!
3.424 :I [RS485] 158: IsAnyBodyWith x000000000000000110:18
3.426 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000000000110:18
3.428 :I [RS485] 159: IsAnyBodyWith x1000000000000000110:19
3.430 :N [RS485] NoMask x1000000000000000110:19!
3.432 :I [RS485] 160: IsAnyBodyWith x0000000000000000110:19
3.434 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000000000110:19
3.436 :I [RS485] 161: IsAnyBodyWith x10000000000000000110:20
3.438 :N [RS485] NoMask x10000000000000000110:20!
3.440 :I [RS485] 162: IsAnyBodyWith x00000000000000000110:20
3.442 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000000000000110:20
3.444 :I [RS485] 163: IsAnyBodyWith x100000000000000000110:21
3.446 :N [RS485] NoMask x100000000000000000110:21!
3.448 :I [RS485] 164: IsAnyBodyWith x000000000000000000110:21
3.450 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000000000000110:21
3.452 :I [RS485] 165: IsAnyBodyWith x1000000000000000000110:22
3.454 :N [RS485] NoMask x1000000000000000000110:22!
3.456 :I [RS485] 166: IsAnyBodyWith x0000000000000000000110:22
3.458 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000000000000110:22
3.460 :I [RS485] 167: IsAnyBodyWith x10000000000000000000110:23
3.462 :N [RS485] NoMask x10000000000000000000110:23!
3.464 :I [RS485] 168: IsAnyBodyWith x00000000000000000000110:23
3.466 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000000000000000110:23
3.468 :I [RS485] 169: IsAnyBodyWith x100000000000000000000110:24
3.470 :N [RS485] NoMask x100000000000000000000110:24!
3.472 :I [RS485] 170: IsAnyBodyWith x000000000000000000000110:24
3.474 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000000000000000110:24
3.476 :I [RS485] 171: IsAnyBodyWith x1000000000000000000000110:25
3.478 :N [RS485] NoMask x1000000000000000000000110:25!
3.480 :I [RS485] 172: IsAnyBodyWith x0000000000000000000000110:25
3.482 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000000000000000110:25
3.484 :I [RS485] 173: IsAnyBodyWith x10000000000000000000000110:26
3.486 :N [RS485] NoMask x10000000000000000000000110:26!
3.488 :I [RS485] 174: IsAnyBodyWith x00000000000000000000000110:26
3.490 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000000000000000000110:26
3.492 :I [RS485] 175: IsAnyBodyWith x100000000000000000000000110:27
3.494 :N [RS485] NoMask x100000000000000000000000110:27!
3.496 :I [RS485] 176: IsAnyBodyWith x000000000000000000000000110:27
3.498 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000000000000000000110:27
3.500 :I [RS485] 177: IsAnyBodyWith x1000000000000000000000000110:28
3.502 :N [RS485] NoMask x1000000000000000000000000110:28!
3.504 :I [RS485] 178: IsAnyBodyWith x0000000000000000000000000110:28
3.506 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000000000000000000110:28
3.508 :I [RS485] 179: IsAnyBodyWith x10000000000000000000000000110:29
3.510 :N [RS485] NoMask x10000000000000000000000000110:29!
3.512 :I [RS485] 180: IsAnyBodyWith x00000000000000000000000000110:29
3.514 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x00000000000000000000000000110:29
3.516 :I [RS485] 181: IsAnyBodyWith x100000000000000000000000000110:30
3.518 :N [RS485] NoMask x100000000000000000000000000110:30!
3.520 :I [RS485] 182: IsAnyBodyWith x000000000000000000000000000110:30
3.522 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x000000000000000000000000000110:30
3.524 :I [RS485] 183: IsAnyBodyWith x1000000000000000000000000000110:31
3.526 :N [RS485] NoMask x1000000000000000000000000000110:31!
3.528 :I [RS485] 184: IsAnyBodyWith x0000000000000000000000000000110:31
3.530 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask:x0000000000000000000000000000110:31
3.532 :I [RS485] 185: IsAnyBodyWith :32
3.534 :N [RS485] NoMask :32!
3.536 :I [RS485] 186: IsAnyBodyWith :32
3.538 :W [RS485] ACK Addr 0x6=0000_0000_0000_0000_0000_0000_0000_0110 Mask::32
3.540 :W [RS485] SpotAddr 0x6!
3.542 :W [RS485] MuteAddr 0x6
3.544 :I [RS485] 187: IsAnyBodyWith x010:3
3.546 :N [RS485] NoMask x010:3!
3.548 :I [RS485] 188: IsAnyBodyWith x00:2
3.550 :N [RS485] NoMask x00:2!
-->

Плюсы этого метода

1++Алгоритм сканирования RS485 простой. Его может реализовать даже программист-микроконтроллеров с экстремально низкой квалификацией.

2++эффективность

3++Быстрота работы в сравнении с перебором всех адресов.

4++Нет нужды в дополнительных проводах. Всё что надо это одна витая пара интерфейса RS485.

Минусы

1--Master устройство должно быть микроконтроллером с полноценным драйвером GPIO и UART. Не получится просто взять первый попавшийся китайский переходник USB-RS485, подключить его к PC и написать консольное Windows приложение, которое выполнит сканирование RS485 шины. Надо чтобы была не просто возможность читать\писать байты в RS485, но и переключать функции пинов с GPIO на UART и обратно. Причем надо переключать функции пинов быстро чтобы успеть принять сигналы от Slave nodes.

2--Нужна программная поддержка этого простенького протокола сканирования RS485 как на стороне master так и на стороне slave устройств.

3--Очень трудно сделать в run-time переключение пина из UART_RX в GPIO-IN если ваш мастер RS485 это embedded Linux SoC. Как правило low level API в Linux такого не позволяет так как Linux это не RTOS. Однако, на самом деле не обязательно переключать функции GPIO c UART на GPIO. Если у Slave(ва) адрес совпал с маской, то он может прижать шину просто отправив несколько раз 0x00. Мастер увидит это как принятие пакета с неправильной контрольной суммой или UART периферия выдаст прерывание по Overrun и поймет, что это ACK сигнал.

Вывод

Теперь и вы умеете сканировать шину RS485 и можете учить других. Этот простой алгоритм сканирования адресов на общей шине подойдет не только для RS485. Его можно реализовать для любого другого интерфейса с топологией "общая шина". Это может быть интерфейс 1-wire, LIN или даже вовсе беспроводные интерфейсы типа GFSK, LoRa или UWB.

Словарь

Акроним

Расшифровка

RS485

Recommended Standard 485

LSB

Least Significant Bit

MAC

medium access control

PC

personal computer

UART

Universal asynchronous receiver-transmitter

SoC

System on a chip

GPIO

General-purpose input/output

Links

https://habr.com/ru/companies/wirenboard/articles/737402/

https://habr.com/ru/companies/milandr/articles/540084/

https://we.easyelectronics.ru/STM32/stm32-1-wire-poisk-ustroystv.html

https://www.analog.com/en/app-notes/1wire-search-algorithm.html

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


  1. Nansch
    04.08.2023 23:13
    +2

    А профибас-дп сможете так просканировать?


    1. aabzel Автор
      04.08.2023 23:13

      Я Profibus DP не сталкивался.
      Что можно почитать про физический уровень Profibus DP?


      1. Nansch
        04.08.2023 23:13

        Инфы море, хоть с официального сайта, хоть в свободном доступе. Но этот протокол работает поверх всё той же спецификации RS-485. Линия сбалансированная и в состоянии покоя на проводниках поддерживается стандартное напряжение, чтобы устройства не считывали помехи, когда никто не передаёт. Так что ничего занулять для сканирования нельзя.


  1. Nick_Shl
    04.08.2023 23:13
    +18

    Нет такой шины RS-485. Это физический уровень. А протокол может быть любой. Поэтому какую вы там шину сканировали вообще не понятно.

    ModBus тоже использует RS-485 и там всего 255 устройств возможно.


  1. kipar
    04.08.2023 23:13
    +2

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


    1. aabzel Автор
      04.08.2023 23:13
      -1

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

      Отличное предложение! Но как драйвер UART на стороне мастера поймет что идет мусор?


      1. Nick_Shl
        04.08.2023 23:13
        +3

        Все мусор, если запрос идёт на широковещательный адрес. Главное тут есть этот мусор или нет. А дальше классический бинарный поиск: https://ru.wikipedia.org/wiki/Двоичный_поиск


      1. kipar
        04.08.2023 23:13
        +1

        Мусор — мастер примет какие-то байты, но при этом контрольная сумма не сойдется.
        Теоретически, правда, есть шанс что при наличии parity bit ничего принято не будет, но тут могу представить три варианта — отключить parity bit (всегда так делаю, так что дальше уже мои гипотезы), проверять parity error (если мастер мк а не комп), сделать ответ подлиннее, тогда хоть у одного байта да сойдется.


  1. Goron_Dekar
    04.08.2023 23:13
    +19

    Делал и видел множество вариантов RS485 устройств. И вижу, что в статье чушь.

    1) RS485 это стандарт физического уровня. В нём тупо нет ни то, что адресов, но и даже пакетов. Он заканчивается уровнем байта (8 бит плюс минус ) https://ru.wikipedia.org/wiki/RS-485

    2) Всё, что тут написано, написано про какую-то реализацию протокола поверх RS485, но не самого распространённого - не modbus, потому что modbus имеет только 1 байт адреса (иногда больше, но это уже не очень кошерный modbus) https://en.wikipedia.org/wiki/Modbus

    3) и, вишенка на торте! Указаный алгоритм побитного прощупования тупо противоречит стандарту modbus и стандарту RS485.

    Hidden text

    Вообще по уровню самоуверенности этой чуши возникает ощущение, что пишет либо плохой, но настырный студент, либо ИИ.


  1. horon
    04.08.2023 23:13
    +1

    Писал как то утилю которая с 1 до 255 на всех общепринятых скоростях\чётностях сканирует. Модбас и околомодбасные протоколы - сканирует хорошо. Автор пишет не про RS485 а про какой-то протокол, при этом название протокола не говорит. Это какой то квест?)


    1. iliasam
      04.08.2023 23:13
      +1

      Автор сам явно не определился с протоколом:

      "Трудность в том что адреса устройств RS485 имеют существенно более высокую разрядность, как правило это 32 бита (4байта) или MAC адреса по 48бит (6 байт)"


    1. aabzel Автор
      04.08.2023 23:13
      -2

      Автор пишет не про RS485 а про какой-то протокол, при этом название протокола не говорит.

      Это технология, которая может быть реализована в любом протоколе, который работает поверх RS-485. Будь до ModBus или xModem.


      1. maledog
        04.08.2023 23:13
        -1

        Не может. В ModBus не принято говорить хором. Так что только перебор по конкретным адресам. Еще мастер может послать сообщение всем устройствам через широковещательный адрес но ответ на него не предусмотрен. Теоретически можно предусмотреть очередность ответа через <адрес> * 100ms, но поддерживать это будут ваши два с половиной устройства. И это уже будет не ModBus.


        1. aabzel Автор
          04.08.2023 23:13

          Не может. В ModBus не принято говорить хором.


          Смотрите,
          https://habr.com/ru/companies/wirenboard/articles/737402/

          в контроллерах Wiren Board тоже есть одновременный ModBus ответ на сканирование


  1. Sun-ami
    04.08.2023 23:13
    +3

    Зачем использовать для RS-485 адрес длиной более 8 бит, если трансиверы RS-485 могут вытянуть в качестве нагрузки лучшем случае 256 аналогичных трансиверов, а часто — всего лишь 64, и это не считая ёмкости самих проводов? И уж тем более 32 или 48 бит? Гораздо актуальнее — автоматическое назначение адреса на шине, с идентификацией по тому же MAC или серийному номеру.


    1. aabzel Автор
      04.08.2023 23:13
      -1

      Зачем использовать для RS-485 адрес длиной более 8 бит, если трансиверы RS-485 могут вытянуть в качестве нагрузки лучшем случае 256 аналогичных трансиверов

      Дело в том что в качестве адресов иногда используют MAC адреса устройств. А они в свою очередь являются производной серийного номера SN.
      Поэтому адреса широкие хоть и узлов сети мало.


    1. vk6677
      04.08.2023 23:13
      +1

      Вы правы, та же max485 регламентирует работу не более 128 микросхем на линии.

      Но, возможно, какой-то производитель оборудования решил сделать 4 миллиарда устройств с заранее прошитым адресом, где каждое устройство с "завода" имеет уникальный номер.


      1. aabzel Автор
        04.08.2023 23:13
        -1

        Да. Именно так.


  1. aumi13
    04.08.2023 23:13
    +2

    1--Трудность в том что адреса устройств RS485 имеют существенно более высокую разрядность, как правило это 32 бита (4байта) или MAC адреса по 48бит (6 байт).

    нет стандарта на 485 где бы описывалась адресацыя. да и не нужна здесь многобайтовость.

    Этот простой алгоритм сканирования адресов на общей шине подойдет не только для RS485. Его можно реализовать для любого другого интерфейса с топологией общая шина. Это может быть и 1Wire, LIN или даже вовсе беспроводные интерфейсы типа LoRa или UWB.

    ващета в 1варе поиск адреса устройства так и выполняеца, разработанный в конце 90-х годов фирмой Dallas.

    Поздравляю с изобретением велосипеда.


    1. aabzel Автор
      04.08.2023 23:13
      -2

      ващета в 1варе поиск адреса устройства так и выполняеца, разработанный в конце 90-х годов фирмой Dallas.

      Поздравляю с изобретением велосипеда.

      Может тогда пришлете pdf c AppNote того как это там описывается?


      1. iliasam
        04.08.2023 23:13
        +2

        Тут описание, но не у всех откроется без VPN: https://www.analog.com/en/app-notes/1wire-search-algorithm.html

        Тут один из вариантов описания на русском: https://we.easyelectronics.ru/STM32/stm32-1-wire-poisk-ustroystv.html


        1. aabzel Автор
          04.08.2023 23:13

          Тут один из вариантов описания на русском

          В тексте с we.easyelectronics.ru не такой же алгоритм сканирования как тут. Там даже таких слов как маска нет. И один бит там кодируют двумя битами.


          1. pvvv
            04.08.2023 23:13
            +1

            Там даже таких слов как маска нет.

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


  1. me21
    04.08.2023 23:13
    +1

    У меня в протоколе сканирование выполнялось после определённой команды-бродкаста. Отвечали все устройства по очереди, с задержкой, пропорциональной их адресу.


    1. aabzel Автор
      04.08.2023 23:13
      -2

      На шине 3 устройства с адресам: 0x00000001, 0xFFFFFFFD. 0xFFFFFFFE.
      Сначала отвечает первый потом пауза 13 лет и отвечают последние 2.))

      В итоге мастер думает что на шине одно устройство с адресом 0x00000001

      Отличное решение.


      1. me21
        04.08.2023 23:13
        +2

        Ну у меня в протоколе адреса однобайтные, поэтому даже для адресов 1 и 255 это работает. Длительность сканирования примерно пропорциональна количеству устройств на линии.


      1. GreedyHamster
        04.08.2023 23:13
        +1

        А что мешает использовать двойную адресацию? Внешняя - 1-255, внутренняя - произвольная. Опрашиваются 255max адресов, слэйв в ответе пересылает свой внутренний адрес.


  1. alex_kag
    04.08.2023 23:13
    +3

    я может совсем тупой, но какой mac на rs485 ?


  1. jogick
    04.08.2023 23:13
    +1

    Много лет работал с 485-м, писал программы для работы с ним, делал устройства с разными протоколами, но у меня даже подозрений нет, с каким же устройством работает автор статьи. В большинстве случаев это были modbus-подобные протоколы, ну или dmx-подобные


  1. vk6677
    04.08.2023 23:13
    +1

    Оборудование какого производителя использует 32 бит на адрес в 485 ?

    Возможна любая реализация поверх 485. Пытались стандартизовать Modbus, но по прежнему куча производителей делает по своему.

    И вообще может даже микроконтроллер не нужен на этой линии. Как-то с помощью микросхем 485/422 передавал сигнал с датчика холла на значительное расстояние в "шумном" оборудовании.


    1. pvvv
      04.08.2023 23:13
      +1

      Оборудование какого производителя использует 32 бит на адрес в 485 ?

      Нормальные производители таким онанизмом заниматься не будут, сделают нормальный способ задать 7-8битный адрес устройству

      но приходилось как-то изобретать подобный велосипед для подключения кучи однотипных устройств по 485, для которых совсем не хотелось руками раздавать каждому логические адреса на шине (джамперами / в еепром), но у которых есть уникальный chip ID в МК, 64битный, по которому их можно различать, и, просканировав шину мастером при старте, раздать им соответствующие логические 128 адресов для последующей адресации на шине. некий убогий аналог dhcp для rs485.

      собственно для 1wire всё уже давно придумано.

      а слэйвам для этого надо только две команды:

      1) отозваться хоть как-то, если присланный мастером ID больше чем собственный и плевать на коллизии, наличие просто стартового бита в ответе означает что на шине кто-то есть. и без дополнительного дергания IO.

      2) получить свой логический однобайтный адрес и в дальнейшем перестать отзываться на запросы с ID, чтобы не мешать остальным.

      дальше бинарый поиск.


  1. GreedyHamster
    04.08.2023 23:13
    +3

    RS485 - это интерфейс. По спецификации поддерживает подключение до 256 устройств, т.е. в 32-битном адресе нет смысла. О протоколе, к-рый (якобы) используется в данном опусе - ни слова. И при описанном алгоритме получить 100% результат - маловероятно. Причина банальна: помехи. Именно поэтому используются кодированный запрос/кодированный ответ.