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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.06.2013, 17:27   #1
vovken1997
Дружелюбный
Форумчанин
 
Аватар для vovken1997
 
Регистрация: 23.02.2012
Сообщений: 692
Вопрос Чтение COM порта

Здравствуйте!
Я разбираюсь с COM портами. Сделал инициализацию и запись. С последним не уверен, т.к. особо не на что отправить. Работаю я в Delphi XE3, как я понял к ней нету стабильных компонентов для работы с ком портами.
Подскажите пожайлуста работающую функцию для чтений из порта. Я пробывал эту:
Код:
procedure TReadThread.Execute;
var
 ComStat: TComStat;
 dwMask, dwError: DWORD;
 OverRead: TOverlapped;
 Buf: array[0..$FF] of Byte;
 dwRead: DWORD;
begin
 OverRead.hEvent := CreateEvent(nil, True, False, nil);
 if OverRead.hEvent = Null then
  raise Exception.Create('Error creating read event');

 FreeOnTerminate*:=*True;

 while not Terminated do
 begin
  if not WaitCommEvent(hPort, dwMask, @OverRead) then
  begin
   if GetLastError = ERROR_IO_PENDING then
    WaitForSingleObject(OverRead.hEvent, INFINITE)
   else
    raise Exception.Create('Error waiting port event');
  end;

  if not ClearCommError(hPort, dwError, @ComStat) then
   raise Exception.Create('Error clearing port');

  dwRead*:= ComStat.cbInQue;

  if dwRead*> 0 then
  begin
   if not ReadFile(hPort, Buf, dwRead, dwRead, @OverRead) then
    raise Exception.Create('Error reading port');
   // В Buf находятся прочитанные байты
   //*Далее идет обработка принятых байтов
  end;
 end; {while}
end;
Но она почему-то не работает. Пишет делфи, что не знает в двух случаях переменную dwRead (я подчеркнул).

То что я зделал в приложении. Осталась только функция для чтения.
Помогите пожайлуста...
Вложения
Тип файла: rar COM.rar (135.5 Кб, 188 просмотров)
-==ЛЮБОЕ ЗНАНИЕ ДОСТИГАЕТСЯ ТОЛЬКО СОБСТВЕННЫМИ УСИЛИЯМИ!!!==-
vovken1997 вне форума Ответить с цитированием
Старый 30.06.2013, 23:19   #2
vovken1997
Дружелюбный
Форумчанин
 
Аватар для vovken1997
 
Регистрация: 23.02.2012
Сообщений: 692
По умолчанию

Код:
...

type
TByteArr = array of byte;
...
var
  Form1: TForm1;
  COM: integer;
  hCOM: THandle;
  COMEd: boolean = False;
  ReadCom: TReadCom;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if (ComboBox1.ItemIndex>=0) and (COMEd=False) then
  begin
    COM:=StrToInt(ComboBox1.Items.Strings[ComboBox1.ItemIndex]);
    Memo1.Lines.Add('Подключение к: COM'+IntToStr(COM));
    hCOM:=OpenPort(COM);
    if hCOM<>INVALID_HANDLE_VALUE then
    begin
      Memo1.Lines.Add('COM'+IntToStr(COM)+' успешно открыт');
      COMEd:=True;
      ReadCom:=TReadCOM.Create(False);
      ReadCom.Priority:=tpNormal;
    end;
  end else
    Memo1.Lines.Add('Выберите порт и убедитесь, что вы уже не подключены к нему');
end;


procedure TForm1.Button3Click(Sender: TObject);
begin
if COMEd=true then
begin
  if Edit1.Text<>'' then
  begin
      if WritePort(hCOM, Edit1.Text)=true then
      Memo1.Lines.Add('Отправлено в COM'+IntToStr(COM)+': '+Edit1.Text)
      else
      Memo1.Lines.Add('Передать информацию в '+IntToStr(COM)+' не удалось');
  end;
end
else
  Memo1.Lines.Add('Подключитесь к порту');

Edit1.Text:='';
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
  for I := 1 to 255 do
  ComboBox1.Items.Add(IntToStr(i));
end;

