Ардуино модбас рту мастер

smarmengol/Modbus-Master-Slave-for-Arduino

Use Git or checkout with SVN using the web URL.

Work fast with our official CLI. Learn more.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

libmodbus is a library that provides a Serial Modbus implementation for Arduino.

A primary goal was to enable industrial communication for the Arduino in order to link it to industrial devices such as HMIs, CNCs, PLCs, temperature regulators or speed drives.

now you can use software serial with the update from Helium6072!

LICENSE.txt GNU Licence file keywords.txt Arduino IDE colouring syntax

/documentation Library documentation generated with Doxygen.

/examples Sample sketches to implement miscellaneous settings:

/examples/advanced_slave Modbus slave node, which links Arduino pins to the Modbus port. /examples/RS485_slave Modbus slave adapted to the RS485 port /examples/simple_master Modbus master node with a single query /examples/simple_slave Modbus slave node with a link array /examples/software_serial_simple_master Modbus master node that works via software serial

Refer to this documentation to Install this library:

Starting with version 1.0.5, you can install 3rd party libraries in the IDE.

Do not unzip the downloaded library, leave it as is.

In the Arduino IDE, navigate to Sketch > Import Library. At the top of the drop down list, select the option to «Add Library».

You will be prompted to select this zipped library.

Return to the Sketch > Import Library menu. You should now see the library at the bottom of the drop-down menu. It is ready to be used in your sketch.

The zip file will have been expanded in the libraries folder in your Arduino sketches directory.

NB : the library will be available to use in sketches, but examples for the library will not be exposed in the File > Examples until after the IDE has restarted.

It is not compatible with ARDUINO LEONARDO and not tested under ARDUINO DUE and newer boards.

Common to Master and Slave:

Implement other Serial settings: parity, stop bits, .

End frame delay, also known as T35

Test it with several Arduino boards: UNO, Mega, etc..

Extend it to Leonardo

Function code 1 and 2 still not implemented

Function code 15 still not implement

Other codes under development

New features by Helium6072 29 July 2016

  1. «port->flush();» changed into «while(port->read() >= 0);»
  1. software serial compatible

New constructor Modbus::Modbus(uint8_t u8id) and method void Modbus::begin(SoftwareSerial *sPort, long u32speed) that makes using software serial possible. Check out sexample «software_serial_simple_master» and learn more!

Источник

Arduino.ru

ModbusRTU, ModbusTCP Arduino и OWEN PLC

  • Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии

ModbusRTU, ModbusTCP Arduino и OWEN PLC

В этой теме я постараюсь описать свои эксперементы с промышленным протоколом Modbus для локальной сети и RS485 мне удалось как управлять ардуиной с ПЛК так и ардуиной управлять плк и модулями вводы вывода от овена.

SimpleModbus — Modbus библиотеки для Ардуино, которые позволяют Вам предавать посылки по последовательному интерфейсу с использованием протокола Modbus RTU. Обе библиотеки SimpleModbusMaster и SimpleModbusSlave поддерживают Modbus функции 3 и 16, кроме того, SimpleModbusMaster поддерживают Modbus функции 1, 2, 4 и 15. Передача поддерживает на обеих библиотеках функции 16 и 15. Обе библиотеки имеют похожий интерфейс. Есть всего две необходимых функции modbus_update () и modbus_configure (). Обе библиотеки были проверены промышленном оборудовании: на отечественном оборудовании PLC OWEN и модулях ввода вывода. Дополнительно библиотека SimpleModbusSlave была проверена с тестером Modbus Poll.

Библиотеки стабильно работают. Вся работа библиотеки выполняется в фоновом режиме. Ваша программа выполнятся без задержек. Примеры и библиотеки хорошо прокомментированы и интуитивно понятны это позволит вам легко создать свой первый проект с Modbus.
Библиотеки написаны с применением объектно-ориентированного подхода, на языке C не используя C ++. Это облегчает портирование программного обеспечения библиотеки на другие платформы, который поддерживают компилятор C.

