Comport (to access USB) - new to C#


J

jodleren

Hi all

I have programmed for 20 years, but only little in C/C++ and even less
in C#. I am learning the hard way now.

Right, to the issue:

I have create a small app, which should communicate with a PCB.
We use a FreeRTOS CDC demo to access the PCB. The connection is
actually by USB.

In Hyperterminal and a Delphi app I have no problems.

However, in C# I can open the port, but my app stops when writing to
the com port.

Using COM1, a real port with a null modem it works.
Usinc COM3 for my PCB, I can see that it gets some data, as I cannot
access it afterwards from any other app. I have to restart the PCB. I
asume that it sends one byte but the waits for something.
Still, I dont get it.

I am lost - any ideas?

Sonnich

private void button1_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Open();
button1.Enabled = !serialPort1.IsOpen;
}

private void serialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
int count = (sender as SerialPort).BytesToRead;
byte[] buffer = new byte[count];
int offset = 0;
serialPort1.Read(buffer, offset, count);

if (label1.InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate()
{
label1.Text = Encoding.ASCII.GetString(buffer);
label1.Text = label1.Text + " " +
count.ToString();
}));
}
else
{
label1.Text = buffer.ToString(); //.Trim()
//label1.Text = label1.Text + " " + count.ToString();
}
}

private void button2_Click(object sender, EventArgs e)
{
serialPort1.Write("!VERSION\r"); <- stops here
label1.Text = "sent";
}
 
Ad

Advertisements

J

jodleren

jodleren said:
[...]
I have create a small app, which should communicate with a PCB.
We use a  FreeRTOS CDC demo to access the PCB. The connection is
actually by USB.
In Hyperterminal and a Delphi app I have no problems.
However, in C# I can open the port, but my app stops when writing to
the com port.
Using COM1, a real port with a null modem it works.
Usinc COM3 for my PCB, I can see that it gets some data, as I cannot
access it afterwards from any other app. I have to restart the PCB. I
asume that it sends one byte but the waits for something.
Still, I dont get it.
I am lost - any ideas?

Other than some oddness about your DataReceived event handler (mainly,
the non-invoked code doesn't match the invoked code, though the setting
Text and the retrieving it to do some more concatenation is a bit
non-optimal too), there's nothing obviously wrong about the code you posted.

So, either the problem exists in the code you didn't post, or it has
something to do with the hardware device specifically (either it's not
working properly, or the serial port isn't configured appropriately for
the device).  Either way, it's going to be difficult to diagnose the
problem from this end of the conversation.  :)

Pete

I am aware of the differnces, but that is not the issue right now.
I am trying to write to the device, and if it worked - it would turn
on some LEDs.
Since it works from my delphi app, from hyperterminal, and not from C#
there are a few possibilites:
1) the serial port acts differently - as I am new I am not 100% if I
have sat it up correctly.
2) other problems related to how the component talks to the driver
etc.

What I want is basically:

Delphi code, works:
FComm := TComm.Create(nil);
// setup comport
FComm.DeviceName := 'COM3';
FComm.BaudRate := br115200;
FComm.Parity := paNone;
FComm.Stopbits := sb10;
FComm.Databits := da8;
FComm.Open;
// send data
FComm.Write('!WD_WORD_ARM 99 101');

Which should be:

serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Open();
serialPort1.Write("!WD_WORD_ARM 99 102\r");

To me, they are the same - but something goes wrong. This is where I
wonder - could it be something I missed here?

Sonnich
 
J

jodleren

jodleren said:
[...]
I have create a small app, which should communicate with a PCB.
We use a  FreeRTOS CDC demo to access the PCB. The connection is
actually by USB.
In Hyperterminal and a Delphi app I have no problems.
However, in C# I can open the port, but my app stops when writing to
the com port.
Using COM1, a real port with a null modem it works.
Usinc COM3 for my PCB, I can see that it gets some data, as I cannot
access it afterwards from any other app. I have to restart the PCB. I
asume that it sends one byte but the waits for something.
Still, I dont get it.
I am lost - any ideas?
Other than some oddness about your DataReceived event handler (mainly,
the non-invoked code doesn't match the invoked code, though the setting
Text and the retrieving it to do some more concatenation is a bit
non-optimal too), there's nothing obviously wrong about the code you posted.
So, either the problem exists in the code you didn't post, or it has
something to do with the hardware device specifically (either it's not
working properly, or the serial port isn't configured appropriately for
the device).  Either way, it's going to be difficult to diagnose the
problem from this end of the conversation.  :)

I am aware of the differnces, but that is not the issue right now.
I am trying to write to the device, and if it worked - it would turn
on some LEDs.
Since it works from my delphi app, from hyperterminal, and not from C#
there are a few possibilites:
1) the serial port acts differently - as  I am new I am not 100% if I
have sat it up correctly.
2) other problems related to how the component talks to the driver
etc.

What I want is basically:

Delphi code, works:
  FComm := TComm.Create(nil);
  // setup comport
  FComm.DeviceName := 'COM3';
  FComm.BaudRate := br115200;
  FComm.Parity := paNone;
  FComm.Stopbits := sb10;
  FComm.Databits := da8;
  FComm.Open;
  // send data
  FComm.Write('!WD_WORD_ARM 99 101');

Which should be:

            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = System.IO.Ports.Parity.None;
            serialPort1.StopBits = System.IO.Ports.StopBits..One;
            serialPort1.DataBits = 8;
            serialPort1.Open();
            serialPort1.Write("!WD_WORD_ARM 99 102\r");

To me, they are the same - but something goes wrong. This is where I
wonder - could it be something I missed here?

Sonnich

That should be
serialPort1.BaudRate = 115200; :)
Still, this is not my real problem - it still does not talk to my
device
 
R

Rick Lones

jodleren said:
jodleren said:
[...]
I have create a small app, which should communicate with a PCB.
We use a FreeRTOS CDC demo to access the PCB. The connection is
actually by USB.
In Hyperterminal and a Delphi app I have no problems.
However, in C# I can open the port, but my app stops when writing to
the com port.
Using COM1, a real port with a null modem it works.
Usinc COM3 for my PCB, I can see that it gets some data, as I cannot
access it afterwards from any other app. I have to restart the PCB. I
asume that it sends one byte but the waits for something.
Still, I dont get it.
I am lost - any ideas?
Other than some oddness about your DataReceived event handler (mainly,
the non-invoked code doesn't match the invoked code, though the setting
Text and the retrieving it to do some more concatenation is a bit
non-optimal too), there's nothing obviously wrong about the code you posted.

So, either the problem exists in the code you didn't post, or it has
something to do with the hardware device specifically (either it's not
working properly, or the serial port isn't configured appropriately for
the device). Either way, it's going to be difficult to diagnose the
problem from this end of the conversation. :)

Pete

I am aware of the differnces, but that is not the issue right now.
I am trying to write to the device, and if it worked - it would turn
on some LEDs.
Since it works from my delphi app, from hyperterminal, and not from C#
there are a few possibilites:
1) the serial port acts differently - as I am new I am not 100% if I
have sat it up correctly.
2) other problems related to how the component talks to the driver
etc.

What I want is basically:

Delphi code, works:
FComm := TComm.Create(nil);
// setup comport
FComm.DeviceName := 'COM3';
FComm.BaudRate := br115200;
FComm.Parity := paNone;
FComm.Stopbits := sb10;
FComm.Databits := da8;
FComm.Open;
// send data
FComm.Write('!WD_WORD_ARM 99 101');

Which should be:

serialPort1.PortName = "COM3";
serialPort1.BaudRate = 9600;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.DataBits = 8;
serialPort1.Open();
serialPort1.Write("!WD_WORD_ARM 99 102\r");

To me, they are the same - but something goes wrong. This is where I
wonder - could it be something I missed here?

Sonnich

Well, just from looking at the two snippets it seems as though you are using
9600 baud from your C# app where your Delphi code is talking to the device at
115200 baud. That doesn't look right (unless you have reconfigured your
external device meanwhile).

Also, your C# app is setting up for one stop bit. The Delphi one is setting
stop bits to "sb10" which is evidently some constant - but are you sure it means
1 stop bit rather than, e.g., 2?

Finally, you need to be damn sure about the encoding of what you are sending and
also abouth whether Delphi's Write() is the same as .Net's when it comes to such
things as automatically appending line feeds after carriage returns and things
like that. (Or is .Net sending Unicode by default, e.g.?)

FWIW, I found the native .Net SerialPort surprisingly difficult to work with in
text mode. I ended up treating the I/O as binary bytes to avoid nasty surprises
from issues like those alluded to above.

