<< Click to Display Table of Contents >> Navigation: Modbus Universal MasterOPC Server > Руководство по языку Lua 5.1 > Примеры и полезности > Чтение файлов по Modbus > Описание функции 0x14 (Read File Function) |
Еще одним вариантом получения архивов по Modbus является считывание файлов из устройства при помощи 20-функции (функция 0x14). Данная функция позволяет считывать из файлов записи произвольной структуры. Каждый файл может содержать до 10 тысяч записей, количество файлов может составлять 65535. Количество получаемых за один запрос данных – 245 байт.
Функция имеет следующую структуру запроса:
Обозначение поля |
Размер |
Диапазон значений |
Адрес устройства |
1 Byte |
0x00 – 0xFF |
Номер функции |
1 Byte |
0x14 |
Количество байт |
1 Byte |
0x07 – 0xF5 |
Запрос X, тип ссылки |
1 Byte |
0x06 |
Запрос X, номер файла |
2 Byte |
0x0001 – 0xFFFF |
Запрос X, номер записи |
2 Byte |
0x0000 – 0x270F |
Запрос X, длина записи |
2 Byte |
N Byte |
Запрос X+1, тип ссылки… |
|
|
… |
||
CRC – контрольная сумма |
2 Byte |
|
Номер устройства – Modbus адрес устройства.
Номер функции – порядковый номер функции запроса (0x14).
Количество байт – суммарное количество байт всех элементов "ЗапросX" (тип файла, номер записи, длина записи).
Следующие элементы описывают структуру выполняемого запроса чтения записи из файла:
Тип ссылки – согласно спецификации всегда 6.
Номер файла – номер запрашиваемого файла.
Номер записи – номер интересующей записи из файла.
Длина записи – количество элементов (регистров) которые нужно считать из записи.
Далее следует описание запроса следующей записи, если таковые имеются.
CRC – контрольная сумма Modbus запроса.
Устройство посылает ответ следующей структуры:
Обозначение поля |
Размер |
Диапазон значений |
Адрес устройства |
1 Byte |
0x01 – 0xFF |
Номер функции |
1 Byte |
0x14 |
Длина ответа |
1 Byte |
0x07 – 0xF5 |
Запрос X, длина ответа |
1 Byte |
0x07 – 0xF5 |
Запрос X, тип ссылки |
1 Byte |
0x06 |
Запрос X, данные записи |
Nx2 Bytes |
|
Запрос X+1, длина ответа… |
|
|
… |
||
CRC – контрольная сумма |
2 Byte |
|
Адрес устройства и номер функции имеют такое же назначение, как и при запросе.
Длина ответа – общая длина принятых элементов запроса (в байтах). Каждый запрос содержит собственное поле с количеством байт в запросе.
Следующие элементы описывают полученные данные из записи файла:
Длина ответа – количество принятых байт в данной записи.
Тип ссылки – согласно спецификации всегда 6.
Данные записи – полученные из записей регистры данных. Каждый регистр занимает 2 байта.
Подробнее прочитать про функцию 0x14, с примерами запросов и ответа, вы можете в официальном стандарте Modbus, на странице 32-33:
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
Итак, чтобы получить данные из записи в файле, нам нужно передать номер файла, номер записи и количество требуемых регистров из записи.
Для выполнения запроса чтения файлов по протоколу Modbus в MasterOPC есть специальная функция - modbus.ReadFileFunction(). В качестве аргументов, функция принимает 5 параметров:
1 параметр – количество получаемых из записи таблиц.
2 параметр – таблица с номерами считываемых файлов. Таблица должна содержать столько номеров файлов, сколько задано количество получаемых таблиц.
3 параметр – таблица с номерами считываемых записей. Таблица должна содержать столько номеров записей, сколько задано количество получаемых таблиц.
4 параметр – таблица количества принимаемых элементов для каждой получаемой таблицы. Таблица должна содержать столько элементов, сколько задано количество получаемых таблиц.
5 параметр – таблица таблиц масок. Таблица должна содержать столько таблиц масок, сколько задано количество получаемых таблиц.
Функция возвращает от двух и более значений:
1 – код ошибки. При корректном ответе равен нулю.
2..N – принятые таблицы значений отформатированные по заданным маскам. Количество принимаемых таблиц зависит от заданного пользователем значения (первый входной аргумент функции).
В качестве примера, рассмотрим пример запроса из справки по данной функции. В приведенном ниже коде мы будем запрашивать из файла 1, две записи – 1 и 10, каждая запись будет содержать по 5 элементов типа "2 –байтное знаковое целое" - Int16.
Приведем код полностью, а затем разберем его построчно.
local err,dstlen --объявление переменных
local file = {1,1} --объявление и инициализация таблицы файлов
local rec = {1,10} --объявление и инициализация таблицы записей
local len = {5,5} --объявление и инициализация таблицы количества принимаемых элементов для каждой из принимаемых таблиц.
local dstdata = {} --объявление таблицы для принятия данных из записи 1
local dstdata2= {} --объявление таблицы для принятия данных из записи 10
local dstmsk1 = {"int16:5:10"} --маска первой таблицы (для записи 1). Тип значения Int16, количество элементов – 5, чередование старшим байтов вперед
local dstmsk2 = {"int16:5:10"} -- маска второй таблицы (для записи 2). Тип значения Int16, количество элементов – 5, чередование старшим байтов вперед
local dstmsk = {dstmsk1,dstmsk2} --создание таблицы таблиц с масками чтение архива из устройства
err,dstdata,dstdata2 = modbus.ReadFileFunction(2,file,rec,len,dstmsk);
--если ошибки нет
if err == 0 then
--то выводим в журнал сообщения с полученными значениями
server.Message("d1=",dstdata[1],",",dstdata[2],",",dstdata[3], ",",dstdata[4], ",",dstdata[5]);
server.Message("d2=",dstdata2[1],",",dstdata2[2],",",dstdata2[3], ",",dstdata2[4], ",",dstdata2[5]);
else
server.Message("error");
end
В первых девяти строках идет объявление и инициализация переменных. Переменная file – таблица, которая содержит два элемента – две единицы, это номера файлов. Поскольку мы считываем две записи из файла 1, то элемент содержит две единицы. Переменная rec – таблица, которая содержит номера записей – 1 и 10. Переменная len – таблица, которая содержит количество требуемых элементов из каждой записи. Из каждой записи мы будем запрашивать по 5 элементов. Переменные dstdata и dstdata2 – это таблицы, в которые мы будем записывать принимаемые значения.
Переменные dstmsk1 и dstmsk2 – это таблицы, которые содержат маску принимаемых данных из записи. Сейчас в обе маски записана строковая константа "int16:5:10". Первый элемент строковой константы – тип принимаемого числа, в данном случае – Int16. Второй элемент строки – количество элементов данного типа, в данном случае 5. Третий элемент строки – чередование байт, в данном случае старшим байтом вперед (для элементов Byte и String задавать чередование байт не нужно). По этой маске будут дешифрованы принятые из записи байты, и такие элементы будут содержаться в выходной таблице (в данном случае в таблицах dstdata и dstdata2).
В нашем случае мы запрашивает 5 однотипных элементов, если бы нам требовалось запросить элементы разных типов, то их нужно было поочередно прописать в строке маски. Например, нам требуется получить от устройства данные в следующем порядке – 3 числа Int16, 2 числа Float, 4 числа Byte. В этом случае маска запроса будет выглядеть следующим образом:
local dstmsk1 = {"int16:3:10", "Float:2:32107654","Byte:4"}
Далее объявляется переменная dstmsk – это таблица, содержащая в себе таблицы масок преобразований. То есть в данную таблицу мы поместили две таблицы с масками преобразования для каждой записи.
Далее в строке происходит непосредственное выполнение запроса на чтение записи из файла.
err,dstdata,dstdata2 = modbus.ReadFileFunction(2,file,rec,len,dstmsk);
В функцию передаются аргументы: количество получаемых таблиц (количество запрашиваемых записей), номера файлов, номера записей, длина записей, и маски запроса – переменные которые мы предварительно инициализировали нужными данными. Функция присваивает переменной err флаг ошибки, а переменным dstdata и dstdata2 полученные от прибора и отформатированные по маске значения.
Затем, если ошибки нет (err равен нулю), то в лог журнала выводятся значения элементов массива.