bg

SQL в MODBUS: Отправка значений из базы данных в MODBUS

Задача:

Необходимо записывать значение в контроллер PLC из базы данных, используя протокол MODBUS.

Требования:

  • Data Logger Suite Enterprise или пробная версия. Этот логгер может одновременно работать с MODBUS RTU или MODBUS TCP.

Подразумевается, что:

Вы настроили параметры связи в вашем устройстве:

  • MODBUS TCP - IP адрес, маску подсети, адрес шлюза. Вы должны задать статический IP адрес в устройстве.
  • MODBUS RTU - скорость передачи данных и количество бит данных.

Порядок действий:

1. Создайте новую конфигурацию, используя кнопку "Зеленый Плюс" в главном окне программы (рис. 1). Обычно, вам нужно выбрать интерфейс "TCP/IP" для MODBUS TCP, и интерфейс "RS232" для MODBUS RTU. В данном примере приведены настройки подключения для MODBUS TCP. Если ваше устройство использует протокол MODBUS RTU, то посмотрите тут. Если вы уже настроили подключение ранее, то переходите к шагу №2.

Настройки сетевого подключения
Рис. 1. Настройки сетевого подключения

2. Перейдите к странице "Модули - Запрос Анализ Фильтрация". Выберите "MODBUS TCP" или "MODBUS RTU" из списков, как показано на рисунке 2. Затем кликните на кнопке "Настроить.

Выбор модуля MODBUS
Рис. 2. Выбор модуля MODBUS

3. Кликните на кнопке "Действие - Добавить запрос" и добавьте запросы для записи данных (рис. 3-5).

3.1. Установите код функции MODBUS:

  • 6 (запись одного регистра) - если нужно записать значение, которое занимает в памяти контроллера или устройства один регистр (2 байта). Для примера, это могут быть типы данных word, uint16, int16, decimal16.
  • 16 (запись нескольких регистров) - если вы хотите записать значение, которое занимает несколько регистров (dword, uint32, int32, decimal32, float и т.п.).

3.2. Укажите количество регистров в поле "Считать регистров":

  • word, int16, unt16 - один регистр MODBUS (2 байта).
  • dword, int32, uint32, float - два регистра (4 байта).
  • int64, double precision float - четыре регистра (8 байт).

3.3. Адрес данных в памяти не имеет значения. Модуль будет получать его из базы данных.

3.4. Выберите метод запроса "Событие". Затем укажите идентификатор события в виде "WRITE-INT", "WRITE-FLOAT" или "WRITE-UINT16". Вы можете использовать любой идентификатор, но его надо будет поменять и в скрипте ниже.

Замечание: Вы должны создать запрос и задать уникальный идентификатор события для каждого типа данных. Например, один запрос записывает значения типа "int", а другой значения типа "float".

3.5. Добавьте один элемент ответа с именем "VALUE".

Добавления запроса для записи данных
Рис. 3. Добавления запроса для записи данных

Запись Int32
Рис. 4. Запись Int32

Запись Float
Рис. 5. Запись Float

4. Подготовьте таблицу в базе данных SQL. Вы можете использовать прототипы ниже. Эта таблица будет содержать одну строчку для одного значения, которое, в зависимости от типа данных может занимать несколько регистров. Значение в колонке "DATE_TIME_STAMP" содержит время добавления или изменения значения. Логгер будет использовать эту колонку для отслеживания изменений в таблице.

Ниже приведены скрипты для создания таблиц в популярных базах данных, которые мы рекомендуем использовать.