Библиотека мастера RTU

Библиотека slave RTU

Примеры к библиотекам

Файлы для плк 110 овен

Полное описание библиотеки мастера на английском

Для связи по RS485 я использовал шилд

RS485 Shield для Ардуино. RS485 Shield для Ардуино.
Вот такой шилд я прикупил для своего Ардуино его очень удобно использовать для создания устройств с RS485. Шилд поддерживает управление приёмом передачей в автоматическом и ручном режиме выбор переключателем.

Описание RS485 Shield V1.0

В стандарте RS-485 для передачи и приёма данных используется одна витая пара проводов, иногда сопровождаемая экранирующей оплеткой или общим проводом. Передача данных осуществляется с помощью дифференциальных сигналов.
Разница напряжений между проводниками одной полярности означает логическую единицу, разница другой полярности — ноль.

Особенности
— Питание 5.0 В
— 16 цифровой порт ввода-вывода (в том числе интерфейс I2C)
— 6 аналоговых I/O портов
— Переключатель в режима программирования
— Автоматический / ручной переключатель режима трансивера
— Светодиоды RX TX
— Стандартный интерфейс RS485, мини-интерфейс RS485 (PH2.0) и выводы RS485
— Область для прототипирования
— Кнопка сброса
— Размер 55 x 53 мм

Пример программы для ардуино для работы с шилдом

купить можно на Amperka.ru или Ebey

Пример работы с библиотекой мастера RTU

Пример работы с библиотекой SLAVE RTU

Вот ссылка на библиотеку Modbus TCP я ее кстати прокоментировал но версию с коментариями позже найду и выложу пока в оригенале

позже добавлю еще про ардуино модбус мастер и модуль ввода как slave устройсво

Источник

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 58. Обмен данными между платами Ардуино через UART по протоколу ModBus. Библиотека Tiny_ModBusRTU_Master.

В уроке представлю библиотеку поддержки протокола ModBus для ведущего контроллера. С помощью нее реализую обмен данными между двумя платами Ардуино.

В предыдущем уроке мы разработали локальный контроллер для сети с протоколом ModBus. В качестве ведущего ModBus устройства использовали компьютер. В этом уроке подключим локальный контроллер к другой плате Ардуино. Т.е. реализуем систему из урока 49, только с использованием протокола ModBus.

В предыдущем уроке я представил библиотеку Tiny_ModBusRTU_Slave. Надеюсь, вы оценили, как просто с помощью нее создавать программное обеспечение ведомого ModBus контроллера. В этом уроке я представлю аналог этой библиотеки для ведущего устройства.

Библиотека Tiny_ModBusRTU_Master.

Загрузить библиотеку можно по этой ссылке:

Tiny_ModBusRTU_Master позволяет простыми средствами реализовать программное обеспечение ведущих ModBus контроллеров. Может быть использована совместно с интерфейсами RS-232, RS-422, RS-485, UART и т.п. Поддерживает управление состоянием передатчика в шинных интерфейсах, например в RS-485.

Библиотека является своеобразной ”ответной частью” библиотеки Tiny_ModBusRTU_Slave. Но может быть использована и с другими ведомыми контроллерами в ModBus сетях.

Библиотека работает в фоновом режиме, параллельным процессом. Все операции происходят в обработчике прерывания по таймеру. В основном цикле программа только инициирует обмен данными.

Библиотека поддерживает минимальный набор функций для работы с регистрами хранения (всего 3 функции). Это основные операции, которых, как правило, достаточно для управления любыми контроллерами.

Код функции Название Описание
03 READ HOLDING REGISTERS Чтение значений одного или нескольких регистров хранения
06 FORCE SINGLE REGISTER Запись в один регистр хранения
16 FORCE MULTIPLE REGISTERS Последовательная запись нескольких регистров хранения

Описание класса Tiny_ModBusRTU_Master выглядит так:

public:
Tiny_ModBusRTU_Master(byte timeOutTransmit, byte timeOutRecieve); // конструктор
Tiny_ModBusRTU_Master(byte timeOutTransmit, byte timeOutRecieve, byte directPin); // конструктор
void update(); // загрузка данных
void read(byte adress, unsigned int* reg, unsigned int holdingRegBegin, unsigned int holdingRegNumber); // чтение регистров хранения
void writeSingle(byte adress, unsigned int data, unsigned int holdingRegBegin); // запись одного регистра хранения
void writeMultiple(byte adress, unsigned int* reg, unsigned int holdingRegBegin, unsigned int holdingRegNumber); // запись нескольких регистров хранения
byte state; // состояние обмена
>;

Tiny_ModBusRTU_Master(byte timeOutTransmit, byte timeOutRecieve, byte directPin) — конструктор.

Создает объект Tiny_ModBusRTU_Master со следующими параметрами:

  • timeOutTransmit – время паузы (тишины) между фреймами. Зависит от скорости обмена. Должно быть не менее времени, необходимого для передачи 3,5 байта. Рассчитывается, как timeOutTransmit, умноженное на время периода вызова функции update().
  • timeOutRecieve – время тайм-аута ответа ведомого устройства. Время ожидания приема первого байта от ведомого устройства. Рассчитывается, как timeOutRecieve, умноженное на время периода вызова функции update(). При отсутствии ответа за это время формируется ошибка тайм-аута (код 2).
  • directPin – номер вывода разрешения передатчика ведущего устройства. Вывод используется в шинных интерфейсах, у которых передатчик имеет три состояния. Параметр необязательный. При отсутствии параметра вывод не используется.

Tiny_ModBusRTU_Master master(8, 30, 13); // создаем объект, времена тайм-аутов 4 и 15 мс, управляющий вывод 13

Методы.

void update() – управление обменом. Метод должен регулярно вызываться в параллельном процессе, например, в прерывании по таймеру.

Метод полностью управляет обменом данными. Основная программа только вызывает функцию, инициирующую обмен с нужными параметрами. Сам обмен происходит параллельным процессом. О завершении операции основной программе сообщает свойство state — состояние обмена. Во время обмена программа не останавливается, не зависает.

void read(byte adress, unsigned int* reg, unsigned int holdingRegBegin, unsigned int holdingRegNumber) – чтение регистров хранения. Функция инициирует чтение одного или нескольких регистров хранения. Имеет следующие аргументы:

  • adress – адрес ведомого устройства. Может иметь значения от 1 до 247.
  • reg – указатель на массив для прочитанных данных.
  • holdingRegBegin – начальный адрес регистров хранения.
  • holdingRegNumber – количество регистров хранения.

master.read(1, regTable, 0, 5); // инициация чтения 5 регистров хранения начиная с адреса 0, у контроллера с адресом 1, в массив regTable

void writeSingle(byte adress, unsigned int data, unsigned int holdingRegBegin) — запись одного регистра хранения. Функция инициирует запись одного регистра хранения. Имеет следующие параметры:

  • adress – адрес ведомого устройства. Может иметь значения от 0 до 247. В случае, если адрес равен 0, инициируется широковещательный режим. При этом данные передаются всем ведомым контроллерам одновременно и ответ не ожидается.
  • data – данное для записи в регистр хранения.
  • holdingRegBegin – адрес регистра хранения.

master.writeSingle(1, (unsigned int)button1.flagPress, 5); // запись регистра хранения с адресом 5, контроллера с адресом 1

void writeMultiple(byte adress, unsigned int* reg, unsigned int holdingRegBegin, unsigned int holdingRegNumber) — запись нескольких регистров хранения. Инициирует запись нескольких регистров хранения. Имеет параметры:

  • adress – адрес ведомого устройства. Может иметь значения от 0 до 247. В случае, если адрес равен 0, инициируется широковещательный режим. При этом данные передаются всем ведомым контроллерам одновременно и ответ не ожидается.
  • reg – указатель на массив данных записи.
  • holdingRegBegin – начальный адрес регистров хранения.
  • holdingRegNumber – количество регистров хранения.

master.writeMultiple(1, regTable, 5, 2); // запись 2 регистров хранения начиная с адреса 5, контроллер с адресом 1

byte state – public свойство класса — состояние обмена. Сообщает о результате операции. Может иметь следующие значения:

  • 0 — операция завершена успешно;
  • 1 — идет операция;
  • 2 — ошибка тайм-аута;
  • 4 — ошибка данных;
  • 8 — недопустимый адрес данных;
  • 16 — код функции не поддерживается;
  • 32 – другая ошибка.

Применение библиотеки Tiny_ModBusRTU_Master.

Для практической реализации программы ведущего контроллера необходимо:

Подключить библиотеку Tiny_ModBusRTU_Master;

создать объект Tiny_ModBusRTU_Master;

задать параметры UART (через класс Serial);

реализовать прерывание по таймеру и в его обработчике разместить функцию update().

Теперь в основной программе можно инициировать операции обмена функциями: read(), writeSingle() или writeMultiple.

Для проверки завершения операции в основной программе надо контролировать состояние свойства state. Как только его значение перестает быть равным 1, операция завершена. При state=0 операция завершена успешно.

Реализация ведущего контроллера с протоколом ModBus RTU.

Я использовал центральный контроллер из урока 49 без каких-либо изменений схемы.

У меня контроллер выглядит так.

Программу для центрального будем разрабатывать новую. Для локального — программа из предыдущего урока.

Напомню, что центральный контроллер должен считывать из локального:

  • температуру;
  • напряжение;
  • состояние кнопки.

Кроме того центральный контроллер должен управлять светодиодом локального контроллера и выводить статистику обмена: количество циклов обмена и ошибок.

Напомню формат регистров хранения локального контроллера.

Номер регистра Формат числа Параметр
0 float Температура
1
2 float Напряжение
3
4 бит Состояние кнопки (мл. бит)
5 бит Состояние светодиода (мл. бит)

С регистров 0-4 мы будем считывать данные, а в регистр 5 – записывать.

Первый вариант программы центрального контроллера я разработал в демонстрационных целях. У него понятная логика работы, но программа зависает в ожидании окончания операции обмена. Т.е. не используется главное преимущество библиотеки Tiny_ModBusRTU_Master – работа в фоновом режиме.

После инициации операции обмена программа ждет момента, когда переменная state перестанет быть равной 1. Т.е. когда операция закончится.

master.read(1, regTable, 0, 5); // чтение регистров хранения
while(master.state == 1) <> // ожидание данных

Обратите внимание, что в этом случае при объявлении объекта Tiny_ModBusRTU_Master надо использовать квалификатор volatile. Об этом написано в уроке 10.

Полностью скетч выглядит так.

// центральный контроллер с протоколом ModBus
#include
#include
#include
#include

volatile Tiny_ModBusRTU_Master master(8, 30, 13);
LiquidCrystal disp(6, 7, 2, 3, 4, 5); // объект дисплей
volatile Button button1(10, 30); // кнопка 1 подключена к выводу 10

unsigned int regTable[6]; // таблица регистров
unsigned int cyclCount= 0; // счетчик циклов
unsigned int errorCount= 0; // счетчик ошибок

void setup() <
Timer1.initialize(500); // инициализация таймера 1, период 500 мкс
Timer1.attachInterrupt(timerInterrupt, 500); // задаем обработчик прерываний
Serial.begin(9600);
disp.begin(20, 4); // инициализируем дисплей 4 x 20 символов
>

master.read(1, regTable, 0, 5); // чтение регистров хранения
while(master.state == 1) <> // ожидание данных

