Ардуино

Arduino RS-485: Подключение, описание и примеры с кодами

Интерфейс RS-485

RS-485 является одним из наиболее распространенных интерфейсов передачи данных.

Для передачи сигнала используется всего два провода. Обычно применяется витая пара UTP, но можно использовать и простой кабель. Ну, а связка Arduino и RS-485 открывает большие возможности в различных DIY проектах.

Интересные факты о RS-485

Максимальная длина линии интерфейса RS-485 составляет 1200 метров и подключить к одному кабелю можно до 32 устройств. Предком интерфейса RS-485 является RS-232.

Преимущество связки Arduino RS-485

  • Длина линии связи, которая может достигать 1200 метров.
  • Подключение к одной линии до 32 устройств.
  • Помехоустойчивость.
  • Простота реализации.
  • Любая Arduino может быть ведущим или ведомым устройством.

Недостатки RS-485

  • Скорость уменьшается с увеличением длины провода.
  • Полудуплексный режим, то есть прием и передача производится по одной паре проводов.

RS-485 на практике

При передачи данных на расстояние от 500 метров потребуется экранированный UTP кабель. Скорость может снизиться до 50 Кбит/с, но этого вполне достаточно для передачи показаний с датчиков.

Схема подключения Arduino по RS-485

Для подключения плат Arduino по интерфейсу RS-485 потребуется конвертирующий модуль на базе MAX485. Это

Модуль TTL to RS-485
Преобразователь логики Arduino в RS-485

Схема соединения двух Arduino UNO

Схема подключения RS-485 к RS-485
Подключение Arduino к Arduino через 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

Теперь платы 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++]='
#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); } } } }
'; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }

Код программы для второй платы 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++]='
#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); } } } }
'; if( !strcmp(buffer, "ping") ){ digitalWrite(13, state); state = !state; digitalWrite(SerialTxControl, RS485Transmit); Serial.print("pong"); delay(10); digitalWrite(SerialTxControl, RS485Receive); } } } }

Разновидности микросхем RS-485

Существуют различные микросхемы RS-485 – MAX485, ADM485, SP485, SN75176. Функциональные возможности которых идентичны, назначения выводов совершенно одинаковые.

Микросхемы представлены в SOIC-8 и DIP-8 корпусах.

Защита от помех

  1. Снижение скорости передачи данных повышает помехоустойчивость. Не устанавливайте скорость большую, чем требуется для нормального функционирования системы.
  2. Не прокладывайте сигнальный кабель вместе или вблизи силовых кабелей.
  3. В промышленных зонах рекомендуется применять экранированную витую пару с последующем заземлением экрана.
  4. Использование индуктивных фильтров для избавления системы от высокочастотных помех.

Заключение

Интерфейс 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

Вячеслав Ким

Привет, меня зовут Вячеслав. Я создаю электронные устройства, иногда печатаю на 3D принтере, режу  лазером и веду канал на YouTube. А в этом блоге, я пишу про микроэлектронику, Arduino и робототехнику.

View Comments

  • Скажите, будет ли интересна статья про подключение Датчика температуры и влажности к Arduino, который поддерживает интерфейс RS-485?

    Есть ещё релейные модули, которые могут управлять нагрузкой, моторами, светом, розетками.

Share
Published by
Вячеслав Ким

Recent Posts

Контроллер автоматической подсветки лестницы «Laika Pro»

Промо страница контроллера "Laika" Обновленный контроллер "Laika Pro" на 28 каналов Датчики движения (обнаружения) Миниатюрный…

4 years ago

Создаем аппарат ИВЛ в Кыргызстане

Меня зовут Вячеслав Ким. Я являюсь выпускником Alumni программы IVLP США. Входя в группу по…

4 years ago

We are making an ALV unit in Kyrgyzstan

My name is Vyacheslav Kim, a US IVLPA program alumni. Being a part of working…

4 years ago

DFPlayer Mini – Обзор и описание MP3 модуля для Arduino

Введение DFPlayer Mini - это миниатюрный MP3 проигрыватель для плат Arduino. Недорогой MP3 модуль может работать без…

4 years ago

Счетчик YouTube подписчиков на ESP8266 и OLED дисплее

Что это за устройство? Если у вас есть канал на Youtube и вы почти популярны,…

4 years ago

Копилка со счетчиком монет на Arduino с OLED дисплеем

https://www.youtube.com/watch?v=lyBiI67T2Zw <pre class="lang:arduino decode:true " > /* Created 2017 Remixed from AlexGyver */ //-------НАСТРОЙКИ--------- #define…

4 years ago