I have some device that i need to make a connection using SerialPort.
This device receiving commands from my side and also sending data to me.
I doing all the send/receive in same class => same thread.
I have been connected to this device and i succeed to send/receive command and data from/to this device.
One of the command that i need to send every 25 milliseconds is 'give me your status' - that mean that i asking the device to send be back some struct with data.
In case i missing some receiving data ... when i doing 'serialPortStream.BytesToRead' ( test if there are some data to get ) will i find on my ByteReading the older buffer that i did not rad yet ?
how many packages i will have there in case i missed the last package that i needed to read or maybe the new data received will delete the old data that alread received before ?
Use an OnRecieveData handler that saves the data to a ConcurrentQueue or something similar.
namespace Test
{ class Program
{
const int bufSize = 2048;
static void Main(string[] args)
{
Byte[] buf = new Byte[bufSize];
SerialPort sp = new SerialPort("COM1", 115200);
sp.DataReceived += port_OnReceiveData; // Add DataReceived Event Handler
sp.Open();
// Wait for data or user input to continue.
Console.ReadLine();
sp.Close();
}
private static void port_OnReceiveData(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort) sender;
switch(e.EventType)
{
case SerialData.Chars:
{
Byte[] buf = new Byte[bufSize];
port.Read(buf, 0, bufSize)
Console.WriteLine("Recieved data! " + buf.ToString());
break;
}
case SerialData.Eof:
{
// means receiving ended
break;
}
}
}
}
}
Related
I am building a console application which will be scheduled in Task Scheduler of Windows to run my code every day at a set hour. Summing up, this application will read and write through SerialPort. When I send something to the Arduino, I need to receive something from it to finish up what I've sent and execute the command.
In other words, I will send something so see if the door is opened, if it is the application will run a code to close it. If the door is already closed I will send a bunch of characters to be displayed into the Arduino Led Display.
So I've developed a code but I am not sure if it's totally correct, if possible help me improve it. There is any changes I could make?
static void Main(string[] args)
{
SerialPort comport = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
comport.Open();
string start = "?";
string carriageReturn = "\r";
string text = string.Empty;
string mensage = "#" + "r" + "\r";
string mensage2 = "#" + "{" + texto + "\r";
try
{
while (true)
{
//Send to the Arduino
comport.Write(start+ "*" + carriageReturn);
//If the serial port have bytes to read
if (comport.BytesToRead > 0)
{
//Buffer with data
byte[] dados = HexStringToByteArray(mensage);
//Handle data
comport.Read(dados, 0, dados.Length);
//Send again to execute the the command
comport.Write(start + "*" + carriageReturn);
}
if (comport.BytesToRead > 0)
{
comport.Write(start + "*" + carriageReturn);
byte[] dados2 = HexStringToByteArray(mensage2);
comport.Read(dados2, 0, dados2.Length);
comport.Write(text);
}
comport.Close();
}
}
catch(Exception ex)
{
}
}
private static byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
EDIT:
My basic input output mapping/relationship is:
I will send ?*\r to the Arduino, then I will wait for a answer.
If the answer from Arduino is #r\r I will send the ?*\r again.
If the answer from the Arduino is #{/r I will send a string to him.
Here is a first attempt of my revision.
You should consider to use the DataReceived event and have an Exit-Strategy. Up to now your program never exits.
static void Main(string[] args)
{
SerialPort port = new SerialPort("COM1", 9600, Parity.Odd, 7, StopBits.One);
// register the event
port.DataReceived += Port_DataReceived;
//open the port
port.Open();
try
{
// start the communication
port.Write("?*\r");
Console.WriteLine("Waiting for response");
// Your manual exit strategy. Hit a kKeyboard-key to end this game
while (!Console.KeyAvailable)
{
}
}
catch (Exception ex)
{
Console.WriteLine("Writing failed! \nError: " + ex.Message);
}
}
The DataReceived event will be fired as soon as the Arduino sends you something. If it doesn't you can just quit your program manually.
Inside the event you can do your entire logic. As you already posted the input-output mapping you can just hack it into solid code as it is written in your post. If it is only 2 cases you could also use a switch/case construct:
private static void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = sender as SerialPort;
// read input
string incoming = port.ReadExisting();
switch (incoming)
{
case "#r\r":
// send the message back
port.Write("?*\r");
break;
case #"#{/r":
port.Write("Display this!");
break;
default:
Console.WriteLine("Unknown command from Arduino!\n Command: " + incoming);
break;
}
}
I hope it helps
If I understand your description properly (closing the door will be done by arduino, right?), this is the task:
A task scheduled console app triggers an arduino via Serial to check a status and execute something (if status tells thats necessary)
Arduino reports back status (and eventually that task was performed)
You could do it very simple:
"?" --> PC sends a trigger: Check door status and behave accordingly
Then PC waits for a response:
"1" <-- Arduino response ( door was already closed )
"2" <-- or alternate response ( I closed the door )
Arduino could send anything else to indicate an error. (feel free to invent as much as adequate)
Additionally, it's possible that arduino does not respond at all. So what would your scheduled console app do then?
You do not need to send/receive more than a byte, to have it simpler for Arduino and your little Serial PC code.
The PC code does not have a user interface, so there's no need for Arduino to respond immediately, if closing the door should take a while.
Hello and thanks for considering this query:
I am sending a command from a PC over a virtual serial port to an embedded system which echos back the command when the embedded system has completed the command.
I can send the command fine and see the echo, when the command is completed by the embedded sytem, but I am having trouble finding a suitable way to wait or delay the program until the echoed command is received, so that I may proceed and send the next command. I suppose its a type of "high level" flow control that I'm trying to implement.
The code is in C#.
I'd like to wait fro the echo and have a timeout as well in case communication is lost between the PC and embedded system, so that the program does not freeze.
Any wizz kids out there that can suggest a neat way to do this?
I am not a great c# programmer, just learning.
This is the receive function that I have:
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// If the com port has been closed, do nothing
if (!comport.IsOpen) return;
// This method will be called when there is data waiting in the port's buffer
// Determain which mode (string or binary) the user is in
if (CurrentDataMode == DataMode.Text)
{
// Read all the data waiting in the buffer
string data = comport.ReadExisting();
// Display the text to the user in the terminal
Log(LogMsgType.Incoming, data);
}
else
{
// Obtain the number of bytes waiting in the port's buffer
int bytes = comport.BytesToRead;
// Create a byte array buffer to hold the incoming data
byte[] buffer = new byte[bytes];
// Read the data from the port and store it in our buffer
comport.Read(buffer, 0, bytes);
// Show the user the incoming data in hex format
Log(LogMsgType.Incoming, ByteArrayToHexString(buffer));
}
}
This is an example of a call to Transmitt a command:
text = "AR" + 50 + "\r"; //transmit a command to move
this.comport.Write(text);
Currently I'm using a time Delay [Thread.Sleep(TIMEGAP)] and assuming that the message is executed and that the echo back from the embedded system is fine BUT I do not check it and also wait a very long time to ensure that it is completed:
text = "AR" + 50 + "\r"; //transmit a command to move
this.comport.Write(text);
Thread.Sleep(TIMEGAP); //Timegap = 10000ms
I really would like to replace the time delay call [Thread.Sleep(TIMEGAP)] with a function/method that monitors the response on the serial port, checks to see that it is the same as the one sent and then allows the program code to proceed to the next command, AND if the correct echo [AR50\r in the above example] is not received in say for example 5 seconds, then the program reports an error.
Any suggestions?
Thank you!
The easiest way is not to use the DataReceived event, but by setting a ReadTimeout and using the Read method.
And since you're dealing with ASCII, you should check out the ReadLine method.
Both will throw a TimeoutException if ReadTimeout has elapsed without incoming data.
If, however, the embedded system can send unsolicited messages, the you'll need an other approach. Then you could put the echo you're expecting in a global string variable, and have the receive event set a ManualResetEvent when the echo has been received. Then you can wait for the ManualResetEvent with a timeout. This will also involve thread synchronization using the lock statement.
If GC is not an issue, I would probably start with something like this:
using System.Text;
using System.IO.Ports;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static string serialBuffer = "";
static string expectedEcho = null;
static object expectedEchoLock = new object();
static ManualResetEvent expectedEchoReceived = new ManualResetEvent(false);
static SerialPort port = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One);
static void Main(string[] args)
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (port.BytesToRead > 0)
{
byte[] buffer = new byte[port.BytesToRead];
int bytesRead = port.Read(buffer, 0, buffer.Length);
if (bytesRead <= 0) return;
serialBuffer += Encoding.UTF8.GetString(buffer, 0, bytesRead);
string[] lines = serialBuffer.Split('\r', '\n');
// Don't process the last part, because it's not terminated yet
for (int i = 0; i < (lines.Length - 1); i++)
{
if (lines[i].Length > 0)
ProcessLine(lines[i]);
}
serialBuffer = lines[lines.Length - 1]; // keep last part
}
}
static void ProcessLine(string line)
{
bool unsolicitedMessageReceived = false;
lock (expectedEchoLock)
{
if (line == expectedEcho)
{
expectedEchoReceived.Set();
}
else
{
unsolicitedMessageReceived = true;
}
}
if (unsolicitedMessageReceived)
{
// Process unsolicited/unexpected messages
}
}
/// <summary>
/// Send a command and wait for echo
/// </summary>
/// <param name="command">The command to send</param>
/// <returns>True when echo has been received, false on timeout.</returns>
static bool SendCommand(string command)
{
lock (expectedEchoLock)
{
expectedEchoReceived.Reset();
expectedEcho = command;
}
port.Write(command);
return expectedEchoReceived.WaitOne(5000); // timeout after 5 seconds
}
}
}
I am trying to read data from an RS-232 port. Does anyone have an example of how I get the data from the port/buffer and make sure that I have all the data as it can be multiline data.
Do I simply read it as follows ?
string Rxstring = port.ReadLine();
Console.WriteLine(Rxstring);
Q: how to get the date from the port/buffer, or input data from your connected device. AND make sure that you have all the data.
A: i have worked extensively with .net serial port class drivers where i was tasked to create reliable, robust code. this means that a connected device under test has to run and NOT fail over a LONG period of time. Serial port can AND does lose data! don't forget that.
//from top of the head;
using System.Port.IO;
using System.Port;
private class mywindowsForm: Form
{
StringBuilder sbReceived = new StringBuilder();
string Received = string.Empty;
int byteCOUNT = 0;
System.Windows.Timers.Timer serialTimer;
//Default constructor
myWindowsForm()
{
//assume that you clicked and dragged serial port in
serialPort1 = new SerialPort();//create new serial port instance
serialPort1.Baud = 9600;
serialPort1.DataReceived+=<Tab><Enter>
//serial port timer
serialTimer = new System.Windows.Timers.Timer(500);//set to 500ms time delay
serialTimer.Elapsed+=<TAB><ENTER>
}
void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//serial port has detected input data
//however, we only want to get serial data so,
if(e.EventType !=SerialData.Chars) return;
//good design practice dictates that we have an event handler that we invoke
this.BeginInvoke(new eventhandler(AddReceive));//beginInvoke is designed to deal with asynchronous processes like serial port data.
}
private void AddReceive(object s, EventArg e)
{
byteCOUNT=serialPort1.BytesToRead;//count the number of bytes in RX buffer
if(byteCOUNT > 0)
{
string ST = serialPort1.ReadTo("\n");//lets get one line at a time
sbReceived.Append(ST);//add whatever has been RX'd to our container.
serialPort1.Interval =100;
serialPort1.Start();//to be sure we have all data, check to see for stragglers.
}
}
void serialTimer(object Sender, TimerElapsedEventArgs e)
{
serialTimer.Stop();
this.BeginInvoke(new EventHandler(ReadData));
}
void ReadData(object Sender, EventArgs e)
{
//parse output for required data and output to terminal display (build one using rich text box)
Received = sbReceived.ToString();
//and if we have ANY MORE incoming data left over in serial buffer
if(Received.Length > 0)
{
//your data
}
}
}
this should be plenty to get you started. this is result of years of creating customized terminal emulators in c#. there are other things that can be done, particularly if you have large amount of i/o data you need to set up handshaking with device. you have to let the device handle at a rate that the device is happy with. in cases where larger data has to be transferred consider setting up a simple packet passing protocol and command semaphore construct - or use a protocol as defined that the controller / device is designed to work with.
Try this:
using System.IO.Ports;
...
private SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
Console.WriteLine(port.ReadExisting());
Details can be found at Coad's Code.
Let's say I want to have a function which reads data from the SerialPort
and returns a byte[].
public byte[] RequestData(byte[] data)
{
//See code below
}
Something as simple as this really doesn't work/perform well and isn't very reliable:
byte[] response = new byte[port.ReadBufferSize];
port.Open();
port.Write(data, 0, data.Length);
Thread.Sleep(300); //Without this it doesn't even work at all
Console.WriteLine("Bytes to read: {0}", port.BytesToRead);
int count = port.Read(response, 0, port.ReadBufferSize);
Console.WriteLine("Read {0} bytes", count);
port.Close();
port.Dispose();
return response.GetSubByteArray(0, count);
I also tried replacing the Thread.Sleep with something like:
while (port.BytesToRead < 14)
{
//Maybe Thread.Sleep(10) here?
}
But that causes problems to. (PS: I know I need at least 14 bytes)
Of course a better way (I think) would be to have something like:
port.ReceivedBytesThreshold = 14;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
port.Write(data, 0, data.Length);
And then having a handler of course:
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
while (port.BytesToRead > 0)
{
//Read the data here
}
}
But then I can't return the data as the result of the function I wanted to define?
The client code using this would have to subscribe to an event raised by this code,
but then how would it know the response is really the response to the request it just made.
(Multiple messages might be sent, and I can imagine one message taking longer to process on the other side than the other, or something).
Any advise would be welcome
UPDATE
The following code works a lot better, but if I remove the Thread.Sleep() statements it once again stops working properly. For example, the serial port monitoring tool clearly indicates 17 bytes have been written on the serial line. The first time BytesToRead = 10 and the next time BytesToRead = 4 , but then BytesToRead remains 0 so where did the last 3 bytes go to ?
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
while (port.BytesToRead > 0)
{
Console.WriteLine("Bytes to read: {0}", port.BytesToRead);
var count = port.BytesToRead;
byte[] buffer = new byte[count];
var read = port.Read(buffer, 0, count);
if (count != read)
Console.WriteLine("Count <> Read : {0} {1}", count, read);
var collectAction = new Action(() =>
{
var response = dataCollector.Collect(buffer);
if (response != null)
{
this.OnDataReceived(response);
}
});
collectAction.BeginInvoke(null, null);
Thread.Sleep(100);
}
}
Here's how I've done it:
I have a wrapper for the class that accepts the vital data for the connection in the constructor and does the basic setup in that constructor. The consumer of the class calls a Connect method, which fires off another thread to perform the connection (non-blocking).
When the connection is complete, a StateEvent is fired indicating the connection is completed. At this time a Send queue is setup, a thread to work that queue is fired off and a read thread is also setup. The read thread reads 128 characters of data from the SerialPort, converts that to a string and then fires an event to pass along the received data. This is wrapped in a while thread that loops as long as the connection is maintained. When the consumer wants to send something, a Send method simply enqueues the data to be sent.
As far as knowing that the response is in response to something that was sent really isn't the job of a connection class. By abstracting away the connection into something as easy to handle as that, the consumer of the class can cleanly maintain the logic to determine if the response is what it expected.
Aren't serial ports fun. My only thought is that your fifo, assuming your device has one and its enabled, is being overrun.
Problem solved:
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var count = port.BytesToRead;
byte[] buffer = new byte[count];
var read = port.Read(buffer, 0, count);
var response = dataCollector.Collect(buffer);
if (response != null)
{
this.OnDataReceived(response);
}
}
It seems the problem wasn't actually this code but the code in the dataCollector.Collect() method.
I am attempting to create a small application to collect data received from an external sensor attached to COM10. I have successfully created a small C# console object and application that opens the port and streams data to a file for a fixed period of time using a for-loop.
I would like to convert this application to use the dataReceived event to stream instead. After reading the Top 5 SerialPort Tips, I still can't seem to get this to work and don't know what I am missing. I rewrote the console application so that all the code is in Main and is pasted below. Can someone please help enlighten me as to why the event handler port_OnReceiveDatazz is not being called even though I know that there is data being sent to the port by the hardware?
Thanks
Thanks to #Gabe, #Jason Down, and #abatishchev for all the suggestions. I am stumped and can't seem to get the event handler to work. Perhaps it has something to do with the device. I can live with just reading the port in a thread and streaming the data straight to file.
Code
namespace serialPortCollection
{ class Program
{
static void Main(string[] args)
{
const int bufSize = 2048;
Byte[] buf = new Byte[bufSize]; //To store the received data.
SerialPort sp = new SerialPort("COM10", 115200);
sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
sp.Open();
sp.WriteLine("$"); //Command to start Data Stream
// Wait for data or user input to continue.
Console.ReadLine();
sp.WriteLine("!"); //Stop Data Stream Command
sp.Close();
}
// My Event Handler Method
private static void port_OnReceiveDatazz(object sender,
SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort) sender;
const int bufSize = 12;
Byte[] buf = new Byte[bufSize];
Console.WriteLine("DATA RECEIVED!");
Console.WriteLine(spL.Read(buf, 0, bufSize));
}
}
}
I think your issue is the line:**
sp.DataReceived += port_OnReceiveDatazz;
Shouldn't it be:
sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
**Nevermind, the syntax is fine (didn't realize the shortcut at the time I originally answered this question).
I've also seen suggestions that you should turn the following options on for your serial port:
sp.DtrEnable = true; // Data-terminal-ready
sp.RtsEnable = true; // Request-to-send
You may also have to set the handshake to RequestToSend (via the handshake enumeration).
UPDATE:
Found a suggestion that says you should open your port first, then assign the event handler. Maybe it's a bug?
So instead of this:
sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
sp.Open();
Do this:
sp.Open();
sp.DataReceived += new SerialDataReceivedEventHandler (port_OnReceiveDatazz);
Let me know how that goes.
First off I recommend you use the following constructor instead of the one you currently use:
new SerialPort("COM10", 115200, Parity.None, 8, StopBits.One);
Next, you really should remove this code:
// Wait 10 Seconds for data...
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(10);
Console.WriteLine(sp.Read(buf,0,bufSize)); //prints data directly to the Console
}
And instead just loop until the user presses a key or something, like so:
namespace serialPortCollection
{ class Program
{
static void Main(string[] args)
{
SerialPort sp = new SerialPort("COM10", 115200);
sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
sp.Open();
sp.WriteLine("$"); //Command to start Data Stream
Console.ReadLine();
sp.WriteLine("!"); //Stop Data Stream Command
sp.Close();
}
// My Event Handler Method
private static void port_OnReceiveDatazz(object sender,
SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort) sender;
byte[] buf = new byte[spL.BytesToRead];
Console.WriteLine("DATA RECEIVED!");
spL.Read(buf, 0, buf.Length);
foreach (Byte b in buf)
{
Console.Write(b.ToString());
}
Console.WriteLine();
}
}
}
Also, note the revisions to the data received event handler, it should actually print the buffer now.
UPDATE 1
I just ran the following code successfully on my machine (using a null modem cable between COM33 and COM34)
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
Thread writeThread = new Thread(new ThreadStart(WriteThread));
SerialPort sp = new SerialPort("COM33", 115200, Parity.None, 8, StopBits.One);
sp.DataReceived += port_OnReceiveDatazz; // Add DataReceived Event Handler
sp.Open();
sp.WriteLine("$"); //Command to start Data Stream
writeThread.Start();
Console.ReadLine();
sp.WriteLine("!"); //Stop Data Stream Command
sp.Close();
}
private static void port_OnReceiveDatazz(object sender,
SerialDataReceivedEventArgs e)
{
SerialPort spL = (SerialPort) sender;
byte[] buf = new byte[spL.BytesToRead];
Console.WriteLine("DATA RECEIVED!");
spL.Read(buf, 0, buf.Length);
foreach (Byte b in buf)
{
Console.Write(b.ToString() + " ");
}
Console.WriteLine();
}
private static void WriteThread()
{
SerialPort sp2 = new SerialPort("COM34", 115200, Parity.None, 8, StopBits.One);
sp2.Open();
byte[] buf = new byte[100];
for (byte i = 0; i < 100; i++)
{
buf[i] = i;
}
sp2.Write(buf, 0, buf.Length);
sp2.Close();
}
}
}
UPDATE 2
Given all of the traffic on this question recently. I'm beginning to suspect that either your serial port is not configured properly, or that the device is not responding.
I highly recommend you attempt to communicate with the device using some other means (I use hyperterminal frequently). You can then play around with all of these settings (bitrate, parity, data bits, stop bits, flow control) until you find the set that works. The documentation for the device should also specify these settings. Once I figured those out, I would make sure my .NET SerialPort is configured properly to use those settings.
Some tips on configuring the serial port:
Note that when I said you should use the following constructor, I meant that use that function, not necessarily those parameters! You should fill in the parameters for your device, the settings below are common, but may be different for your device.
new SerialPort("COM10", 115200, Parity.None, 8, StopBits.One);
It is also important that you setup the .NET SerialPort to use the same flow control as your device (as other people have stated earlier). You can find more info here:
http://www.lammertbies.nl/comm/info/RS-232_flow_control.html
By the way, you can use next code in you event handler:
switch(e.EventType)
{
case SerialData.Chars:
{
// means you receives something
break;
}
case SerialData.Eof:
{
// means receiving ended
break;
}
}
I was having the very same problem with a modem that had previously worked and then one day just stopped raising the DataReceived event.
The solution in my case, very randomly, was to enable RTS e.g.
sp.RtsEnable = true;
No idea why that worked on this particular bit of kit (not a comms man at all really), nor why it had worked and then stopped but it may help somebody else one day so just posting it just in case...
Might very well be the Console.ReadLine blocking your callback's Console.Writeline, in fact. The sample on MSDN looks ALMOST identical, except they use ReadKey (which doesn't lock the console).
I believe this won't work because you are using a console application and there is no Event Loop running. An Event Loop / Message Pump used for event handling is setup automatically when a Winforms application is created, but not for a console app.
Be aware that there are problems using .NET/C# and any COM port higher than COM9.
See: HOWTO: Specify Serial Ports Larger than COM9
There is a workaround in the format: "\\.\COM10" that is supported in the underlying CreateFile method, but .NET prevents using that workaround format; neither the SerialPort constructor nor the PortName property will allow a port name that begins with "\"
I've been struggling to get reliable communications to COM10 in C#/.NET. As an example, if I have a device on COM9 and COM10, traffic intended for COM10 goes to the device on COM9! If I remove the device on COM9, COM10 traffic goes to the device on COM10.
I still haven't figured how to use the handle returned by CreateFile to create a C#/.NET style SerialPort object, if I knew how to do that, then I think I could use COM10+ just fine from C#.
switch(e.EventType)
{
case SerilData.Chrs:
{
// means you receives something
break;
}
case SerialData.Eo:
{
// means reciving ended
break;
}
}
First of all change your line to:
sp.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);
Second, be aware that DataReceived is fired every time a byte arrives - so the data you read is likely to be a single character each time, and "buffer" will never hold an entire message if you overwrite it every time you handle the event.