CREATE TABLE [dbo].[MODBUS_DATA_WRITE](
	[ID] [decimal](10, 0) IDENTITY(1,1) NOT NULL,
	[DATE_TIME_STAMP] [datetime] NULL DEFAULT (getdate()),
	[DATA_SOURCE] [nvarchar](32) NOT NULL,
	[DEVICE_ID] [int] NOT NULL,
	[OFFSET] [int] NULL,
	[VALUE1] [int] NULL,
	[VALUE2] [float] NULL,
	[VALUE3] [smallint] NULL
 CONSTRAINT [PK_MODBUS_DATA_WRITE] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TRIGGER dbo.MODBUS_DATA_WRITE_TRIGGER
ON dbo.MODBUS_DATA_WRITE
AFTER UPDATE 
AS BEGIN
   SET NOCOUNT ON
   UPDATE dbo.MODBUS_DATA_WRITE
   SET DATE_TIME_STAMP = GETDATE()
   FROM INSERTED
   WHERE INSERTED.ID = MODBUS_DATA_WRITE.ID
END
GO 

CREATE TABLE `MODBUS_DATA_WRITE` (
 `ID` int(11) NOT NULL auto_increment,
 `DATE_TIME_STAMP` DATETIME NULL,
 `DATA_SOURCE_NAME` VARCHAR(32) NOT NULL,
 `DEVICE_ID` INTEGER NOT NULL,
 `OFFSET` INTEGER NULL,
 `VALUE1` INTEGER NULL,
 `VALUE2` DOUBLE NULL,
 `VALUE3` INTEGER NULL,
  PRIMARY KEY  (`ID`)
) ENGINE=InnoDB;

CREATE TRIGGER MODBUS_DATA_WRITE_BI BEFORE INSERT ON `MODBUS_DATA_WRITE`
    FOR EACH ROW SET NEW.DATE_TIME_STAMP = IFNULL(NEW.DATE_TIME_STAMP, NOW());

CREATE TRIGGER MODBUS_DATA_WRITE_BU BEFORE UPDATE ON `MODBUS_DATA_WRITE`
    FOR EACH ROW SET NEW.DATE_TIME_STAMP = IFNULL(NEW.DATE_TIME_STAMP, NOW());

CREATE TABLE "MODBUS_DATA_WRITE" (
  "ID" SERIAL,
  "DATE_TIME_STAMP" timestamp DEFAULT NULL,
  "DATA_SOURCE_NAME" varchar(32) NOT NULL,
  "DEVICE_ID" integer NOT NULL,
  "OFFSET" integer NULL,
  "VALUE1" integer NULL,
  "VALUE2" real NULL,
  "VALUE3" integer NULL,
  PRIMARY KEY ("ID")
);

CREATE OR REPLACE FUNCTION MODBUS_DATA_WRITE_BI_TRIGGER()
  RETURNS trigger AS
$BODY$
BEGIN
 NEW.DATE_TIME_STAMP := COALESCE(NEW.DATE_TIME_STAMP, NOW());
 RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql;

CREATE TRIGGER MODBUS_DATA_WRITE_BI BEFORE INSERT ON "MODBUS_DATA_WRITE"
    FOR EACH ROW EXECUTE PROCEDURE MODBUS_DATA_WRITE_BI_TRIGGER();

CREATE TRIGGER MODBUS_DATA_WRITE_BU BEFORE UPDATE ON "MODBUS_DATA_WRITE"
    FOR EACH ROW EXECUTE PROCEDURE MODBUS_DATA_WRITE_BI_TRIGGER();

5. Создайте новую конфигурацию в логгере с источником данных типа SQL (кнопка с зеленым плюсом в главном окне программы).

Добавление конфигурации SQL
Рис. 6. Добавление конфигурации SQL

6. Настройте соединение с вашей базой данных (стр. №100).

Настройки соединения с базой данных
Рис. 7. Настройки соединения с базой данных

7. Укажите имя таблиц в вашей базе данных, интервал выборки и имя колонки "DATE_TIME_STAMP", по которой будет проверяться наличие новых данных.

Настройки таблицы
Рис. 8. Настройки таблицы

Когда интерфейс SQL считывает новые данные, они появляются в главном окне программы.

Данные из SQL сервера
Рис. 9. Данные из SQL сервера

8. Выберите модуль "OPC parser" в качестве парсера. Этот модуль не требует настройки.

Модуль парсер
Рис. 10. Модуль парсер

9. Script execute - этот модуль выполняет скрипт и пересылает значения из базы данных в соответствующую конфигурацию, с помощью событий. В качестве параметров события передаются имя источника данных (IP адрес или номер порта RS232), адрес устройства и адрес ячейки памяти.

Модуль Script Execute
Рис. 11. Модуль Script Execute

10. Скопируйте и вставьте скрипт, приведенный ниже.

var
 device, addr: integer;
 v1, v2, v3: variant;
 strTargetDataSource: string;
begin
 strTargetDataSource := GetVariable('DATA_SOURCE');
 device := GetVariable('DEVICE_ID'); // MODBUS device ID
 addr := GetVariable('OFFSET'); // MODBUS memory offset
 v1 := GetVariable('VALUE1'); // Int value
 v2 := GetVariable('VALUE2'); // Float value
 v3 := GetVariable('VALUE3'); // UInt16 value

 if VarToStr(v1) <> '' then
   SendEventEx('WRITE-INT', [
   'EVENT-TO-CFG', strTargetDataSource,
   'DEVICE', device,
   'ADDRESS', addr,
   'VALUE', v1
  ]);

 if VarToStr(v2) <> '' then
   SendEventEx('WRITE-FLOAT', [
   'EVENT-TO-CFG', strTargetDataSource,
   'DEVICE', device,
   'ADDRESS', addr,
   'VALUE', v2
  ]);

 if VarToStr(v3) <> '' then
   SendEventEx('WRITE-UINT16', [
   'EVENT-TO-CFG', strTargetDataSource,
   'DEVICE', device,
   'ADDRESS', addr,
   'VALUE', v3
  ]);

end.

Скрипт
Рис. 12. Скрипт

11. Теперь, приложение работает следующим образом:

  • Интерфейс SQL считывает новые данные из базы данных.
  • Парсер "OPC parser" подготавливает данные для модуля "Script Execute".
  • Модуль "Script Execute" выполняет скрипт и перенаправляет данные SQL в разные источники данных и устройства.
  • Модуль "MODBUS" ожидает события и выполняет соответствующий запрос на запись данных.

12. Вы можете выполнить SQL запрос ниже в вашей базе данных, и проверить прохождение данных от базы до контроллера (не забудьте поменять параметры устройства в SQL запросе).


  INSERT INTO MODBUS_DATA_WRITE (DATA_SOURCE, DEVICE_ID, OFFSET, VALUE3) 
VALUES ('192.168.1.3:502', 1, 10, 14321)

Вы можете скачать резервную копию демонстрационной конфигурации и восстановить ее у себе из меню "Файл" в главном окне программы.

Сопутствующие статьи:

MODBUS RTU, MODBUS ASCII, MODBUS/TCP

IEC 62056-21