HTH,
-rick-
 
J

jodleren

jodleren said:
jodleren wrote:
[...]
I have create a small app, which should communicate with a PCB.
We use a  FreeRTOS CDC demo to access the PCB. The connection is
actually by USB.
In Hyperterminal and a Delphi app I have no problems.
However, in C# I can open the port, but my app stops when writing to
the com port.
Using COM1, a real port with a null modem it works.
Usinc COM3 for my PCB, I can see that it gets some data, as I cannot
access it afterwards from any other app. I have to restart the PCB. I
asume that it sends one byte but the waits for something.
Still, I dont get it.
I am lost - any ideas?
Other than some oddness about your DataReceived event handler (mainly,
the non-invoked code doesn't match the invoked code, though the setting
Text and the retrieving it to do some more concatenation is a bit
non-optimal too), there's nothing obviously wrong about the code you posted.
So, either the problem exists in the code you didn't post, or it has
something to do with the hardware device specifically (either it's not
working properly, or the serial port isn't configured appropriately for
the device).  Either way, it's going to be difficult to diagnose the
problem from this end of the conversation.  :)
Pete
I am aware of the differnces, but that is not the issue right now.
I am trying to write to the device, and if it worked - it would turn
on some LEDs.
Since it works from my delphi app, from hyperterminal, and not from C#
there are a few possibilites:
1) the serial port acts differently - as  I am new I am not 100% if I
have sat it up correctly.
2) other problems related to how the component talks to the driver
etc.
What I want is basically:
Delphi code, works:
  FComm := TComm.Create(nil);
  // setup comport
  FComm.DeviceName := 'COM3';
  FComm.BaudRate := br115200;
  FComm.Parity := paNone;
  FComm.Stopbits := sb10;
  FComm.Databits := da8;
  FComm.Open;
  // send data
  FComm.Write('!WD_WORD_ARM 99 101');
Which should be:
            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = System.IO.Ports.Parity.None;
            serialPort1.StopBits = System.IO.Ports.StopBits.One;
            serialPort1.DataBits = 8;
            serialPort1.Open();
            serialPort1.Write("!WD_WORD_ARM 99 102\r");
To me, they are the same - but something goes wrong. This is where I
wonder - could it be something I missed here?

Well, just from looking at the two snippets it seems as though you are using
9600 baud from your C# app where your Delphi code is talking to the device at
115200 baud.  That doesn't look right (unless you have reconfigured your
external device meanwhile).

Also, your C# app is setting up for one stop bit.  The Delphi one is setting
stop bits to "sb10" which is evidently some constant - but are you sure it means
1 stop bit rather than, e.g., 2?

Finally, you need to be damn sure about the encoding of what you are sending and
also abouth whether Delphi's Write() is the same as .Net's when it comes to such
things as automatically appending line feeds after carriage returns and things
like that.  (Or is .Net sending Unicode by default, e.g.?)

FWIW, I found the native .Net SerialPort surprisingly difficult to work with in
text mode.  I ended up treating the I/O as binary bytes to avoid nasty surprises
from issues like those alluded to above.

HTH,
-rick-

As I wrote above, I am aware of the speed. The importance is low, as
the driver should get data anyway and pass it on to USB.
Now I know that it does. The speed is corrected.
sb10 is 1, sb15 and sb20 is 1.5 and 2 stop bits.

I asume, that the Write could be it - I just tried WriteLine. Same.

I found now, that I can send data, close my app, and just open the
connection in HyperTerminal, can data is correctly passed on!
Somehow my C# really writes data, but they get stuck somewhere.
Closing the connection or restaring the C# app does not do the trick.
What can Delphi and HyperTerminal do, that the connection here does
not do?

Sonnich
 
J

jodleren

