Obsługa portów COM z poziomu Delphi (wszystkie windowsy)

lofix

Witam...
Po co nam obsługa portów COM?
Otóż wielu zapewne się nie przyda,ale jeżeli ktoś chciałby podłączyć jakieś diody pod COM i sterować nimi z poziomu Delphi..lub podłączyć swoją komórkę i wysłać SMSa z Delphi (przez komórkę), to artykuł jest właśnie dla niego..
Juz prościej się nie da.. :-)
A więc zaczniemy od zdobycia komponentu do obsługi portów COM.
Ja używam CPorta ponieważ jest bardzo prosty w obsłudze...

Ciężko go znależć w internecie..ale ja go dołączę do Demo programu..

A więc wrzucamy na formę następujące komponenty:
3 Buttony, 1 Edit, 1 Memo,1 CheckBox, komponent CPort.
Kwestia rozmieszczenia to już wasza sprawa...

Teraz oprogramowanie zdarzeń tych komponentów:

Pierwszy button będzie otwierał nam wybrany COM.

//Obsluga Przycisku do otwarcia portu
procedure TMainfrm.BtnOtworzClick(Sender: TObject);
begin
  if ComPort.Connected then//jezeli CPort jest polaczony to..
  begin
    ComPort.Close;//zamknij
    BtnOtworz.Caption:='Otwórz';
  end else begin//jezeli nie jest to..
    ComPort.Open; //otworz..
    BtnOtworz.Caption:='Zamknij';
  end;
end;

Ale zanim spróbujemy ów port otworzyć, warto zajrzeć do ustawień by się przekonać czy nasze urządzenie jest podpięte do portu, do którego chcemy mieć dostep..
Do tego służyć nam będzie króciótki kod (naprawdę) służacy do ustawień:

procedure TMainfrm.BtnSettingsClick(Sender: TObject);
begin
 ComPort.ShowSetupDialog;
 //pokazuje nam okno do ustawien
//jest to juz gotowy dialog zrobiony przez
//autora komponentu
end;

Teraz kolej na rzecz najważniejszą...czyli wysyłanie komend na port COM.
Najważniejsza..nie znaczy najtrudniejsza... :-)

procedure TMainfrm.BtnWyslijClick(Sender: TObject);
var
S: String;
begin
  S:= EdtMsg.Text;//Pobieramy text z Edita do zmiennej
  if CBNewLine.Checked then//jezeli checkbox jest zaznaczony
    S:= S+ #13#10;//to wysylamy to na COM w nowej linii
  ComPort.WriteStr(S);//Wyslanie
end;

I pozostaje nam już tylko odczyt znaków przychodzących z COMa :-)
W zdarzeniu OnRXChar komponentu CPort dodajemy:

procedure TMainfrm.ComPortRxChar(Sender: TObject; Count: Integer);
var
RevS: String;
begin
  ComPort.ReadStr(RevS, Count);//odczytujemy String z Portu
  ComMemo.Text :=ComMemo.Text +Revs;//Wyswietlamy go w Memo
end;

I to by było na tyle z prostego przykładu operacji na portach..pacjent żyje i ma sie dobrze.. :) :)

a oto cały kod programu:


(***********************************************************   
CPort Demo by lofix
     mailto: pigpig@wp.pl
      Pozdrowienia dla ekipy 4programmers
       Kod mozesz w dowolny sposob modyfikowac,rob z nim co chcesz
***********************************************************)

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, CPort;//Z tego korzystamy

type
  TMainfrm = class(TForm)
    ComPort: TComPort;
    BtnOtworz: TButton;
    BtnSettings: TButton;
    EdtMsg: TEdit;
    BtnWyslij: TButton;
    CbNewLine: TCheckBox;
    ComMemo: TMemo;
    StatusBar1: TStatusBar;
    BtnClear: TButton;
    BtnKoniec: TButton;
    procedure BtnOtworzClick(Sender: TObject);
    procedure BtnSettingsClick(Sender: TObject);
    procedure BtnWyslijClick(Sender: TObject);
    procedure ComPortRxChar(Sender: TObject; Count: Integer);
    procedure BtnClearClick(Sender: TObject);
    procedure BtnKoniecClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Mainfrm: TMainfrm;

implementation

{$R *.DFM}


//Obsluga Przycisku do otwarcia portu
procedure TMainfrm.BtnOtworzClick(Sender: TObject);
begin
  if ComPort.Connected then//jezeli CPort jest polaczony to..
  begin
    ComPort.Close;//zamknij
    BtnOtworz.Caption:='Otwórz';
  end else begin//jezeli nie jest to..
    ComPort.Open; //otworz..
    BtnOtworz.Caption:='Zamknij';
  end;
end;

procedure TMainfrm.BtnSettingsClick(Sender: TObject);
begin
 ComPort.ShowSetupDialog;
 //pokazuje nam okno do ustawien
