roboforum.ru

Технический форум по робототехнике.
Текущее время: 19 июл 2025, 01:04

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 17:55 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
Добрый вечер всем! Подскажите пожалуйста,я новенький, совсем новенький :)

Никак не могу на форуме найти ответа на свой вопрос.

В общем, есть у меня ардуина мега, она отправляет данные в COM порт, ну в смысле виртуальный COM порт, на компе. Я написал программу на Delphi, ибо больше ни на чем не умею, которая случает порт. Чтение идет в асинхронном режиме с использованием эвентов. Я до этого ничего подобного не делал и не совсем ещё разбираюсь в этом. Нашел в сети кучу описаний работы и реализовал наконец. Уже 2 дня мучаюсь.

Сначала пытался в синхронном режиме, без эвентов, чтение было, но команды принимались то целиком, то "кусками". Прочитал, что лучше делать с использованием эвентов, но все-равно не получается. В плату залит скетч, который раз в 5 секунд выдает сообщение на COM порт. Стоит точка остановки в дебаггере, эвент работает четко, в момент отправки сообщения платой код активируется. Все бы ничего, но проблема вот в чем. Отправляется строчка текста: ABCD1234, кучу раз она так и принимается, а бывает что проскакивают разы типа CD1234 или 1234 и т.п. Кто может помочь, буду очень благодарен.

Вот код инициализации порта:

Цитата:
begin
PortString := 'COM' + ComboBox5.Text;
CommHandle := CreateFile(PChar(PortString), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
unit2.CommHandle := CommHandle;

if (CommHandle = INVALID_HANDLE_VALUE) then
begin
MessageDlg('Can not open the specified port', mtError, [mbOK], 0);
end
else
begin
GetCommState(CommHandle, DCB);
DCB.BaudRate := CBR_115200;
DCB.Parity := NOPARITY;
DCB.ByteSize := 8;
DCB.StopBits := OneStopBit;

SetCommState(CommHandle, DCB);

end;


код метода execute потока, в котором крутится постоянное ожидание событий и их обработка:

Код:
var
    CurrentState : TComStat;
    AvaibleBytes,
    ErrCode,
    RealRead     : Cardinal;
    ReadOL       : TOverLapped;
    Signaled,
    Mask         : DWORD;
    BytesTrans   : DWORD;
    bReadable    : Boolean;
    MyBuff: array[0..1023] of Char;
begin
FillChar(ReadOL, SizeOf(ReadOL), 0);
ReadOL.hEvent:= CreateEvent(nil, True, True, nil);

SetCommMask(CommHandle, EV_RXCHAR);


WaitCommEvent(CommHandle, Mask, @ReadOL);

Signaled:= WaitForSingleObject(ReadOL.hEvent, INFINITE);
if (Signaled  = WAIT_OBJECT_0) then
  begin
  if GetOverlappedResult(CommHandle, ReadOL, BytesTrans, False) then
    begin

    if (Mask and EV_RXCHAR) <> 0 then
      begin

      ClearCommError(CommHandle, ErrCode, @CurrentState);

      AvaibleBytes:= CurrentState.cbInQue;

      bReadable:= AvaibleBytes > 0;

      if bReadable then
        begin
        ReadFile(CommHandle, MyBuff, SizeOf(MyBuff), RealRead, @ReadOL);// then begin
        mm := string(MyBuff);
       
        Synchronize(addData);
       
        end;
      end;
    end;
  end;
end;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 22:12 
Не в сети
Аватара пользователя

Зарегистрирован: 04 дек 2008, 22:44
Сообщения: 4363
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович
Понизь скорость приема/передачи по порту, 56000 например - мне помогло. Прблема походу у тебя в том что евент не успевает обработаться а ему уже нужно принимать следующий поток данных из порта. Путей здесь два: 1) уже называл выше - понизить скорость приема/передачи 2) оптимизировать код евента

