Выбор протокола (интерфейса) связи между микроконтроллером и периферийными устройствами является важной частью встраиваемых систем. От правильности его выбора зависят многие параметры подобной системы: стоимость, скорость передачи данных, максимальное расстояние связи и т.д.
В предыдущих статьях мы изучили использование интерфейса I2C и интерфейса SPI в платах Arduino. В этой же статье мы рассмотрим использование в платах Arduino интерфейса асинхронной последовательной связи RS-485. Основным преимуществом интерфейса RS-485 является большая дистанция связи. Также он обладает хорошей устойчивостью к помехам, благодаря чему находит применение в условиях со сложной (сильно зашумленной) электромагнитной обстановкой.
В данной статье мы рассмотрим обмен данным между двумя платами Arduino с помощью интерфейса RS-485. Мы будем управлять яркостью свечения светодиода, подключенной к ведомой плате Arduino, с ведущей платы Arduino при помощи передачи значений АЦП (аналогово-цифрового преобразования) с помощью модуля RS-485. Для изменения значений АЦП в ведущей плате Arduino мы будем использовать потенциометр 10 кОм.
Принципы работы интерфейса последовательной связи RS-485
RS-485 представляет собой асинхронный интерфейс последовательной связи, не требующий для своей работы импульсов синхронизации. Для передачи двоичных данных от одного устройства к другому интерфейс использует дифференциальный сигнал.
Если следовать определению из википедии, дифференциальный сигнал представляет собой способ электрической передачи информации с помощью двух противофазных сигналов. В данном методе один электрический сигнал передаётся в виде дифференциальной пары сигналов, каждый по своему проводнику, но один представляет инвертированный сигнал другого, противоположный по знаку. Пара проводников может представлять собой витую пару, твинаксиальный кабель или разводиться по печатной плате. Приёмник дифференциального сигнала реагирует на разницу между двумя сигналами, а не на различие между одним проводом и потенциалом земли.
В нашем случае дифференциальный сигнал образуется при помощи использования положительного и отрицательного напряжения 5V. Интерфейс RS-485 обеспечивает полудуплексную связь (Half-Duplex) при использовании 2-х линий (проводов) и полноценную дуплексную связь (Full-Duplex) при использовании 4-х линий (проводов).
Основные особенности данного интерфейса:
- Максимальная скорость передачи данных в интерфейсе RS-485 – 30 Мбит/с.
- Максимальная дистанция связи – 1200 метров, что значительно больше чем в интерфейсе RS-232.
- Основным достоинством интерфейса RS-485 по сравнению с RS-232 является использование нескольких ведомых (multiple slave) при одном ведущем (single master) в то время как RS-232 поддерживает только одного ведомого.
- Максимальное число устройств, которое можно подключить по интерфейсу RS-485 – 32.
- Также к достоинствам интерфейса RS-485 относится хорошая помехоустойчивость вследствие использования дифференциального сигнала.
- RS-485 обеспечивает более высокую скорость передачи по сравнению с интерфейсом I2C.
Использование интерфейса RS-485 в Arduino
Для использования интерфейса RS-485 в плате Arduino мы будем использовать модуль 5V MAX485 TTL to RS485, в основе которого лежит микросхема Maxim MAX485. Модуль является двунаправленным и обеспечивает последовательную связь на расстояние до 1200 метров. В полудуплексном режиме он обеспечивает скорость передачи данных 2,5 Мбит/с.
Модуль 5V MAX485 TTL to RS485 использует питающее напряжение 5V и логический уровень напряжения также 5V, что позволяет без проблем подключать его к платам Arduino.
Данный модуль имеет следующие особенности:
- работает с напряжениями 5V;
- имеет в своем составе чип MAX485;
- отличается низким энергопотреблением;
- всеми его контактами можно управлять с помощью микроконтроллера;
- размеры платы модуля: 44 x 14mm.
Внешний вид модуля RS-485 показан на следующем рисунке.
Назначение контактов (распиновка) модуля RS-485 приведена в следующей таблице.
Название контакта | Назначение контакта |
VCC | 5V |
A | вход/выход линии RS-485 |
B | вход/выход линии RS-485 |
GND | GND (0V) |
R0 | выход приемника (RX pin) |
RE | разрешение работы приемника |
DE | разрешение работы передатчика |
DI | вход передатчика (TX pin) |
Для подключения модуля к платам Arduino (UNO и NANO) мы будем использовать их последовательные порты на контактах 0 (RX) и 1 (TX). Для передачи данных модулю RS-485 мы будем использовать функцию Serial.print(), а для считывания данных из него – функцию Serial.Read() (или аналогичную).
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Плата Arduino Nano (купить на AliExpress).
- MAX485 TTL to RS485 Converter Module (модуль преобразования логики TTL в RS485, купить на AliExpress) – 2 шт.
- Потенциометр 10 кОм (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Светодиод (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
В нашем проекте плата Arduino Uno будет использоваться в качестве ведущей, а плата Arduino Nano – в качестве ведомой.
Схема проекта
Схема для последовательной связи с помощью интерфейса RS-485 между платами Arduino Uno и Arduino Nano представлена на следующем рисунке.
В следующей таблице представлены необходимые соединения между платой Arduino Uno (ведущей) и модулем RS-485.
RS-485 | Arduino Uno |
DI | 1 (TX) |
DE RE | 8 |
R0 | 0 (RX) |
VCC | 5V |
GND | GND |
A | к контакту A ведомого RS-485 |
B | к контакту B ведомого RS-485 |
В следующей таблице представлены необходимые соединения между платой Arduino Nano (ведомой) и модулем RS-485.
RS-485 | Arduino Nano |
DI | 1 (TX) |
DE RE | 8 |
R0 | D0 (RX) |
VCC | 5V |
GND | GND |
A | к контакту A ведущего RS-485 |
B | к контакту B ведущего RS-485 |
В следующей таблице представлены необходимые соединения между платой Arduino Nano и ЖК дисплеем 16х2.
ЖК дисплей 16х2 | Arduino Nano |
VSS | GND |
VDD | +5V |
V0 | к центральному контакту потенциометра для управления контрастностью ЖК дисплея |
RS | D2 |
RW | GND |
E | D3 |
D4 | D4 |
D5 | D5 |
D6 | D6 |
D7 | D7 |
A | +5V |
K | GND |
Потенциометр 10 кОм подключен к аналоговому контакту A0 платы Arduino UNO. Светодиод подключен к контакту D10 платы Arduino Nano.
Объяснения программ для плат Arduino UNO и Arduino Nano
Для программирования обоих плат используется среда Arduino IDE. Убедитесь в том, что вы выбрали правильный порт из пункта меню Tools->Port и правильный тип платы из пункта меню Tools->Board.
Полный код программ приведен в конце статьи, здесь же мы рассмотрим их основные фрагменты. Видео, демонтсрирующее работу проекта, также приведено в конце статьи.
Объяснение программы для платы Arduino UNO (ведущей)
В программе для ведущей стороны нам просто необходимо считывать значение напряжения с выхода потенциометра, подключенного к аналоговому контакту A0 и затем с помощью функции SerialWrite передавать их модулю RS-485 через контакты последовательного порта (0,1) платы Arduino UNO.
Инициализация последовательной связи на контактах (0,1) производится с помощью следующей команды:
1 |
Serial.begin(9600); |
Для считывания аналогового значения на контакте A0 платы Arduino UNO и его сохранения в переменной potval используется команда:
1 |
int potval = analogRead(pushval); |
Перед передачей значения переменной potval по последовательному порту необходимо на контактах DE и RE модуля RS-485 установить напряжение высокого уровня (HIGH). Данные контакты подключены у нас к контакту 8 платы Arduino UNO, поэтому просто используем команду:
1 |
digitalWrite(enablePin, HIGH); |
Далее просто передаем по последовательному порту значение переменной potval.
1 |
Serial.println(potval); |
Объяснение программы для платы Arduino Nano (ведомой)
На ведомой стороне (Slave side) значение переменной целого типа, полученное от ведущего модуля RS-485, можно будет считать на контактах последовательного порта связи (0,1) платы Arduino Nano. Просто считываем эти значения и сохраняем их в переменной. Принятые значения будут в диапазоне 0-1023, поэтому преобразуем их к диапазону 0-255 чтобы управлять яркостью свечения светодиода с помощью широтно-импульсной модуляции (ШИМ).
Затем это конвертированное значение мы с помощью функции AnalogWrite подаем на контакт D10 (является ШИМ-контактом), к оторому подключен светодиод – таким образом мы управляем яркостью его свечения. Также эти значения мы будем показывать на экране ЖК дисплея 16х2.
Для того, чтобы модуль RS-485, подключенный к ведомой плате Arduino, мог принимать эти значения от ведущего модуля, необходимо на его контактах DE и RE установить напряжение низкого уровня (LOW). Для этого просто устанавливаем LOW на контакте D8 (enablePin) платы Arduino Nano.
1 |
digitalWrite(enablePin, LOW); |
Для считывания значения из последовательного порта и сохранения его в переменной используем команду:
1 |
int pwmval = Serial.parseInt(); |
Затем конвертируем это значение из диапазона 0-1023 в диапазон 0-255 и сохраняем полученное значение в переменной:
1 |
int convert = map(pwmval,0,1023,0,255); |
Затем подаем это значение на контакт D10, к которому подключен светодиод:
1 |
analogWrite(ledpin,convert); |
Для отображения этого значения на экране ЖК дисплея 16x2 используем следующую последовательность команд:
1 2 3 4 |
lcd.setCursor(0,0); lcd.print("PWM FROM MASTER"); lcd.setCursor(0,1); lcd.print(convert); |
Тестирование работы проекта
Когда мы с помощью потенциометра будем устанавливать значение ШИМ равное 0, светодиод будет в выключенном состоянии.
А когда с помощью потенциометра мы будем устанавливать значение ШИМ равное 251, светодиод будет гореть с максимальной яркостью.
Исходный код программы (скетча)
Код программы для ведущей платы (Arduino UNO)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
//Master code (Arduino UNO) //Serial Communication Between Arduino using RS-485 int enablePin = 8; int pushval = A0; int potval =0 ; void setup() { Serial.begin(9600); // initialize serial at baudrate 9600: pinMode(enablePin, OUTPUT); pinMode(pushval,INPUT); delay(10); digitalWrite(enablePin, HIGH); // (always high as Master Writes data to Slave) } void loop() { int potval = analogRead(pushval); Serial.println(potval); //Serial Write POTval to RS-485 Bus delay(100); } |
Код программы для ведомой платы (Arduino Nano)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
//Slave code (Arduino NANO) //Serial Communication Between Two Arduinos using RS-485 //Circuit Digest #include <LiquidCrystal.h> //Include LCD library for using LCD display functions int enablePin = 8; int ledpin = 10; LiquidCrystal lcd(2,3,4,5,6,7); // Define LCD display pins RS,E,D4,D5,D6,D7 void setup() { lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); lcd.setCursor(0,1); lcd.print("RS485 ARDUINO"); delay(3000); lcd.clear(); Serial.begin(9600); // initialize serial at baudrate 9600: pinMode(ledpin,OUTPUT); pinMode(enablePin, OUTPUT); delay(10); digitalWrite(enablePin, LOW); // (Pin 8 always LOW to receive value from Master) } void loop() { while (Serial.available()) //While have data at Serial port this loop executes { lcd.clear(); int pwmval = Serial.parseInt(); //Receive INTEGER value from Master throught RS-485 int convert = map(pwmval,0,1023,0,255); //Map those value from (0-1023) to (0-255) analogWrite(ledpin,convert); //PWM write to LED lcd.setCursor(0,0); lcd.print("PWM FROM MASTER"); lcd.setCursor(0,1); lcd.print(convert); //Displays the PWM value delay(100); } } |
Добрый день,
Сообщение для администратора сайта microkontroller.ru
Хотели бы посотрудничать с вашим проектом. Не нашли на сайте контактного емайла или формы обратной связи. Напишите пожалуйста dk@tmelectronics.ru по поводу размещения рекламы на вашем проекте.
Спасибо!
Добрый вечер. Я написал на указанную вами почту
Всем привет! Так как в этой теме я новичок, хотел бы спросить у вас. Можно ли с помощью модуля MAX485 связать Arduino и промышленный модем(iRZ ATM21.А)?
Цель заключается в передаче информации с Arduino через пром. модем по GSM/GPRS.
Условия такие, что сама установка Arduino будет находится там где не ловит сети интернет, только мобильная связь.
Добрый вечер. А ваш промышленный модем iRZ ATM21.А какой протокол для связи использует? Насколько я понимаю, вам здесь модуль MAX485 будет не нужен. Вам будет нужен GSM модуль. Посмотрите на нашем сайте все проекты с GSM модулями, так много проектов где они подключаются к плате Ардуино.
Протокол используется RS-485. Тут проблема заключается в том, что я делаю курсовую работу. И изначально, я думал применить обычный GSM модуль. Но мой руководитель против его использования. Говорит, связь не надежная и лучше использовать какой-то промышленный модем. Вот и встал вопрос, возможно ли как то передавать данные с Arduino по этому модему(iRZ ATM21) где поддерживается протокол RS-485.
Ну тут можно либо очень длинный кабель использовать (вот пример такой статьи), либо использовать, к примеру, модуль LoRa - против него ваш руководитель не против?
Предполагается что сама установка будет находится в очень далеких местах от города, где только ловит мобильная связь. На сколько мне известно у LoRa дистанция доходит до 15км~. Но в условиях где нет интернета этой длины не хватит
Ну тогда получается какое то противоречие: с одной стороны установка находится там, где кроме мобильной связи больше ничего не ловит, но, с другой стороны, мобильную связь для взаимодействия с ней использовать нельзя. Тут я даже не знаю что вам подсказать. Не будете же вы самодельную радиостанцию паять.