====== 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]]