_________________
if(!Operate) Read(pDatasheet);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 22:23 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
на разных скоростях пробовал, до 14400 опускался и не помогало :( тоже сначала показалось что так решу проблему

но попробую ещё поэксперементировать. пробовал на 115200, на 57600 и на 14400


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 22:26 
Не в сети
Аватара пользователя

Зарегистрирован: 04 дек 2008, 22:44
Сообщения: 4363
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович
А шнур какой у тебя COM портовый (имеется ввиду длина, экранирование)?

_________________
if(!Operate) Read(pDatasheet);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 22:31 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
По поводу экранирования не знаю, длина пол-метра примерно, шнурок mini USB

скорость 4800 и все-равно проскакивают ошибки :( не знаю что с этим делать


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 22:56 
Не в сети
Аватара пользователя

Зарегистрирован: 04 дек 2008, 22:44
Сообщения: 4363
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович
Попробуйте оптимизировать код

_________________
if(!Operate) Read(pDatasheet);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 23:24 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
в том то и дело, что я не знаю что тут можно оптимизировать, я крутил и так и так уже, все перепробовал :(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 23:30 
Не в сети
Аватара пользователя

Зарегистрирован: 04 дек 2008, 22:44
Сообщения: 4363
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович
По сути в евенте сделать получение и сохранение данных, а обработку в основной программе делай

_________________
if(!Operate) Read(pDatasheet);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 23:34 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
в эвенте имеется ввиду в потоке да?

думаешь поможет?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 20 окт 2010, 23:45 
Не в сети
Аватара пользователя

Зарегистрирован: 04 дек 2008, 22:44
Сообщения: 4363
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович
1)Да в потоке
2)Я так оптимизировал

_________________
if(!Operate) Read(pDatasheet);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 21 окт 2010, 13:58 
Не в сети

Зарегистрирован: 06 июл 2010, 16:36
Сообщения: 198
Откуда: Черногорск
прог. языки: Objective-C, C#, C, C++
Вам можно попробовать модернизировать посылку и организовать приём данных до символа 13 и/или 10, что соответсвует "\r\n", т.е. до перевода каретки и/или новой строки. Таким образом, принимая пришедшие данные до этого символа, будет суммироваться приём посылки. У меня нечто похожее было, но не да делфи, а на C# под VS2008. Принцип один и тот же...


Последний раз редактировалось Rockman 21 окт 2010, 14:04, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 21 окт 2010, 14:02 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
кстати, отправка из контроллера итак идет впаре с этим символом(в конце), да и идеи были сделать что-то похожее, но на крайний случай если не разберусь :)

спасибо за ответ


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 21 окт 2010, 14:06 
Не в сети

Зарегистрирован: 06 июл 2010, 16:36
Сообщения: 198
Откуда: Черногорск
прог. языки: Objective-C, C#, C, C++
Видимо событие приёма данных принимает вытолкнутые асинхронно в буфер данные. Далеко не всегда принимается весь пакет, поэтому частями и получается. Я с arduino так и принимаю данные до \r\n - все работает без проблем, пожалуйста :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 22 окт 2010, 10:04 
Не в сети

Зарегистрирован: 20 окт 2010, 17:38
Сообщения: 32
Откуда: Москва
прог. языки: Delphi,Morph
ФИО: Андрей
Увеличил таймауты до 100, все заработало, правда несколько передач сливаются в одну. На стороне устройства добавил добавку символов #13 и #10, считанный буфер передаю функции, которая "расцепляет" сообщения ориентируясь на эти "разделители". Вроде все работает, пока тестирую.

Нужна на сто процентов стабильная передача, потеря одного из сообщений - весь проект под угрозой, несмотря на то, что аппаратная часть, над которой и бился большую часть времени работает идеально.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Delphi и COM порт
СообщениеДобавлено: 22 окт 2010, 11:19 
Не в сети

Зарегистрирован: 27 авг 2008, 10:45
Сообщения: 1981
Откуда: Харьков
прог. языки: С/С++
Если нужна на 100% стабильная - скорее всего нужен сверху протокол, устойчивый к потерям. Чтобы на каждый пакет в ответ слал подтверждение, пакеты защищены контрольными суммами и передающее устройство, не получив подтверждения, отправляло пакет повторно.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO