RS-485 является одним из наиболее распространенных интерфейсов передачи данных.
Для передачи сигнала используется всего два провода. Обычно применяется витая пара UTP, но можно использовать и простой кабель. Ну, а связка Arduino и RS-485 открывает большие возможности в различных DIY проектах.
Интересные факты о RS-485
Максимальная длина линии интерфейса RS-485 составляет 1200 метров и подключить к одному кабелю можно до 32 устройств. Предком интерфейса RS-485 является RS-232.
RS-485 на практике
При передачи данных на расстояние от 500 метров потребуется экранированный UTP кабель. Скорость может снизиться до 50 Кбит/с, но этого вполне достаточно для передачи показаний с датчиков.
Для подключения плат Arduino по интерфейсу RS-485 потребуется конвертирующий модуль на базе MAX485. Это
Модуль TTL to RS-485
Преобразователь логики Arduino в RS-485
Напомним, что в один момент времени устройство может либо принимать, либо отправлять данные. Для указания устройства в качестве приемника или передатчика на модулях присутствуют контакты DE и RE. Высокий уровень на контактах – режим передатчика, низкий – приёмника.
Программа для передатчика – Она будет отправлять в Serial Port строку “test” один раз в секунду.
Программа для приемника – При появлении в эфире строки “test” будет мигать светодиодом на плате Arduino (13 пин).
#define SerialTxControl 2 // Пин 2 будет переключать режим приёмник/передатчик #define RS485Transmit HIGH #define RS485Receive LOW void setup(void) { Serial.begin(9600); // задаем скорость последовательного порта pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Transmit); // переводим устройство в режим передатчика } void loop(void) { Serial.print("test"); // отправляем текст delay(1000); // Выставляем задержку в 1 секунду }
#define SerialTxControl 2 // Пин 2 будет переключать режим приёмник/передатчик #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; // Переменная для хранения данных из буфера byte state = 0; void setup(void) { Serial.begin(9600); // задаем скорость последовательного порта pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); // переводим устройство в режим приёмника } void loop(void) { int i=0; if( Serial.available() ){ // если в порт пришли какие-то данные delay(5); // немного ждём, чтобы вся пачка данных была принята портом while( Serial.available() ){ buffer[i++] = Serial.read(); // считываем данные и записываем их в буфер } } if(i>0){ // если в буфере что-то есть buffer[i++]='#define SerialTxControl 2 // Пин 2 будет переключать режим приёмник/передатчик #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; // Переменная для хранения данных из буфера byte state = 0; void setup(void) { Serial.begin(9600); // задаем скорость последовательного порта pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); // переводим устройство в режим приёмника } void loop(void) { int i=0; if( Serial.available() ){ // если в порт пришли какие-то данные delay(5); // немного ждём, чтобы вся пачка данных была принята портом while( Serial.available() ){ buffer[i++] = Serial.read(); // считываем данные и записываем их в буфер } } if(i>0){ // если в буфере что-то есть buffer[i++]='\0'; // превращаем содержимое буфера в строку, добавляя нулевой символ if( strcmp(buffer, "test") ){ // если принятая строка равна тексту ping digitalWrite(13, state); // мигаем светодиодом state = !state; } } }'; // превращаем содержимое буфера в строку, добавляя нулевой символ if( strcmp(buffer, "test") ){ // если принятая строка равна тексту ping digitalWrite(13, state); // мигаем светодиодом state = !state; } } }
Теперь платы Arduino буду менять режим приемника/передатчика в момент отправки сообщения.
#define SerialTxControl 2 #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; byte state = 0; void setup(void) { Serial.begin(115200); pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); } void loop(void) { int i=0; if( Serial.available() ){ delay(5); while( Serial.available() ){ buffer[i++] = Serial.read(); } if(i>0){ buffer[i++]='#define SerialTxControl 2 #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; byte state = 0; void setup(void) { Serial.begin(115200); pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); } void loop(void) { int i=0; if( Serial.available() ){ delay(5); while( Serial.available() ){ buffer[i++] = Serial.read(); } if(i>0){ buffer[i++]=''; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }#define SerialTxControl 2 #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; byte state = 0; void setup(void) { Serial.begin(115200); pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); } void loop(void) { int i=0; if( Serial.available() ){ delay(5); while( Serial.available() ){ buffer[i++] = Serial.read(); } if(i>0){ buffer[i++]='\0'; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }'; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }
#define SerialTxControl 2 #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; byte state = 0; void setup(void) { Serial.begin(115200); pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); } void loop(void) { int i=0; if( Serial.available() ){ delay(5); while( Serial.available() ){ buffer[i++] = Serial.read(); } if(i>0){ buffer[i++]='#define SerialTxControl 2 #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; byte state = 0; void setup(void) { Serial.begin(115200); pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); } void loop(void) { int i=0; if( Serial.available() ){ delay(5); while( Serial.available() ){ buffer[i++] = Serial.read(); } if(i>0){ buffer[i++]=''; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }#define SerialTxControl 2 #define RS485Transmit HIGH #define RS485Receive LOW char buffer[100]; byte state = 0; void setup(void) { Serial.begin(115200); pinMode(13, OUTPUT); pinMode(SerialTxControl, OUTPUT); digitalWrite(SerialTxControl, RS485Receive); } void loop(void) { int i=0; if( Serial.available() ){ delay(5); while( Serial.available() ){ buffer[i++] = Serial.read(); } if(i>0){ buffer[i++]='\0'; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }'; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }
Существуют различные микросхемы RS-485 – MAX485, ADM485, SP485, SN75176. Функциональные возможности которых идентичны, назначения выводов совершенно одинаковые.
Интерфейс RS-485 применяется в промышленных системах из-за устойчивости к помехам и возможностью передавать данные на большие расстояния.
Но этот интерфейс нашел применение в домашних системах Умного дома и проектах Arduino по тем же причинам.
RS-485 широко используется с протоколами ModBus и DMX512.
* ModBus – открытый коммуникационный протокол.
* DMX512 – протокол передачи данных между контроллерами и световым оборудованием.
Wikipedia: https://ru.wikipedia.org/wiki/RS-485
Datasheet MAX485: https://datasheets.maximintegrated.com/en/ds/MAX1487-MAX491.pdf
Промо страница контроллера "Laika" Обновленный контроллер "Laika Pro" на 28 каналов Датчики движения (обнаружения) Миниатюрный…
Меня зовут Вячеслав Ким. Я являюсь выпускником Alumni программы IVLP США. Входя в группу по…
My name is Vyacheslav Kim, a US IVLPA program alumni. Being a part of working…
Введение DFPlayer Mini - это миниатюрный MP3 проигрыватель для плат Arduino. Недорогой MP3 модуль может работать без…
Что это за устройство? Если у вас есть канал на Youtube и вы почти популярны,…
https://www.youtube.com/watch?v=lyBiI67T2Zw <pre class="lang:arduino decode:true " > /* Created 2017 Remixed from AlexGyver */ //-------НАСТРОЙКИ--------- #define…
View Comments
Скажите, будет ли интересна статья про подключение Датчика температуры и влажности к Arduino, который поддерживает интерфейс RS-485?
Есть ещё релейные модули, которые могут управлять нагрузкой, моторами, светом, розетками.