I too found myself in the position of going on using CBuilder 6 and the free Turbopower serial port component for much longer than I expected. I had a couple of warnings about this cosy state of affairs. The first being that after getting XE I could not load the Turbopower component.
So far so good! For testing and see thing clears I send from Arduino secuently a 27 char string: ( instead of a string filled with 24 'values' ending with 'end') 'N888end' N: string with numbers 'Laabbbcccdddeeefffggghhhend' L: string with letters Now I can see if a diplayed string on my Lazarus form is from one and the same sended string or an mixed string from 2 sended string! After a while and lots of coding and 'adjustments' I got a stable displayed string. ( apearently I don't need a delimiter in Lazars, but I DO in mikropAscal Arduino when receving from RS232 ) Next thing I wanted to run the application for a long time and 'catch' wrong strings by just checking: first char is it an 'L' or an 'N'?
If not: increment and display the errornumber on my form. As learned the first char in a string is placed at position 0 as in stringIN0, but then I found out i had to check stringIN1.
See, picture. Ok, not a big deal but what does it mean? Still, have to do troubleshouting etc, sometimes the application hangs soon, other times it runs longer.
( could it because of debug-mode instead of runnng it as a 'free' programm? ) By the way somehow I don't trust the timers, or maybe I have a programm-error/mistake. I also need some code if there's nog data OR time out, see.CODE 'cause it reads even when there is a time out OR no dataReady. I see several problems. (1) The loop will fail to run if there are 27 or more characters in the comm buffer (2) The timeout value is never reset, so eventually your delay loop will only sleep for 1 mSec and then exit (3) I don't understand what you are trying to accomplish with the loop, delay, and reading the input while the buffer contains less than 27 characters.
![Component Component](http://wiki.freepascal.org/images/c/cf/P_SEN_003.png)
You might want to bypass the dataRead until the buffer has at least the 27 characters that make up the string. So when waitingData =27, you can do the dataRead which will read the entire string and remove 27 characters from the buffer. There is no need for your timeout loop, as the dataRead will read either a packet or a terminated string.
You can check the length of the string to see if it is the expected 27 characters. Something else to consider is how strings are defined in Pascal and Lazarus. A 'short' string has its length (up to 255 characters) in a byte at stIn0, and a 'wide' string uses two bytes to allow up to 65535 characters. There is also a PChar which is a null terminated string. Here is an explanation I got from the comp.lang.pascal.delphi.misc usenet newsgroup. I think I see what you are trying to do. I assume that timer2 is an ISR that runs at a certain rate to poll the serial port and display the string.
So you have a loop that runs until there are at least 27 characters in the buffer, or timeout occurs. If there is a timeout then it exits the ISR and waits for another timer2 interrupt.
It seems that it would be better to use the 'FOnRxData: TNotifyEvent;' and code an event handler to process the data. And you might want to read the serial port one byte at a time so you can detect the start character and build the string until the last character is received, and then display the result. If the strings are being sent at a comfortably readable rate (up to 5/sec), you should be able to see the data change.
You might also want to display the strings in a TMemo box so you can observe the sequential strings. Timer2 sends to Arduino and Arduino repsonses immidiately with following code: ( by the way, I removed timer1 that indicated the system time each 1000ms ) I understand I have to change the Lazarus code and I need top learn more en get more understanding. Next week, gonna work and use your suggestions from your previous posts! Tnx in advance! Here my Arduino mikroPascal code ( only the main-code and procedure. Not the init etc ) After receiving/reading the string coming from Lazarus, the Arduino imidiately responds! Just used the Usart Terminla and that shows that the string coming from Arduino are sends 100% Ok.
Defenitly I have to work on the lazarus part! TLazSerial v0.1 Serial Port Component for Lazarus (windows and linux). By Jurassic Pork 03/2013 This library is Free software; you can rediStribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is diStributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; withOut even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a Copy of the GNU Library General Public License along with This library; if not, Write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA, USA.
Based on: - SdpoSerial v0.1.4 CopyRight (C) 2006-2010 Paulo Costa [email protected] - Synaser library by Lukas Gebauer - TcomPort component Features: Changed: baudrate values. Stop bits new value: 1.5 new event: onstatus new property FRcvLineCRLF: if this property is true, you use RecvString in place of RecvPacket when you read data from the port. New procedure ShowSetupDialog to open a port settings form: the device combobox contain the enumerated ports. New procedure to enumerate real serial port on linux ( in synaser). Demo: a simulator of serial port gps + serial port receiver: you can send NMEA frames ( GGA GLL RMC) to the opened serial port (start gps simulator). You can change speed and heading. In the memo you can see what is received from the opened serial port.
In the status bar you can see the status events. Hi, after a break, started again! Took antoher direction.with succes! Keep in mind: - Lazarus sends a string each 'delta-seconds', in my code: 200ms. There's only 1 timer in the code. Arduino waits for string to receive and IMMEDIALETY ( the smallest response-time ) returns a string after receiving what switches between Labcdend and N1234end ( like a flip-flop ) Therefore I can do this in Lazarus: ( later it will be more sophisticated, due time-outs and more string-error-checking etc ) Still, the code is far from ok and isn't free from hanging, but now allmost each received string by pc is ok.
And now I don'ts have that strange acting from stringlenght. ( still have to investigate the comment about PAnsiChar etc ) And in case of a hang, this is after a much longer time. ( basicly the code: ) Timer.
Is it possible (using Indy for example) to map a serial port to a remote server's TCP port? I have an old application that talks to a data collection system via RS232 and now the equipment has changed to remove the serial port externally and instead connect it to a WiFi AP on board. You can connect to that WiFi network and then the internal serial port data are available on port 2101 on the AP itself. I would like to create a small utility to map from a serial port to the TCP such that I do not have to start digging deep into the application code to modify the connection system there. Any suggestions? - Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51.
And for alternatives: I see that you were the one asking the question then also And still I have found no solution. I dropped it then but now I am again trying to do it. This time around I am looking for a way to make it cross-platform too. For some of the targets I want to build in FreePascal. Note that some time ago I needed to do an Ethernet to WiFi redirector to run on a Raspberry Pi and was directed here towards an Indy component that was already doing almost exactly what I needed. So I could quickly create the utility and run it on the Raspberry Pi.
Now I need a serial to WiFi in the same kind of setting but now for support of old applications. Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51. I suggested a solution: com0com seems NOT to to be a component or object you can use in your own sources. It looks more like a readymade utility and with a LOT of config stuff to go through. I tried doing it recently but got stucked.
It is not a Delphi component but it does provide the means to fake a modem type link between two Windows PCs over an IP network and terminating in virtual COM ports for use with legacy software that expects to see such things. And, if nothing else, I expect that the source code would provide a useful example of how to write a Windows kernel-mode virtual COM port driver.
Now I need a serial to WiFi in the same kind of setting but now for support of old applications. I gather from your original post that (a) you are responsible for a client program that receives data from a data collection system (DCS) supplied by another party and (b) that the DCS has now been updated to communicate via IP and WiFi rather than the 'RS232' previously used. If so, then it seems to me that there will be two main aspects to the problem: identifying / untangling the protocol that the DCS manufacturer has used to encapsulate the collected data1 and (ii) if you really cannot change your client program, creating a virtual COM port driver for Windows (and the equivalent for any other platform that is needed). 1 Perhaps you have documentation for the new protocol? If the DCS is from a third party then presumably the manufacturers provide their own client program upon which you could, in extremis, use WireShark to reverse engineer the data?
(Your mention of port 2101 makes me wonder if the DCS is now using something like MSMQ over RPC to wrap the data.) - Bob Evans. I want to do it within Pascal so I have some control, but I do not know enough low level stuff to be able to do it down to the hardware. So building blocks like Indy10 and similar is what I am looking for. The IP-related parts of the task should be fairly straightforward to achieve with Indy. But I suspect that other aspects will prove to be the more challenging. Yes, that is correct.
I have now realized that the big programming problem lies in the virtual com port task. I have tried AsyncPro with its TApdWinsockPort and TApdComPort and using these it is possible to make the mapping program. However without the virtual com port I have to use two (2) real com ports connected together by a null modem cable, not so fun. Anyway I have a solution but cannot test it fully because where I am now I do not have any of the serial adapters for my PC available. If com0com can help out here it would be good at least during testing.
The last time I saw this question come up in this newsgroup (in September 2012), Unfortunately Embarcadero crashed the newsgroup/forum so all history was lost. The possibility to create a personal archive of relevant postings is one reason why many of us choose to use NNTP to access these forums Off Topic: Right you are, I have been using NNTP with Forte Free Agent for more than a decade. At the time of the Embarcadero forum crash I had an archive of selected groups reaching back almost 10 years. But after the repair I could no longer use Free Agent (no SSH support) but had to switch to XanaNews and lost my old archive. Could of course fire it up to just search for old posts, but it seldom happens. Is it possible to import a Free Agent archive to XanaNews?
I suggested a solution: com0com seems NOT to to be a component or object you can use in your own sources. It looks more like a readymade utility and with a LOT of config stuff to go through. I tried doing it recently but got stucked.
It is not a Delphi component but it does provide the means to fake a modem type link between two Windows PCs over an IP network and terminating in virtual COM ports for use with legacy software that expects to see such things. And, if nothing else, I expect that the source code would provide a useful example of how to write a Windows kernel-mode virtual COM port driver. I think that would defeat my original wish to have a solution fixed in a couple of days. Another option is to go into the old utility and switch out the serial communications component for a TApdWinsockPort, which can serve as a regular serial port or a socket connector depending on configuration. This is probably the better fix anyway, but will take some non-trivial time for coding and testing.
The existing com port component is included in the classes handling teh communication. And (ii) if you really cannot change your client program, creating a virtual COM port driver for Windows (and the equivalent for any other platform that is needed).
This is the part I am having problems with, I will probably go into the application itself and provide it with the needed TCP/IP connectivity instead. It would be the cleaner solution. But I am aiming at moving towards Linux using FreePascal so I have in the end to find a replacement for AsyncPro since it seems not to be ported to FPC. Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51.
I have tried AsyncPro with its TApdWinsockPort and TApdComPort and using these it is possible to make the mapping program. However without the virtual com port I have to use two (2) real com ports connected together by a null modem cable, not so fun. Anyway I have a solution but cannot test it fully because where I am now I do not have any of the serial adapters for my PC available. If com0com can help out here it would be good at least during testing. I haven't looked to see how com0com wraps the payload data while it is traversing the IP domain but, for it to be any use to you for quick testing with com0com at one end and something else at the other, the protocols would need to match. Com0com seems NOT to to be a component or object you can use in your own sources. It looks more like a readymade utility and with a LOT of config stuff to go through.
I tried doing it recently but got stucked. It is not a Delphi component but it does provide the means to fake a modem type link between two Windows PCs over an IP network and terminating in virtual COM ports for use with legacy software that expects to see such things. And, if nothing else, I expect that the source code would provide a useful example of how to write a Windows kernel-mode virtual COM port driver.
Com0com source code as a study example. Two main aspects to the problem: i) identifying / untangling the protocol that the DCS manufacturer has used to encapsulate the collected data1 There is no change at all to the protocol or data packaging! Maybe not in the high-level application data, when you look at it end-to-end. But it is still going to be necessary to wrap that in something to get it safely across an IP network (e.g. SLIP, PPP, some proprietary protocol, or whatever). If you don't have control of the 'over-the-net' protocol employed by the maker of the data collection system, you are just going to have to work with their choice.
But I am aiming at moving towards Linux using FreePascal so I have in the end to find a replacement for AsyncPro since it seems not to be ported to FPC. AIUI AsynchPro is designed around the Win32 API, not the Linux serial comms APIs. Of course the Linux server support promised for the forthcoming Delphi Tokyo might make all this kind of stuff very simple to do, but. In the absence of detail info from the supplier about their implementation of the middle layers of the stack, I would by now be reaching for their client program plus WireShark to find out what is really going on and hence what I would need to do to make my end work. Bob Evans. Another option is to go into the old utility and switch out the serial communications component for a TApdWinsockPort, which can serve as a regular serial port or a socket connector depending on configuration. Why not just let the existing COM port handler remain in place to handle legacy hardware but add a separate handler for the data that come in over IP?
Sigh, I made a test and opened the application code (it is now in Delphi XE5) only to find that I have not been able to install AsyncPro in XE5. So switching com port component will not cut it, I have to add a completely different TCP handler and that will probably be an Indy one (TIdTcpClient). However I have tried that avenue too at a few points the last years and got stuck because the main comm class I have written is heavily event driven and Indy is blocking. Back to the intermediate solution or possible com0com. Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51. Blocking sockets do not fit the existing code. You can use Indy's TIdTCPClient in a worker thread and have it fire an event whenever new data arrives.
Depending on the nature of the data, you MIGHT be able to use TIdCmdTCPClient, which has an internal reading thread and fires events when 'commands' are received. Hi Remy, you helped me already to get going on new code with TIdTcpClient in a command line utility for the same target. Being new code I could apply the Indy stuff all right and that utility actually works fine. For testing I also use the mapping utility I built with Indy after you helped me find the right component. Used to connect to the device from anywhere on the network via a Raspberry pi relay. Works like a charm. That was built with FPC/Lazarus on a Raspberry Pi using Indy10.
The task in this thread, however, is to adapt the already existing Windows GUI application with a LOT of functions to talk to the new instrumentation without too much extra work. The code was started back around 2000 so it is not really 'nicely built' and I cannot change out the serial port but have to somehow hook into the entry and exit points of the data with the socket system.
And Async Pro does not cut it since I cannot install it in my XE5. The application was migrated to XE5 a year ago.
Meanwhile I have built a small TCP-to-Serial utility with Delphi 2007 using one com and one winsock port component from Async Pro as proof of concept. Had to install com0com too to create the linked serial ports needed for that (COM90-COM91). And it seems to work for a short while (like two transactions), then there is no data coming back from the socket.
Have to find out where it disappears. Somewhere between here and Texas probably, the test instrument sits over there. Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51. Meanwhile I have built a small TCP-to-Serial utility with Delphi 2007 using one com and one winsock port component from Async Pro as proof of concept.
Had to install com0com too to create the linked serial ports needed for that (COM90-COM91). And it seems to work for a short while (like two transactions), then there is no data coming back from the socket. Then you are probably not handling the socket I/O correctly. I have been using com0com for years, so I know it doesn't lose data on either end.
Remy Lebeau (TeamB). Meanwhile I have built a small TCP-to-Serial utility with Delphi 2007 using one com and one winsock port component from Async Pro as proof of concept. Had to install com0com too to create the linked serial ports needed for that (COM90-COM91). And it seems to work for a short while (like two transactions), then there is no data coming back from the socket. Then you are probably not handling the socket I/O correctly. I have been using com0com for years, so I know it doesn't lose data on either end. Sorry, I did not mean that com0com is to blame.
It seems to be doing its thing properly. In fact I can see the commands from the application coming in to my serial-to-tcp converter but then it should also show the response from the target which is sent the byte via the asyncPro socket port.
But the receive event does not fire after a while. I can connect and put the system in remote mode, getting ACK back.
Then set it to data transfer mode, again getting ACK back. But the next command is not responded to or else the AsyncPro port does not send it out via the socket for some reason. And this is a hard one to diagnose remotely, might need a WireShark session and knowledge of how to work with WireShark. Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51. Got stuck because the main comm class I have written is heavily event driven and Indy is blocking. Nothing against Indy. That is one reason I use ICS, non blocking.
I downloaded the ICS code and had a look at the client examples. It looks a bit confusing to me right now since the examples seem to be geared towards talking to webservices and the like using and assuming text mode transfers. When the client is set to 'binary' mode it sends the bytes wrapped like in a HTTP webserver, which is not OK. In my application the data are all binary and must not be converted in any way at all. All 256 possible data bytes are part of the messages so there must not be any assumption on the content, which it looks like ICS does in the examples. Could you suggest a barebones client socket example for just sending a number of data bytes to the server and then receiving ALL bytes that are coming back to be processed by another procedure? Basically I want to be able to send a packet of data consisting of the content of a binary array stored in for example a TBytes object.
Then I want to receive all incoming data as it arrives and pass it on unaltered to a processing method which knows about the protocol and the transfer state. Or in fact for the interface utility all incoming data should be sent on via the serial port to the old application. Would be grateful for a bare minimum code example using the client socket in ICS.
Bo Berglund Sweden & Texas now using XanaNews 1.20-0cfde51.