private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
comport.ReadTimeout = 300;
String s = comport.ReadExisting();
using (StreamWriter sw = new StreamWriter(@"C:\test.txt",true))
{
sw.Write(DateTime.Now.ToShortTimeString() +" "+ s);
sw.Flush();
sw.Close();
}
}
The above method is used to write data from the SerialPort to a text file. Below is the result I get in the test.txt:
4:22 PM 1
4:22 PM 2
3
4
5
6
4:22 PM 7
4:22 PM 8
4:22 PM 9
a
4:22 PM b
4:22 PM c
4:22 PM d
4:22 PM e
4:22 PM f
Why for "3,4,5,6" there are no time ahead
I was lost and could no find the reason....
anyone can help me

why the format is not uniform
stlinarus
mabrouk,
1) the serial port driver does not add anything to the data. When I said that the newline probably came from the serial port I meant that the newline was transmitted from the originator of the data. I should also add that I don't know if it was a simple \n or a \r\n (I don't think a single \r would be recognized, but I'm not sure about that). Both sequences are quite common, even though \n is sometimes preferred as it saves the transmission of one byte.
2) No, the \n is not added by the reading operation, regardless of how you read the data. The only thing that may happen during a receive operation, if you ask for a string, is that the encoder specified for the stream converts the received bytes. By default the SerialPort uses the ASCII encoding. This is not good if you expect to receive characters with a value > 127.
3) No. The ReadLine method reads up to the newline, included, then strips the newline from the returned string.
4) Again: no. The newline is never added from the receiving functions.
5) It depends. My personal approach is to read data as they are available, and append them to my own buffer. I can then inspect the buffer to see if there is a complete set of data (this can be done by searching for a terminator, or some other condition) and if so extract the value from the buffer (or raise some event). I usually do this to avoid blocking operations, but there are several good alternatives.
6) Yes. Assuming you have a string:
string line = "1,32,554,12,93232,0";
you could simply write:
foreach (string token in line.Split (',')) {
int i = int.Parse (token);
Console.WriteLine ("Found numer: {0}", i);
}
HTH
--mc
Tomik
Thanks
with your code, the result is like:
5:05 PM 1
2
3
4
5
6
5:05 PM 7
8
9
a
b
c
d
5:05 PM e
5:05 PM f
5:05 PM 10
5:05 PM 11
5:05 PM 12
13
5:05 PM 14
15
16
Well, I do not know what is the usage of Debug.WriteLine(log); how to write the string to log file For output window, you mean I should use console.output
It seems with writeline(), there will be a new line if the format is OK...however, why there will be data without time ahead...It seems "2,3,4,5,6" are just one data...
Is it related to the format of the data from the SerialPort OH....
b6s
Thanks Cossi,
It seems the incoming speed is too fast...
Your code gives out:
5:35 PM <<<1
>>>
5:35 PM <<<2
3
>>>
5:35 PM <<<4
>>>
5:35 PM <<<5
>>>
5:35 PM <<<6
>>>
5:35 PM <<<7
>>>
5:35 PM <<<8
>>>
5:35 PM <<<9
a
b
c
d
>>>
So, what should I do How to split up the string I should first split the incoming string to "1", "2", "3"... and then write each one with time to the file
Is there any method to receive only one character at one time since that "s" will have only one element...
I am afraid I will lose some data
Or maybe modify the speed of the SerialPort...
Mark Dahl
Mario;
regarding your comments " I presume the newline comes from the serial port so that your input is probably something like: "1\n2\n3\n..." " I have some questions
1- does the serial port driver put "\n" after each character transmitted in this case mentioned why would the driver insert \n because the code using char [] as the receiving entity, is that something .net do, similar to C
2- however if he used string as the receiving entity, the \n would be inserted after the string
3- in case if the receivin entity is a readLn, then the line when read will have \n or .net put something (EOL) symbol for realLn
4- if the data coming as a set of numbers separated by commas with \n\r as the marker (as traditionally done) for the parser to to know it is end of line received. then does realLn would add \n
5- what is correct .net behavior and what would be the proper practice for receiving data stream to parse into a set of integers numbers C practices for receiving data is not similar to C# syntax
6- comma separated set of numbers can parsed to short strings then to int value to represent the number what is the proper syntax for this operation.
thanks for your information
koosha
Maybe there is other place where you touch C:\test.txt. Just for test make some debuging. Create a string variable and fill it with log that you're putting in log file. Then write it to output window and also to file.
string log = DateTime.Now.ToShortTimeString() + "\t" + s;
Debug.WriteLine(log);
sw.WriteLine(log)
Check to see what it's logged in Output window.
By the way you don't have to do any cleanup for sw. It is automaticaly done by using structure.
digitalslavery
Thanks a lot Mario Cossi!!
It works OK now with your suggestion!
string[] parts = s.Split(new string[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string part in parts)
{
sw.WriteLine("{0}\t{1}", DateTime.Now.ToLongTimeString(), part);
}
I did not use the new char[] since there will be errors shown when build, to use new string[], the result I received is just what I want!
10:14:14 AM 1
10:14:14 AM 2
10:14:14 AM 3
10:14:14 AM 4
10:14:14 AM 5
10:14:14 AM 6
10:14:14 AM 7
10:14:14 AM 8
10:14:14 AM 9
10:14:14 AM a
10:14:14 AM b
10:14:14 AM c
10:14:14 AM d
10:14:14 AM e
10:14:14 AM f
10:14:14 AM 10
10:14:14 AM 11
10:14:14 AM 12
10:14:14 AM 13
10:14:14 AM 14
10:14:14 AM 15
cverdon
mario;
thank you, much, for your answers.
the issue of threads:
1- i am interested in serial comm with WPF on winXP.
i am reading in the serialPort class Doc .net 2.0,
wpf requires [SAThread]. and serial port class requires a separate thread.
invoke is used to carry the serialEvent... notice through a delegate to a function contains Invoke.
most of the comments I read is for .net 2.0 (WPF is .net 3.0 application model).
I am assuming that Invoke does not the creation of a thread to be used is that correct
does the same apply to WPF, by using Invoke and not using threads
2- the DOc example use thread, is that applicable now to WPF
-----------------------------------------------
the chatting sample in DOC show this line:
Thread readThread = new Thread (read);
_serialPort.Open();
_continue = true;
readThread.Start();
........then the read and write functions calls:
_serialPort.WriteLine( string.Format( .......));
string message = _serialPort.RealLine();
........ then, if will quit:
readThread.Join();
_serialPort.Close();
----------------------------------------------------------
3- it is not clear to me the use of Invoke without the use of threads,
if the serialPort class to fucntion needs separate threads from the winForm or WPF
cyprix
mario;
another question in one of your comments:
port.Write (i.ToString ());
to transfer a number to write to port.
1- want to construct a set of number to a set of series of numbers comma delimited: 23,4574,0,7862\n
each is int within an array. the problem of bytes conversion it seems as you described before.
can we use ConvertAll to convert the array to bytes, then it will be similar to the described problem
I need to have my data in an array of integers before I send and and after I receive. I see there are many ways to do that and really the serialPort requires specific way to be correct and that is my question.
what is the proper way to convert the array of integers similar to the above comments (i.ToString());
to be proper string of bytes for transmission with comma delimited and \n using single command for each cell of the array and add the comma and \n within the loop or we can use ConvertAll can be used then send each cell oa the array to por.Write and add delimiter and \n within the loop
thank for your comments
Deeps_123
Pockey,
I'll have to guess... You don't seem to be adding a newline when you write your data to the file, so I presume the newline comes from the serial port so that your input is probably something like: "1\n2\n3\n..." somehow spaced in time.
If your input is very fast, you might not be fast enough to catch every individual character coming from the serial port. If so, maybe the second time around you found yourself with "2\n3\n4\n5\n6\n" in the buffer. ReadExisting would have read up everything, and printed that out exactly as you show it.
To verify if this is the case, change your code slightly so that you can distinguish individual events. For instance try:
sw.WriteLine (string.Format ("{0}\t<<<{1}>>>", DateTime.Now.ToShortTimeString (), s);
You will see the <<< and >>> marking the beginning and the end of the received string.
If it turned out that your input is indeed too fast, you might have to split up the received string so that you emit the file correctly.
HTH
--mc
Duane Douglas
Pockey,
you shouldn't lose any data. The problem I was mentioning before is just that by the time you get to serve your event, more characters can be received... it only takes about 1ms per character at 9600 baud and you can have delays of several milliseconds, but not enough late to overflow your buffer.
Now, if s is the string where you store the data you received:
string [] parts = s.Split (new char [] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
foreach (string part in parts) {
Console.WriteLine ("{0}\t{1}", DateTime.Now.ToShortTimeString (), part);
}
Warning: this will work ONLY if you are absolutely sure that your data are composed of single characters: if not you could receive "10" as "1" and "0", which is probably not what you want. In this case, I would recommend using ReadLine() with a timeout instead.
HTH
--mc