====== RS-485 (Troyka-модуль) ====== [[amp>product/troyka-rs485?utm_source=man&utm_campaign=rs485&utm_medium=wiki|RS-485 (Troyka-модуль)]] поможет построить протяжённую проводную сеть из 32 устройств, используя всего два провода. {{ :продукты:troyka-rs485:troyka-rs485_overview.jpg?nolink |}} ===== Видеообзор ===== {{youtube>F29RE25_Yhw?large}} ===== Подключение и настройка ===== RS-485 (Troyka-модуль) общается с управляющей платой по протоколу [[видеоуроки:6-serial-и-processing|UART]] через сигнальные пины ''RO(TX)'' и ''DI(RX)''. Cигнальный пин ''↑↓'' служит для переключения модуля из режима приёмника в режим передатчика. Для работы с модулем подойдёт [[amp>product/arduino-troyka-shield?utm_source=man&utm_campaign=rs485&utm_medium=wiki|Troyka Shield]]. {{ :продукты:troyka-rs485:troyka-rs485_scheme_troyka.png?nolink |}} Если хотите оставить минимум проводов — возьмите [[amp>product/arduino-troyka-slot-shield?utm_source=man&utm_campaign=rs485&utm_medium=wiki|Troyka Slot Shield]]. {{ :продукты:troyka-rs485:troyka-rs485_scheme_troykaslot.png?nolink |}} ==== SoftwareSerial ==== Некоторые платы Arduino прошиваются через пины 0 и 1 ([[amp>product/arduino-uno|Uno]], [[amp>product/arduino-mega-2560|Mega 2560]], [[amp>product/arduino-adk|ADK]] и [[amp>product/iskra-mini|Iskra Mini]]). Перед прошивкой таких плат отключите модуль от пинов RX и TX. Если необходимо одновременно работать с RS485 и подключать контроллер к компьютеру, подключите пины TX и RX к другим контактам управляющей платы. Для примера подключим управляющие пины RS485-модуля ''RO'' и ''DI'' — на ''8'' и ''9'' пин Arduino через Troyka Shield. {{ :продукты:troyka-rs485:troyka-rs485_scheme_troyka_soft.png?nolink |}} ===== Примеры работы для Arduino ===== RS-485 (Troyka-модуль) работает в [[https://ru.wikipedia.org/wiki/%D0%94%D1%83%D0%BF%D0%BB%D0%B5%D0%BA%D1%81_(%D1%82%D0%B5%D0%BB%D0%B5%D0%BA%D0%BE%D0%BC%D0%BC%D1%83%D0%BD%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8)|полудуплексном режиме]] — приём и передача идут по одной паре проводов с разделением по времени — один говорит, остальные слушают. Передатчиком может выступать любое устройство в сети. Для этого подайте логическую единицу на пин ''↑↓'' — модуль перейдет в режим передачи. Рассмотрим несколько примеров построение сети на модулях RS-485. ==== Простая сеть ==== Соедините в сеть через RS-485 по двум проводам ''A'' и ''B'' два устройства [[amp>collection/arduino?utm_source=man&utm_campaign=rs485&utm_medium=wiki | Arduino]] через [[amp>product/arduino-troyka-slot-shield?utm_source=man&utm_campaign=rs485&utm_medium=wiki | Troyka Slot Shield]]. Одно будет передатчиком (//Master//), другое — приёмником (//Slave//). Подключите к //Master// [[amp>product/troyka-button?utm_source=man&utm_campaign=rs485&utm_medium=wiki | кнопку (Troyka-модуль)]] к пину ''A4'', а к //Slave//[[amp>product/troyka-led-module?utm_source=man&utm_campaign=rs485&utm_medium=wiki | светодиод «Пиранья» (Troyka-модуль)]] к ''8'' пину. {{ :продукты:troyka-rs485:troyka-rs485_scheme_example1.png?nolink |}} Прошейте устройства скетчами представленными ниже. === Ведущее устройство === // даём разумное имя для пинов, к которым подключены кнопки #define BUTTON_PIN_YELLOW A4 // была ли жёлтая кнопка отпущена? boolean buttonStateYellow = true; // состояние жёлтого светодиода boolean ledStateYellow = false; void setup() { // открываем последовательный порт на пинах 1 и 0 // к которому подключён модуль RS-485 Serial1.begin(9600); // 5 пин в режим выхода pinMode(5, OUTPUT); // подаём высокий уровень на 5 пин // значит устройство будет передавать данные digitalWrite(5, HIGH); } void loop() { // отпущена ли кнопка прямо сейчас... boolean buttonStateNowYellow = digitalRead(BUTTON_PIN_YELLOW); // если кнопка была отпущена и не отпущена сейчас if (buttonStateYellow && !buttonStateNowYellow) { delay(10); // считываем сигнал снова buttonStateNowYellow = digitalRead(BUTTON_PIN_YELLOW); if (!buttonStateNowYellow) { // если она всё ещё нажата // значит это клик! Инвертируем сигнал светодиода ledStateYellow = !ledStateYellow; if (ledStateYellow) { // посылаем на модули RS-485 символ «a» Serial1.print('a'); } else { // посылаем на модули RS-485 символ «b» Serial1.print('b'); } } } // запоминаем последнее состояние кнопки для новой итерации buttonStateYellow = buttonStateNowYellow; } === Ведомое устройство === // даём разумное имя для пина, к которому подключен светодиод #define LED_PIN_YELLOW 8 void setup() { // открываем последовательный порт на пинах 1 и 0 // к которому подключён модуль RS-485 Serial1.begin(9600); // 5 пин в режим выхода pinMode(LED_PIN_YELLOW, OUTPUT); } void loop() { // если появились данные с модуля RS-485 if (Serial1.available() > 0) { // считываем char c = Serial1.read(); // если символ равен 'a' if (c == 'a') { // зажигаем светодиод digitalWrite(LED_PIN_YELLOW, HIGH); } else if (c == 'b') { // если символ равен 'b' // гасим светодиод digitalWrite(LED_PIN_YELLOW, LOW); } } } При нажатии на кнопку — светодиод загорится, при повторном — погаснет. ==== Сложная сеть ==== Добавьте в сеть ещё одно устройство //Slave 2//. Соедините контакты питания ''V'' и ''G'' у //Slave 1// и //Slave 2//. Так устройство //Slave 2// будет получать не только данные, но и питание от //Slave 1//. Подключите к //Master// ещё одну [[amp>product/troyka-button?utm_source=man&utm_campaign=rs485&utm_medium=wiki | кнопку (Troyka-модуль)]] к пину ''A3'', а к //Slave 2//[[amp>product/troyka-led-module?utm_source=man&utm_campaign=rs485&utm_medium=wiki | светодиод «Пиранья» (Troyka-модуль)]] к ''8'' пину. {{ :продукты:troyka-rs485:troyka-rs485_scheme_example2.1.png?nolink |}} При передаче питания по сети длинна провода между источником питания и приёмникам не должна превышать 50 метров. Прошейте устройства этими скетчами. === Ведущее устройство === // даём разумное имя для пинов, к которым подключены кнопки #define BUTTON_PIN_YELLOW A4 #define BUTTON_PIN_BLUE A3 // была ли жёлтая кнопка отпущена? boolean buttonStateYellow = true; // была ли синяя кнопка отпущена? boolean buttonStateBlue = true; // состояние жёлтого светодиода boolean ledStateYellow = false; // состояние синего светодиода boolean ledStateBlue = false; void setup() { // открываем последовательный порт на Serial Serial.begin(9600); // открываем последовательный порт на пинах 1 и 0 Serial1.begin(9600); // 5 пин в режим выхода pinMode(5, OUTPUT); // подаём высокий уровень на 5 пин // значит устройство будет передавать данные digitalWrite(5, HIGH); } void loop() { // отпущена ли кнопка прямо сейчас boolean buttonStateNowYellow = digitalRead(BUTTON_PIN_YELLOW); boolean buttonStateNowBlue = digitalRead(BUTTON_PIN_BLUE); // если кнопка была отпущена и не отпущена сейчас if (buttonStateYellow && !buttonStateNowYellow) { delay(10); // считываем сигнал снова buttonStateNowYellow = digitalRead(BUTTON_PIN_YELLOW); if (!buttonStateYellow) { // если она всё ещё нажата // значит это клик! Инвертируем сигнал светодиода ledStateYellow = !ledStateYellow; if (ledStateYellow) { // посылаем на модули RS-485 символ «a» Serial1.print('a'); } else { // посылаем на модули RS-485 символ «b» Serial1.print('b'); } } } // запоминаем последнее состояние кнопки для новой итерации buttonStateYellow = buttonStateNowYellow; // если кнопка была отпущена и не отпущена сейчас if (buttonStateBlue && !buttonStateNowBlue) { delay(10); // считываем сигнал снова buttonStateNowBlue = digitalRead(BUTTON_PIN_BLUE); if (!buttonStateNowBlue) { // если она всё ещё нажата // значит это клик! Инвертируем сигнал светодиода ledStateBlue = !ledStateBlue; if (ledStateBlue) { // посылаем на модули RS-485 символ «y» Serial1.print('y'); } else { // посылаем на модули RS-485 символ «z» Serial1.print('z'); } } } // запоминаем последнее состояние кнопки для новой итерации buttonStateBlue = buttonStateNowBlue; } === Ведомое устройство 1 === // даём разумное имя для пина, к которому подключен светодиод #define LED_PIN_YELLOW 8 void setup() { // открываем последовательный порт на пинах 1 и 0 // к которому подключён модуль RS-485 Serial1.begin(9600); // 5 пин в режим выхода pinMode(LED_PIN_YELLOW, OUTPUT); } void loop() { // если появились данные с модуля RS-485 if (Serial1.available() > 0) { // считываем char c = Serial1.read(); // если символ равен 'a' if (c == 'a') { // зажигаем светодиод digitalWrite(LED_PIN_YELLOW, HIGH); } else if (c == 'b') { // если символ равен 'b' // гасим светодиод digitalWrite(LED_PIN_YELLOW, LOW); } } } === Ведомое устройство 2 === // даём разумное имя для пина, к которому подключен светодиод #define LED_PIN_BLUE 8 void setup() { // открываем последовательный порт на пинах 1 и 0 // к которому подключён модуль RS-485 Serial1.begin(9600); // 5 пин в режим выхода pinMode(LED_PIN_BLUE, OUTPUT); } void loop() { // если появились данные с модуля RS-485 if (Serial1.available() > 0) { // считываем char c = Serial1.read(); // если символ равен 'y' if (c == 'y') { // зажигаем светодиод digitalWrite(LED_PIN_BLUE, HIGH); } else if (c == 'z') { // если символ равен 'z' // гасим светодиод digitalWrite(LED_PIN_BLUE, LOW); } } } При нажатии на жёлтую кнопку — светодиод загорится на //Slave 1//, при повторном — погаснет. Синяя кнопка аналогично включает и выключает светодиод на //Slave2 //. ===== Примеры работы для Espruino ===== RS-485 (Troyka-модуль) работает в [[https://ru.wikipedia.org/wiki/%D0%94%D1%83%D0%BF%D0%BB%D0%B5%D0%BA%D1%81_(%D1%82%D0%B5%D0%BB%D0%B5%D0%BA%D0%BE%D0%BC%D0%BC%D1%83%D0%BD%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8)|полудуплексном режиме]] — приём и передача идут по одной паре проводов с разделением по времени — один говорит, остальные слушают. Передатчиком может выступать любое устройство в сети. Для этого подайте логическую единицу на пин ''↑↓'' — модуль перейдет в режим передачи. Рассмотрим несколько примеров построение сети на модулях RS-485. ==== Простая сеть ==== Соедините в сеть через RS-485 по двум проводам ''A'' и ''B'' два устройства [[amp>product/iskra-js?utm_source=man&utm_campaign=troyka-barometer-v2&utm_medium=wiki | Iskra JS]] через [[amp>product/arduino-troyka-slot-shield?utm_source=man&utm_campaign=rs485&utm_medium=wiki | Troyka Slot Shield]]. Одно будет передатчиком (//Master//), другое — приёмником (//Slave//). Подключите к //Master// [[amp>product/potentiometer?utm_source=man&utm_campaign=rs485&utm_medium=wiki | потенциометр (Troyka-модуль)]] к пину ''A0''. {{ :продукты:troyka-rs485:troyka-rs485_scheme_iskrajs_example1.png?nolink |}} Прошейте устройства скетчами представленными ниже. === Ведущее устройство === var rs485 = require('@amperka/rs-485').connect({ serial: Serial3, speed: 115200, dirPin: P3, lineEnding: '\n' }); setInterval(function() { var value = Math.round(analogRead(A0) * 100); rs485.println(JSON.stringify({value: value})); }, 500); === Ведомое устройство === // slave var rs485 = require('@amperka/rs-485').connect({ serial: Serial3, speed: 115200, dirPin: P3, lineEnding: '\n' }); var buf = ""; var line = ""; rs485.on('data', function(data) { buf += data; var idx = buf.indexOf("\n"); while (idx >= 0) { line = buf.substr(0, idx); buf = buf.substr(idx + 1); idx = buf.indexOf("\n"); } let device = JSON.parse(line); print("Value " + device.value); }); ==== Сложная сеть ==== Соедините в сеть через RS-485 по двум проводам ''A'' и ''B'' три устройства [[amp>product/iskra-js?utm_source=man&utm_campaign=troyka-barometer-v2&utm_medium=wiki | Iskra JS]] через [[amp>product/arduino-troyka-slot-shield?utm_source=man&utm_campaign=rs485&utm_medium=wiki | Troyka Slot Shield]]. Два будут передатчиками (//Master//), другое — приёмником (//Slave//). Обычно по RS-485 только одно устройство может передавать данные, поэтому если подключено несколько передающих устройств, то каждое должно передавать данные в разное время, такая схема называеться //Multi-master//. К каждому //Master// подключите [[amp>product/potentiometer?utm_source=man&utm_campaign=rs485&utm_medium=wiki | потенциометр (Troyka-модуль)]] к пину ''A0''. {{ :продукты:troyka-rs485:troyka-rs485_scheme_iskrajs_example2.png?nolink |}} Прошейте устройства скетчами представленными ниже. === Ведущее устройство 1 === var rs485 = require('@amperka/rs-485').connect({ serial: Serial3, speed: 115200, dirPin: P3, lineEnding: '\n' }); setInterval(function() { var value = Math.round(analogRead(A0) * 100); rs485.println(JSON.stringify({id: 0, value: value})); }, 200); === Ведущее устройство 2 === var rs485 = require('@amperka/rs-485').connect({ serial: Serial3, speed: 115200, dirPin: P3, lineEnding: '\n' }); setInterval(function() { var value = Math.round(analogRead(A0) * 100); rs485.println(JSON.stringify({id: 1, value: value})); }, 437); === Ведомое устройство === // slave var rs485 = require('@amperka/rs-485').connect({ serial: Serial3, speed: 115200, dirPin: P3, lineEnding: '\n' }); var buf = ""; var line = ""; rs485.on('data', function(data) { buf += data; var idx = buf.indexOf("\n"); while (idx >= 0) { line = buf.substr(0, idx); buf = buf.substr(idx + 1); idx = buf.indexOf("\n"); } let device = JSON.parse(line); print("Devive #" + device.id); print(" - Value " + device.value); }); ===== Элементы платы ===== {{ :продукты:troyka-rs485:troyka-rs485_annotation.png?nolink |}} ==== Микросхема SN65176BDR ==== Микросхема SN65176BDR (MAX485) — это приёмопередатчик на интерфейсе RS-485. RS-485 — один из наиболее распространенных способов передачи сигнала по проводам на длинные расстояния. Устройства в такой сети соединяются витой парой — двумя скрученными проводами. В основе интерфейса RS-485 лежит принцип дифференциальной (балансной) передачи данных — один сигнала передаётся сразу по двум проводам. По одному проводу (условно A) идет оригинальный сигнал, по другому (условно B) — его инверсная копия. Если на одном проводе ''1'', то на другом ''0'' и наоборот. Таким образом, между двумя проводами витой пары всегда есть разность потенциалов: при ''1'' она положительна, при ''0'' — отрицательна. ==== Клеммник интерфейса RS-485 ==== Клеммники под винт предназначены для подключения устройства в шину RS-485 с возможностью передачи питания. ^ Обозначения \\ на клеммнике ^ Назначение ^ | ''A'' и ''B'' |Для подключения дифференциальной пары проводов (шина RS-485)| | ''V'' и ''G'' |Для передачи или приёма питания от других модулей| ==== Troyka контакты ==== //1 группа// * Земля (G) — соедините с землёй микроконтроллера. * Питание (V) — соедините с питанием микроконтроллера. * Сигнальный (RO) — цифровой выход приемопередатчика. Используется для передачи данных в микроконтроллер. Подключите к пину ''RX'' микроконтроллера. //2 группа// * Сигнальный (↑↓) — подключите к сигнальному пину микроконтроллера. Служит для выбора режима модуля — приёмник или передатчик. При высоком уровне — работа на прием, при низком — на передачу. * Не используется. * Сигнальный (DI) — цифровой вход приемопередатчика. Используется для приёма данных из микроконтроллера. Подключите к пину ''TX'' микроконтроллера. ==== Светодиодная индикация ==== ^ Имя светодиода ^ Назначение ^ | RX и TX |Мигают при обмене данными между RS485 и управляющим устройством.| | DIR |Горит, если модуль в режиме передатчика| ==== Обвязка для согласования уровней напряжения ==== Необходима для сопряжения устройств с разными питающими напряжениями. В нашем случае это может быть управляющая плата Iskra JS с ''3,3'' вольтовой логикой и RS485(Troyka-модуль) с ''5'' вольтовой логикой. ===== Принципиальная и монтажная схемы ===== {{:продукты:troyka-rs485:troyka-rs485_schematic.png?direct&350 |}} {{ :продукты:troyka-rs485:troyka-rs485_layout.png?direct&300|}} ===== Характеристики ===== * Напряжение питания: 3,3–5 В * Потребляемый ток: 10 мА * Максимальное расстояние связи: 1200 м * Максимальное количество узлов в сети: 32 * Интерфейс: последовательный порт (UART) * Чип RS-485: SN65176BDR (MAX485) * Габариты: 25,4×25,4 мм ===== Ресурсы ===== * [[js:rs-485|Описание библиотеки для Iskra JS]] * {{:продукты:troyka-rs485:sn75176b.pdf|Datasheet на SN65176BDR}} * [[http://masters.donntu.org/2004/fema/kovalenko/library/art7.html|Подробнее об интерфейсе RS-485]]