Posted 2010-03-17 15:31:46 | 
Устройства:  Эльф-04 через Modbus |  Версия: v.0.1
Modbus драйвер для теплосчетчика ЭльфДрайвер для ДК использует стандартную библиотеку Libmodbus v.2.0.3 от Stephane Raimbault. Первый вариант реализовывал на базе другой библиотеки libmodbus 0.0.1. Однако, столкнулся с трудностями интеграции библиотеки с основным ядром ДК. С библиотекой от Стефана же проблем не возникло, все очень четко и продумано. Немного опишу процедуру использования.

Шаг первый - конфигурация ["./configure" в директории пакета]
Шаг второй - компиляция ["make" там же]
Шаг третий - инсталляция ["make install"]
Библиотека устанавливается в "/usr/local/bin", заголовочные файлы в "/usr/local/include".
Линкуем библиотеку в make файле своего проекта -lmodbus.

В драйвере устройства (в нашем случае тепловычислителя Эльф), 
прописываем неоходимые действия, например чтение данных:
 //1.   Установить в регистр Архив(40001 + 3) значение соответствующее требуемому архиву.
 result = preset_single_register(&mb_param, this->adr, ADR_ARCHTYPE, rs); 
// this->adr - адрес устройства, ADR_ARCHTYPE - адрес регистра типа читаемого архива, 
rs - тип архива (9-текущие, 26-часовые, 27-дневные, 28-по месяцам)

 //2.      Заполните поля ГОД, МЕСЯЦ, ДЕНЬ, ЧАС(40001+0 - 40001+1) значениями, 
соответствующими дате требуемой архивной записи.
 rs=(10)*256+currenttime->tm_mon+1;
 result = preset_single_register(&mb_param, this->adr, ADR_YEAR, rs); 
 if (type==DAY_ARCHIVE) rs=(currenttime->tm_mday-1)*256+currenttime->tm_hour;
 else rs=currenttime->tm_mday*256+currenttime->tm_hour;
 result = preset_single_register(&mb_param, this->adr, ADR_YEAR+1, rs);

 //3.   Установить биты AId, Id в регистре Статус(40001 + 6) в значение 0, а биты  Dbd, AIc в 1.
 if (type>9) rs=0x6A;  else rs=0;
 result = preset_single_register(&mb_param, this->adr, ADR_STATUS, rs);

     // Читаем циклически нужное количество записей, метка времени при этом декрементируется.
     //4.       Считать таблицу измерительных параметров. Регистры имеют формат данных Тип1.
     result = read_input_registers(&mb_param, this->adr, ADR_DATA, 20, (uint16_t *)data);
     data_in[0]=data[16]; data_in[3]=data[15]; data_in[2]=data[14]; data_in[1]=data[13];
     q=*(float*)(data_in);


Результат работы программы примерно следующий.

[elf] total 1 ELF add to list
Opening /dev/ttyS1 at 4800 bauds (none)
[elf] open com-port success
[01][04][03][42][00][04][51][99]
Waiting for a message (13 bytes)...
<01><04><08><03><02><00><04><03><03><09><00><40><0C>
[elf] ELF [23403309] software
[01][04][00][00][00][03][B0][0B]
Waiting for a message (11 bytes)...
<01><04><06><0A><03><11><0E><2D><1C><23>
[elf] ELF time [17-03-2010 14:45:00]
[01][06][00][03][00][09][B9][CC]
Waiting for a message (8 bytes)...
<01><06><00><03><00><09>
[01][06][00][06][00][00][69][CB]
Waiting for a message (8 bytes)...
<01><06><00><06><00><00><69>
[01][04][01][00][00][14][F1][F9]
Waiting for a message (45 bytes)...
<01><04><28><39><2D><0E><00><80><00><00><00><00><00><00><00><00><00><00><48><11><36><0A>
<00><00><00><00><4A><50><3C><1A><00><42><99><89><00><42><99><01><5C><38>
[elf] [14:45:57] q1=0.000000, q2=0.000002, t1=76.972656, t2=76.767586, v1=0.000000, v2=0.009417 
// считанные текущие данные

[01][06][00][03][00][1B][39][C1]
Waiting for a message (8 bytes)...
<01><06><00><03><00><1B><39>
[01][06][00][00][0A][03][CF][6B]
Waiting for a message (8 bytes)...
<01><06><00><00><0A><03><6B>
[01][06][00][01][10][0D][14][0F]
Waiting for a message (8 bytes)...
<01><06><00><01><10><0D><14><0F>
[01][06][00][06][00][6A][E9][E4]
Waiting for a message (8 bytes)...
<01><06><00><06><00><6A>
[01][04][01][00][00][14][F1][F9]
Waiting for a message (45 bytes)...
<01><04><28><0A><03><10><00><80><00><00><00><00><41><00><00><00><00><00><00><00><00>
<00><00><00><00><00><00><00><00><47><42><99><87><61><42><99><00><00><00><00><6B>
[elf] [16-03-2010 00:00:00] q=0.000000, t1=76.965584, t2=76.763672, v1=0.000000, v2=0.000000 
// считанные архивные данные
Вот и все. Удачного программирования.
Заметки:
Перспектива:
Драйвер будет сильно дорабатываться под новые задачи и пожелания, будет реализовано чтение всех параметров прибора.
Скачать программу: 
Скачать исходники: 
Протокол: doc/Modbus RTU.doc
Описание: