Объединим в сеть передачи данных несколько плат Ардуино. Будем использовать стандартный интерфейс UART с минимальной аппаратной доработкой (добавим к каждой плате только один диод).
Предыдущий урок Список уроков Следующий урок
В предыдущих уроках мы обменивались данными между платами Ардуино через радиальные интерфейсы UART, RS-232, RS-422, ИРПС. Все эти интерфейсы позволяли соединять между собой только 2 платы.
Для подключения нескольких плат хотя бы одна из них должна иметь несколько радиальных интерфейсов. Но даже в этом случае могут быть созданы сети только достаточно сложных, запутанных топологий: кольцо, звезда, дерево и т.п. Недостатки таких сетей очевидны:
- Требуется несколько радиальных интерфейсов. Где их взять на простых платах Ардуино.
- Не просто реализовать программное управление этими интерфейсами.
- Достаточно сложное физическое соединение устройств. Несколько кабелей подключены к разным разъемам.
- Физическая среда передачи данных состоит из нескольких линий связи. Например, ИРПС требует 2 витые пары.
- Система непросто расширяется. Требуется перекоммутация кабелей , необходимы новые кабели, могут потребоваться дополнительные интерфейсы. Серьезные проблемы при расширении системы могут возникнуть и с программным обеспечением.
От всех этих недостатков свободна локальная сеть с топологией ”Общая шина”. Она представляет собой одну линию связи, параллельно которой подключаются устройства – платы Ардуино.
- На каждой плате используется только один интерфейс независимо от количества устройств в сети.
- Требуется только один кабель.
- При добавлении новых плат в сеть они просто подключаются к линии связи. Система доращивается, а не перестраивается.
- Программные средства управления сетью не меняются. Просто появляются новые устройства с новыми адресами.
- Существуют стандартные протоколы передачи данных, ориентированные на такую структуру сети.
- Конфигурация сети проста и понятна.
В качестве физической среды передачи данных также будем использовать самый простой вариант – витую пару. Проще и дешевле ничего не существует.
Итак, мы собираемся реализовать сеть из нескольких плат Ардуино:
- С топологией ”Общая шина”.
- В качестве физической среды передачи данных будем использовать самый простой вариант – витую пару.
- Протокол передачи данных - ModBus RTU.
- Для реализации программного обеспечения применим библиотеки Tiny_ModBusRTU_Master и Tiny_ModBusRTU_Slave.
- В качестве сетевых интерфейсов будем использовать штатные интерфейсы UART с минимальной доработкой.
- Система будет состоять из центрального контроллера и нескольких локальных контроллеров.
В качестве центрального контроллера и локальных контроллеров будем использовать устройства, разработанные в предыдущих 2 уроках.
Преобразование стандартного интерфейса UART для подключения к односигнальной линии связи.
Мы собираемся использовать для передачи данных между контроллерами одну сигнальную линию. Интерфейс UART имеет две линии вход RxD и выход TxD. В предыдущих уроках мы использовали для связи между интерфейсами 2 сигнала: выход одного контроллера подключали к входу второго и выход второго соединяли с входом первого.
Сейчас нам надо делать обмен данными по одной сигнальной линии. Кроме того к этой линии будут подключены несколько контроллеров. Неактивные контроллеры не должны мешать передаче данных. Т.е. надо осуществлять коммутацию входов и выходов интерфейсов UART для каждого контроллера сети.
Сделать это можно двумя способами:
- с использованием передатчиков с тремя состояниями;
- за счет передатчиков реализующих “монтажное ИЛИ” на линии связи.
В упрощенном виде логический выход имеет следующую схему. Я привел схему на биполярных транзисторах, хотя в современных микроконтроллерах используются полевые.
Транзисторы работают в ключевом режиме.
- Если открыт верхний транзистор, а нижний закрыт, то на выходе будет напряжение близкое к 5 В, т.е. логическая 1.
- Когда открыт нижний транзистор, а верхний закрыт, выход будет подключен к общему проводу, что соответствует логическому 0.
Если мы электрически соединим такие передатчики между собой, то они будут мешать друг другу. При разных уровнях на выходах будет происходить замыкание, протекать недопустимые токи. Может ничего и не сгорит благодаря внутренней защите микросхем, но работать, точно не будет.
Решить такую проблему можно за счет использования логических выходов с тремя состояниями. У передатчика с тремя состояниями есть дополнительный управляющий вход. При запрещающем уровне сигнала на этом входе закрываются оба транзистора, и выход полностью отключается.
Можно выходы UART плат Ардуино подключить к линии связи через передатчики с тремя состояниями. Неактивные контроллеры будут отключать свои передатчики, освобождая линию связи для обмена данными. Именно так мы поступим в следующем уроке, когда будем использовать приемопередатчики RS-485.
Такой способ широко распространен, но имеет свои недостатки. В нашем случае это:
- Необходимость использования дополнительных микросхем – элементов с тремя состояниями. В принципе микроконтроллер способен переводить любой свой вывод в третье состояние, но это потребует более тонкого программирования, отказ от стандартных функций Serial.
- При неправильной коммутации передатчиков могут происходить замыкания их выходов.
- Для управления состоянием передатчиков требуется лишний выход микроконтроллера.
В этом уроке мы будем использовать самый простой способ коммутации передатчиков на линии связи.
Монтажное ИЛИ.
Существует еще один тип логического выхода – выход с “открытым коллектором” (выход ОК). Упрощенная схема выхода ОК выглядит так.
Передатчик с ОК не формирует напряжение на выходе. При логическом 0 он замыкает выход на землю, при логической 1 - бросает его в воздухе. Напряжение на таком выходе появляется только при подключении к нему внешнего резистора.
Если объединить несколько выходов с ОК то получится схема ”монтажного ИЛИ”.
Логический 0 на любом выходе приведет к логическому нулю на общей линии. Именно поэтому схема называется ”монтажное ИЛИ”. Или один выход замкнут, или другой, или несколько.
Для того, чтобы перевести передатчик в неактивное состояние (отключить) достаточно сформировать на его выходе логическую 1. Вспомните, что в момент ожидания на выходе TxD интерфейса UART формируется именно логическая 1. Т.е. нам ничего не надо отключать. Передатчик UART закончит передачу, на его выходе будет логическая 1, благодаря чему он освободит линию связи для других передатчиков.
Любая неправильная коммутация выходов передатчиков не приведет к замыканию их выходов. Ничего никогда не сгорит.
Существуют логические микросхемы с ОК, но мы поступим проще. Активный логический выход легко преобразуется в выход с ОК с помощью одного диода.
Таким образом, преобразование сигналов стандартного интерфейса UART для подключения к односигнальной линии связи сводится к добавлению одного диода.
А схема соединения плат Ардуино одним сигналом в общую сеть выглядит так.
Резисторы лучше размещать на физических краях линии связи.
Эта схема справедлива только для плат Ардуино без встроенного конвертера интерфейсов USB-UART. Например, для платы Arduino Pro Mini.
У плат с конвертером интерфейсом сигнал RxD подключен через резистор 1 кОм к выходу микросхемы-конвертера. Этот выход при неактивном состоянии USB связи с компьютером находится на уровне 5 В. Т.е. подтягивающие резисторы уже находятся в каждой плате Ардуино.
Т.е. для плат Ардуино с конвертером USB-UART (например, Arduino UNO, Arduino Nano) схема соединения в сеть выглядит еще проще.
Правда наличие внутренних резисторов ограничивает число плат в сети. Каждый резистор сопротивлением 1 кОм при переводе линии в уровень 0 формирует втекающий ток 5 мА в активный передатчик. С учетом нагрузочной способности выходов микроконтроллеров ATmega, по такой схеме можно подключить 4-5 плат. Для Arduino Pro Mini ограничения по этому параметру не существует.
Практическая реализация локальной сети из плат Ардуино.
Я использовал локальный контроллер, разработанный в уроке 48. Добавил только диод, о котором столько написано выше.
Спаял еще один такой же контроллер.
Центральный контроллер был разработан в уроке 49. Опять же добавлен диод.
Все три контроллера объединил двумя проводами в сеть. Питание локальных контроллеров взял от сигнала 5 В центрального контроллера.
В локальные контроллеры я загрузил программу из урока 57. Скетч можно загрузить по этой ссылке
Только в локальных контроллерах надо задать разные адреса в строке:
Tiny_ModBusRTU_Slave slave(1, 8, regTable, 6, 13); // создаем объект ModBus, адрес 1, таймаут 4 мс, массив regTable, размер 6
Первый параметр в скобках это адрес. Я задал адреса 1 и 2.
Для центрального контроллера я написал программу, которая каждые 0,5 сек опрашивает локальные контроллеры с адресами 1 и 2 и выводит информацию на дисплей. Все как в предыдущем уроке, только для 2 локальных контроллеров.
Загрузить программу центрального контроллера можно по ссылке:
В программе используются библиотеки Tiny_ModBusRTU_Slave и Tiny_ModBusRTU_Master. Они подробно описаны в предыдущих 2 уроках. Думаю, в программе все понятно. Опять же весь обмен происходит параллельным процессом. Программа никогда не зависает. В цикл loop() можно добавлять другие задачи.
Проверка работы системы.
Включил. Все работает. Проверил термодатчики, покрутил переменные резисторы, понажимал кнопки. Все правильно, ошибок обмена нет.
Нажал кнопку сброса одного локального контроллера, т.е. отключил его.
Посыпались ошибки первого контроллера, второй работает.
То же сделал с другим локальным контроллером.
Я снял короткий фильм о работе системы.
В программах при объявлении объектов ModBus я специально в каждом контроллере задал сигнал управления передатчиком на 13 вывод – светодиод общего назначения. Поэтому при передаче данных любым контроллером этот светодиод мигает.
Несколько слов о помехоустойчивости подобных сетей.
Все написанное в уроке 50 справедливо для этого варианта сети. Только контроллеров стало больше, больше возможных токов утечек, земляных токов, контуров и т.п.
Эмпирически я считаю, что при питании контроллеров от гальванически развязанных источников питания длина линии связи может достигать 5-10 м. С экранированной витой парой еще больше. При питании контроллеров от общего источника я бы ограничил расстояние между самыми дальними устройствами 2-3 м. Конечно, многое зависит от условий эксплуатации, в частности, от уровня помех.
Также на помехозащищенность несколько влияет тип диодов. Лучше использовать диоды Шоттки. За счет низкого падения напряжения на нем в открытом состоянии уровень логического 0 в линии связи будет ниже, а помехоустойчивость выше.
В следующем уроке будем создавать локальную сеть из плат Ардуино, используя интерфейс RS-485.
День добрый, Эдуард! А если контроллеры в сети не однотипные, например один главный «уно» и три локальных «мини про», нужен тогда подтягивающий резистор?
Здравствуйте!
Лучше поставить. Тогда в вашей системе будет 3 резистора. Если Arduino UNO физически расположена на краю линии, тогда достаточно будет одного резистора на другом крае. Если линия не длинная, то можно попробовать и без резисторов, с одним внутренним.
Понял, спасибо.
В «Уно» уже есть втроенный, но я бы, например, поставил ещё один на дальнем от главного контроллера конце шины.
Эдуард, очень интересно было бы соединить протокол MODBUS с передачей данных по WiFi с помощью модуля ESP8266. Наверняка сделать это можно, ведь «умные дома» уже работают, но там другой протокол.
Здравствуйте!
Это протокол ModBus TCP. Возможно я буду использовать его в уроках.
тоже очень интересует этот вопрос. буду признателен, если осветите тему подключения к nodeMCU ESP8266
Здравствуйте! Эдуард, а Вы не планируете сделать уроки по nrf24L01. Очень интересует возможность создания беспроводной сети на этих микросхемах. И уместно ли использование протокола ModBus?
Очень жду следующий урок, не получается разобраться с rs-485 для такой топологии сети
Здравствуйте!
Времени сейчас очень мало. Но я постараюсь в ближайшее время написать урок.
День добрый!
Внимательно прочитал Ваши уроки, получил удовольствие от хорошего языка и расширил кругозор. Благодарю за дотошность описания любых действий — очень помогает. И жду следующего урока.
Здравствуйте!
Спасибо за добрые слова. Только сегодня вернулся из Абхазии. Начну писать уроки более менее регулярно.
Эдуард здравствуйте! Огромное спасибо, что делитесь Вашим опытом и подходом к разработке различных устройств. Бесценный материал. С огромным интересом прочитал Ваши статьи и беру Ваши наработки для своих устройств (не коммерческие) Начинаю волноваться, так как уже октябрь подходит к концу, а обновлений в статьях нет. Уверен, что все читатели соскучились.
Здравствуйте!
Спасибо за добрые слова. В ближайшее время выложу очередной урок и, надеюсь, буду писать более или менее регулярно.
То чувство, когда сам нашел вот эти два магазина, а потом наткнулся на этот сайт и увидел эти два баннера справа..
Спасибо за урок)
День добрый
почему то в proteus работать не хочет(((
Здравствуйте! Спасибо за уроки, сделал по предыдущим и этому уроку соединения между двумя ардуино , всё получилось, работает стабильно. Для гальванической развязки ещё раньше приобрел ADUM1311, а для связи RS482 модули, это всё для расстояния ~ 30метров, осваивая ваши уроки, пробовал использовать ADUM1311 , но ясно что знаний мало, если возможно подскажите как использовать ADUM1311 для развязки между двумя ардуино? Для развязки по питанию есть B0505S-1WR2, DC/DC преобразователи.
Здравствуйте!
В уроке 61 написано, как сделать гальваническую развязку RS485 на оптронах. Оптроны можно заменить на элементы ADUM.
Спасибо, за ответ, в соединении от ADUM к Rx, Tx и (управляющий пин) нужны сопротивления. У вас в 61уроке говорится «Линия у меня не длинная» это сколько ~ метров, у меня линия ~ 30метров , если можете исходя из вашего опыта, подскажите, понятно что всё надо самому бы пробовать и высчитывать, ведь условия оговорены.
Если будете использовать интерфейс RS485, то длина линии может быть до 1200 м.
Посмотрите уроки 60 и 61.
Здравствуйте Эдуард не могу найти библиотеки Tiny_ModBusRTU_Master.h
Tiny_ModBusRTU_Slave.h
Tiny_ModBusRTU_Slave.h не видит
Здравствуйте!
Загрузите из уроков 57 и 58. Они там.