Никак не могу на форуме найти ответа на свой вопрос.
В общем, есть у меня ардуина мега, она отправляет данные в 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;