Тел. (495) 972-27-12

Интерфейс RS-485 протокол MODBUS RTU.

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Тима » 11 июл 2015, 17:36

После подключения экрана вроде дело сдвинулось. Начал моргать индикатор обмена по RS-485 на МВА8. Но на экране выводит "0".
Вопрос остается в силе: нужно считать данные из ячеек с адресами 4 и 5. Где их указывать?
Вот сам скетч:
Code: [Выделить всё] [Expand/Collapse]
#include <SimpleModbusMaster.h>
#include <Arduino.h>
#include <Wire.h>
#include <MicroLCD.h>


LCD_SSD1306 lcd;
 
// Настройки интерфейса
#define baud 9600       // Скорость
#define timeout 1000    // Длительность ожидание ответа
#define polling 200     // Длительность паузы между запросами
#define retry_count 10  // Количество попыток обмена до отключения канала
 
// Выход контроллера для управления направлением драйвера
#define TxEnablePin 2
 
// Выход для управления светодиодом
#define LED 13
 
// Количество регистров на стороне ведущего устройства для хранения данных
#define TOTAL_NO_OF_REGISTERS 1
 
// Простой способ подсчета количтества создаваемых объектов packet.
// TOTAL_NO_OF_PACKETS обновляется автоматически.
enum
{
  PACKET1,
  TOTAL_NO_OF_PACKETS // Этот элемент должен быть последним
};
 
Packet packets[TOTAL_NO_OF_PACKETS];
 
unsigned int regs[TOTAL_NO_OF_REGISTERS];
 
void setup()
{
  // Инициализируем каждый обект packet
  modbus_construct(&packets[PACKET1], 0, READ_HOLDING_REGISTERS, 0, 1, 0);
 
  // Инициализируем конечный автомат протокола MODBUS
  modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
 
  // Инициализируем последовательный порт для отладочного вывода
 lcd.begin();
 
  // Настраиваем порт для светодиода
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
}
 
void loop()
{
  modbus_update();
 
        lcd.setFont(FONT_SIZE_MEDIUM);
        lcd.setCursor(0, 0); lcd.print("MODBUS RTU");
   lcd.setCursor(0, 2);lcd.print(regs[0]);
}
 
GeSHi © Codebox Plus
Тима
 
Сообщения: 119
Зарегистрирован: 16 ноя 2012, 21:03

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Mr.Kubikus » 12 июл 2015, 00:11

Тима писал(а):Пока не получается считать данные с МВА8.
Может это быть из-за того, что порт SERIAL один?
Если так, буду пробовать отправлять данные не на порт , а на экран.

Все верно. У ATmega328, которая стоит в UNO, только один встроенный аппаратный приемопередатчик UART, поэтому через него не получится одновременно обмениваться по протоколу MODBUS и выводить данные в консоль. Как вариант, для вывода в терминал можно использовать программную реализацию последовательного порта SoftwareSerial или, как ты написал выше, выводить данные на дисплей через свободные линии ввода-вывода.

И еще, нужно считать данные из ячеек с адресами 4 и 5. Где их указывать?

Для начала надо подключить МВА8 к компу через адаптер RS485 "ОВЕН АС3" (или аналогичный), установить с помощью программы "Конфигуратор МВА8" требуемые настройки и затем убедиться, что измерительные каналы работают. После этого можно тестировать с Arduino.

Важный момент! МВА8 переходит на работу по новому сетевому протоколу только после выключения и включения питания.

В регистрах с адресами 4 и 5 в МВА8 хранится результат измерения входа №1 в представлении с плавающей точкой. Может показаться странным, что под один результат отведено два регистра. Дело в том, что данные в формате с плавающей точкой занимают 32 бита, а один регистр в протоколе MODBUS имеет размер 16 бит поэтому под результат и отведено два 16-битных регистра.

После получения значений на стороне Arduino надо будет собрать из двух 16-битных слов одно 32-битное двойное слово. Тут есть риск перепутать порядок слов и получить в результате непонятно что. Поэтому я рекомендую сначала выполнить чтение из регистра с адресом 1, в котором хранится целое значение измерения входа №1 со смещением точки. В программе строка 58 будет выглядеть так:
Code: [Выделить всё] [Expand/Collapse]
  1. modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 1, 1, 0);
GeSHi © Codebox Plus

Второй параметр в вызове функции - это адрес МВА8 на шине. Адрес 0 зарезервирован для широковещательных команд. Поэтому мы используем адрес 1 или любой свободный, но не более 247. Этот адрес также надо установить в конфигураторе МВА8 в параметре "Addr Базовый адрес прибора".
Четвертый параметр - это адрес регистра в памяти МВА8, который надо прочитать. В нашем случае нам нужен регистр с адресом 1.

Проверь, пожалуйста, этот вариант и если на дисплее появятся адекватные цифры, то тогда перейдем к результату в формате с плавающей точкой.
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Тима » 12 июл 2015, 08:00

Code: [Выделить всё] [Expand/Collapse]
Для начала надо подключить МВА8 к компу через адаптер RS485 "ОВЕН АС3" (или аналогичный), установить с помощью программы "Конфигуратор МВА8" требуемые настройки и затем убедиться, что измерительные каналы работают. После этого можно тестировать с Arduino.
GeSHi © Codebox Plus

