EMERGENCY: Problem with COM port (RS232) communication

A

AlliXSenoS

hi to everybody

I have a small but urgent problem... seems me and my friend got ourselves
in a project a bit out of our league, and now we're stuck. and the delivery
date was... um. last month :)

the program is supposed to communicate with a COM port-based device that is
actually a reader for keys (a lo-tek version of USB thumbdrives) that carry
information.

the communication is done in 'bytes' because the device is pretty stupid
and uses 1-byte commands and responses

we picked up this code from some MSDN page dealing with COM port
communication:

#region COM port HocusPocus
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(
string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare,
int securityattributes,
[MarshalAs(UnmanagedType.U4)]FileMode creationdisposition,
int flags, IntPtr template);
#endregion

public void Connect()
{
if (!Connected)
{
try
{
IntPtr ptr = CreateFile(_port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero);
stream = new FileStream(ptr, FileAccess.ReadWrite);
}
catch (ArgumentException)
{
throw new InvalidOperationException("Cannot open
communication port. Please close all other applicaions using port COM 1.");
}
}
else
throw new InvalidOperationException("Already connected");
}


public void Send(byte b)
{
stream.WriteByte(b);

int response = 0;

timer.Reset();
while ((response != 32) || (!timer.Timeout))
{
response = stream.ReadByte();
response = response & 0x20;
}
}



the problem is that the stream.ReadByte call hangs and never returns
anything. the programs hangs here, and we've been busting our heads over
this. we used a terminal program to test the equipment we're communicating
with and it returns 0xE0 if there's an error or 0xE1 if the command is
understood. but our program just sits there waiting... forever



can anyone please help us, we're in deeep trouble if we don't get this
running.


thanks,
Luka
 
T

Trevor

AlliXSenoS said:
hi to everybody

I have a small but urgent problem... seems me and my friend got ourselves
in a project a bit out of our league, and now we're stuck. and the delivery
date was... um. last month :)

the program is supposed to communicate with a COM port-based device that is
actually a reader for keys (a lo-tek version of USB thumbdrives) that carry
information.

the communication is done in 'bytes' because the device is pretty stupid
and uses 1-byte commands and responses

we picked up this code from some MSDN page dealing with COM port
communication:


I am going to guess that FileStream.ReadByte is really calling ReadFile
for 1 byte. The default behavior of ReadFile is to block until a byte is
received. You can change this by calling SetCommTimeouts or by polling the
serial port using ClearCommError and not issuing a read until you KNOW you
have a byte ready. Both of these are native API functions. You didn't
mention anything about baud rate. Are you sure the COM settings are
configured correctly? GetCommState/SetCommState will allow you to configure
the port. You call GetCommState first and then change whatever you need to
change in the DCB structure it populates for you and then you call
SetCommState.

HTH
 
N

Nicholas Paldino [.NET/C# MVP]

AlliXSenoS,

When calling the CreateFile method, you probably should call pass
FILE_FLAG_NO_BUFFERING (0x20000000) and FILE_FLAG_WRITE_THROUGH (0x80000000)
in for the flags value, indicating that you don't want anything to be
buffered. It is possible that there is a buffer that the OS is trying to
fill, which it is waiting on (after all, not many people want to read one
byte at a time, and there is probably no length descriptor on the COM port,
so it thinks that it can just keep reading and reading).

Also, of course, make sure you are opening the right COM port =)

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

AlliXSenoS said:
hi to everybody

I have a small but urgent problem... seems me and my friend got ourselves
in a project a bit out of our league, and now we're stuck. and the delivery
date was... um. last month :)

the program is supposed to communicate with a COM port-based device that is
actually a reader for keys (a lo-tek version of USB thumbdrives) that carry
information.

the communication is done in 'bytes' because the device is pretty stupid
and uses 1-byte commands and responses

we picked up this code from some MSDN page dealing with COM port
communication:

#region COM port HocusPocus
[DllImport("Kernel32.dll")]
static extern IntPtr CreateFile(
string filename,
[MarshalAs(UnmanagedType.U4)]FileAccess fileaccess,
[MarshalAs(UnmanagedType.U4)]FileShare fileshare,
int securityattributes,
[MarshalAs(UnmanagedType.U4)]FileMode creationdisposition,
int flags, IntPtr template);
#endregion

public void Connect()
{
if (!Connected)
{
try
{
IntPtr ptr = CreateFile(_port, FileAccess.ReadWrite,
FileShare.ReadWrite, 0, FileMode.Create, 0, IntPtr.Zero);
stream = new FileStream(ptr, FileAccess.ReadWrite);
}
catch (ArgumentException)
{
throw new InvalidOperationException("Cannot open
communication port. Please close all other applicaions using port COM 1.");
}
}
else
throw new InvalidOperationException("Already connected");
}


public void Send(byte b)
{
stream.WriteByte(b);

int response = 0;

timer.Reset();
while ((response != 32) || (!timer.Timeout))
{
response = stream.ReadByte();
response = response & 0x20;
}
}



the problem is that the stream.ReadByte call hangs and never returns
anything. the programs hangs here, and we've been busting our heads over
this. we used a terminal program to test the equipment we're communicating
with and it returns 0xE0 if there's an error or 0xE1 if the command is
understood. but our program just sits there waiting... forever



can anyone please help us, we're in deeep trouble if we don't get this
running.


thanks,
Luka
 
A

AlliXSenoS

I am going to guess that FileStream.ReadByte is really calling
ReadFile for 1 byte. The default behavior of ReadFile is to block
until a byte is received. You can change this by calling
SetCommTimeouts or by polling the serial port using ClearCommError and
not issuing a read until you KNOW you have a byte ready. Both of these
are native API functions. You didn't mention anything about baud rate.
Are you sure the COM settings are configured correctly?
GetCommState/SetCommState will allow you to configure the port. You
call GetCommState first and then change whatever you need to change in
the DCB structure it populates for you and then you call SetCommState.

uhm. yeah. I'm stupid. I never bothered with the baud rate. as soon as we set
the baud rate to 9600, it worked like a charm

thanks to both of you for replying.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top