jodleren said:
jodleren wrote:
[...]
I have create a small app, which should communicate with a PCB.
We use a  FreeRTOS CDC demo to access the PCB. The connection is
actually by USB.
In Hyperterminal and a Delphi app I have no problems.
However, in C# I can open the port, but my app stops when writing to
the com port.
Using COM1, a real port with a null modem it works.
Usinc COM3 for my PCB, I can see that it gets some data, as I cannot
access it afterwards from any other app. I have to restart the PCB.I
asume that it sends one byte but the waits for something.
Still, I dont get it.
I am lost - any ideas?
Other than some oddness about your DataReceived event handler (mainly,
the non-invoked code doesn't match the invoked code, though the setting
Text and the retrieving it to do some more concatenation is a bit
non-optimal too), there's nothing obviously wrong about the code youposted.
So, either the problem exists in the code you didn't post, or it has
something to do with the hardware device specifically (either it's not
working properly, or the serial port isn't configured appropriately for
the device).  Either way, it's going to be difficult to diagnose the
problem from this end of the conversation.  :)
Pete
I am aware of the differnces, but that is not the issue right now.
I am trying to write to the device, and if it worked - it would turn
on some LEDs.
Since it works from my delphi app, from hyperterminal, and not from C#
there are a few possibilites:
1) the serial port acts differently - as  I am new I am not 100% ifI
have sat it up correctly.
2) other problems related to how the component talks to the driver
etc.
What I want is basically:
Delphi code, works:
  FComm := TComm.Create(nil);
  // setup comport
  FComm.DeviceName := 'COM3';
  FComm.BaudRate := br115200;
  FComm.Parity := paNone;
  FComm.Stopbits := sb10;
  FComm.Databits := da8;
  FComm.Open;
  // send data
  FComm.Write('!WD_WORD_ARM 99 101');
Which should be:
            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = System.IO.Ports.Parity..None;
            serialPort1.StopBits = System.IO.Ports.StopBits.One;
            serialPort1.DataBits = 8;
            serialPort1.Open();
            serialPort1.Write("!WD_WORD_ARM 99 102\r");
To me, they are the same - but something goes wrong. This is where I
wonder - could it be something I missed here?
Sonnich
Well, just from looking at the two snippets it seems as though you are using
9600 baud from your C# app where your Delphi code is talking to the device at
115200 baud.  That doesn't look right (unless you have reconfigured your
external device meanwhile).
Also, your C# app is setting up for one stop bit.  The Delphi one is setting
stop bits to "sb10" which is evidently some constant - but are you sureit means
1 stop bit rather than, e.g., 2?
Finally, you need to be damn sure about the encoding of what you are sending and
also abouth whether Delphi's Write() is the same as .Net's when it comes to such
things as automatically appending line feeds after carriage returns andthings
like that.  (Or is .Net sending Unicode by default, e.g.?)
FWIW, I found the native .Net SerialPort surprisingly difficult to workwith in
text mode.  I ended up treating the I/O as binary bytes to avoid nasty surprises
from issues like those alluded to above.
HTH,
-rick-

As I wrote above, I am aware of the speed. The importance is low, as
the driver should get data anyway and pass it on to USB.
Now I know that it does. The speed is corrected.
sb10 is 1, sb15 and sb20 is 1.5 and 2 stop bits.

I asume, that the Write could be it - I just tried WriteLine. Same.

I found now, that I can send data, close my app, and just open the
connection in HyperTerminal, can data is correctly passed on!
Somehow my C# really writes data, but they get stuck somewhere.
Closing the connection or restaring the C# app does not do the trick.
What can Delphi and HyperTerminal do, that the connection here does
not do?

Sonnich

serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;

This did the trick.
Seems like there are sure differences from Delphi components to C#

I succeeded today, will go home, and continue tomorrow.

Hope I am still welcome here

Sonnich
 
Ad

Advertisements

J

Jeff Johnson

I asume, that the Write could be it - I just tried WriteLine. Same.

If the problem had been with Write(), using WriteLine() would NOT have fixed
anything. All WriteLine() does is append CR/LF to the end of the data.

The potential problem that Rick was referring to was whether text (for
example "Hello") was being sent as these ASCII bytes:

48 65 6C 6C 6F

or these Unicode (UTF-16) bytes:

48 00 65 00 6C 00 6C 00 6F 00
 
R

Rick Lones

Jeff said:
If the problem had been with Write(), using WriteLine() would NOT have fixed
anything. All WriteLine() does is append CR/LF to the end of the data.
The potential problem that Rick was referring to was whether text (for
example "Hello") was being sent as these ASCII bytes:

48 65 6C 6C 6F

or these Unicode (UTF-16) bytes:

48 00 65 00 6C 00 6C 00 6F 00

Yes, that is one concern. I would suggest the OP try something like the
following (untested) diagnostic code, which forces the output to be 8-bit bytes
rather than trying to send any kind of characters. If this doesn't work, try
the same bytes, but with an appended '\n'. Followed by whatever other crazy
variations the OP can think of until the device responds. I would fully reset
the external device between attempts.

I am assuming here (but it seems reasonable) that the app is simply in some way
not sending precisely whatever the device on the other side is looking for and
so it does not respond. The problem would typeically be either with the setup
of the port or with the detailed format of the command being sent. Or sillier
things like using the wrong type of cable, of course, but this does not sound
too likely here.

-rick-

// caveat: untested code follows

using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace ConsoleApplication3
{
class Program
{
static SerialPort sp;

static void Main(string[] args)
{
sp = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
sp.DtrEnable = true;
sp.RtsEnable = true;
sp.Open();

byte[] b1 = Encoding.ASCII.GetBytes("!VERSION\r");

sp.Write(b1, 0, b1.Length);
Console.WriteLine("Sent byte count: " + b1.Length.ToString());
Console.WriteLine("Sleeping for 1000 milliseconds . . .");
Thread.Sleep(1000);

Console.WriteLine("Awake, polling serial port . . .");
int bytesin = sp.BytesToRead;
Console.WriteLine("Received byte count: " + bytesin.ToString());
Console.ReadLine();
}
}
}
 
R

Rick Lones

Peter said:
Jeff said:
[...]
The potential problem that Rick was referring to was whether text (for
example "Hello") was being sent as these ASCII bytes:

48 65 6C 6C 6F

or these Unicode (UTF-16) bytes:

48 00 65 00 6C 00 6C 00 6F 00

The SerialPort class sends ASCII bytes.

Thankfully, the OP has identified the settings that are different
between his Delphi code and his C# code (either because the defaults are
different or because they are explicitly set one place and/or the other
to be different).

Pete

The framing at the h/w level is normally 8-bit bytes. But, according to the
(2.0) documentation: "The SerialPort class supports the following encodings:
ASCIIEncoding, UTF8Encoding, UnicodeEncoding, UTF32Encoding, and any encoding
defined in mscorlib.dll where the code page is less than 50000 or the code page
is 54936."

That said, I am recalling now that the issue I have seen with the .Net serial
port was not that it sent Unicode unexpectedly but that it didn't seem to treat
all 8-bit patterns the same when in text mode and that this was true whether the
Encoding was set to ASCII or UTF-8. We were talking to an embedded device which
sent a mix of printable and non-printable (meaning > 0x7F) codes, always ending
with "\r\n". The third-party control that we had been using was working fine
with this in text mode, but when we upgraded to .Net 2.0 and converted to the
native control, the non-printable codes seemed to be getting modified on the way
in. By "text mode" I mean that we were using constructs like ReadTo("\n"),
rather than just reading and processing bytes.

Probably this was due to some misunderstanding on my part about how to set
things up. I've done a lot of serial comm and consider myself pretty
experienced, but I never was able to get the .Net control receiving correctly
until I switched to a totally byte-oriented way of processing the input. The
experience of trying to use this control in text mode was just unexpectedly
frustrating and the results seemed completely non-intuitive. I wish I still had
the exact code and input string that was causing problems, I would post it if so.

The documentation for ReadTo states: "If it is necessary to switch between
reading text and reading binary data from the stream, select a protocol that
carefully defines the boundary between text and binary data, such as manually
reading bytes and decoding the data." Which certainly seems to be the case, but
there is no further explanation offered.

Not to get too far off the track here, I think the OP might also look at and/or
play around with the control's Handshake settings.

-rick-
 
Ad

Advertisements

O

Orhan Albay

Hello,

Are you still having problems with the serial port ? if so, I developed a serial port programming language in C# specially designed to simplify the development of RS232 based applications and it also has a built-in debugger.

It is freely available on sourceforge.

Would you please take a look and try it ? If you have any questions, please feel free to ask.

[Screen shots]
http://www.anyserialport.com/screenshots

[Download]
http://sourceforge.net/projects/anyserialport/

[User Guide]
http://www.anyserialport.com/help

Thank you,

Orhan

Submitted via EggHeadCafe - Software Developer Portal of Choice
Silverlight 3D Animated Topic Selector With Titled Menu Items
http://www.eggheadcafe.com/tutorial...ed-topic-selector-with-titled-menu-items.aspx
 

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

Top