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

Обсуждаем Arduino, Raspberry Pi и другие электронные компоненты и проекты DIY
Тима
Сообщения: 131
Зарегистрирован: 16 ноя 2012, 21:03

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

Сообщение Тима »

После подключения экрана вроде дело сдвинулось. Начал моргать индикатор обмена по RS-485 на МВА8. Но на экране выводит "0".
Вопрос остается в силе: нужно считать данные из ячеек с адресами 4 и 5. Где их указывать?
Вот сам скетч:

Код: Выделить всё

#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]); 
}
 
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

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

Сообщение Mr.Kubikus »

Тима писал(а):Пока не получается считать данные с МВА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 будет выглядеть так:

Код: Выделить всё

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

Проверь, пожалуйста, этот вариант и если на дисплее появятся адекватные цифры, то тогда перейдем к результату в формате с плавающей точкой.
С уважением, Григорий
GitHub FB ВК
Тима
Сообщения: 131
Зарегистрирован: 16 ноя 2012, 21:03

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

Сообщение Тима »

Код: Выделить всё

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

Код: Выделить всё

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

Код: Выделить всё

Второй параметр в вызове функции - это адрес МВА8 на шине. Адрес 0 зарезервирован для широковещательных команд.
А вот этого я не знал. У меня МВА8 под адресом "0".

Код: Выделить всё

Четвертый параметр - это адрес регистра в памяти МВА8, который надо прочитать. В нашем случае нам нужен регистр с адресом 1.
Ясно. А 5й и 6й параметры это что?

Код: Выделить всё

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

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

Сообщение Тима »

Заработало!!! :P
IMG_20150712_121736.jpg
IMG_20150712_121736.jpg (97.2 КБ) 39306 просмотров
Чтение данных с ячейки с адресом "1". К нему подключена термопара. На экране отображает целочисленное значение, при нагреве меняется.
Теперь задача в отображении хотя бы одного значения после запятой.
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

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

Сообщение Mr.Kubikus »

Ясно. А 5й и 6й параметры это что?
Пятый параметр для разных функций MODBUS имеет разный смысл. Для функций 3, 4 и 16 - это количество запрашиваемых регистров.
Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg объявленный в строке 53:

Код: Выделить всё

unsigned int regs[TOTAL_NO_OF_REGISTERS];
С уважением, Григорий
GitHub FB ВК
Тима
Сообщения: 131
Зарегистрирован: 16 ноя 2012, 21:03

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

Сообщение Тима »

Код: Выделить всё

Пятый параметр для разных функций MODBUS имеет разный смысл. Для функций 3, 4 и 16 - это количество запрашиваемых регистров. 
Т.е. если четвертый параметр "1", пятый "3" то при считывании будет:
regs[0] - это значение 1й ячейки,
regs[1] - это значение 2й ячейки,
regs[2] - это значение 3й ячейки.
Я верно понял?
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

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

Сообщение Mr.Kubikus »

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

Код: Выделить всё

float ch1 = 0.0;
ch1 = regs[0] / 10;
На дисплей выводить переменную ch1.
С уважением, Григорий
GitHub FB ВК
Аватара пользователя
Mr.Kubikus
Сотрудник ПАКПАК
Сообщения: 1018
Зарегистрирован: 22 окт 2010, 23:57

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

Сообщение Mr.Kubikus »

Т.е. если четвертый параметр "1", пятый "3" то при считывании будет:
regs[0] - это значение 1й ячейки,
regs[1] - это значение 2й ячейки,
regs[2] - это значение 3й ячейки.
Я верно понял?
Все верно. Только не забудь изменить макроопределение TOTAL_NO_OF_REGISTERS. Если из слейва запрашиваешь 3 регистра, то тогда в массиве reg должно быть не меньше трех ячеек для хранения полученных данных.
С уважением, Григорий
GitHub FB ВК
Тима
Сообщения: 131
Зарегистрирован: 16 ноя 2012, 21:03

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

Сообщение Тима »

Чтобы получить один разряд после запятой надо в конфигураторе МВА8 для интересующего измерительно канала задать параметр dP=1, а в коде для Arduino надо будет полученный результат поделить на 10:
Все заработало. :P Вот только, если добавить манипуляции с выводом вещественного числа, скетч в дуину не влезает. Надо либо другую, менее емкую библу для экрана использовать, либо другую дуину с большей памятью брать.
Raider
Сообщения: 2
Зарегистрирован: 17 авг 2015, 15:02

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

Сообщение Raider »

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