Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Lazarus, Free Pascal, CodeTyphon
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.08.2019, 08:47   #1
PTyTb32
Форумчанин
 
Регистрация: 06.10.2013
Сообщений: 216
Вопрос Чтение ttyUSB0

Привет имеется такой код
Код:
procedure SdpoSerial1RxData(Sender: TObject);
var Rx, Line, s:string;
i:integer;
begin
sleep(50); //это немного помогает, да знаю надо убрать
Rx:=SdpoSerial1.ReadData;
line:='';
for i:=0 to length(Rx) - 1 do
line:=line+' '+inttoHex(ord(Rx[i+1]),2);
memo1.lines.add('Rx: '+line);
end;
при отправке 2-х и более сообщений пакеты приходят не целыми, а частями. тут модбас по этому я не знаю сколько байт будет сообщение думал уже с помощью потока сделать, но тоже не вышло..
Подскажите как правильно принимать такие данные плез...
PTyTb32 вне форума Ответить с цитированием
Старый 02.08.2019, 08:51   #2
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

Принимайте все что есть, а в другом потоке производите разбор.
К устройству наверняка есть мануал в котором описано какие пакеты идут и какой длиной.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 02.08.2019, 08:53   #3
PTyTb32
Форумчанин
 
Регистрация: 06.10.2013
Сообщений: 216
По умолчанию

Цитата:
Сообщение от WorldMaster Посмотреть сообщение
К устройству наверняка есть мануал в котором описано какие пакеты идут и какой длиной.
в этом мануале сказано какие регистры за что отвечают и что используется ModBus RTU
3-й байт говорит сколько байт будет дальше, но он третий... он не первый, как его ловить? бывает приходит в мемо такое:
Rx: 01
Rx: 03 06 d3 ....
и какой из них 3?


И как данные передать в поток? вызывается процедура SdpoSerial1RxData и в ней я создаю новый поток и передаю ему полученные данные, к примеру там будет 01, потом снова вызывается эта процедура и снова создает поток передавая ему остальные данные, в итоге 1 пакет данных в 2-х потоках

Последний раз редактировалось PTyTb32; 02.08.2019 в 08:59.
PTyTb32 вне форума Ответить с цитированием
Старый 02.08.2019, 09:31   #4
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

На делфи не писал уже тыщу лет. Не скажу что там да как. Но принцип везде одинаковый.
Создаете большой буфер.
Как там у вас опрос происходит? По событию или самостоятельно читать надо?
Если по событию то ваще все хорошо. Пихаете все данные в общий буфер и все.
Затем у вас наверняка есть какой то стартовый байт. После приема данных смотрите в буфер ищете первый попавшийся байт похожий на стартовый. Затем берете следующий байт где у вас там длина, если в буфере есть столько данных то достаете их и проверяете на правильность или разбираете там как вам нужно.
Если данных нету то ждете пока еще придет.
Если данные не прошли проверку то ищете следующий байт похожий на стартовый а все что до него отбрасываете.

и будет вам счастье.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 02.08.2019, 10:00   #5
PTyTb32
Форумчанин
 
Регистрация: 06.10.2013
Сообщений: 216
По умолчанию

Цитата:
Сообщение от WorldMaster Посмотреть сообщение
Как там у вас опрос происходит? По событию или самостоятельно читать надо?
создается список событий к примеру такого то числа во столько то включить указанный пин, а 3 других пина в автомате работают (зависят от трех пинов другого устройства) и таймер идет по этому списку смотрит что нужно делать в каждом пункте
ModBus устроен таким образом что 1 бит это всегда адрес, второй всегда функция, третий количество бит дальше, без учета CRC и сам CRC. дело в том что стартовых байт может быть очень много.. а таймер работает быстро.. и я совсем не могу представить как организовать поток..... пытаюсь как в примере сделать и программа зависает
PTyTb32 вне форума Ответить с цитированием
Старый 02.08.2019, 10:29   #6
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

Чего то вы путаете наверное байт и бит.
У вас отношения мастер и раб. что еще может быть проще.
Вы инициируете передачу:
Отправляете пакет запроса и ждете в ответ требуемое количество байт для определения длины. В вашем случае 3. То есть крутитесь в цикле while пока не дождетесь 3 байт. Затем у вас уже известно сколько дальше будет данных и продолжаете ждать пока весь пакет не придет.

Это уже второй метод получения данных.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 02.08.2019, 10:35   #7
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Модбас RTU строго регламентирует задержку между байтами пакета, это во-первых, и работает только по запросу мастера во-вторых. Поэтому некоторая задержка перед выдачей команды - и читать до нужной длины либо тайм-аута. Приход одного байта - это битый пакет, такого не должно быть часто. Возможно таймауты порта занижены. Или вольная трактовка modbus разрабами железа )) Попробуйте дописывать принятые данные в конец буфера до нужной длины либо тайм-аута.

