Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > считать данные с контроллера по СОМ-порту


Автор: Тиль 21.9.2010, 13:04
Есть контроллер. К нему прилагается описание производителя. необходимо считать данные с данного контроллера, но с теми параметрами, которые есть в документации не получается. ВОт мой код:
Код

procedure TMainFrm.Button1Click(Sender: TObject);
const
  SendBuf: array [0..6] of Byte = ($01, $03, $00, $02D, $02E, $02F, $30);
var
  ReadBuf: PByte; // буф. чтения
  Count: Integer; // ск. прочитано
  S: String;
  I: Integer;
begin
  MyPort.Write(@SendBuf[0], Length(SendBuf));  // запись
  Count := MyPort.SleepAndRead(100, Pointer(ReadBuf)); // пауза 100 мс и чтение
   if (Count > 0) then
  for I := 0 to Count -1 do
  begin
    S := S + '/' + IntToStr(ReadBuf^);
    Inc(ReadBuf);
  end else
    S := 'нет данных...';
  Memo1.Lines.Add(S);
end


в чем может быть пробьлема?данных при чтении нет просто...

Автор: UniBomb 21.9.2010, 13:20
Тиль, по коду мало чего могу сказать, но вот первое что бросилось в глаза - неправильно составленная команда. Должно быть восемь байт (01 03 00 2D 2E 2F 89 BF). 89 BF - это контрольная сумма. Но даже если бы запрос был правильным, то вам пришли бы не данные, а исключение: 2E, 2F - это количество считываемых регистров. Столько регистров в тех приборах нет, и максимальное количество передаваемых байт равно 133.

Автор: Тиль 21.9.2010, 13:44
а как тогда их считать? с другим блоком у меня так канало
ВОТ:
Код

SendBuf: array [0..7] of Byte = ($33, $04, $02, $40, $00, $06, $74, $76);

Автор: UniBomb 21.9.2010, 14:11
Тиль, расскажите мне какой смысл вкладываете в этот набор данных.

Автор: Тиль 21.9.2010, 14:36
в них содержатся значения о контроллере, которые мне необходимо считать.......или вы про что спрашиваете?

Автор: UniBomb 21.9.2010, 14:46
Тиль, нет, я хотел, что бы вы рассказали мне что означает каждый байт в ваших посылках. У меня просто складывается впечатление, что вы совершенно незнакомы с модбасом. Команда 03 выглядит следующим образом:

|адрес устройства|команда|первый регистр (ст.б.)|первый регистр (мл.б.)|количество регистров(ст.б.)|количество регистров(мл.б.)|crc16(ст.б.)|crc16(мл.б.)|

Таким образом получается, что вы пытаетесь запросить 11823 регистров (это $02E, $02F в вашем запросе) начиная с регистра номер 2D. Правильной контрольной суммы вы не предоставили и прибор имеет полное право проигнорировать ваш запрос. Запрашивать надо столько регистров, что бы ответ не превышал 133 байта. Т.е. максимум 64 регистра.

О том как считать crc16 можно почитать например http://www.google.ru/search?hl=ru&newwindow=1&rlz=1C1_____en___RU387&q=%D1%80%D0%B0%D1%81%D1%87%D1%91%D1%82+crc16+%D0%B2+delphi&aq=f&aqi=&aql=&oq=&gs_rfai=.


Цитата(Тиль @  21.9.2010,  14:44 Найти цитируемый пост)
с другим блоком у меня так канало

Если верить описанию прибора из аттача, то "канать" ну никак не могло, ибо функция 04 приборами не поддерживается.

Добавлено через 2 минуты и 57 секунд
И да, для отладки работы c различными приборами лучше всего пользоваться различными терминальными программами с поддержкой нужных протоколов. Для работы с модбасом рекомендую использовать http://www.agrostroy.ru/index.php?page=4.

Автор: Тиль 22.9.2010, 05:21
в том то и дело что незнаком...

Автор: UniBomb 22.9.2010, 10:49
Цитата(Тиль @  22.9.2010,  06:21 Найти цитируемый пост)
в том то и дело что незнаком... 

Так с этого и надо было начинать. Ознакомление с протоколом можно начать с http://www.modbus.org/specs.php страницы. Так же в интернетах не так уж и редко встречаются описания протокола на русском.

Что можно добавить: из описания прибора видно, что поддерживаются функции 3 и 6. Функция 3 - это чтение регистров (одного или нескольких) хранения, функция 6 соответсвенно запись (правда только одного).

Формат функции чтения я уже приводил выше. С учётом описания прибора функция может иметь следующий вид:

Код

01 03 00 2D 00 10 D4 0F
|  |    |    |     |
|  |    |    |     +-- CRC16
|  |    |    +-------- количество регистров, которые хотим прочитать
|  |    +------------- адрес первого регистра
|  +------------------ команда
+--------------------- адрес устройства в сети



Читать 16 регистров (т.е. все) начиная с адреса 2D.

ответ будет такого вида:

01 03 20 xx xx xx .... xx xx crc crc

Число 20 (в 16-ричной сс) означает количество байт данных в поле данных (это байты xx).

Функция 06 ничем не сложнее и имеет схожий синтаксис:

Код

01 06 00 2D xx xx yy yy
|  |    |    |     |
|  |    |    |     +-- CRC16
|  |    |    +-------- значение переписываемого регистра
|  |    +------------- адрес перезаписываемого регистра
|  +------------------ команда
+--------------------- адрес устройства в сети


Если команда успешно выполнена, то ответ совпадает с запросом.


Что касается CRC16 - в интернете полно реализаций (например http://ru.wikipedia.org/wiki/%D0%A6%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B8%D0%B7%D0%B1%D1%8B%D1%82%D0%BE%D1%87%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4#CRC-16), только следует помнить, что для модбаса полином должен быть A001 и начальное сначение FFFF.

Автор: northener 23.9.2010, 02:33
Цитата(Тиль @  22.9.2010,  05:21 Найти цитируемый пост)
в том то и дело что незнаком... 

А для кого мы пишем описания, документацию и т.п.?
И это при том при всём, что писать документацию - нет более ненавистной работы!

Автор: Тиль 30.9.2010, 07:32
все нормально все читается за исключением одного: у меня в первом регистре лежит четырехзначтное число, вот оно то и не читается..
мне выдается такой ответ от прибора:
/1/3/32/8/50/165/0/0/0/170/0/132/0/0/0/0/0/248/0/209/255/255/6/92/0/9/0/0/0/0/0/0/0/0/33/50
я нашел программу производителя которая считывает с этого прибора, там показатели такие:см.аттач
сразу видно что все данные нашлись:
/1/3/32/8/50/0/165/0/0/0/170/0/132/0/0/0/0/0/248/0/209/255/255/6/92/0/9/0/0/0/0/0/0/0/0/33/50
а вот верхнее значение, которое стоит самым первым нет(2126)
в чем может быть дело? 
я так понял из этого ответа:
1-адрес устройства,3-функция чтения, 32-количество отданных байт, и вот в 8/50 и кроется это число 2126...только вот как прочитать его?


все очень оказалось просто:8*256+50=2098

Автор: UniBomb 1.10.2010, 08:17
/*невнимательно прочитал последнее сообщение*/

Автор: tyro 7.3.2011, 16:15
Подскажите пожалуйста, а как разделить фреймы (то есть определить начало следующего сообщения) при приеме информации по протоколу modbus rtu?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)