function TForm1.OpenPort(Open_COM: integer): THandle;
var
Open_hCOM: THandle;
dcbCOM: TDCB;
Open: boolean;
begin
    Open:=True;
    Open_hCOM:=CreateFile(PWideChar('COM'+IntToStr(Open_COM)), GENERIC_READ or GENERIC_WRITE, 0, nil,OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    if Open_hCOM=INVALID_HANDLE_VALUE then
    begin
        Memo1.Lines.Add('Подключиться к порту COM'+IntToStr(COM)+' не удалось');
        Open:=False;
    end;

    if (not GetCommState(Open_hCOM, dcbCOM)) and (Open=True) then
    begin
        Memo1.Lines.Add('Запросить настройки с порта COM'+IntToStr(COM)+' не удалось');
        Open_hCOM:=INVALID_HANDLE_VALUE;
        Open:=False;
    end;

    dcbCOM.BaudRate := CBR_9600;
    dcbCOM.Parity := NOPARITY;
    dcbCOM.ByteSize := 8;
    dcbCOM.StopBits := ONESTOPBIT;

    if (not SetCommState(Open_hCOM,dcbCOM)) and (Open=true) then
    begin
        Memo1.Lines.Add('Установить настройки для COM'+IntToStr(COM)+' не удалось');
        Open_hCOM:=INVALID_HANDLE_VALUE;
        Open:=False;
    end;

    if (not PurgeComm(Open_hCOM, PURGE_TXCLEAR or PURGE_RXCLEAR)) and (Open=true) then
    begin
        Memo1.Lines.Add('Сбросить COM'+IntToStr(COM)+' не удалось');
        Open_hCOM:=INVALID_HANDLE_VALUE;
        Open:=False;
    end;

    if (not SetCommMask(Open_hCOM, EV_RXCHAR)) and (Open=true) then
    begin
        Memo1.Lines.Add('Перевести в обычный режим COM'+IntToStr(COM)+' не удалось');
        Open_hCOM:=INVALID_HANDLE_VALUE;
        Open:=False;
    end;

    OpenPort:=Open_hCOM;
end;


function TForm1.ReadPort(RD_hCOM: THANDLE): string;
var
OverRead: TOverlapped;
read: boolean;
buf: array of Byte;
dwRead: DWORD;
begin
read:=true;
OverRead.hEvent:= CreateEvent(nil, True, False, nil);
if OverRead.hEvent=NULL then read:=False;

if not ReadFile(RD_hCOM,buf, dwRead, dwRead, @Overread) then read:=false;

ReadPort:=ByteToString(buf);
end;

function TForm1.WritePort(WR_hCOM: THANDLE;Str: string): boolean;
var
 dwWrite: DWORD;
 OverWrite: TOverlapped;
 WriteBytes: array of Byte;
 Write: boolean;
 i: integer;
begin
 Write:=True;
 //Строка в массив байт
  SetLength(WriteBytes, Length(str));
    for I := 0 to Length(str) - 1 do
        WriteBytes[I] := ord(str[I + 1]) - 48;

  OverWrite.hEvent := CreateEvent(nil, True, False, nil);
 if OverWrite.hEvent = Null then write:= false;

 if (not WriteFile(WR_hCOM, WriteBytes, SizeOf(WriteBytes),dwWrite, @OverWrite)) and (GetLastError <> ERROR_IO_PENDING) then Write:=False;

 WritePort:=Write;
end;

function TForm1.ByteToString(const Value: Array of Byte): String;
var
    I: integer;
    S : String;
    Litera: char;
begin
    S := '';
    for I := Length(Value)-1 Downto 0 do
    begin
        Litera := Chr(Value[I] + 48);
        S := Litera + S;
    end;
    Result := S;
end;


{ TReadCom }

procedure TReadCom.Execute;
var
str: string;
begin
   while True do
   begin
       str:=Form1.ReadPort(hCOM);
       if str<>'' then Form1.Memo1.Lines.Add('Принято из порта '+IntToStr(COM)+': '+str);
   end;
end;

end.
Вот. Не много поменял. Порт открывает нормально, но когда посылает данные в ком порт, от устройства ответ не получает. Даже не знаю в чём проблема. Ошибок ни каких при работе не присылает. Я посылаю информацию на Arduino UNO, где такой код:
Код:
char msg = ' ';
int pin = 13;

void setup()
{
  pinMode(pin, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  msg = Serial.read();  
  
  Serial.print('OK:'+msg);
}
Ребят, помогите пожайлуста.
-==ЛЮБОЕ ЗНАНИЕ ДОСТИГАЕТСЯ ТОЛЬКО СОБСТВЕННЫМИ УСИЛИЯМИ!!!==-
vovken1997 вне форума Ответить с цитированием
Старый 01.07.2013, 20:31   #3
vovken1997
Дружелюбный
Форумчанин
 
Аватар для vovken1997
 
Регистрация: 23.02.2012
Сообщений: 692
По умолчанию

Короче, частично разобрался. Данные принимаю, но к сожалению в кривой иероглафической форме.
Кто знает, что это за кодировка и как перевести на нормальный язык???
-==ЛЮБОЕ ЗНАНИЕ ДОСТИГАЕТСЯ ТОЛЬКО СОБСТВЕННЫМИ УСИЛИЯМИ!!!==-
vovken1997 вне форума Ответить с цитированием
Старый 01.07.2013, 20:45   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

похоже на UTF8.
а может у вас там бинарные данные, а не тупо текст?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2013, 20:50   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

vovken1997, скопируйте и в любом онлайн-декодере попробуйте определить. Тоже подозреваю, что utf8 вперемешку с бинарными данными
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.07.2013, 21:54   #6
vovken1997
Дружелюбный
Форумчанин
 
Аватар для vovken1997
 
Регистрация: 23.02.2012
Сообщений: 692
По умолчанию

Я общаюсь с платой Arduino UNO в которой запрограммирован код:
Код:
void setup()
{
  Serial.begin(9600);
}

void loop()
{
    Serial.print('123');
}
Спасибо за совет, сейчас попробую раскодировать.


Не раскодируется, пример текста:
Цитата:
Прочитано из порта COM5: +ЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’В ЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’В ЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’В ЄЉЄВЄЉз9аfШ ЇNђчєl0}ъt№ЖћШ@l 7m±A~Щ`пк1І№6(І’°БЊ3д{b±ЃЬґЕщe ѓлЦЊ‘Ч€
Дbѓ*Дr;,6И/\їvґlDіБМ™3е{b±ЃЬ
Прочитано из порта COM5: +Љ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄ ЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄ ЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’Љ
Прочитано из порта COM5: +ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉ
Прочитано из порта COM5: +Љ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄ ЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄ ЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄЉЉ’ВЄ ЉЉ’ВЄЉЉ’ВЄ                                  
COM5 отключон
-==ЛЮБОЕ ЗНАНИЕ ДОСТИГАЕТСЯ ТОЛЬКО СОБСТВЕННЫМИ УСИЛИЯМИ!!!==-

Последний раз редактировалось vovken1997; 01.07.2013 в 22:02.
vovken1997 вне форума Ответить с цитированием
Старый 01.07.2013, 22:55   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вам нужен маркер начала пакета данных, у вас скорее всего теряется пару байт.
так же если у вас юникод делфи, то читать надо в ансистроки.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2013, 23:07   #8
vovken1997
Дружелюбный
Форумчанин
 
Аватар для vovken1997
 
Регистрация: 23.02.2012
Сообщений: 692
По умолчанию

Вот такая у меня ситуация. С платой я ошибался, я отправлял цифры как строку, когда попробывал передать как цифры, к примеру передовал 54, то получил:
Цитата:
+54
Њ+L
Њ+L - это переход на новую строку.

Как теперь сделать, чтоб принимать не циифры, а буквы?
-==ЛЮБОЕ ЗНАНИЕ ДОСТИГАЕТСЯ ТОЛЬКО СОБСТВЕННЫМИ УСИЛИЯМИ!!!==-
vovken1997 вне форума Ответить с цитированием
Старый 01.07.2013, 23:35   #9
vovken1997
Дружелюбный
Форумчанин
 
Аватар для vovken1997
 
Регистрация: 23.02.2012
Сообщений: 692
По умолчанию

УРА!!!!!!!!!!
Вся информация отправленная с платы в нормальном виде приходит на компьютер, если забыть про то, что перед каждой строчкой знак "+", но его легко убрать.

До платы вся информация идёт в ASCII кодировке. То есть отправили вы "0", прийдёт на плату "48" и т.д.
Пример программы для Arduino UNO:
Код:
int ledPin1=7;
int ledPin2=8;
int state=0;

void setup()
{
  pinMode(ledPin1,OUTPUT);
  pinMode(ledPin2,OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available()>0)
  {
    state=Serial.read();
  }
  if (state==48) digitalWrite(ledPin1,LOW);
  if (state==49) digitalWrite(ledPin1,HIGH); 
  if (state==50) digitalWrite(ledPin2, LOW);
  if (state==51) digitalWrite(ledPin2,HIGH);
}
К портам 7 и 8 подключите светодиоды.

Теперь, если плата подключена к компьютеру, можно открыть COM терминал, подключиться к порту на котором находиться плата, и отправив "1", к примеру, зажеч светодиод на 7-ом порту, а отправив "0", вы его потушите и т.д.

В вложении исходник терминала, может кому пригодиться.
Вложения
Тип файла: rar COM терминал.rar (146.6 Кб, 547 просмотров)
-==ЛЮБОЕ ЗНАНИЕ ДОСТИГАЕТСЯ ТОЛЬКО СОБСТВЕННЫМИ УСИЛИЯМИ!!!==-

Последний раз редактировалось vovken1997; 02.07.2013 в 00:29. Причина: Всё получилось, вопросы заменены на исходники
vovken1997 вне форума Ответить с цитированием
Старый 09.11.2013, 11:32   #10
den4ik221
Новичок
Джуниор
 
Регистрация: 09.11.2013
Сообщений: 1
По умолчанию

Я тоже работаю с делфи и ардуино, пробовал отправлять данные на ардуино с делфи через порт, спокойно отправляется, что цифры, что буквы. С платы в порт тоже отправить данные не проблема, но вот принять данные на дельфи, это уже проблема, не могу разобраться что к чему, язык ардуино знаю, но в дельфи не силен может кто поможет?
den4ik221 вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение com-порта на java danyamaster Фриланс 3 15.02.2013 14:09
Склейка шестнадцатиричных чисел, чтение с COM порта vpn Общие вопросы C/C++ 2 05.02.2013 10:05
Чтение с COM-порта через HyperTerminal rashid1988 Общие вопросы Delphi 9 20.04.2012 09:56
Чтение данных с COM порта 232 Dimitr_88 Общие вопросы C/C++ 10 03.09.2010 10:39
чтение с COM-порта в отдельном потоке не получается lexluter1988 Общие вопросы .NET 2 25.05.2010 20:40