И таки да, сколько байт должен выплюнуть в ответ модбас - известно заранее
Black Fregat вне форума Ответить с цитированием
Старый 02.08.2019, 11:07   #8
PTyTb32
Форумчанин
 
Регистрация: 06.10.2013
Сообщений: 216
По умолчанию

Цитата:
Сообщение от Black Fregat Посмотреть сообщение
и читать до нужной длины либо тайм-аута.
таймаут отпадает я использую преобразователь порта. количество байт то 5 то 71 приходит хотя прошу 7... он не теряет данные если он их забыл, то он ставит их в начало следующего пакета. в процедуре приема данных уже крутятся 2 цикла while 1 ждет минимум 3 байта, второй ждет (значение 3-го байта +2) после чего считаю что покет полностью получен, но нет все равно происходит несусветная дичь! Более того эта программа должна будет крутиться на распберри и тут уже не уверен что мой говнокод ее не погубит..если бы получалось я бы не стал спрашивать, но последние пару дней я просто перебераю варианты того как можно это реализовать и получаю либо кашу данных либо зависание программы (когда она почему то виснет в цикле)

даже с 1 реле если работать я вижу картину
TX(8):...
RX(7):...
TX(8):...
RX(6):...
TX(8):...
RX(9):...
в скобках количество байт в пакете

процедура приема

Код:
procedure TForm1.SdpoSerial1RxData(Sender: TObject);
var
  Line, s: string;
  i, Count: integer;

begin
  Rx := Rx + SdpoSerial1.ReadData;
  Line := '';
  while Length(Rx) < 3 do
  begin
    Application.ProcessMessages;
    Rx := rx + SdpoSerial1.ReadData;
  end;

  Count := HexToInt(IntTohex(Ord(Rx[3]), 2)) + 2;
  while Length(Rx) < Count do
  begin
    Application.ProcessMessages;
    Rx := rx + SdpoSerial1.ReadData;
  end;
  //rx = 05 03 02 00 01 88 44
  for i := 0 to Length(Rx) - 1 do
  begin
    Line := Line + ' ' + IntTohex(Ord(Rx[i + 1]), 2);

  end;

  memo1.Lines.add('RX(' + IntToStr(Length(Rx)) + '): ' + Line);
  if HexToInt(IntTohex(Ord(Rx[1]), 2)) > 4 then
    if HexToInt(IntTohex(Ord(Rx[5]), 2)) = 0 then
      set_smh(HexToInt(IntTohex(Ord(Rx[1]), 2)) - 4, 5, ); //тут не хватает регистра
  rx := '';

Последний раз редактировалось PTyTb32; 02.08.2019 в 11:18.
PTyTb32 вне форума Ответить с цитированием
Старый 02.08.2019, 11:34   #9
WorldMaster
Старожил
 
Аватар для WorldMaster
 
Регистрация: 25.08.2011
Сообщений: 2,841
По умолчанию

а вы уверены что вот здесь есть данные?
Код:
begin
    Application.ProcessMessages;
    Rx := rx + SdpoSerial1.ReadData;  <----
  end;
Может там есть флаг какойнибудь?? типа ByteToRead или CountInBuffer?
Ну и вставьте там задержку в цикле мс 20 или 50.

Код:
Length(Rx)
Это строка или массив?? Строка наверное.. то как вы длину то смотрите?
Мне кажется лучше организовать массив байт длиной в 255 например и счетчик считанных байт.
Skype - wmaster_s E-Mail - WorldMasters@gmail.com
Работаем по 3 критериям - быстро, качественно, недорого. Заказчик выбирает любые два.
WorldMaster вне форума Ответить с цитированием
Старый 02.08.2019, 11:46   #10
PTyTb32
Форумчанин
 
Регистрация: 06.10.2013
Сообщений: 216
По умолчанию

Цитата:
Сообщение от WorldMaster Посмотреть сообщение
Это строка или массив?? Строка наверное.. то как вы длину то смотрите?
это строка, и в ней что то написано, я даже не знаю в каком формате там данные, однако вот так
Код:
IntTohex(Ord(Rx[3]), 2)
я получаю "03" - длинна данных в 10-и ричном фиде формата строки
PTyTb32 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
XML чтение nwhta WPF, UWP, WinRT, XAML 0 18.11.2014 14:08
Чтение mp3 Predator199 PHP 5 04.09.2012 19:28
чтение XML Gudzik11 Общие вопросы Delphi 2 05.12.2011 21:25
Чтение ini romanzi Общие вопросы Delphi 1 20.06.2011 13:33
Чтение MDL Gr@nd Общие вопросы Delphi 0 08.06.2009 06:58