April 25, 2024, 10:37:42 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Serial Port Problems

Started by rangerm, January 25, 2011, 08:50:41 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

rangerm

I've been modifiying an existing piece of software I wrote years ago for data acquisition over an RS232 port.  It relies on the original commread example from Ibasic, but the software isn't the problem (or doesn't appear to be).  But I'm at a bit of a loss, so I'm wondering where to go.

I'm attempting to run the software on a laptop using a USB-to-Serial adapter.  The software runs well for awhile, then the serial port locks up along with the software.  I believe the problem is in the device driver, but would appreciate others opinion.

Here's what I've done:

I've run the software successfully for several hours before the software locks up.  I end the task (using windows task manager), but cannot access the COM port using Hyperterminal to see if it is a hardware/software problem.  I cannot access the COM port until I let Windows restart the device.  Then HT can access the COM port without issue.

I've allowed Hyperterminal to monitor the COM port (reading bytes, just as my software does) for several hours, but the terminal never locks up.  Disconnecting the terminal, and starting my software resulted in a COM port lockup after about 15 minutes.  Again, allowing Windows to restart the USB-to-Serial adapter resolved the problem.

Something about the way HT and my software interact with the device appears to be the difference.  Trouble is, I don't know if it's the software (itself) or the way the software interacts with the hardware (device driver?).  The device is based on a Prolific chipset and I've read that the FTDI chipset is more reliable, but would like to eliminate all other possibilities before I invest.

The pertinent code is (I've left out the kernel132 stuff, but suffice to say it's identical to the original commread example):
Quotehcom = CreateFileA(COM$,@GENERICREAD | @GENERICWRITE,0,0,@OPENEXISTING,0,0)

IF hcom <> -1
   SetCommTimeouts(hcom,timeout)
   IF GetCommState(hcom,dcb1)
      rem PRINT "Com port open, Current baud = ",dcb1.BaudRate
      dcb1.BaudRate = 9600
      dcb1.ByteSize = 8
      dcb1.StopBits = @ONESTOPBIT
      dcb1.Parity = @NOPARITY
      IF SetCommState(hcom,dcb1) = 0
         PRINT "Error setting com parameters"
      ELSE
         rem PRINT "Baud rate changed to ",dcb1.BaudRate
      ENDIF
      REM we continue to read the port until all bytes are read
      REM or someone presses the space bar.
      DO
         IF ReadFile(hcom,data,1,bytesread,0) <> 0
            rem PRINT data
            rem datastring$=datastring$+data
         ENDIF
      UNTIL (data = CHR$(2))

      DO
         IF ReadFile(hcom,data,1,bytesread,0) <> 0
            rem PRINT data
            datastring$=datastring$+data
         ENDIF
      UNTIL (data = CHR$(3))
   ENDIF
   success = CloseHandle(hcom)
ELSE
   PRINT "Could not open com port"
ENDIF

I haven't tried altering the code to set flow control parameters, but can't figure why that would make any difference, since the software works for awhile then stops when the COM port locks up; and works normally when it's restarted.

Any thoughts or experiences?

Egil

The same thing happened here. When checking the task manager, i found that the program was still running. I beleive the reason was that the comport had not closed properly.
I did not investigate further as Paul Turley came up with his Serial Library Component. And after I started to use the component, the problems were gone, mainly because I now control the ports myself.

I recomend you buy the Serial Library  when Larry Sykes comes around to post it again.
Support Amateur Radio  -  Have a ham  for dinner!

rangerm

Tried making the following modification to see if it would help.
Quote
success = CloseHandle(hcom)
IF CloseHandle(hcom) <>0
ENDIF
Unfortunately it didn't.  I'll keep looking for the Serial Library to see if it becomes available.

The program itself runs fine in XP (using the same USB-to-Serial adapter), but it's Win 7 that's giving me the problem (which is why the device driver was my assumption).  The fact that Hyperterminal ran (in Win 7 with same adapter/device driver) just fine really has me confused though.

sapero

Rangerm, check your code for safety:
     DO
        IF ReadFile(hcom,data,1,bytesread,0) <> 0
           rem PRINT data
           datastring$=datastring$+data
        ENDIF

Doing so is okay in sample programs, but in programs running for hours/days, you should check if datastring$ has some space left before appending new bytes to it.
If datastring$ is defined as standalone STRING variable, you cal safely append up to 255 bytes to it, plus one byte for the hidden terminating zero.

What will happen if the loop will execute more than 255 times? - Some variable defined before or after datastring$ will be corrupted by the next append to datastring$. Depending on what the corrupted variable does, your program may enter an infinite loop, crash, or just quit (silent crash).
Change the fourth line to
if (len(datastring$)<255) then datastring$=datastring$+dat ' else print "error: the message is too long"
The value 255 is valid, if datastring$ is defined as
string datastring$
' or
def datastring$ as string
' or
def datastring$ : string
' or
istring datastring$[256] ' 256 or more

In other cases the value 255 should be changed to 254. You should know that the total size of a string is 255 bytes (254 bytes for text + one byte for NULL), but if the string is a standalone variable, you have one more byte from the alignment - total 256 bytes.

Find other places in your program, and add the checking before you append the data. Actual size plus data size plus one should be never greater than than the total size of target buffer.

rangerm

datastring$ is defined as an ISTRING with a max size of of 981.

The device I'm monitoring outputs a string (via RS-232) that begins with a CHR$(2) and terminates with CHR$(3).  Within that string is a 20-character date/time, followed by 30-character channels' data sets, with each channel's worth of data a single line ending with a carriage return.  The length of the string depends on the number of channels the device is monitoring.

Once I've read the string, I parse the data as needed.  I control the length of the string from the device itself.  The program itself only listens to the COM port (one-way communication).

I think Egil may be on the right track as far as closing the port, but I can't tell.  The "CreateFileA" line has an exclusive hold on the COM port, and when the program locks I can't access that port from Hyperterminal, so I thought he might be right.  That's why I added the "IF CloseHandle(hcom) <>0 ENDIF" thinking it might resolve any issues with that, but I admit I'm only the most casual programmer, so I could be missing something.  Am I correct in assuming that......
QuoteIF CloseHandle(hcom) <>0
ENDIF
.....would attempt to close the port until it succeeds, or does this only attempt to perform the action once and perhaps my program hangs if it can't?  If not, I'm assuming I'd have to add a "Do-Untiil" to insure the port gets closed.  Not sure what that would look like (within the program), though.  Problem is, the program is stable in XP using the same USB-Serial adapter, so I was convinced the problem was the device driver (in Win7).

I originally wrote the program in QB45, and I translated it to IBasic, now making further changes within CBasic.

sapero

January 25, 2011, 04:54:16 PM #5 Last Edit: January 25, 2011, 04:56:12 PM by sapero
CloseHandle(hcom) will always close the handle (if the handle is valid). The additional IF checks if the operation succeeded, but does nothing on success, because there is no code between "IF expression" ... endif.
Once you call CloseHandle, the handle cannot be used, but another handle may be assigned to this variable.

[Debugging is not available in Creative Basic] Process Explorer may help you finding out, where your program hung. Just compile your program in debug mode, start it from the editor (it will run under the debugger) or from your file manager. When you notice that it stopped working, open Process Explorer, double-click the process, switch to Threads tab, select the main thread and couble-click it. PE will display a call-stack - the chain of function calls.

Another great help is PRINT - put it anywhere, to see what the program will do in the next step, and what is the result.

print TIME$," calling second ReadFile in function xyz"
success = ReadFile ...
print TIME$, " result = ", success

ckoehn

Don't have my code handy, but I'm running Win7 x64 with a Radio Shack  USB-to-Serial adapter (this adapter works on anything from my experience in XStream radio communications) and it works fine.

Later,
Clint

Rock Ridge Farm (Larry)

I have a new comlib ready to release - I was hoping to release it with V2.
Let me finish the loader and I can have it ready next week if you are interested.
It is almost the same as the older comlib but allows any com port to be used.

Larry

Egil

Quote from: Rock Ridge Farm (Larry) on January 26, 2011, 06:55:03 AM
I have a new comlib ready to release - I was hoping to release it with V2.
Let me finish the loader and I can have it ready next week if you are interested.
It is almost the same as the older comlib but allows any com port to be used.

That's good news Larry!
Almost can't wait till you get it ready. Maybe I misunderstand, but when you say ...hoping to release it with V2, I recon you mean IWB v2. I really hope the comlib you are talking about above also include the CB version, because lately I have mainly been using CB. IWB has been kind of put on hold, waiting for V2. But since I personally still have a lot to learn about basic Windows programming, it doesn't really matter.

By the way, last night I noticed that the CB comlib produce errors if Autodefine "Off" is used. Maybe this is something that needs to be looked into?

Egil
Support Amateur Radio  -  Have a ham  for dinner!

rangerm

Well, after many times trying, I splurged and bought another USB-to-Serial adapter.  This one solved the problem, so I've concluded that the problem is/was an incompatible device driver in Windows 7.

The new (working) adapter is this one:

http://www.usconverters.com/index.php?main_page=product_info&cPath=67&products_id=290&zenid=a515e93e328f6a7b942445b1b43d2810

I'd read that the adapters based on the Prolific chip have been problematic (like the old one I was using).  This new one is based on an FTDI chip.

I've been running the program (actively logging data) for 10 straight hours without a hitch.  Hope that helps others.

Egil

Quote from: rangerm on January 31, 2011, 03:52:37 PM
Well, after many times trying, I splurged and bought another USB-to-Serial adapter.  This one solved the problem, so I've concluded that the problem is/was an incompatible device driver in Windows 7.

Your post made me think... Maybe this could be the cause of some "unexplainable" experience I have had here.
I have four USB to RS-232 converter cables, two brand new, and two bought five or six years ago. Device Manager reports all of them to be "Prolific USB to Serial Cables". For two days now, I have been experimenting, and this is what I found:

1.
One of the old cables some times produces noise in an UHF protable radio sitting on a shelf 4 meters away. This noise increase to a very high level, and is always present, when the modem (TNC) is disconnected from the cable. But Device Manager still reports the comports to be present.

2.
One of my modems (TNC) needs a DB-25 connector, while the converter cables all use DB-9 connectors. Therefore I use a four foot long (1.22m) modem cable with suitable connectors between the Prolific cable and the modem.
When this setup is used with the same (old) cable as mentioned above, communication some times suddenly stops, and Device Manager can't find the comport. With this setup the radio noise is extensive all the time.

3.
All the other three cables work as expected, whithout any trace of radio noise, and with any combination of modem and extension cable.

4.
Finally, if the terminal program is run from within the CB editor (which is not likely to happen in "real life" applications), and new receive data is occouring at the same time, the program locks up if it is restarted without exiting and restarting the CB Editor. This happens with all four cables. But here is what really puzles me: When doing this with a precompiled .EXE file, I was not able to produce the same fault condition.

I have also used a 22ft extension cable between the converter cable and modem, and the results were similar to those above. It would be nice to hear what other people, using different brands of USB to RS-232 converters have experienced.


Regards

Egil
Support Amateur Radio  -  Have a ham  for dinner!

rangerm

Mine was a combination of Item #1 and #2.  My CB program suddenly could not "receive" data through the COM port (although device manager said the COM port was present and working properly, however I could not access the port using other programs)

The problem only occured when I was using my "receiving" software, and not using hyperterminal.  It's definitely strange. 

In any case, my software worked flawlessly for almost 72 hours, until WIN7 went through an automatic update (at 3:00 AM Saturday) and rebooted the machine.  I've since restarted my software, and no problems evident so far.