if(master.state == 0) <
// данные получены
cyclCount++; // счетчик циклов
disp.clear(); // очистка экрана
disp.print(«C=»);
disp.print(cyclCount);
disp.print(» E=»);
disp.print(errorCount);
disp.setCursor(0, 1);
disp.print(«T=»);
disp.print(* ((float *)regTable),1);
disp.print(» C U=»);
disp.print(* ( ((float *)regTable) +1 ),1);
if ( (regTable[4] & 1) == 0) disp.print(» V B=F»);
else disp.print(» V B=P»);
>
else <
// ошибка обмена
errorCount++; // счетчик ошибок
disp.clear(); // очистка экрана
disp.print(«C=»);
disp.print(cyclCount);
disp.print(» E=»);
disp.print(errorCount);
disp.setCursor(0, 1);
disp.print(«ERROR= «);
disp.print(master.state);
>

master.writeSingle(1, (unsigned int)button1.flagPress, 5); // запись регистра хранения (светодиод)
while(master.state == 1) <> // ожидание данных
if(master.state != 0) errorCount++;
delay(500);
>

// ————————— обработчик прерывания 500 мкс
void timerInterrupt() <
master.update(); // проверка данных обмена
button1.scanState(); // обработка сигнала кнопки 1
>

При загрузке скетча из Arduino IDE необходимо удерживать кнопку сброса локального контроллера нажатой. В этом состоянии микроконтроллер отключается и не мешает загрузке программы в центральный контроллер.

Проверка работы программы.

Запустил систему, ошибок обмена нет, данные правильные. Убедился, что по нажатию кнопки центрального контроллера зажигается светодиод локального контроллера.

Нажал кнопку сброса локального контроллера. Посыпались ошибки.

Отпустил кнопку – обмен возобновился, ошибки прекратились.

Другой вариант программы.

Во втором варианте программа не зависает, ожидая окончания операции обмена. Каждый проход цикла loop() происходит без задержек. В квалификаторе volatile при объявлении объекта Tiny_ModBusRTU_Master нет необходимости. Обмен происходит в фоновом режиме, программу можно дополнить другими задачами в цикле loop().

// центральный контроллер с протоколом ModBus
#include
#include
#include
#include

Tiny_ModBusRTU_Master master(8, 30, 13);
LiquidCrystal disp(6, 7, 2, 3, 4, 5); // объект дисплей
Button button1(10, 30); // кнопка 1 подключена к выводу 10

unsigned int regTable[6]; // таблица регистров
unsigned int cyclCount= 0; // счетчик циклов
unsigned int errorCount= 0; // счетчик ошибок
byte mode=0; // режим: 0 — чтение, 1 — запись

void setup() <
Timer1.initialize(500); // инициализация таймера 1, период 500 мкс
Timer1.attachInterrupt(timerInterrupt, 500); // задаем обработчик прерываний
Serial.begin(9600);
disp.begin(20, 4); // инициализируем дисплей 4 x 20 символов
master.read(1, regTable, 0, 5); // чтение регистров хранения
>

else <
// запись регистра хранения
if(master.state != 1) <
// операция завершена
if(master.state != 0) errorCount++;
master.read(1, regTable, 0, 5); // чтение регистров хранения
mode++;
cyclCount++; // счетчик циклов
>
>
delay(500);
>

// ————————— обработчик прерывания 500 мкс
void timerInterrupt() <
master.update(); // проверка данных обмена
button1.scanState(); // обработка сигнала кнопки 1
>

Функционально программа полностью аналогична предыдущему варианту.

В предыдущих уроках мы использовали радиальные интерфейсы, а значит, могли объединить в сеть только 2 устройства. В следующем уроке простыми средствами преобразуем радиальный интерфейс UART в магистральный. С помощью него по двух проводной линии связи соединим в локальную сеть 3 платы Ардуино.

Источник

Adblock
detector