Hi All, I am trying to develop a simple application which will access a card reader I have connected to com1. It wont be nessesary for any handshaking although I will want an event that is activated by data coming in via that port. Does anybody know of a simple VCL component to handle this - visual components I find easier to use so I have been loking around for one but havent found anything that actually works? I have tried Async32 but cant get that to operate - it wouldnt even let me select 1 stop bit as it seemed to restrict you to either 10,15,or 20 which was a bit strange. I would appreciate any suggestions Thanks Dave. I use a component to access the ComPort. Pretty good, freeware with sources.
Jan 5, 2019 - If you have a couple of USB serial. Delphi serial port free download. Serial port to network proxy This project provides a proxy that allo.
'TComPort is a component that encapsulates Win API serial communication. Serial communication programming is one of the most difficult and not very well documented area in windows programming. Use of TComPort component makes serial communication programming easier than ever.
No knowledge of Win API needed.' This is Delphi 5 compatible, but I ported it to Delphi 7 without problem, as it provide the sources. Regards, Fernando. Gmayo, I thought the same concerning the 10 is 1, 20 is 2 etc but it didnt seem to work out that way - I guess I was probably doing something wrong! I would really appreciate a little sample code on how to read from a com port, as I mentioned I am reading from a RFID card reader that dosnt use CTS,DTR or basically anything apart from just squirting out a card number (prefixed with an ascii code) when it reads a card. Knightmad - i have downloaded the Tcomport but do not know how to port it through for Delphi7 as you mentioned you did - could you advise me how to do that??
Thanks to you both and hopefully I will hear some more from you both Dave.
'Philip' wrote. function TForm1.ReceivePacket: String; //Dumps receive buffer to string var d: array1.80 of Char; s: String; BytesRead: Cardinal; i: Integer; begin s:= '; if ReadFile (ComFile, d, sizeof(d), BytesRead, Nil) then for i:= 1 to BytesRead do s:= s + di; Result:= s; end;.
Any help would be appreciated. Philip, I suggest using a COM-port component like Dejan Crnila's TComport from Then you can read and accumulate the characters as they come in inside an OnRxChar event handler. Then from you button event handler, you can fetch the accumulated characters and empth the array. HTH, JohnH Philip 8/5/2008, 13:15 น.
'Philip' wrote in message news:[email protected]. You can't use third party components with Delphi Turbo Explorer free edition. Yes, you can. You just can't install them into the IDE for use at design-time. But you can instantiate them at runtime. In the case of open-source components, you could add the source code directly to the project if you don't want to use packages.
If I could just figure out how to write my own events then I would be there. Microsoft has detailed documentation on how to handle port events, with code snippets (that you could translate into Pascal): Gambit John Herbster 8/5/2008, 18:26 น.
I suggest using a COM-port component like Dejan Crnila's TComport. 'Philip' wrote You can't use third party components with Delphi Turbo Explorer free edition. If you take Remy's advice to 'instantiate them at runtime', it is really not difficult. You just.include. the TComport source modules and place the module names in the appropriate.uses. clauses. Then at runtime, maybe in the OnFormCreate, You instantiate the TComport objects by doing something like Comport1:= TComport.Create(self); Then you have to set each of the Comport properties according to your programs needs.
That includes creating your own OnRxChar event handler and assigning it to Comport1.OnRxChar:= HTH, JohnH Martin James 8/5/2008, 23:29 น. 'Philip' wrote in message news:[email protected]. Hi, I can read from the serial port when triggered by an event, for example from a button click:- If you want to fire a 'SerialRxData' event, this is 'normally' done by a synchronized call from a read thread through an event property. A read thread is used because of the blocking nature of the WaitCommEvent API when overlapped I/O is not used. This works OK, (mostly). A better alternative is to actually use overlapped I/O and completion routines - one thread can then receive and transmit bufferfulls of data and detect comm events from many serial ports 'at the same time'. Main-thread events can be fired with buffer class instance parameters from a window to which your serial thread posts messages.Don't try this at home.
Unless you want to try for a homebrew solution using synchronized calls, or are happy with overlapped I/O, multiThreading etc, and need very high performance and can put up with lots of debugging, follow the advice of others and create an instance of a serial port component that already works. Rgds, Martin Philip 9/5/2008, 1:41 น. I accept that using the comport library is probably the way to go, but I'm still curious, and I'm enjoying messing about with this for the time being. I haven't quite figured out what the problem is with nonoverlapped I/O. I understand that you can't send and receive at the same time.
That might be a problem if you are running a networking protocol over serial, but if you are talking to a device that has some kind of command / response type protocol then it wouldn't be a problem would it? Even if a byte did arrive whilst you are transmitting it doesn't get lost or cause a delay will it?
It just means that it gets buffered by hardware/OS and we can't read from the buffer until we finish transmitting. The biggest problem seems to be waiting for bytes to arrive and commtimeouts etc, however if we have an event to tell us that bytes are in the buffer then there's no wait. I presume that if I am transmitting bytes and one arrives then the event handler will be triggered to read bytes, but will be blocked until the transmit has finished, and then it will execute fine; is that right?
I think I could live with that. Thanks, Philip Philip 9/5/2008, 7:13 น. I tried what John suggested, and it does work, but with one small hicup (see below). Expanding what John said, this is how you do it:- 1. Unzip the ComPort sources onto your hard drive 2. In your project select Project/Add to Project. Select CPort.pas from the ComPort sources Repeat for the other seven.pas files 3.
Under type add 'ComPort1: TComPort;' 4. In your project Object Inspector/Events create an event handling procedure for event OnCreate. To this procedure add 'ComPort1:= TComport.Create(self);', example:- procedure TForm1.FormCreate(Sender: TObject); begin ComPort1:= TComport.Create(self); end; 6. To make a procedure that receives packets make something like this:- procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer); var Str: String; begin ComPort1.ReadStr(Str, Count); myreceivedpackets:= Str; end; 7. To run that procedure when a packet arrives do something like this:- ComPort1.CustomBaudRate:= mybaudrate; ComPort1.Open; ComPort1.OnRxChar:= CommPort1RxChar; Now some questions. When I compile my program I get this error message:- 'Field Form1.ComPort1 does not have a corresponding component. Remove the declaration?
Yes/No/Cancel' If I click 'no' then the program compiles and runs fine. What is causing this? How can I fix it? My procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer) requires an integer to be passed to it telling the routine how many packets to read from the serial port buffer. The program is working fine and the correct number is passed, but I'm not sure how setting ComPort1.OnRxChar:= CommPort1RxChar achieved this. It almost feels like the statement should be the other way round too.
Going from a program that already worked in Delphi 7 with the ComPort installed in the IDE seems quite easy. However doing all this from scratch for the first time in Turbo Delphi Explorer might be a bit challenging without some clear examples or instructions. Thanks, Philip John Herbster 9/5/2008, 7:37 น. 'Philip' wrote 3. Under type add 'ComPort1: TComPort;' I think that 'ComPort1: TComPort' should be declared in the 'private' section of your form's declaration. Also note that I have move some lines around:. Private ComPort1: TComPort; MyReceivedPackets: string; procedure ComPort1RxChar(Sender: TObject; Count: Integer);.
ComPort1:= TComport.Create(self); ComPort1.CustomBaudRate:= mybaudrate; ComPort1.OnRxChar:= CommPort1RxChar; ComPort1.Open;. Procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer); var Str: String; begin ComPort1.ReadStr(Str, Count); MyReceivedPackets:= MyReceivedPackets + Str; end; What is causing this? How can I fix it?
I think that moving the variable to the private section will fix that. HTH, JohnH Martin James 9/5/2008, 7:52 น. 'Philip' wrote in message news:[email protected].
I accept that using the comport library is probably the way to go, but I'm still curious, and I'm enjoying messing about with this for the time being. I haven't quite figured out what the problem is with nonoverlapped I/O. You can't send and receive at the same time in the same thread. I understand that you can't send and receive at the same time. That might be a problem if you are running a networking protocol over serial, but if you are talking to a device that has some kind of command / response type protocol then it wouldn't be a problem would it? It's not a serios problem anyway - a sperarate receive thread works OK in non-overlapped mode. Even if a byte did arrive whilst you are transmitting it doesn't get lost or cause a delay will it?
It will not normally get lost, no. It just means that it gets buffered by hardware/OS and we can't read from the buffer until we finish transmitting. In many cases, this is not a problem, true. The biggest problem seems to be waiting for bytes to arrive and commtimeouts etc, however if we have an event to tell us that bytes are in the buffer then there's no wait. 'Event' means different things in different contexts An event in Delphi is often accepted to be an event fired in the main thread by a message.
A comm event is someting that has to be waited for., The wait is blocking, and any user thread that calls WaitCommEvent in non-overlapped mode can expect to be useless for any other purpose. i presume that if I am transmitting bytes and one arrives then the event handler will be triggered to read bytes, but will be blocked until the transmit has finished, and then it will execute fine; is that right? I think I could live with that. The main problem is that a thread calling readFile in non-overlapped mode, or waitCommEvent in non-overlapped mode, will be blocked until characters arrive. This means that if you transmit a protocol unit and then call readFile/waitCommEvent from your main thread, your main thread will get stuck if the requested data is not received. To retain sanity, either use overlapped I/O, (preferably in a secondary thread), or non-overlapped I/O and definitely a secondary read thread.
Rgds, Martin Philip 9/5/2008, 7:56 น. 'Philip' wrote in message news:[email protected]. ComPort1.Open; ComPort1.OnRxChar:= CommPort1RxChar; You should be assigning the event handler before opening the port, not afterwards. When I compile my program I get this error message:- 'Field Form1.ComPort1 does not have a corresponding component. Remove the declaration? Yes/No/Cancel' If I click 'no' then the program compiles and runs fine.
What is causing this? How can I fix it? Your form's DFM has a reference to a TComPort object that is not declared in the form class's 'published' section.
You can either let the IDE remove the reference from the DFM for you, and continue using the OnCreate event to instantiate the TComPort manualy. Or else simply move your TComPort declarating into the published section, rename it to match the object Name in the DFM, get rid of the OnCreate handler altogether, and let the RTL handle the rest for you at runtime.
My procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer) requires an integer to be passed to it telling the routine how many packets to read from the serial port buffer. The program is working fine and the correct number is passed, but I'm not sure how setting ComPort1.OnRxChar:= CommPort1RxChar achieved this.
You are assigning an event handler. The TComPort component calls the event handler automatically whenever data arrives on the port. Going from a program that already worked in Delphi 7 with the ComPort installed in the IDE seems quite easy.
That is why your DFM still had an old reference in it. You migrated an existing project from an earlier IDE version. Gambit [email protected] 20/3/2015, 16:25 น.