Я это знаю. Все настройки сделал.


Code: [Выделить всё] [Expand/Collapse]
Важный момент! МВА8 переходит на работу по новому сетевому протоколу только после выключения и включения питания.
GeSHi © Codebox Plus

Тоже сделано.


Code: [Выделить всё] [Expand/Collapse]
Второй параметр в вызове функции - это адрес МВА8 на шине. Адрес 0 зарезервирован для широковещательных команд.
GeSHi © Codebox Plus

А вот этого я не знал. У меня МВА8 под адресом "0".


Code: [Выделить всё] [Expand/Collapse]
Четвертый параметр - это адрес регистра в памяти МВА8, который надо прочитать. В нашем случае нам нужен регистр с адресом 1.
GeSHi © Codebox Plus

Ясно. А 5й и 6й параметры это что?


Code: [Выделить всё] [Expand/Collapse]
Проверь, пожалуйста, этот вариант и если на дисплее появятся адекватные цифры, то тогда перейдем к результату в формате с плавающей точкой.
GeSHi © Codebox Plus

Хорошо. Сегодня проверю.
Тима
 
Сообщения: 119
Зарегистрирован: 16 ноя 2012, 21:03

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Тима » 12 июл 2015, 12:24

Заработало!!! :P
IMG_20150712_121736.jpg

Чтение данных с ячейки с адресом "1". К нему подключена термопара. На экране отображает целочисленное значение, при нагреве меняется.
Теперь задача в отображении хотя бы одного значения после запятой.
Тима
 
Сообщения: 119
Зарегистрирован: 16 ноя 2012, 21:03

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Mr.Kubikus » 12 июл 2015, 12:26

Ясно. А 5й и 6й параметры это что?


Пятый параметр для разных функций MODBUS имеет разный смысл. Для функций 3, 4 и 16 - это количество запрашиваемых регистров.
Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg объявленный в строке 53:
Code: [Выделить всё] [Expand/Collapse]
  1. unsigned int regs[TOTAL_NO_OF_REGISTERS];
GeSHi © Codebox Plus
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Тима » 12 июл 2015, 12:33

Code: [Выделить всё] [Expand/Collapse]
Пятый параметр для разных функций MODBUS имеет разный смысл. Для функций 3, 4 и 16 - это количество запрашиваемых регистров.
GeSHi © Codebox Plus

Т.е. если четвертый параметр "1", пятый "3" то при считывании будет:
regs[0] - это значение 1й ячейки,
regs[1] - это значение 2й ячейки,
regs[2] - это значение 3й ячейки.
Я верно понял?
Тима
 
Сообщения: 119
Зарегистрирован: 16 ноя 2012, 21:03

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Mr.Kubikus » 12 июл 2015, 12:35

Ура!
Теперь задача в отображении хотя бы одного значения после запятой.


Чтобы получить один разряд после запятой надо в конфигураторе МВА8 для интересующего измерительно канала задать параметр dP=1, а в коде для Arduino надо будет полученный результат поделить на 10:
Code: [Выделить всё] [Expand/Collapse]
  1. float ch1 = 0.0;
  2. ch1 = regs[0] / 10;
GeSHi © Codebox Plus


На дисплей выводить переменную ch1.
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Mr.Kubikus » 12 июл 2015, 12:39

Т.е. если четвертый параметр "1", пятый "3" то при считывании будет:
regs[0] - это значение 1й ячейки,
regs[1] - это значение 2й ячейки,
regs[2] - это значение 3й ячейки.
Я верно понял?


Все верно. Только не забудь изменить макроопределение TOTAL_NO_OF_REGISTERS. Если из слейва запрашиваешь 3 регистра, то тогда в массиве reg должно быть не меньше трех ячеек для хранения полученных данных.
С уважением, Григорий
GitHub FB ВК TW
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
 
Сообщения: 878
Изображения: 49
Зарегистрирован: 22 окт 2010, 23:57
Откуда: Москва

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Тима » 12 июл 2015, 13:52

Чтобы получить один разряд после запятой надо в конфигураторе МВА8 для интересующего измерительно канала задать параметр dP=1, а в коде для Arduino надо будет полученный результат поделить на 10:

Все заработало. :P Вот только, если добавить манипуляции с выводом вещественного числа, скетч в дуину не влезает. Надо либо другую, менее емкую библу для экрана использовать, либо другую дуину с большей памятью брать.
Тима
 
Сообщения: 119
Зарегистрирован: 16 ноя 2012, 21:03

Re: Интерфейс RS-485 протокол MODBUS RTU.

Сообщение Raider » 17 авг 2015, 15:06

Оч. полезная тема, от себя могу добавить по поводу вывода знаков после запятой:
valueFromSensor = (float)regs[1]/100.00;
C преобразователем собранном на ADM485 работает прекрасно!
Raider
 
Сообщения: 2
Зарегистрирован: 17 авг 2015, 15:02

Пред.След.

Вернуться в Arduino и Ко. ♥♥♥



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron