В предыдущей статье на нашем сайте мы рассмотрели проект последовательной связь по протоколу Modbus RS-485 с Arduino (ведомой), в которой плата Arduino выполняла роль ведомого устройства (Slave) и принимала команды от компьютера по протоколу Modbus RS-485. В этой же статье мы рассмотрим аналогичную задачу, но плата Arduino будет выполнять роль ведущего устройства (Master) и передавать данные по протоколу Modbus RS-485 компьютеру, который будет выполнять роль ведомого устройства.
Что такое Modbus
Modbus — протокол, работающий по принципу «клиент-сервер». Широко применяется в промышленности для межмашинного взаимодействия и не только. Протокол Modbus был разработан в 1979 году. Modbus может использоваться для передачи данных через последовательные линии связи RS-485, RS-422, RS-232, а также через сети TCP/IP. В данной статье мы рассмотрим его использование на примере линии RS-485. Достаточно подробно протокол Modbus описан в соответствующей статье Википедии.
Modbus RS-485 использует линию последовательной связи RS-485 для передачи данных. Modbus является программным (не аппаратным) протоколом и состоит из двух частей: Modbus Master (ведущий) и Modbus Slave (ведомый). В сети Modbus RS-485 может быть один ведущий и 127 ведомых устройств, каждое из которых имеет уникальный адрес от 1 до 127.
Modbus чаще всего используется в программируемых логических контроллерах (PLCs — Programmable Logic Controllers). Но также он широко применяется в медицине, транспорте, проектах автоматизации дома и т.п. Modbus имеет 255 функциональных кодов. Наиболее распространены 3 версии данного протокола:
- MODBUS RTU;
- MODBUS ASCII;
- MODBUS/TCP.
Какая разница между протоколами Modbus ASCII и Modbus RTU? По сути, это практически одинаковые протоколы. Только в протоколе Modbus RTU данные передаются последовательно в двоичном коде, а в Modbus ASCII – в ASCII кодах. В этом проекте мы будем использовать Modbus RTU.
В данной статье мы будем использовать последовательную связь по протоколу Modbus RS-485 используя плату Arduino Uno в качестве ведомого устройства (Slave). Мы установим программное обеспечение Simply Modbus Master Software на компьютер и будем управлять двумя светодиодами и сервомотором, подключенными к ведомой плате Arduino. Управлять ими мы будем при помощи передачи специальных значений от Master Modbus Software.
Перед изучением данного проекта вам желательно прочитать статью о последовательной связи с помощью RS-485 между платами Arduino Uno и Arduino Nano. Также мы рассматривали и связь с помощью RS-485 между платами Arduino Uno и Raspberry Pi.
Принципы работы интерфейса последовательной связи 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) |
Как видите, контакты на модуле RS-485 расположены очень логично — с одной стороны к модулю подключается устройство, а с другой — линия.
Модуль преобразования USB в RS-485
На представленном рисунке показан внешний вид адаптера (модуля преобразования) USB в RS-485. Он способен работать в различных операционных системах и обеспечивает интерфейс RS-485 при помощи использования одного из COM портов компьютера. Этот модуль является устройством plug-and-play. Все, что передается через виртуальный COM порт, автоматически преобразуется данным модулем в RS-485, и наоборот. Модуль питается от порта USB – никакого дополнительного питания не требуется.
В компьютере он виден как последовательный/ COM порт и доступен для использования различными приложениями. Модуль обеспечивает полудуплексную связь с помощью интерфейса RS-485. Скорость передачи – от 75 до 115200 бод/с, максимальная – до 6 Мбит/с.
В сети интернет можно найти достаточно много программного обеспечения, способного работать с данным адаптером. Мы в этом проекте будем использовать программу Modbus Slave.
Программное обеспечение Modbus Slave
Программное обеспечение Modbus Slave можно скачать по следующей ссылке (перейдите на открывшемся сайте на вкладку download). Оно позволяет принимать значения (данные) от любого ведущего устройства, работающего по протоколу Modbus, с использованием порта последовательной связи. Подробную информацию о данном программном обеспечении можно прочитать по следующей ссылке.
Перед использованием данной программы необходимо ознакомиться со следующими терминами, используемыми в ней.
Slave ID (идентификатор ведомого)
Каждому ведомому устройству в сети назначается уникальный адрес в диапазоне от 1 до 127. Когда ведущее устройство запрашивает данные, то первый байт, который он передает, содержит адрес ведомого устройства. Благодаря этому каждое ведомое устройство знает стоит ли ему отвечать на этот запрос или нет.
Регистры Modbus
Регистры флагов (Coils) хранят однобитные значения — то есть могут находится в состоянии 0 или 1. Такие регистры могут обозначать текущее состояние выхода (включено реле). Название «coil» буквально и означает обмотку-актюатор электромеханического реле. Регистры флагов допускают как чтение, так и запись. Имеют номера от 1 до 9999.
Дискретные входы (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например, подано напряжение — 1). Эти регистры поддерживают только чтение. Имеют номера от 10001 до 19999.
Регистры ввода (Input Registers) – 16-битные регистры, используемые для ввода информации. Эти регистры поддерживают только чтение. Имеют номера от 30001 до 39999.
Регистры хранения (Holding Registers) представлены двухбайтовым словом и могут хранить значения от 0 до 65535 (0x0000 — 0xFFFF). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). Имеют номера от 40001 до 49999.
Function code (функциональный код)
Второй байт, передаваемый ведущим, содержит функциональный код. Этот код определяет действие, которое необходимо выполнить (считать, записать и т.д.). Действия сгруппированы по таблицам. В протоколе Modbus существует четыре таблицы с данными:
Таблица | Тип элемента | Тип доступа |
Дискретные входы (Discrete Inputs) | один бит | только чтение |
Регистры флагов (Coils) | один бит | чтение и запись |
Регистры ввода (Input Registers) | 16-битное слово | только чтение |
Регистры хранения (Holding Registers) | 16-битное слово | чтение и запись |
В реальной практике чаще всего встречаются устройства, в которых есть только таблица Holding Registers, иногда объединённая с таблицей Input Registers.
Для доступа к этим таблицам существует ряд стандартный функций ModBus:
Чтение:
- 1 (0x01) — чтение значений из нескольких регистров флагов (Read Coil Status).
- 2 (0x02) — чтение значений из нескольких дискретных входов (Read Discrete Inputs).
- 3 (0x03) — чтение значений из нескольких регистров хранения (Read Holding Registers).
- 4 (0x04) — чтение значений из нескольких регистров ввода (Read Input Registers).
Запись одного значения:
- 5 (0x05) — запись значения одного флага (Force Single Coil).
- 6 (0x06) — запись значения в один регистр хранения (Preset Single Register).
Запись нескольких значений:
15 (0x0F) — запись значений в несколько регистров флагов (Force Multiple Coils)
16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)
Наиболее часто используемые на практике функции (функциональные коды) ModBus это 3, 6 и 16 («Read Holding Registers», «Preset Single Register» и «Preset Multiple Registers» — соответственно).
CRC
CRC расшифровывается как Cyclic Redundancy check и переводится как “циклический избыточный код”. Это два байта, которые добавляются к каждому передаваемому сообщению протокола Modbus для обнаружения ошибок.
Необходимые компоненты
Аппаратное обеспечение
- Плата Arduino Uno (купить на AliExpress).
- MAX485 TTL to RS485 Converter Module (модуль преобразования логики TTL в RS485) ( купить на AliExpress).
- USB to RS-485 Converter Module (преобразователь USB в RS-485) ( купить на AliExpress).
- Кнопка – 2 шт.
- Резистор 10 кОм – 2 шт. (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Потенциометр 10 кОм – 2 шт. (купить на AliExpress).
Программное обеспечение
Схема проекта
Схема для последовательной связи по протоколу Modbus RS-485 с платой Arduino (ведущей) представлена на следующем рисунке.
Arduino Uno | Модуль MAX485 TTL to RS485 |
0(RX) | RO |
1(TX) | DI |
3 | DE |
2 | RE |
+5V | VCC |
GND | GND |
В следующей таблице представлены необходимые соединения между модулями MAX485 TTL to RS485 и USB to RS-485.
MAX485 TTL to RS485 | USB to RS-485 (подключен к компьютеру) |
A | A |
B | B |
В следующей таблице представлены необходимые соединения между платой Arduino Uno и ЖК дисплеем 16х2.
ЖК дисплей 16х2 | Плата Arduino Uno |
VSS | GND |
VDD | +5V |
V0 | к потенциометру для управления яркостью/контрастностью дисплея |
RS | 8 |
RW | GND |
E | 9 |
D4 | 10 |
D5 | 11 |
D6 | 12 |
D7 | 13 |
A | +5V |
K | GND |
Две кнопки с подтягивающими резисторами 10 кОм подключены к контактам 4 и 5 платы Arduino. Со среднего контакта потенциометра 10 кОм подается напряжение на аналоговый контакт A0 платы Arduino.
После сборки схемы у нас получилась конструкция следующего вида.
Объяснение программы для Arduino, работающей в качестве ведущего устройства в Modbus
Для того, чтобы плата Arduino могла работать в качестве ведущего устройства в протоколе Modbus, мы будем использовать библиотеку Modbus Master. В нашем проекте к плате Arduino Uno подключены две кнопки и потенциометр чтобы с их помощью передавать данные ведомому устройству Modbus (в нашем случае программе Modbus Slave).
Библиотека <ModbusMaster.h> используется для связи по протоколу Modbus RS-485 ведущим или ведомым устройством с помощью протокола RTU. Скачать библиотеку можно по следующей ссылке. Добавьте ее в Arduino IDE при помощи Sketch->include library->Add .zip Library (zip файл этой библиотеки можно скачать по этой ссылке).
Полный код программы и видео, демонстрирующее работу проекта, приведены в конце данной статьи. Здесь же мы рассмотрим основные фрагменты кода программы.
Первым делом в программе необходимо подключить библиотеки для работы с протоколом Modbus и ЖК дисплеем.
1 2 |
#include <ModbusMaster.h> #include <LiquidCrystal.h> |
Дадим осмысленные имена контактам платы Arduino, к которым подключен модуль MAX485 TTL to RS-485.
1 2 |
#define MAX485_DE 3 #define MAX485_RE_NEG 2 |
Инициализируем объект node класса ModbusMaster.
1 |
ModbusMaster node; |
Запрограммируем две функции (preTrasnmission() и postTrasmission()) чтобы подавать на контакты RE и DE модуля MAX485 TTL to RS-485 напряжение высокого (high) или низкого (low) уровня для того чтобы разрешить передачу или прием данных.
1 2 3 4 5 6 7 8 9 10 |
void preTransmission() { digitalWrite(MAX485_RE_NEG, 1); digitalWrite(MAX485_DE, 1); } void postTransmission() { digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0); } |
Далее в функции void setup () сконфигурируем ЖК дисплей для работы в режиме 16×2, покажем на нем приветственное сообщение и затем очистим его.
1 2 3 4 5 6 7 8 9 |
lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); delay(3000); lcd.clear(); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("Modbus Master"); delay(3000); lcd.clear(); |
Контакты RE и DE установим в режим работы на вывод данных (OUTPUT), а контакты 4 и 5 (к ним подключены кнопки) – в режим работы на ввод данных (INPUT).
1 2 3 4 5 |
pinMode(MAX485_RE_NEG, OUTPUT); pinMode(MAX485_DE, OUTPUT); pinMode(4,INPUT); pinMode(5,INPUT); |
Первоначально на контакты DE и RE модуля MAX-485 TTL to RS-485 подадим напряжение низкого уровня (LOW).
1 2 |
digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0); |
Установим скорость передачи для последовательной связи 115200 бод и инициализируем последовательную связь по протоколу Modbus с ведомым устройством с адресом 1 (slave ID).
1 2 |
Serial.begin(115200); node.begin(1, Serial); |
После этого проверим правильно ли сконфигурирован приемопередатчик RS-485.
1 2 |
node.preTransmission(preTransmission); node.postTransmission(postTransmission); |
Далее в функции void loop() выполним следующие действия.
1. Сначала считаем значение напряжения с аналогового контакта A0 – к нему подключен потенциометр.
1 |
float value = analogRead(A0) |
2. Затем значение с выхода АЦП (аналого-цифрового преобразователя) запишем в регистр 0x40000 чтобы передать его ведомому устройству (Slave) Modbus.
1 |
node.writeSingleRegister(0x40000,value); |
3. После этого отобразим данное значение на экране ЖК дисплея 16×2.
1 2 3 |
lcd.setCursor(0,0); lcd.print("POT Val :"); lcd.print(value); |
4. Далее считаем состояние двух кнопок.
1 2 |
int a= digitalRead(4); int b= digitalRead(5); |
5. Затем, если первая кнопка нажата, то для передачи в ведомое устройство Modbus запишем в регистр 0x40001 значение 1, а если отжата, то значение 0. Аналогично, если вторая кнопка нажата, то для передачи в ведомое устройство Modbus запишем в регистр 0x40002 значение 1, а если отжата, то значение 0.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
if (a == 1) { node.writeSingleRegister(0x40001,1); lcd.setCursor(0,1); lcd.print("S1: 1"); } else { node.writeSingleRegister(0x40001,0); lcd.setCursor(0,1); lcd.print("S1: 0"); } if (b == 1) { node.writeSingleRegister(0x40002,1); lcd.setCursor(8,1); lcd.print("S2: 1"); } else { node.writeSingleRegister(0x40002,0); lcd.setCursor(8,1); lcd.print("S2: 0"); } |
Тестирование работы проекта
После того, как схема собрана и программа загружена в плату Arduino Uno, подсоедините адаптер USB в RS-485 к компьютеру, на котором установлена программа Modbus Slave.
Примечание: откройте диспетчер устройств в Windows и определите COM порт, к которому подключен адаптер USB в RS-485. После этого запустите программу Modbus Slave.
1. При первоначальном запуске в программе Modbus Slave будет гореть надпись No Connection (нет соединения).
2. Откройте пункт меню Open Connection->Connect как показано на следующем рисунке.
3. Появится диалоговое окно, в котором вас попросят ввести регистрационный ключ. Поскольку это trial (пробная) версия программы, то нажмите Register Later.
4. Пробная версия программы будет работать в течение 10 минут после ее запуска.
5. В программе необходимо сделать следующие настройки соединения:
- в качестве соединения (Connection) выберите Serial Port (последовательный порт);
- выберите COM порт, к которому подключен адаптер USB в RS-485;
- в настройках последовательного соединения укажите: скорость – 115200 (такую мы использовали в программе для Arduino), 8 бит данных, нет бита четности, 1 стоповый бит, режим (Mode) – RTU.
После этого нажмите OK.
6. После этого надпись No connection исчезнет. Откройте пункт меню Setup->Slave Definition.
7. В качестве Slave ID (адреса ведомого) введите 1, а в качестве функционального кода (function) выберите “03 Holding Register”. В поле адреса введите 0 и после этого нажмите OK.
8. После этого проверьте, что ID у вас 1, а F – 03. В этом проекте мы используем 3 регистра: 0 – значение с выхода потенциометра (после АЦП), 1 – состояние первой кнопки, 2 – состояние второй кнопки.
9. Нажмите кнопку 2 – вы увидите что в третьей строке появится значение 1. Поскольку кнопка 1 не нажата, то во второй строке будет значение 0, а в первой строке будет отображаться некоторое значение, характеризующее текущее сопротивление потенциометра.
10. Если вы нажмете кнопку 1, то значение 1 появится во второй строке.
11. Если вы нажмете обе кнопки, то значение 1 будет и во второй, и в третьей строке.
12. Когда вы будете вращать ручку потенциометра будет изменяться значение в первой строке.
Исходный код программы (скетча)
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include <ModbusMaster.h> //библиотека для ModbusMaster #include <LiquidCrystal.h> //библиотека для работы с ЖК дисплеем #define MAX485_DE 3 #define MAX485_RE_NEG 2 ModbusMaster node; //объект node класса ModbusMaster LiquidCrystal lcd(8,9,10,11,12,13); //Object lcd for class Liquidcrystal with LCD pins (RS, E, D4, D5, D6, D7) that are connected with Arduino UNO. void preTransmission() //функции для установки состояния контактов DE & RE модуля RS-485 { digitalWrite(MAX485_RE_NEG, 1); digitalWrite(MAX485_DE, 1); } void postTransmission() { digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0); } void setup() { lcd.begin(16,2); lcd.print("CIRCUIT DIGEST"); delay(3000); lcd.clear(); lcd.print("Arduino"); lcd.setCursor(0,1); lcd.print("Modbus Master"); delay(3000); lcd.clear(); pinMode(MAX485_RE_NEG, OUTPUT); pinMode(MAX485_DE, OUTPUT); pinMode(4,INPUT); pinMode(5,INPUT); digitalWrite(MAX485_RE_NEG, 0); digitalWrite(MAX485_DE, 0); Serial.begin(115200); //скорость передачи 115200 бод node.begin(1, Serial); //Slave ID (адрес ведомого) - 1 node.preTransmission(preTransmission); //Callback for configuring RS-485 Transreceiver correctly node.postTransmission(postTransmission); } void loop() { float value = analogRead(A0); node.writeSingleRegister(0x40000,value); //записываем value в 0x40000 holding register lcd.setCursor(0,0); lcd.print("POT Val :"); lcd.print(value); int a= digitalRead(4); //считываем состояния кнопок int b= digitalRead(5); if (a == 1) { node.writeSingleRegister(0x40001,1); // записываем 1 в 0x40001 holding register lcd.setCursor(0,1); lcd.print("S1: 1"); } else { node.writeSingleRegister(0x40001,0); // записываем 0 в 0x40001 holding register lcd.setCursor(0,1); lcd.print("S1: 0"); } if (b == 1) { node.writeSingleRegister(0x40002,1); // записываем 1 в 0x40002 holding register lcd.setCursor(8,1); lcd.print("S2: 1"); } else { node.writeSingleRegister(0x40002,0); // записываем 0 в 0x40002 holding register lcd.setCursor(8,1); lcd.print("S2: 0"); } } |
35 ответов к “Последовательная связь по протоколу Modbus RS-485 с Arduino (ведущей)”
Подскажите, а как опросить несколько датчиков с разными ID .
node.begin(ID, Serial); //Slave ID (адрес ведомого) — 1, Slave ID (адрес ведомого) — 2
Не могу понять как это будет в коде.
Ну указывайте непосредственно Slave ID. Например:
node.begin(1, Serial);
node.begin(2, Serial);
Пример для ID = 2 можно здесь посмотреть — https://github.com/syvic/ModbusMaster/blob/master/examples/Basic/Basic.pde
Но там немного по другому сделано
Указанная библиотека от Syvic не имеет вызовов node.preTransmission(preTransmission) и node.postTransmission(postTransmission). И скетч не компилируется, выкидывая кучу ошибок.
Эти вызова есть в библиотеке ModbusMaster-4-20, с этой библой все компилируется.
Проверяйте прежде чем переписывать статью с других сайтов.
Хорошо, спасибо за конструктивный комментарий
Долго пытался начать изучать Modbus, ничего не получалось. Наткнулся на Вашу статью, все доходчиво, понятно, разложено по полочкам. В языке С я не разбираюсь, но мне понравилось что коммента
рии на русском языке. Просто скопировал,залил скетч. Все скомпилировалось, я даже не ожидал. Загрузил
скетч,собрал схему,скачал, установил Modbus Slave. Все получилось. Огромная благодарность!
Спасибо и вам что оценили мой труд
Здравствуйте !
Очень хорошая статья. Спасибо автору !
Пробовал передавать один параметр с помощью функции node.writeSingleRegister(ADR,DAN); все работает, а как правильно пользоваться функцией node.writeMultipleRegister(???); для передачи нескольких данных разобраться не смог и в статье нет примера с этой функцией. Подскажите как правильно пользоваться функцию node.writeMultipleRegister(???); ?
Добрый день. К сожалению, пока не могу вам помочь потому что нахожусь в отпуске. Если проблема будет для вас еще актуальна, напишите дней через 10, попытаюсь помочь
Здравствуйте ! Спасибо что ответили. Отдыхайте, напишу позднее если не разберусь.
Хорошо
этот не ответит, он видосы с ютуба в виде статей оформляет)
Это что вы имеете ввиду? Я уже много кому отвечал в комментариях на сайте, посмотрите внимательнее. И попрошу без оскорблений
А если все таки не компилируется код , даже с заменой библиотеки выдает ошибки, Arduino Nano
Arduino: 1.8.19 (Windows 10), Плата:»Arduino Nano, ATmega328P (Old Bootloader)»
D:\Users\s\Documents\Arduino\sketch_may26a\sketch_may26a.ino: In function ‘void setup()’:
sketch_may26a:27:23: error: no matching function for call to ‘ModbusMaster::begin(int, HardwareSerial&)’
node.begin(1, Serial); //Slave ID (адрес ведомого) — 1
no matching function for call to ‘ModbusMaster::begin(int, HardwareSerial&)’
Загрузить получилось на другом компьютере код программы, но данные не приходят( в окне монитора Arduino квадратики, а в программе Modbus Pool все по нулям и Timeout error , может где то надо настроить время опроса ?
А почему вы используете программу Modbus Pool, а не Modbus Slave как в статье? Про время опроса не знаю, не изучал данный вопрос. Вы пока первый кто это спросил. Может быть вы бы сначала попробовали изучить Modbus, начав с использования Arduino в качестве ведомой — данная статья более популярна на нашем сайте чем эта. И там в комментариях к ней описано решение ряда проблем с «железом», из-за которых проект может не работать. Может быть, и у вас наблюдается какая-нибудь из этих аппаратных ошибок?
Добрый день! Всё сделал по инструкции, с этой библиотекой(https://github.com/4-20ma/ModbusMaster) всё скомпилировалось, правда с ошибкой warning:
large integer implicitly truncated to unsigned type [-Woverflow]
node.writeSingleRegister(0x40002, 0); // записываем 0 в 0x40002 holding register
Но не работает. Замыкаю кнопку — сообщение в COM порт выводится, в RS485 тишина, пока мониторинг COM порта не открываю не мигают даже диоды TX-RX. Сделал контроль нажатия диодом 13, с ним всё ок. Зато в мониторинг COM выводятся квадраты при нажатии — отжатии кнопки(), как Я понимаю это должна быть моя команда RS.Подскажите, пожалуйста, может Я не на тот COM посылаю сигнал RS? Если так, то как его поменять?
Разобрался, для таких же новичков как Я подскажу. Возможно нужно будет написать Serial1, а не Serial чтоб использовать именно RX TX, а не USB
Спасибо за совет. Надеюсь он поможет начинающим в этой тематике
Добрый день.
Возможно ли редактировать такие параметры связи как контроль четности, количество стоп бит и длина данных? В тексте программы я этого не увидел. По всей видимости они такие: данные — 8 бит; контроль четности — нет; количество стоп бит — 1. Мне нужно установить количество стоп бит — 2. как это можно сделать?
Спасибо
Добрый вечер, Леонид.
Настройка параметров связи последовательного порта в программе Modbus Slave показана в пункте 5 раздела «Тестирование работы проекта» настоящей статьи. Как производить «тонкую» настройку параметров последовательного порта (количество стоповых бит, битов четности, режим связи и т.д.) средствами Ардуино я не знаю, но в любом случае их можно настроить, используя внутри программы для Arduino инструкции для непосредственной настройки регистров микроконтроллера AVR (а он является основой платы Arduino), отвечающих за работу с последовательным портом — это регистры USART и UBR. Как это сделать подробно описано в этой статье — связь AVR ATmega8 и Arduino Uno через UART.
доброго дня!
не компилируется из за ошибки в строке:
node.begin(1, Serial); //Slave ID (адрес ведомого) — 1
и тут: lcd.begin(16,2);
если убрать значения то компиляция проходит.
нашел другую библиотеку эти ошибки ушли >> /4-20ma/ModbusMaster
но появились ошибки дальше… разбираю!
Спасибо за статью!
В общем все работает! Главное внимательно читать материал или посмотреть видео.
Вся загвоздка была в библиотеке. В остальном, для новичков, нужно все таки не просто копировать что пишут, а понимать зачем. Тогда вопросов будет меньше.
И вам спасибо что оценили мой труд. Да, желательно в любом случае понимать суть кода потому что некоторые старые коды для Ардуино могут не работать из-за того что авторы библиотек немного изменили их код с тех времен. Поэтому у нас на сайте почти ко всем кодам представленных программ имеются пояснения
node.begin(1, Serial); //Slave ID (адрес ведомого) — 1
node.preTransmission(preTransmission); //Callback for configuring RS-485 Transreceiver correctly
node.posrTransmission(postTransmission);
на вот это все компилятор ругается на Mega
Павел, к сожалению, пока не могу дать корректный ответ на ваш вопрос по причине своего нахождения в отпуске. Когда приеду, тогда могу попробовать сделать попытку разобраться в вашей проблеме если она к тому времени будет ещё актуальна
Павел, я пока нахожусь в отпуске и, к сожалению, отсюда не могу помочь вам с вашей проблемой
в статье не верные ссылки на библиотеки!
Вот правильные библиотеки, на которых код в статье написан
https://github.com/4-20ma/ModbusMaster
Почему вы считаете что приведенная вами библиотека лучше? Она от 29.09.2016, а по представленной в статье ссылке (https://github.com/syvic/ModbusMaster) можно скачать версию этой библиотеки от другого автора, датированной 02.08.2018
Согласен что чем свежее библиотека, тем лучше.
Но код приведённый в данной статье написан под библиотеку от 4-20ma, а не от syvic.
У библиотек операторы отличаются, при выборе библиотеки syvic’a просто не компилируется скетч.
Возможно, способность компиляции кода определяется не только библиотекой, факторов то много. Но все равно спасибо за подсказанную библиотеку, всегда лучше когда есть выбор из нескольких библиотек
Наконец-то отличная статья об Arduino Modbus TCP в режиме Master!
Автору огромное спасибо!
Вопрос по коду:
Если в сети больше 1 slave-устройства?
«node.begin(1, Serial)» — здесь «node» выступает именем устройства или это оператор?
Или каждый раз прерывать связь типа «node.end(1, Serial)» и затем начинать новый сеанс с нужным устройством «node.begin(2, Serial)»?
Да, ошибся Modbus RTU)
при компиляции ошибку выдаёт:
exit status 1
no matching function for call to ‘ModbusMaster::begin(int, HardwareSerial&)’
Может быть, это из-за того что вы использовали не ту библиотеку, которая рекомендована в статье? И где вы такую функцию в коде программы нашли? Что то я не вижу
node — это объект класса ModbusMaster, через него и осуществляются все операции по протоколу Modbus. Насчет вашего вопроса не уверен, но, возможно, что для работы с еще одним slave-устройством понадобится создать еще один объект класса ModbusMaster. Но это не точно, это просто мое предположение