//jest to juz gotowy dialog zrobiony przez
//autora komponentu
end;

procedure TMainfrm.BtnWyslijClick(Sender: TObject);
var
S: String;
begin
  S:= EdtMsg.Text;//Pobieramy text z Edita do zmiennej
  if CBNewLine.Checked then//jezeli checkbox jest zaznaczony
    S:= S+ #13#10;//to wysylamy to na COM w nowej linii
  ComPort.WriteStr(S);//tu wysylamy
end;

procedure TMainfrm.ComPortRxChar(Sender: TObject; Count: Integer);
var
RevS: String;
begin
  ComPort.ReadStr(RevS, Count);//odczytujemy String z Portu
  ComMemo.Text :=ComMemo.Text +Revs;//Wyswietlamy go w Memo
end;


//ponizej 2 procedurki (czyszczaca Memo i Zamykajaca program
procedure TMainfrm.BtnClearClick(Sender: TObject);
begin
ComMemo.Clear;//Czyscimy Memo
end;

procedure TMainfrm.BtnKoniecClick(Sender: TObject);
begin
Application.Terminate;//Koniec programu
end;

end.

Jeżeli ktoś jest zainteresowany komunikacją po kablu z komórką to polecam poczytanie o komendach AT..za ich pomoca można z Delphi zrobić duużo (chocby LogoManagera :-) )

Stąd możesz pobrać komponent wraz z DEMO (Strona projektu na SF.net)

31 komentarzy

Witam, tutorial świetny, bez problemu łączę się do COMa jednak okazuje się, że na moje potrzeby nie do końca się sprawdza. Tworzę aplikację, która musi jedynie odbierać dane przesłane przez inną aplikację na tym porcie i tutaj pojawia się mój problem. Tylko jedna z aplikacji może otworzyć port, po otwarciu przez pierwszą druga powoduję błąd połączenie informujący, że port jest już zajęty. Moje pytanie teraz brzmi jak uzyskać połączenie, które tylko monitoruje przepływ danych na COMie, który został otwarty przez inny program?

Dzięki za odpowiedź. Choć nie do końca to tak działa jak piszesz. Zmienna wymagana to TBaudRate (i taką pobiera z listy wyboru) a nie string. Ale dziś znalazłem już na to rozwiązanie. Dzięki za zainteresowanie i chęć pomocy.

Zajrzyj do helpa ComPort...
Masz tam jak byk opisaną właściwość CustomBaudRate (integer)

np:
//odczyt
Edit1.Text := IntToStr(ComPort1.CustomBaudRate);
//zapis
ComPort1.CustomBaudRate := StrToInt(Edit1.Text);

Witam serdecznie Tutek pierwsza klasa!
Pozwolę sobie odgrzebać ten temat:
Mam pytanie, jak pobrać wartość BaudRate portu COM aby ją wyświetlić?
Edit2.Text := ComPort.Port; - wyświetla nuner COMu.
Edit3.Text := ComPort.BaudRate; - natomiast pobranie prędkości wyświetla błąd:
[Error] sterowanie.pas(68): Incompatible types: 'TBaudRate' and 'String'

Jak pogodzić te dwie różne zmienne?

kolego jak rozpakowujesz ten pakiet biblioteczny do dowolnego folderu w delphi to rozpakowuje sie do jeszcze jednego podkatalogu. musisz skopiować zawartość tego podkatalogu do katalogu powyższego. sprawdz czy zadziałało

Więc jak w końcu to zainstalować? Mam Delphi 07, w momencie uruchamiania pakietow (dpk) wyskakuje nowa zakładka (common cos-tam) ale i tak nie moge znaleźć komponentu CPORT, a w momencie kompilownaia source kompiluje i zade komponenty nie dochodza ;/

Co do LPT to polecam zlportio. Wystarczy zapytać google. I działa pod wszystkimi windowsami.

Suuper :) o to mi chodziło. Wielkie dzięki.

Działający komponent można pobrać z zaprzyjaźnionej stronki:
http://www.elektroda.pl/rtvforum/download.php?id=40416
w archiwum zip jest też szczegółowy opis jak go poprawnie zainstalować

a tu również kawałek artykułu na w/w temat:
http://www.elektroda.pl/rtvforum/viewtopic.php?t=139435&highlight=comport

w końcu można zacząć prawdziwą zabawę z procesorami

World is mine :D

a jak sprawdzić czy dane piny są zwarte?
np. żeby zrobić klawiaturę do programu

Nie widzę tego komponentu, (z linku autora, wskakuję na "edytujesz artykuły"), nie znajduję go ani w komponentach, ani w programach. Link od unnamed działa, comport nawet się zainstalował i skompilował, ale w XP odmowa dostępu do portu :(
Znalazłem w sieci inny, na wszystkie windowsy, ale za dolarki, zaś ten: http://www.winsoft.sk/comport.htm po zainstalowaniu wytwarza komunikat: nie można odnaleźć ComPort.bpl
Może ktoś zrobił to na XP w Delphi 2005 i coś poradzi?

Fajne... Spróbuje przez to mojego P800 podłączyć...

No dobra to zainstalowalem komponent znalazlem na
http://delphi.icm.edu.pl/ftp/d30share/comport.zip
Wszystko jest zx godnie z opisem lofix-a tyle ze mam maly blad z kturym nie moge se dac rady. Mianowicie podczasz kompilacji wyskakuje komunikat
Field MainFrm.ComPort does not have a corresponding component.
Remove the declaration?
Jak dam "No" to przekompiluje ole w moencie otwarcia portu jest error access voliation xxxxxxxxxxxx
Plese Help Me .

A jak sterowac tym portem w formie ma pojawic sie napiecie na bicie 1, brak napiecia, napiecie na bicie 2 brak napiecia (...)

Witam
Jest bardzo dobre procedury, tylko może jakieś dobre przykłady, bo w CPort.hlp jest mało przykładów, może znacie strony lub opisy dokładnie jak się robi program i schematy. Góry dziękuje zyzio

nie posiadam i nie wiem jak swtorzyc plik DesignEditors.dcu. jakas podpowiedz?

Piszesz,że trudno jest dostać ten komponent...

Wchodź na http://www.torry.net i tam on jest!

Wszystko cacy, ale nie wiem jak wysterować piny inne niż 2do9(szyna danych), np.pin1 a ta biblioteka niedaje takiej możliwości(chyba).
Na zakończenie wszystkim mogę polecić podobną bibliotekę (smallPort), która w toszkę inny sposób realizuje komunikację(wygodniejszy).
Pozdrowienia dla WSZYSTKICH a zwłaszcza dla LOFIX-a.
jeżeli ktośby chciał jakieś info o współpracy kompa z jakimiś silnikami to dajcie znać.

Mnie pod D7 wypisuje że brakuje pliku .RES i nic z instalacji komponentu.

Aby bez kłopotów dodać komponent do Delphi trzeba poczytać test w Cporcie tam jest opisane.
Mam D7 i wszystko działa PIĘKNIŚCIE

Czy to można zrobić na Delphi Personal. Bo mi coś nie wychodzi, podczas istalowania komponentu wystąpiły problemy, opanowalem je a teraz podczas kompilacji programu pisze ze nie moze znalesc pliku DsgnIntf.dcu ico mam zrobić??

Dzieki temu zbudowalem sobie uklad sterowania moddingiem mojego kompa:)

Przy probie kompilacji CPort w Delphi5 pojawia sie komunikat o braku pliku DsgnIntf.dcu; nie ma go na dysku (ani tez pliku DesignIntf.dcu), czy mam jakies niepelne Delphi???

Nareszcie ktoś się za to wziął!!! Jesteś mistrzem!!!
Mam tylko prośbę: możesz zarzucić link do schematu podłączenia kompa do komórki (Najlepiej dla Siemensa S35i) ?

wstrzymaj sie z calowaniem :/

lofix ! cool :-) jak bym byl laska to bym cie pocalowal :-) hahahah, a ta to tylko daje ci oskara :-) wez machnij sie stary na porty LPT tak jak juz ktos tu wspominal :-) np. laczenie komputerow (cos ala windowsowe laczenie lub ala laczenie w Total Commanderq) :-) to by byl jeszcze wiekszy wypas :-) a jak narazie - gratulacje i czekam na art o LPT

Wunderfull (moze byc wroclawski) dla lofixa

Nareszcie ktoś napisał artykuł na ten temat. Proponuję też aby zająć się również LPT, bo też często ktoś się o to pyta. A może by jeszcze tak dorzucić parę ciekawych rozwiązań hardware'u komunikującego się z kompem (schematy itede itepe...)????

Duże piwo dla lofix-a!!! :)))

Wreszcie coś ciekawego dla ludzi od procków

THX, Przyda sie ;)

Ostatni instalowałem sobie kompoonent CPort i rzeczywiście przy próbie kompilacji wyskakuje błąd: Brak pliku DsgnIntf.dcu!!!!!! Ale poradziłem sobie z tym w taki sposób, jak już gdzieś to czytałem na tej witrynie. Mianowicie zamiast deklaracji modułu DsgnIntf.dcu zadeklarowałem dwa inne: DesignIntf.dcu oraz DesignEditors.dcu i wszystko działa - w Delphi 7, nie wiem jak w innych.
Przy problemach w wersjach 5 i 6 wejdźcie na strone Borlanda:
http://www.borland.pl/tech/dsgnintf.shtml
tam znajdziecie pomoc lub spróbujcie tego co zaproponował lofix na:
http://4programmers.net/view_faq.html?id=393

Powodzenia

P.S. Dzięki lofix, przyda się bardzo.